| Index: ui/gfx/render_text.cc
|
| ===================================================================
|
| --- ui/gfx/render_text.cc (revision 100008)
|
| +++ ui/gfx/render_text.cc (working copy)
|
| @@ -247,6 +247,12 @@
|
| sel.set_caret_pos(end.caret_pos());
|
| sel.set_caret_placement(end.caret_placement());
|
| }
|
| +
|
| + if (!IsCursorablePosition(sel.selection_start()) ||
|
| + !IsCursorablePosition(sel.selection_end()) ||
|
| + !IsCursorablePosition(sel.caret_pos()))
|
| + return false;
|
| +
|
| bool changed = !sel.Equals(selection_model_);
|
| SetSelectionModel(sel);
|
| return changed;
|
| @@ -281,41 +287,28 @@
|
| SetSelectionModel(sel);
|
| }
|
|
|
| -// TODO(xji): it does not work for languages do not use space as word breaker,
|
| -// such as Chinese. Should use BreakIterator.
|
| void RenderText::SelectWord() {
|
| - size_t selection_start = GetSelectionStart();
|
| size_t cursor_position = GetCursorPosition();
|
| - // First we setup selection_start_ and selection_end_. There are so many cases
|
| - // because we try to emulate what select-word looks like in a gtk textfield.
|
| - // See associated testcase for different cases.
|
| - if (cursor_position > 0 && cursor_position < text().length()) {
|
| - if (u_isalnum(text()[cursor_position])) {
|
| - selection_start = cursor_position;
|
| - cursor_position++;
|
| - } else
|
| - selection_start = cursor_position - 1;
|
| - } else if (cursor_position == 0) {
|
| - selection_start = cursor_position;
|
| - if (text().length() > 0)
|
| - cursor_position++;
|
| - } else {
|
| - selection_start = cursor_position - 1;
|
| - }
|
|
|
| - // Now we move selection_start_ to beginning of selection. Selection boundary
|
| - // is defined as the position where we have alpha-num character on one side
|
| - // and non-alpha-num char on the other side.
|
| - for (; selection_start > 0; selection_start--) {
|
| - if (IsPositionAtWordSelectionBoundary(selection_start))
|
| + base::i18n::BreakIterator iter(text(), base::i18n::BreakIterator::BREAK_WORD);
|
| + bool success = iter.Init();
|
| + DCHECK(success);
|
| + if (!success)
|
| + return;
|
| +
|
| + size_t selection_start = cursor_position;
|
| + for (; selection_start != 0; --selection_start) {
|
| + if (iter.IsStartOfWord(selection_start) ||
|
| + iter.IsEndOfWord(selection_start))
|
| break;
|
| }
|
|
|
| - // Now we move selection_end_ to end of selection. Selection boundary
|
| - // is defined as the position where we have alpha-num character on one side
|
| - // and non-alpha-num char on the other side.
|
| - for (; cursor_position < text().length(); cursor_position++) {
|
| - if (IsPositionAtWordSelectionBoundary(cursor_position))
|
| + if (selection_start == cursor_position)
|
| + ++cursor_position;
|
| +
|
| + for (; cursor_position < text().length(); ++cursor_position) {
|
| + if (iter.IsEndOfWord(cursor_position) ||
|
| + iter.IsStartOfWord(cursor_position))
|
| break;
|
| }
|
|
|
| @@ -462,6 +455,10 @@
|
| return cursor_bounds_;
|
| }
|
|
|
| +size_t RenderText::GetIndexOfNextGrapheme(size_t position) {
|
| + return IndexOfAdjacentGrapheme(position, true);
|
| +}
|
| +
|
| RenderText::RenderText()
|
| : text_(),
|
| selection_model_(),
|
| @@ -557,8 +554,7 @@
|
| }
|
|
|
| size_t RenderText::GetIndexOfPreviousGrapheme(size_t position) {
|
| - // TODO(msw): Handle complex script.
|
| - return std::max(static_cast<long>(position - 1), static_cast<long>(0));
|
| + return IndexOfAdjacentGrapheme(position, false);
|
| }
|
|
|
| std::vector<Rect> RenderText::GetSubstringBounds(size_t from, size_t to) {
|
| @@ -632,15 +628,12 @@
|
| SelectionModel::CaretPlacement placement = (caret_pos == cursor) ?
|
| SelectionModel::LEADING : SelectionModel::TRAILING;
|
| size_t selection_start = select ? GetSelectionStart() : cursor;
|
| - SelectionModel sel(selection_start, cursor, caret_pos, placement);
|
| - SetSelectionModel(sel);
|
| + if (IsCursorablePosition(cursor)) {
|
| + SelectionModel sel(selection_start, cursor, 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]));
|
| -}
|
| -
|
| void RenderText::UpdateCachedBoundsAndOffset() {
|
| if (cached_bounds_and_offset_valid_)
|
| return;
|
|
|