| Index: ui/gfx/render_text.cc
|
| diff --git a/ui/gfx/render_text.cc b/ui/gfx/render_text.cc
|
| index 9a72d9a2076700c124b7e4ad43fb561268eebaf2..fce00b589bde6b241fb900d7c6efe8b58e815043 100644
|
| --- a/ui/gfx/render_text.cc
|
| +++ b/ui/gfx/render_text.cc
|
| @@ -182,64 +182,52 @@ 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::MoveCursorLeft(BreakType break_type, bool select) {
|
| - if (break_type == LINE_BREAK) {
|
| - SelectionModel selection(GetSelectionStart(), 0,
|
| - 0, SelectionModel::LEADING);
|
| - if (!select)
|
| - selection.set_selection_start(selection.selection_end());
|
| - MoveCursorTo(selection);
|
| - return;
|
| - }
|
| - SelectionModel position = selection_model_;
|
| + SelectionModel position(selection_model());
|
| + position.set_selection_start(GetCursorPosition());
|
| // Cancelling a selection moves to the edge of the selection.
|
| - if (!EmptySelection() && !select) {
|
| + if (break_type != LINE_BREAK && !EmptySelection() && !select) {
|
| // Use the selection start if it is left of the selection end.
|
| SelectionModel selection_start(GetSelectionStart(), GetSelectionStart(),
|
| - GetSelectionStart(), SelectionModel::LEADING);
|
| + SelectionModel::LEADING);
|
| if (GetCursorBounds(selection_start, false).x() <
|
| GetCursorBounds(position, false).x())
|
| position = selection_start;
|
| - // If |move_by_word|, use the nearest word boundary left of the selection.
|
| + // For word breaks, use the nearest word boundary left of the selection.
|
| if (break_type == WORD_BREAK)
|
| - position = GetLeftCursorPosition(position, true);
|
| + position = GetLeftSelectionModel(position, break_type);
|
| } else {
|
| - position = GetLeftCursorPosition(position, break_type == WORD_BREAK);
|
| + position = GetLeftSelectionModel(position, break_type);
|
| }
|
| - if (!select)
|
| - position.set_selection_start(position.selection_end());
|
| + if (select)
|
| + position.set_selection_start(GetSelectionStart());
|
| MoveCursorTo(position);
|
| }
|
|
|
| void RenderText::MoveCursorRight(BreakType break_type, bool select) {
|
| - if (break_type == LINE_BREAK) {
|
| - SelectionModel selection(GetSelectionStart(), text().length(),
|
| - text().length(), SelectionModel::PREVIOUS_GRAPHEME_TRAILING);
|
| - if (!select)
|
| - selection.set_selection_start(selection.selection_end());
|
| - MoveCursorTo(selection);
|
| - return;
|
| - }
|
| - SelectionModel position = selection_model_;
|
| + SelectionModel position(selection_model());
|
| + position.set_selection_start(GetCursorPosition());
|
| // Cancelling a selection moves to the edge of the selection.
|
| - if (!EmptySelection() && !select) {
|
| + if (break_type != LINE_BREAK && !EmptySelection() && !select) {
|
| // Use the selection start if it is right of the selection end.
|
| SelectionModel selection_start(GetSelectionStart(), GetSelectionStart(),
|
| - GetSelectionStart(), SelectionModel::LEADING);
|
| + SelectionModel::LEADING);
|
| if (GetCursorBounds(selection_start, false).x() >
|
| GetCursorBounds(position, false).x())
|
| position = selection_start;
|
| - // If |move_by_word|, use the nearest word boundary right of the selection.
|
| + // For word breaks, use the nearest word boundary right of the selection.
|
| if (break_type == WORD_BREAK)
|
| - position = GetRightCursorPosition(position, true);
|
| + position = GetRightSelectionModel(position, break_type);
|
| } else {
|
| - position = GetRightCursorPosition(position, break_type == WORD_BREAK);
|
| + position = GetRightSelectionModel(position, break_type);
|
| }
|
| - if (!select)
|
| - position.set_selection_start(position.selection_end());
|
| + if (select)
|
| + position.set_selection_start(GetSelectionStart());
|
| MoveCursorTo(position);
|
| }
|
|
|
| @@ -253,8 +241,6 @@ bool RenderText::MoveCursorTo(const Point& point, bool select) {
|
| SelectionModel selection = FindCursorPosition(point);
|
| if (select)
|
| selection.set_selection_start(GetSelectionStart());
|
| - else
|
| - selection.set_selection_start(selection.selection_end());
|
| return MoveCursorTo(selection);
|
| }
|
|
|
| @@ -267,7 +253,9 @@ bool RenderText::IsPointInSelection(const Point& point) {
|
| }
|
|
|
| void RenderText::ClearSelection() {
|
| - SetCursorPosition(GetCursorPosition());
|
| + SelectionModel sel(selection_model());
|
| + sel.set_selection_start(GetCursorPosition());
|
| + SetSelectionModel(sel);
|
| }
|
|
|
| void RenderText::SelectAll() {
|
| @@ -503,15 +491,15 @@ RenderText::RenderText()
|
| display_offset_() {
|
| }
|
|
|
| -SelectionModel RenderText::GetLeftCursorPosition(const SelectionModel& current,
|
| - bool move_by_word) {
|
| - size_t position = current.selection_end();
|
| - SelectionModel left = current;
|
| - if (!move_by_word) {
|
| - left.set_selection_end(std::max(static_cast<long>(position - 1),
|
| - static_cast<long>(0)));
|
| - return left;
|
| - }
|
| +SelectionModel RenderText::GetLeftSelectionModel(const SelectionModel& current,
|
| + BreakType break_type) {
|
| + if (break_type == LINE_BREAK)
|
| + return SelectionModel(0, 0, SelectionModel::LEADING);
|
| + size_t pos = std::max(static_cast<long>(current.selection_end() - 1),
|
| + static_cast<long>(0));
|
| + if (break_type == CHARACTER_BREAK)
|
| + return SelectionModel(pos, pos, SelectionModel::LEADING);
|
| +
|
| // Notes: We always iterate words from the begining.
|
| // This is probably fast enough for our usage, but we may
|
| // want to modify WordIterator so that it can start from the
|
| @@ -519,59 +507,54 @@ SelectionModel RenderText::GetLeftCursorPosition(const SelectionModel& current,
|
| base::i18n::BreakIterator iter(text(), base::i18n::BreakIterator::BREAK_WORD);
|
| bool success = iter.Init();
|
| DCHECK(success);
|
| - if (!success) {
|
| - left.set_selection_end(position);
|
| - return left;
|
| - }
|
| - int last = 0;
|
| + if (!success)
|
| + return current;
|
| while (iter.Advance()) {
|
| if (iter.IsWord()) {
|
| size_t begin = iter.pos() - iter.GetString().length();
|
| - if (begin == position) {
|
| + if (begin == current.selection_end()) {
|
| // The cursor is at the beginning of a word.
|
| // Move to previous word.
|
| break;
|
| - } else if (iter.pos() >= position) {
|
| + } else if (iter.pos() >= current.selection_end()) {
|
| // The cursor is in the middle or at the end of a word.
|
| // Move to the top of current word.
|
| - last = begin;
|
| + pos = begin;
|
| break;
|
| } else {
|
| - last = iter.pos() - iter.GetString().length();
|
| + pos = iter.pos() - iter.GetString().length();
|
| }
|
| }
|
| }
|
|
|
| - left.set_selection_end(last);
|
| - return left;
|
| + return SelectionModel(pos, pos, SelectionModel::LEADING);
|
| }
|
|
|
| -SelectionModel RenderText::GetRightCursorPosition(const SelectionModel& current,
|
| - bool move_by_word) {
|
| - size_t position = current.selection_end();
|
| - SelectionModel right = current;
|
| -
|
| - if (!move_by_word) {
|
| - right.set_selection_end(std::min(position + 1, text().length()));
|
| - return right;
|
| - }
|
| +SelectionModel RenderText::GetRightSelectionModel(const SelectionModel& current,
|
| + BreakType break_type) {
|
| + if (break_type == LINE_BREAK)
|
| + return SelectionModel(text().length(),
|
| + GetIndexOfPreviousGrapheme(text().length()), SelectionModel::TRAILING);
|
| + size_t pos = std::min(current.selection_end() + 1, text().length());
|
| + if (break_type == CHARACTER_BREAK)
|
| + return SelectionModel(pos, pos, SelectionModel::LEADING);
|
|
|
| base::i18n::BreakIterator iter(text(), base::i18n::BreakIterator::BREAK_WORD);
|
| bool success = iter.Init();
|
| DCHECK(success);
|
| - if (!success) {
|
| - right.set_selection_end(position);
|
| - return right;
|
| - }
|
| - size_t pos = 0;
|
| + if (!success)
|
| + return current;
|
| while (iter.Advance()) {
|
| pos = iter.pos();
|
| - if (iter.IsWord() && pos > position) {
|
| + if (iter.IsWord() && pos > current.selection_end())
|
| break;
|
| - }
|
| }
|
| - right.set_selection_end(pos);
|
| - return right;
|
| + return SelectionModel(pos, pos, SelectionModel::LEADING);
|
| +}
|
| +
|
| +size_t RenderText::GetIndexOfPreviousGrapheme(size_t position) const {
|
| + // TODO(msw): Handle complex script.
|
| + return std::max(static_cast<int>(position - 1), static_cast<int>(0));
|
| }
|
|
|
| void RenderText::ApplyCompositionAndSelectionStyles(
|
|
|