Chromium Code Reviews| 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,12 @@ |
| return cursor_bounds_; |
| } |
| +size_t RenderText::GetIndexOfNextGrapheme(size_t position) { |
| + // TODO(xji): Handle complex script. |
| + return std::min(static_cast<long>(position + 1), |
|
msw
2011/09/14 02:43:48
Both of these static casts have lint errors:
"Use
xji
2011/09/15 23:38:13
Merged win/linux impls.
|
| + static_cast<long>(text_.length())); |
| +} |
| + |
| RenderText::RenderText() |
| : text_(), |
| selection_model_(), |
| @@ -575,6 +574,10 @@ |
| return std::vector<Rect>(1, rect); |
| } |
| +bool RenderText::IsCursorablePosition(size_t position) { |
| + return true; |
|
msw
2011/09/14 02:43:48
I think this can potentially be pure virtual, and
xji
2011/09/15 23:38:13
Done.
|
| +} |
| + |
| void RenderText::ApplyCompositionAndSelectionStyles( |
| StyleRanges* style_ranges) const { |
| // TODO(msw): This pattern ought to be reconsidered; what about composition |
| @@ -632,15 +635,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; |