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 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
213 return changed; | 213 return changed; |
214 } | 214 } |
215 | 215 |
216 bool RenderText::MoveCursorTo(const Point& point, bool select) { | 216 bool RenderText::MoveCursorTo(const Point& point, bool select) { |
217 SelectionModel selection = FindCursorPosition(point); | 217 SelectionModel selection = FindCursorPosition(point); |
218 if (select) | 218 if (select) |
219 selection.set_selection_start(GetSelectionStart()); | 219 selection.set_selection_start(GetSelectionStart()); |
220 return MoveCursorTo(selection); | 220 return MoveCursorTo(selection); |
221 } | 221 } |
222 | 222 |
| 223 bool RenderText::SelectRange(const ui::Range& range) { |
| 224 size_t text_length = text().length(); |
| 225 size_t start = std::min(range.start(), text_length); |
| 226 size_t end = std::min(range.end(), text_length); |
| 227 |
| 228 if (!IsCursorablePosition(start) || !IsCursorablePosition(end)) |
| 229 return false; |
| 230 |
| 231 size_t pos = end; |
| 232 SelectionModel::CaretPlacement placement = SelectionModel::LEADING; |
| 233 if (start < end) { |
| 234 pos = GetIndexOfPreviousGrapheme(end); |
| 235 DCHECK_LT(pos, end); |
| 236 placement = SelectionModel::TRAILING; |
| 237 } else if (end == text_length) { |
| 238 SelectionModel boundary = GetTextDirection() == base::i18n::RIGHT_TO_LEFT ? |
| 239 LeftEndSelectionModel() : RightEndSelectionModel(); |
| 240 pos = boundary.caret_pos(); |
| 241 placement = boundary.caret_placement(); |
| 242 } |
| 243 SetSelectionModel(SelectionModel(start, end, pos, placement)); |
| 244 return true; |
| 245 } |
| 246 |
223 bool RenderText::IsPointInSelection(const Point& point) { | 247 bool RenderText::IsPointInSelection(const Point& point) { |
224 if (EmptySelection()) | 248 if (EmptySelection()) |
225 return false; | 249 return false; |
226 // TODO(xji): should this check whether the point is inside the visual | 250 // TODO(xji): should this check whether the point is inside the visual |
227 // selection bounds? In case of "abcFED", if "ED" is selected, |point| points | 251 // selection bounds? In case of "abcFED", if "ED" is selected, |point| points |
228 // to the right half of 'c', is the point in selection? | 252 // to the right half of 'c', is the point in selection? |
229 size_t pos = FindCursorPosition(point).selection_end(); | 253 size_t pos = FindCursorPosition(point).selection_end(); |
230 return (pos >= MinOfSelection() && pos < MaxOfSelection()); | 254 return (pos >= MinOfSelection() && pos < MaxOfSelection()); |
231 } | 255 } |
232 | 256 |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
443 } | 467 } |
444 | 468 |
445 const Point& RenderText::GetUpdatedDisplayOffset() { | 469 const Point& RenderText::GetUpdatedDisplayOffset() { |
446 UpdateCachedBoundsAndOffset(); | 470 UpdateCachedBoundsAndOffset(); |
447 return display_offset_; | 471 return display_offset_; |
448 } | 472 } |
449 | 473 |
450 SelectionModel RenderText::GetLeftSelectionModel(const SelectionModel& current, | 474 SelectionModel RenderText::GetLeftSelectionModel(const SelectionModel& current, |
451 BreakType break_type) { | 475 BreakType break_type) { |
452 if (break_type == LINE_BREAK) | 476 if (break_type == LINE_BREAK) |
453 return SelectionModel(0, 0, SelectionModel::LEADING); | 477 return LeftEndSelectionModel(); |
454 size_t pos = std::max(static_cast<long>(current.selection_end() - 1), | 478 size_t pos = std::max(static_cast<long>(current.selection_end() - 1), |
455 static_cast<long>(0)); | 479 static_cast<long>(0)); |
456 if (break_type == CHARACTER_BREAK) | 480 if (break_type == CHARACTER_BREAK) |
457 return SelectionModel(pos, pos, SelectionModel::LEADING); | 481 return SelectionModel(pos, pos, SelectionModel::LEADING); |
458 | 482 |
459 // Notes: We always iterate words from the beginning. | 483 // Notes: We always iterate words from the beginning. |
460 // This is probably fast enough for our usage, but we may | 484 // This is probably fast enough for our usage, but we may |
461 // want to modify WordIterator so that it can start from the | 485 // want to modify WordIterator so that it can start from the |
462 // middle of string and advance backwards. | 486 // middle of string and advance backwards. |
463 base::i18n::BreakIterator iter(text(), base::i18n::BreakIterator::BREAK_WORD); | 487 base::i18n::BreakIterator iter(text(), base::i18n::BreakIterator::BREAK_WORD); |
(...skipping 20 matching lines...) Expand all Loading... |
484 } | 508 } |
485 | 509 |
486 return SelectionModel(pos, pos, SelectionModel::LEADING); | 510 return SelectionModel(pos, pos, SelectionModel::LEADING); |
487 } | 511 } |
488 | 512 |
489 SelectionModel RenderText::GetRightSelectionModel(const SelectionModel& current, | 513 SelectionModel RenderText::GetRightSelectionModel(const SelectionModel& current, |
490 BreakType break_type) { | 514 BreakType break_type) { |
491 if (text_.empty()) | 515 if (text_.empty()) |
492 return SelectionModel(0, 0, SelectionModel::LEADING); | 516 return SelectionModel(0, 0, SelectionModel::LEADING); |
493 if (break_type == LINE_BREAK) | 517 if (break_type == LINE_BREAK) |
494 return SelectionModel(text().length(), | 518 return RightEndSelectionModel(); |
495 GetIndexOfPreviousGrapheme(text().length()), SelectionModel::TRAILING); | |
496 size_t pos = std::min(current.selection_end() + 1, text().length()); | 519 size_t pos = std::min(current.selection_end() + 1, text().length()); |
497 if (break_type == CHARACTER_BREAK) | 520 if (break_type == CHARACTER_BREAK) |
498 return SelectionModel(pos, pos, SelectionModel::LEADING); | 521 return SelectionModel(pos, pos, SelectionModel::LEADING); |
499 | 522 |
500 base::i18n::BreakIterator iter(text(), base::i18n::BreakIterator::BREAK_WORD); | 523 base::i18n::BreakIterator iter(text(), base::i18n::BreakIterator::BREAK_WORD); |
501 bool success = iter.Init(); | 524 bool success = iter.Init(); |
502 DCHECK(success); | 525 DCHECK(success); |
503 if (!success) | 526 if (!success) |
504 return current; | 527 return current; |
505 while (iter.Advance()) { | 528 while (iter.Advance()) { |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
630 // LTR character. | 653 // LTR character. |
631 // | 654 // |
632 // Pan to show the cursor when it overflows to the left. | 655 // Pan to show the cursor when it overflows to the left. |
633 delta_offset = display_rect_.x() - cursor_bounds_.x(); | 656 delta_offset = display_rect_.x() - cursor_bounds_.x(); |
634 } | 657 } |
635 display_offset_.Offset(delta_offset, 0); | 658 display_offset_.Offset(delta_offset, 0); |
636 cursor_bounds_.Offset(delta_offset, 0); | 659 cursor_bounds_.Offset(delta_offset, 0); |
637 } | 660 } |
638 | 661 |
639 } // namespace gfx | 662 } // namespace gfx |
OLD | NEW |