OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/gfx/render_text.h" | 5 #include "ui/gfx/render_text.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/i18n/break_iterator.h" | 9 #include "base/i18n/break_iterator.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 | 80 |
81 StyleRange::StyleRange() | 81 StyleRange::StyleRange() |
82 : font(), | 82 : font(), |
83 foreground(SK_ColorBLACK), | 83 foreground(SK_ColorBLACK), |
84 strike(false), | 84 strike(false), |
85 underline(false), | 85 underline(false), |
86 range() { | 86 range() { |
87 } | 87 } |
88 | 88 |
89 SelectionModel::SelectionModel() { | 89 SelectionModel::SelectionModel() { |
90 Init(0, 0, 0, PREVIOUS_GRAPHEME_TRAILING); | 90 Init(0, 0, 0, LEADING); |
91 } | 91 } |
92 | 92 |
93 SelectionModel::SelectionModel(size_t pos) { | 93 SelectionModel::SelectionModel(size_t pos) { |
94 Init(pos, pos, pos, PREVIOUS_GRAPHEME_TRAILING); | 94 Init(pos, pos, pos, LEADING); |
| 95 } |
| 96 |
| 97 SelectionModel::SelectionModel(size_t start, size_t end) { |
| 98 Init(start, end, end, LEADING); |
95 } | 99 } |
96 | 100 |
97 SelectionModel::SelectionModel(size_t end, | 101 SelectionModel::SelectionModel(size_t end, |
98 size_t pos, | 102 size_t pos, |
99 CaretPlacement placement) { | 103 CaretPlacement placement) { |
100 Init(end, end, pos, placement); | 104 Init(end, end, pos, placement); |
101 } | 105 } |
102 | 106 |
103 SelectionModel::SelectionModel(size_t start, | 107 SelectionModel::SelectionModel(size_t start, |
104 size_t end, | 108 size_t end, |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
259 sel.set_selection_start(GetCursorPosition()); | 263 sel.set_selection_start(GetCursorPosition()); |
260 SetSelectionModel(sel); | 264 SetSelectionModel(sel); |
261 } | 265 } |
262 | 266 |
263 void RenderText::SelectAll() { | 267 void RenderText::SelectAll() { |
264 SelectionModel sel(0, text().length(), | 268 SelectionModel sel(0, text().length(), |
265 text().length(), SelectionModel::LEADING); | 269 text().length(), SelectionModel::LEADING); |
266 SetSelectionModel(sel); | 270 SetSelectionModel(sel); |
267 } | 271 } |
268 | 272 |
| 273 // TODO(xji): it does not work for languages do not use space as word breaker, |
| 274 // such as Chinese. Should use BreakIterator. |
269 void RenderText::SelectWord() { | 275 void RenderText::SelectWord() { |
270 size_t selection_start = GetSelectionStart(); | 276 size_t selection_start = GetSelectionStart(); |
271 size_t cursor_position = GetCursorPosition(); | 277 size_t cursor_position = GetCursorPosition(); |
272 // First we setup selection_start_ and selection_end_. There are so many cases | 278 // First we setup selection_start_ and selection_end_. There are so many cases |
273 // because we try to emulate what select-word looks like in a gtk textfield. | 279 // because we try to emulate what select-word looks like in a gtk textfield. |
274 // See associated testcase for different cases. | 280 // See associated testcase for different cases. |
275 if (cursor_position > 0 && cursor_position < text().length()) { | 281 if (cursor_position > 0 && cursor_position < text().length()) { |
276 if (u_isalnum(text()[cursor_position])) { | 282 if (u_isalnum(text()[cursor_position])) { |
277 selection_start = cursor_position; | 283 selection_start = cursor_position; |
278 cursor_position++; | 284 cursor_position++; |
(...skipping 19 matching lines...) Expand all Loading... |
298 // is defined as the position where we have alpha-num character on one side | 304 // is defined as the position where we have alpha-num character on one side |
299 // and non-alpha-num char on the other side. | 305 // and non-alpha-num char on the other side. |
300 for (; cursor_position < text().length(); cursor_position++) { | 306 for (; cursor_position < text().length(); cursor_position++) { |
301 if (IsPositionAtWordSelectionBoundary(cursor_position)) | 307 if (IsPositionAtWordSelectionBoundary(cursor_position)) |
302 break; | 308 break; |
303 } | 309 } |
304 | 310 |
305 SelectionModel sel(selection_model()); | 311 SelectionModel sel(selection_model()); |
306 sel.set_selection_start(selection_start); | 312 sel.set_selection_start(selection_start); |
307 sel.set_selection_end(cursor_position); | 313 sel.set_selection_end(cursor_position); |
308 sel.set_caret_placement(SelectionModel::PREVIOUS_GRAPHEME_TRAILING); | 314 sel.set_caret_pos(GetIndexOfPreviousGrapheme(cursor_position)); |
| 315 sel.set_caret_placement(SelectionModel::TRAILING); |
309 SetSelectionModel(sel); | 316 SetSelectionModel(sel); |
310 } | 317 } |
311 | 318 |
312 const ui::Range& RenderText::GetCompositionRange() const { | 319 const ui::Range& RenderText::GetCompositionRange() const { |
313 return composition_range_; | 320 return composition_range_; |
314 } | 321 } |
315 | 322 |
316 void RenderText::SetCompositionRange(const ui::Range& composition_range) { | 323 void RenderText::SetCompositionRange(const ui::Range& composition_range) { |
317 CHECK(!composition_range.IsValid() || | 324 CHECK(!composition_range.IsValid() || |
318 ui::Range(0, text_.length()).Contains(composition_range)); | 325 ui::Range(0, text_.length()).Contains(composition_range)); |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
535 if (!success) | 542 if (!success) |
536 return current; | 543 return current; |
537 while (iter.Advance()) { | 544 while (iter.Advance()) { |
538 pos = iter.pos(); | 545 pos = iter.pos(); |
539 if (iter.IsWord() && pos > current.selection_end()) | 546 if (iter.IsWord() && pos > current.selection_end()) |
540 break; | 547 break; |
541 } | 548 } |
542 return SelectionModel(pos, pos, SelectionModel::LEADING); | 549 return SelectionModel(pos, pos, SelectionModel::LEADING); |
543 } | 550 } |
544 | 551 |
545 size_t RenderText::GetIndexOfPreviousGrapheme(size_t position) const { | 552 size_t RenderText::GetIndexOfPreviousGrapheme(size_t position) { |
546 // TODO(msw): Handle complex script. | 553 // TODO(msw): Handle complex script. |
547 return std::max(static_cast<int>(position - 1), static_cast<int>(0)); | 554 return std::max(static_cast<int>(position - 1), static_cast<int>(0)); |
548 } | 555 } |
549 | 556 |
550 void RenderText::ApplyCompositionAndSelectionStyles( | 557 void RenderText::ApplyCompositionAndSelectionStyles( |
551 StyleRanges* style_ranges) const { | 558 StyleRanges* style_ranges) const { |
552 // TODO(msw): This pattern ought to be reconsidered; what about composition | 559 // TODO(msw): This pattern ought to be reconsidered; what about composition |
553 // and selection overlaps, retain existing local style features? | 560 // and selection overlaps, retain existing local style features? |
554 // Apply a composition style override to a copy of the style ranges. | 561 // Apply a composition style override to a copy of the style ranges. |
555 if (composition_range_.IsValid() && !composition_range_.is_empty()) { | 562 if (composition_range_.IsValid() && !composition_range_.is_empty()) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
595 delta_offset = display_rect_.right() - cursor_bounds_.right(); | 602 delta_offset = display_rect_.right() - cursor_bounds_.right(); |
596 } else if (cursor_bounds_.x() < display_rect_.x()) { | 603 } else if (cursor_bounds_.x() < display_rect_.x()) { |
597 // Pan to show the cursor when it overflows to the left. | 604 // Pan to show the cursor when it overflows to the left. |
598 delta_offset = display_rect_.x() - cursor_bounds_.x(); | 605 delta_offset = display_rect_.x() - cursor_bounds_.x(); |
599 } | 606 } |
600 display_offset_.Offset(delta_offset, 0); | 607 display_offset_.Offset(delta_offset, 0); |
601 cursor_bounds_.Offset(delta_offset, 0); | 608 cursor_bounds_.Offset(delta_offset, 0); |
602 } | 609 } |
603 | 610 |
604 } // namespace gfx | 611 } // namespace gfx |
OLD | NEW |