| 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 |