| Index: ui/gfx/render_text.cc
|
| ===================================================================
|
| --- ui/gfx/render_text.cc (revision 97884)
|
| +++ ui/gfx/render_text.cc (working copy)
|
| @@ -162,6 +162,10 @@
|
| CheckStyleRanges(style_ranges_, text_.length());
|
| #endif
|
| cached_bounds_and_offset_valid_ = false;
|
| +
|
| + // Reset selection model. SetText should always followed by SetSelectionModel
|
| + // or SetCursorPosition in upper layer.
|
| + SetSelectionModel(SelectionModel(0, 0, SelectionModel::LEADING));
|
| }
|
|
|
| void RenderText::SetSelectionModel(const SelectionModel& sel) {
|
| @@ -184,13 +188,8 @@
|
| return selection_model_.selection_end();
|
| }
|
|
|
| -void RenderText::SetCursorPosition(const size_t position) {
|
| - SelectionModel sel(selection_model());
|
| - sel.set_selection_start(position);
|
| - sel.set_selection_end(position);
|
| - sel.set_caret_pos(GetIndexOfPreviousGrapheme(position));
|
| - sel.set_caret_placement(SelectionModel::TRAILING);
|
| - SetSelectionModel(sel);
|
| +void RenderText::SetCursorPosition(size_t position) {
|
| + MoveCursorTo(position, false);
|
| }
|
|
|
| void RenderText::MoveCursorLeft(BreakType break_type, bool select) {
|
| @@ -199,8 +198,7 @@
|
| // Cancelling a selection moves to the edge of the selection.
|
| if (break_type != LINE_BREAK && !EmptySelection() && !select) {
|
| // Use the selection start if it is left of the selection end.
|
| - SelectionModel selection_start(GetSelectionStart(), GetSelectionStart(),
|
| - SelectionModel::LEADING);
|
| + SelectionModel selection_start = GetSelectionModelForSelectionStart();
|
| if (GetCursorBounds(selection_start, false).x() <
|
| GetCursorBounds(position, false).x())
|
| position = selection_start;
|
| @@ -221,8 +219,7 @@
|
| // Cancelling a selection moves to the edge of the selection.
|
| if (break_type != LINE_BREAK && !EmptySelection() && !select) {
|
| // Use the selection start if it is right of the selection end.
|
| - SelectionModel selection_start(GetSelectionStart(), GetSelectionStart(),
|
| - SelectionModel::LEADING);
|
| + SelectionModel selection_start = GetSelectionModelForSelectionStart();
|
| if (GetCursorBounds(selection_start, false).x() >
|
| GetCursorBounds(position, false).x())
|
| position = selection_start;
|
| @@ -308,12 +305,8 @@
|
| break;
|
| }
|
|
|
| - SelectionModel sel(selection_model());
|
| - sel.set_selection_start(selection_start);
|
| - sel.set_selection_end(cursor_position);
|
| - sel.set_caret_pos(GetIndexOfPreviousGrapheme(cursor_position));
|
| - sel.set_caret_placement(SelectionModel::TRAILING);
|
| - SetSelectionModel(sel);
|
| + MoveCursorTo(selection_start, false);
|
| + MoveCursorTo(cursor_position, true);
|
| }
|
|
|
| const ui::Range& RenderText::GetCompositionRange() const {
|
| @@ -349,9 +342,9 @@
|
| cached_bounds_and_offset_valid_ = false;
|
| }
|
|
|
| -base::i18n::TextDirection RenderText::GetTextDirection() const {
|
| - // TODO(msw): Bidi implementation, intended to replace the functionality added
|
| - // in crrev.com/91881 (discussed in codereview.chromium.org/7324011).
|
| +base::i18n::TextDirection RenderText::GetTextDirection() {
|
| + if (base::i18n::IsRTL())
|
| + return base::i18n::RIGHT_TO_LEFT;
|
| return base::i18n::LEFT_TO_RIGHT;
|
| }
|
|
|
| @@ -426,7 +419,7 @@
|
| if (x >= right) return SelectionModel(right_pos);
|
| // binary searching the cursor position.
|
| // TODO(oshima): use the center of character instead of edge.
|
| - // Binary search may not work for language like arabic.
|
| + // Binary search may not work for language like Arabic.
|
| while (std::abs(static_cast<long>(right_pos - left_pos)) > 1) {
|
| int pivot_pos = left_pos + (right_pos - left_pos) / 2;
|
| int pivot = font.GetStringWidth(text().substr(0, pivot_pos));
|
| @@ -497,7 +490,7 @@
|
| if (break_type == CHARACTER_BREAK)
|
| return SelectionModel(pos, pos, SelectionModel::LEADING);
|
|
|
| - // Notes: We always iterate words from the begining.
|
| + // Notes: We always iterate words from the beginning.
|
| // This is probably fast enough for our usage, but we may
|
| // want to modify WordIterator so that it can start from the
|
| // middle of string and advance backwards.
|
| @@ -529,6 +522,8 @@
|
|
|
| SelectionModel RenderText::GetRightSelectionModel(const SelectionModel& current,
|
| BreakType break_type) {
|
| + if (text_.empty())
|
| + return SelectionModel(0, 0, SelectionModel::LEADING);
|
| if (break_type == LINE_BREAK)
|
| return SelectionModel(text().length(),
|
| GetIndexOfPreviousGrapheme(text().length()), SelectionModel::TRAILING);
|
| @@ -576,6 +571,31 @@
|
| }
|
| }
|
|
|
| +Point RenderText::ToTextPoint(const Point& point) {
|
| + Point p(point.Subtract(display_rect_.origin()));
|
| + p = p.Subtract(GetUpdatedDisplayOffset());
|
| + if (base::i18n::IsRTL())
|
| + p.Offset(GetStringWidth() - display_rect_.width() + 1, 0);
|
| + return p;
|
| +}
|
| +
|
| +Point RenderText::ToViewPoint(const Point& point) {
|
| + Point p(point.Add(display_rect_.origin()));
|
| + p = p.Add(GetUpdatedDisplayOffset());
|
| + if (base::i18n::IsRTL())
|
| + p.Offset(display_rect_.width() - GetStringWidth() - 1, 0);
|
| + return p;
|
| +}
|
| +
|
| +void RenderText::MoveCursorTo(size_t position, bool select) {
|
| + size_t caret_pos = GetIndexOfPreviousGrapheme(position);
|
| + SelectionModel::CaretPlacement placement = (caret_pos == position) ?
|
| + SelectionModel::LEADING : SelectionModel::TRAILING;
|
| + size_t selection_start = select ? GetSelectionStart() : position;
|
| + SelectionModel sel(selection_start, position, caret_pos, placement);
|
| + SetSelectionModel(sel);
|
| +}
|
| +
|
| bool RenderText::IsPositionAtWordSelectionBoundary(size_t pos) {
|
| return pos == 0 || (u_isalnum(text()[pos - 1]) && !u_isalnum(text()[pos])) ||
|
| (!u_isalnum(text()[pos - 1]) && u_isalnum(text()[pos]));
|
| @@ -598,9 +618,16 @@
|
| // Show all text whenever the text fits to the size.
|
| delta_offset = -display_offset_.x();
|
| } else if (cursor_bounds_.right() > display_rect_.right()) {
|
| + // TODO(xji): when the character overflow is a RTL character, currently, if
|
| + // we pan cursor at the rightmost position, the entered RTL character is not
|
| + // displayed. Should pan cursor to show the last logical characters.
|
| + //
|
| // Pan to show the cursor when it overflows to the right,
|
| delta_offset = display_rect_.right() - cursor_bounds_.right();
|
| } else if (cursor_bounds_.x() < display_rect_.x()) {
|
| + // TODO(xji): have similar problem as above when overflow character is a
|
| + // LTR character.
|
| + //
|
| // Pan to show the cursor when it overflows to the left.
|
| delta_offset = display_rect_.x() - cursor_bounds_.x();
|
| }
|
| @@ -608,4 +635,18 @@
|
| cursor_bounds_.Offset(delta_offset, 0);
|
| }
|
|
|
| +SelectionModel RenderText::GetSelectionModelForSelectionStart() {
|
| + size_t selection_start = GetSelectionStart();
|
| + size_t selection_end = GetCursorPosition();
|
| + if (selection_start < selection_end)
|
| + return SelectionModel(selection_start,
|
| + selection_start,
|
| + SelectionModel::LEADING);
|
| + else if (selection_start > selection_end)
|
| + return SelectionModel(selection_start,
|
| + GetIndexOfPreviousGrapheme(selection_start),
|
| + SelectionModel::TRAILING);
|
| + return selection_model_;
|
| +}
|
| +
|
| } // namespace gfx
|
|
|