| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 281 const std::vector<BreakList<bool> >& styles) | 281 const std::vector<BreakList<bool> >& styles) |
| 282 : colors_(colors), | 282 : colors_(colors), |
| 283 styles_(styles) { | 283 styles_(styles) { |
| 284 color_ = colors_.breaks().begin(); | 284 color_ = colors_.breaks().begin(); |
| 285 for (size_t i = 0; i < styles_.size(); ++i) | 285 for (size_t i = 0; i < styles_.size(); ++i) |
| 286 style_.push_back(styles_[i].breaks().begin()); | 286 style_.push_back(styles_[i].breaks().begin()); |
| 287 } | 287 } |
| 288 | 288 |
| 289 StyleIterator::~StyleIterator() {} | 289 StyleIterator::~StyleIterator() {} |
| 290 | 290 |
| 291 ui::Range StyleIterator::GetRange() const { | 291 gfx::Range StyleIterator::GetRange() const { |
| 292 ui::Range range(colors_.GetRange(color_)); | 292 gfx::Range range(colors_.GetRange(color_)); |
| 293 for (size_t i = 0; i < NUM_TEXT_STYLES; ++i) | 293 for (size_t i = 0; i < NUM_TEXT_STYLES; ++i) |
| 294 range = range.Intersect(styles_[i].GetRange(style_[i])); | 294 range = range.Intersect(styles_[i].GetRange(style_[i])); |
| 295 return range; | 295 return range; |
| 296 } | 296 } |
| 297 | 297 |
| 298 void StyleIterator::UpdatePosition(size_t position) { | 298 void StyleIterator::UpdatePosition(size_t position) { |
| 299 color_ = colors_.GetBreak(position); | 299 color_ = colors_.GetBreak(position); |
| 300 for (size_t i = 0; i < NUM_TEXT_STYLES; ++i) | 300 for (size_t i = 0; i < NUM_TEXT_STYLES; ++i) |
| 301 style_[i] = styles_[i].GetBreak(position); | 301 style_[i] = styles_[i].GetBreak(position); |
| 302 } | 302 } |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 424 position = GetAdjacentSelectionModel(position, break_type, direction); | 424 position = GetAdjacentSelectionModel(position, break_type, direction); |
| 425 } | 425 } |
| 426 if (select) | 426 if (select) |
| 427 position.set_selection_start(selection().start()); | 427 position.set_selection_start(selection().start()); |
| 428 MoveCursorTo(position); | 428 MoveCursorTo(position); |
| 429 } | 429 } |
| 430 | 430 |
| 431 bool RenderText::MoveCursorTo(const SelectionModel& model) { | 431 bool RenderText::MoveCursorTo(const SelectionModel& model) { |
| 432 // Enforce valid selection model components. | 432 // Enforce valid selection model components. |
| 433 size_t text_length = text().length(); | 433 size_t text_length = text().length(); |
| 434 ui::Range range(std::min(model.selection().start(), text_length), | 434 gfx::Range range(std::min(model.selection().start(), text_length), |
| 435 std::min(model.caret_pos(), text_length)); | 435 std::min(model.caret_pos(), text_length)); |
| 436 // The current model only supports caret positions at valid character indices. | 436 // The current model only supports caret positions at valid character indices. |
| 437 if (!IsCursorablePosition(range.start()) || | 437 if (!IsCursorablePosition(range.start()) || |
| 438 !IsCursorablePosition(range.end())) | 438 !IsCursorablePosition(range.end())) |
| 439 return false; | 439 return false; |
| 440 SelectionModel sel(range, model.caret_affinity()); | 440 SelectionModel sel(range, model.caret_affinity()); |
| 441 bool changed = sel != selection_model_; | 441 bool changed = sel != selection_model_; |
| 442 SetSelectionModel(sel); | 442 SetSelectionModel(sel); |
| 443 return changed; | 443 return changed; |
| 444 } | 444 } |
| 445 | 445 |
| 446 bool RenderText::MoveCursorTo(const Point& point, bool select) { | 446 bool RenderText::MoveCursorTo(const Point& point, bool select) { |
| 447 SelectionModel position = FindCursorPosition(point); | 447 SelectionModel position = FindCursorPosition(point); |
| 448 if (select) | 448 if (select) |
| 449 position.set_selection_start(selection().start()); | 449 position.set_selection_start(selection().start()); |
| 450 return MoveCursorTo(position); | 450 return MoveCursorTo(position); |
| 451 } | 451 } |
| 452 | 452 |
| 453 bool RenderText::SelectRange(const ui::Range& range) { | 453 bool RenderText::SelectRange(const gfx::Range& range) { |
| 454 ui::Range sel(std::min(range.start(), text().length()), | 454 gfx::Range sel(std::min(range.start(), text().length()), |
| 455 std::min(range.end(), text().length())); | 455 std::min(range.end(), text().length())); |
| 456 if (!IsCursorablePosition(sel.start()) || !IsCursorablePosition(sel.end())) | 456 if (!IsCursorablePosition(sel.start()) || !IsCursorablePosition(sel.end())) |
| 457 return false; | 457 return false; |
| 458 LogicalCursorDirection affinity = | 458 LogicalCursorDirection affinity = |
| 459 (sel.is_reversed() || sel.is_empty()) ? CURSOR_FORWARD : CURSOR_BACKWARD; | 459 (sel.is_reversed() || sel.is_empty()) ? CURSOR_FORWARD : CURSOR_BACKWARD; |
| 460 SetSelectionModel(SelectionModel(sel, affinity)); | 460 SetSelectionModel(SelectionModel(sel, affinity)); |
| 461 return true; | 461 return true; |
| 462 } | 462 } |
| 463 | 463 |
| 464 bool RenderText::IsPointInSelection(const Point& point) { | 464 bool RenderText::IsPointInSelection(const Point& point) { |
| 465 if (selection().is_empty()) | 465 if (selection().is_empty()) |
| 466 return false; | 466 return false; |
| 467 SelectionModel cursor = FindCursorPosition(point); | 467 SelectionModel cursor = FindCursorPosition(point); |
| 468 return RangeContainsCaret( | 468 return RangeContainsCaret( |
| 469 selection(), cursor.caret_pos(), cursor.caret_affinity()); | 469 selection(), cursor.caret_pos(), cursor.caret_affinity()); |
| 470 } | 470 } |
| 471 | 471 |
| 472 void RenderText::ClearSelection() { | 472 void RenderText::ClearSelection() { |
| 473 SetSelectionModel(SelectionModel(cursor_position(), | 473 SetSelectionModel(SelectionModel(cursor_position(), |
| 474 selection_model_.caret_affinity())); | 474 selection_model_.caret_affinity())); |
| 475 } | 475 } |
| 476 | 476 |
| 477 void RenderText::SelectAll(bool reversed) { | 477 void RenderText::SelectAll(bool reversed) { |
| 478 const size_t length = text().length(); | 478 const size_t length = text().length(); |
| 479 const ui::Range all = reversed ? ui::Range(length, 0) : ui::Range(0, length); | 479 const gfx::Range all = reversed ? gfx::Range(length, 0) : |
| 480 gfx::Range(0, length); |
| 480 const bool success = SelectRange(all); | 481 const bool success = SelectRange(all); |
| 481 DCHECK(success); | 482 DCHECK(success); |
| 482 } | 483 } |
| 483 | 484 |
| 484 void RenderText::SelectWord() { | 485 void RenderText::SelectWord() { |
| 485 if (obscured_) { | 486 if (obscured_) { |
| 486 SelectAll(false); | 487 SelectAll(false); |
| 487 return; | 488 return; |
| 488 } | 489 } |
| 489 | 490 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 510 | 511 |
| 511 for (; selection_max < text().length(); ++selection_max) | 512 for (; selection_max < text().length(); ++selection_max) |
| 512 if (iter.IsEndOfWord(selection_max) || iter.IsStartOfWord(selection_max)) | 513 if (iter.IsEndOfWord(selection_max) || iter.IsStartOfWord(selection_max)) |
| 513 break; | 514 break; |
| 514 | 515 |
| 515 const bool reversed = selection().is_reversed(); | 516 const bool reversed = selection().is_reversed(); |
| 516 MoveCursorTo(reversed ? selection_max : selection_min, false); | 517 MoveCursorTo(reversed ? selection_max : selection_min, false); |
| 517 MoveCursorTo(reversed ? selection_min : selection_max, true); | 518 MoveCursorTo(reversed ? selection_min : selection_max, true); |
| 518 } | 519 } |
| 519 | 520 |
| 520 const ui::Range& RenderText::GetCompositionRange() const { | 521 const gfx::Range& RenderText::GetCompositionRange() const { |
| 521 return composition_range_; | 522 return composition_range_; |
| 522 } | 523 } |
| 523 | 524 |
| 524 void RenderText::SetCompositionRange(const ui::Range& composition_range) { | 525 void RenderText::SetCompositionRange(const gfx::Range& composition_range) { |
| 525 CHECK(!composition_range.IsValid() || | 526 CHECK(!composition_range.IsValid() || |
| 526 ui::Range(0, text_.length()).Contains(composition_range)); | 527 gfx::Range(0, text_.length()).Contains(composition_range)); |
| 527 composition_range_.set_end(composition_range.end()); | 528 composition_range_.set_end(composition_range.end()); |
| 528 composition_range_.set_start(composition_range.start()); | 529 composition_range_.set_start(composition_range.start()); |
| 529 ResetLayout(); | 530 ResetLayout(); |
| 530 } | 531 } |
| 531 | 532 |
| 532 void RenderText::SetColor(SkColor value) { | 533 void RenderText::SetColor(SkColor value) { |
| 533 colors_.SetValue(value); | 534 colors_.SetValue(value); |
| 534 | 535 |
| 535 #if defined(OS_WIN) | 536 #if defined(OS_WIN) |
| 536 // TODO(msw): Windows applies colors and decorations in the layout process. | 537 // TODO(msw): Windows applies colors and decorations in the layout process. |
| 537 cached_bounds_and_offset_valid_ = false; | 538 cached_bounds_and_offset_valid_ = false; |
| 538 ResetLayout(); | 539 ResetLayout(); |
| 539 #endif | 540 #endif |
| 540 } | 541 } |
| 541 | 542 |
| 542 void RenderText::ApplyColor(SkColor value, const ui::Range& range) { | 543 void RenderText::ApplyColor(SkColor value, const gfx::Range& range) { |
| 543 colors_.ApplyValue(value, range); | 544 colors_.ApplyValue(value, range); |
| 544 | 545 |
| 545 #if defined(OS_WIN) | 546 #if defined(OS_WIN) |
| 546 // TODO(msw): Windows applies colors and decorations in the layout process. | 547 // TODO(msw): Windows applies colors and decorations in the layout process. |
| 547 cached_bounds_and_offset_valid_ = false; | 548 cached_bounds_and_offset_valid_ = false; |
| 548 ResetLayout(); | 549 ResetLayout(); |
| 549 #endif | 550 #endif |
| 550 } | 551 } |
| 551 | 552 |
| 552 void RenderText::SetStyle(TextStyle style, bool value) { | 553 void RenderText::SetStyle(TextStyle style, bool value) { |
| 553 styles_[style].SetValue(value); | 554 styles_[style].SetValue(value); |
| 554 | 555 |
| 555 // Only invalidate the layout on font changes; not for colors or decorations. | 556 // Only invalidate the layout on font changes; not for colors or decorations. |
| 556 bool invalidate = (style == BOLD) || (style == ITALIC); | 557 bool invalidate = (style == BOLD) || (style == ITALIC); |
| 557 #if defined(OS_WIN) | 558 #if defined(OS_WIN) |
| 558 // TODO(msw): Windows applies colors and decorations in the layout process. | 559 // TODO(msw): Windows applies colors and decorations in the layout process. |
| 559 invalidate = true; | 560 invalidate = true; |
| 560 #endif | 561 #endif |
| 561 if (invalidate) { | 562 if (invalidate) { |
| 562 cached_bounds_and_offset_valid_ = false; | 563 cached_bounds_and_offset_valid_ = false; |
| 563 ResetLayout(); | 564 ResetLayout(); |
| 564 } | 565 } |
| 565 } | 566 } |
| 566 | 567 |
| 567 void RenderText::ApplyStyle(TextStyle style, | 568 void RenderText::ApplyStyle(TextStyle style, |
| 568 bool value, | 569 bool value, |
| 569 const ui::Range& range) { | 570 const gfx::Range& range) { |
| 570 styles_[style].ApplyValue(value, range); | 571 styles_[style].ApplyValue(value, range); |
| 571 | 572 |
| 572 // Only invalidate the layout on font changes; not for colors or decorations. | 573 // Only invalidate the layout on font changes; not for colors or decorations. |
| 573 bool invalidate = (style == BOLD) || (style == ITALIC); | 574 bool invalidate = (style == BOLD) || (style == ITALIC); |
| 574 #if defined(OS_WIN) | 575 #if defined(OS_WIN) |
| 575 // TODO(msw): Windows applies colors and decorations in the layout process. | 576 // TODO(msw): Windows applies colors and decorations in the layout process. |
| 576 invalidate = true; | 577 invalidate = true; |
| 577 #endif | 578 #endif |
| 578 if (invalidate) { | 579 if (invalidate) { |
| 579 cached_bounds_and_offset_valid_ = false; | 580 cached_bounds_and_offset_valid_ = false; |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 697 int x = 0, width = 1; | 698 int x = 0, width = 1; |
| 698 Size size = GetStringSize(); | 699 Size size = GetStringSize(); |
| 699 if (caret_pos == (caret_affinity == CURSOR_BACKWARD ? 0 : text().length())) { | 700 if (caret_pos == (caret_affinity == CURSOR_BACKWARD ? 0 : text().length())) { |
| 700 // The caret is attached to the boundary. Always return a 1-dip width caret, | 701 // The caret is attached to the boundary. Always return a 1-dip width caret, |
| 701 // since there is nothing to overtype. | 702 // since there is nothing to overtype. |
| 702 if ((GetTextDirection() == base::i18n::RIGHT_TO_LEFT) == (caret_pos == 0)) | 703 if ((GetTextDirection() == base::i18n::RIGHT_TO_LEFT) == (caret_pos == 0)) |
| 703 x = size.width(); | 704 x = size.width(); |
| 704 } else { | 705 } else { |
| 705 size_t grapheme_start = (caret_affinity == CURSOR_FORWARD) ? | 706 size_t grapheme_start = (caret_affinity == CURSOR_FORWARD) ? |
| 706 caret_pos : IndexOfAdjacentGrapheme(caret_pos, CURSOR_BACKWARD); | 707 caret_pos : IndexOfAdjacentGrapheme(caret_pos, CURSOR_BACKWARD); |
| 707 ui::Range xspan(GetGlyphBounds(grapheme_start)); | 708 gfx::Range xspan(GetGlyphBounds(grapheme_start)); |
| 708 if (insert_mode) { | 709 if (insert_mode) { |
| 709 x = (caret_affinity == CURSOR_BACKWARD) ? xspan.end() : xspan.start(); | 710 x = (caret_affinity == CURSOR_BACKWARD) ? xspan.end() : xspan.start(); |
| 710 } else { // overtype mode | 711 } else { // overtype mode |
| 711 x = xspan.GetMin(); | 712 x = xspan.GetMin(); |
| 712 width = xspan.length(); | 713 width = xspan.length(); |
| 713 } | 714 } |
| 714 } | 715 } |
| 715 return Rect(ToViewPoint(Point(x, 0)), Size(width, size.height())); | 716 return Rect(ToViewPoint(Point(x, 0)), Size(width, size.height())); |
| 716 } | 717 } |
| 717 | 718 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 738 | 739 |
| 739 while (index > 0) { | 740 while (index > 0) { |
| 740 index--; | 741 index--; |
| 741 if (IsCursorablePosition(index)) | 742 if (IsCursorablePosition(index)) |
| 742 return index; | 743 return index; |
| 743 } | 744 } |
| 744 return 0; | 745 return 0; |
| 745 } | 746 } |
| 746 | 747 |
| 747 SelectionModel RenderText::GetSelectionModelForSelectionStart() { | 748 SelectionModel RenderText::GetSelectionModelForSelectionStart() { |
| 748 const ui::Range& sel = selection(); | 749 const gfx::Range& sel = selection(); |
| 749 if (sel.is_empty()) | 750 if (sel.is_empty()) |
| 750 return selection_model_; | 751 return selection_model_; |
| 751 return SelectionModel(sel.start(), | 752 return SelectionModel(sel.start(), |
| 752 sel.is_reversed() ? CURSOR_BACKWARD : CURSOR_FORWARD); | 753 sel.is_reversed() ? CURSOR_BACKWARD : CURSOR_FORWARD); |
| 753 } | 754 } |
| 754 | 755 |
| 755 void RenderText::SetTextShadows(const ShadowValues& shadows) { | 756 void RenderText::SetTextShadows(const ShadowValues& shadows) { |
| 756 text_shadows_ = shadows; | 757 text_shadows_ = shadows; |
| 757 } | 758 } |
| 758 | 759 |
| 759 RenderText::RenderText() | 760 RenderText::RenderText() |
| 760 : horizontal_alignment_(base::i18n::IsRTL() ? ALIGN_RIGHT : ALIGN_LEFT), | 761 : horizontal_alignment_(base::i18n::IsRTL() ? ALIGN_RIGHT : ALIGN_LEFT), |
| 761 vertical_alignment_(ALIGN_VCENTER), | 762 vertical_alignment_(ALIGN_VCENTER), |
| 762 directionality_mode_(DIRECTIONALITY_FROM_TEXT), | 763 directionality_mode_(DIRECTIONALITY_FROM_TEXT), |
| 763 text_direction_(base::i18n::UNKNOWN_DIRECTION), | 764 text_direction_(base::i18n::UNKNOWN_DIRECTION), |
| 764 cursor_enabled_(true), | 765 cursor_enabled_(true), |
| 765 cursor_visible_(false), | 766 cursor_visible_(false), |
| 766 insert_mode_(true), | 767 insert_mode_(true), |
| 767 cursor_color_(kDefaultColor), | 768 cursor_color_(kDefaultColor), |
| 768 selection_color_(kDefaultColor), | 769 selection_color_(kDefaultColor), |
| 769 selection_background_focused_color_(kDefaultSelectionBackgroundColor), | 770 selection_background_focused_color_(kDefaultSelectionBackgroundColor), |
| 770 focused_(false), | 771 focused_(false), |
| 771 composition_range_(ui::Range::InvalidRange()), | 772 composition_range_(gfx::Range::InvalidRange()), |
| 772 colors_(kDefaultColor), | 773 colors_(kDefaultColor), |
| 773 styles_(NUM_TEXT_STYLES), | 774 styles_(NUM_TEXT_STYLES), |
| 774 composition_and_selection_styles_applied_(false), | 775 composition_and_selection_styles_applied_(false), |
| 775 obscured_(false), | 776 obscured_(false), |
| 776 obscured_reveal_index_(-1), | 777 obscured_reveal_index_(-1), |
| 777 truncate_length_(0), | 778 truncate_length_(0), |
| 778 fade_head_(false), | 779 fade_head_(false), |
| 779 fade_tail_(false), | 780 fade_tail_(false), |
| 780 background_is_transparent_(false), | 781 background_is_transparent_(false), |
| 781 clip_to_display_rect_(true), | 782 clip_to_display_rect_(true), |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 823 DCHECK(!composition_and_selection_styles_applied_); | 824 DCHECK(!composition_and_selection_styles_applied_); |
| 824 saved_colors_ = colors_; | 825 saved_colors_ = colors_; |
| 825 saved_underlines_ = styles_[UNDERLINE]; | 826 saved_underlines_ = styles_[UNDERLINE]; |
| 826 | 827 |
| 827 // Apply an underline to the composition range in |underlines|. | 828 // Apply an underline to the composition range in |underlines|. |
| 828 if (composition_range_.IsValid() && !composition_range_.is_empty()) | 829 if (composition_range_.IsValid() && !composition_range_.is_empty()) |
| 829 styles_[UNDERLINE].ApplyValue(true, composition_range_); | 830 styles_[UNDERLINE].ApplyValue(true, composition_range_); |
| 830 | 831 |
| 831 // Apply the selected text color to the [un-reversed] selection range. | 832 // Apply the selected text color to the [un-reversed] selection range. |
| 832 if (!selection().is_empty()) { | 833 if (!selection().is_empty()) { |
| 833 const ui::Range range(selection().GetMin(), selection().GetMax()); | 834 const gfx::Range range(selection().GetMin(), selection().GetMax()); |
| 834 colors_.ApplyValue(selection_color_, range); | 835 colors_.ApplyValue(selection_color_, range); |
| 835 } | 836 } |
| 836 composition_and_selection_styles_applied_ = true; | 837 composition_and_selection_styles_applied_ = true; |
| 837 } | 838 } |
| 838 | 839 |
| 839 void RenderText::UndoCompositionAndSelectionStyles() { | 840 void RenderText::UndoCompositionAndSelectionStyles() { |
| 840 // Restore the underline and color breaks to undo the temporary styles. | 841 // Restore the underline and color breaks to undo the temporary styles. |
| 841 DCHECK(composition_and_selection_styles_applied_); | 842 DCHECK(composition_and_selection_styles_applied_); |
| 842 colors_ = saved_colors_; | 843 colors_ = saved_colors_; |
| 843 styles_[UNDERLINE] = saved_underlines_; | 844 styles_[UNDERLINE] = saved_underlines_; |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 922 if (shader) | 923 if (shader) |
| 923 renderer->SetShader(shader.get(), display_rect()); | 924 renderer->SetShader(shader.get(), display_rect()); |
| 924 } | 925 } |
| 925 | 926 |
| 926 void RenderText::ApplyTextShadows(internal::SkiaTextRenderer* renderer) { | 927 void RenderText::ApplyTextShadows(internal::SkiaTextRenderer* renderer) { |
| 927 skia::RefPtr<SkDrawLooper> looper = CreateShadowDrawLooper(text_shadows_); | 928 skia::RefPtr<SkDrawLooper> looper = CreateShadowDrawLooper(text_shadows_); |
| 928 renderer->SetDrawLooper(looper.get()); | 929 renderer->SetDrawLooper(looper.get()); |
| 929 } | 930 } |
| 930 | 931 |
| 931 // static | 932 // static |
| 932 bool RenderText::RangeContainsCaret(const ui::Range& range, | 933 bool RenderText::RangeContainsCaret(const gfx::Range& range, |
| 933 size_t caret_pos, | 934 size_t caret_pos, |
| 934 LogicalCursorDirection caret_affinity) { | 935 LogicalCursorDirection caret_affinity) { |
| 935 // NB: exploits unsigned wraparound (WG14/N1124 section 6.2.5 paragraph 9). | 936 // NB: exploits unsigned wraparound (WG14/N1124 section 6.2.5 paragraph 9). |
| 936 size_t adjacent = (caret_affinity == CURSOR_BACKWARD) ? | 937 size_t adjacent = (caret_affinity == CURSOR_BACKWARD) ? |
| 937 caret_pos - 1 : caret_pos + 1; | 938 caret_pos - 1 : caret_pos + 1; |
| 938 return range.Contains(ui::Range(caret_pos, adjacent)); | 939 return range.Contains(gfx::Range(caret_pos, adjacent)); |
| 939 } | 940 } |
| 940 | 941 |
| 941 void RenderText::MoveCursorTo(size_t position, bool select) { | 942 void RenderText::MoveCursorTo(size_t position, bool select) { |
| 942 size_t cursor = std::min(position, text().length()); | 943 size_t cursor = std::min(position, text().length()); |
| 943 if (IsCursorablePosition(cursor)) | 944 if (IsCursorablePosition(cursor)) |
| 944 SetSelectionModel(SelectionModel( | 945 SetSelectionModel(SelectionModel( |
| 945 ui::Range(select ? selection().start() : cursor, cursor), | 946 gfx::Range(select ? selection().start() : cursor, cursor), |
| 946 (cursor == 0) ? CURSOR_FORWARD : CURSOR_BACKWARD)); | 947 (cursor == 0) ? CURSOR_FORWARD : CURSOR_BACKWARD)); |
| 947 } | 948 } |
| 948 | 949 |
| 949 void RenderText::UpdateLayoutText() { | 950 void RenderText::UpdateLayoutText() { |
| 950 layout_text_.clear(); | 951 layout_text_.clear(); |
| 951 | 952 |
| 952 if (obscured_) { | 953 if (obscured_) { |
| 953 size_t obscured_text_length = | 954 size_t obscured_text_length = |
| 954 static_cast<size_t>(ui::UTF16IndexToOffset(text_, 0, text_.length())); | 955 static_cast<size_t>(ui::UTF16IndexToOffset(text_, 0, text_.length())); |
| 955 layout_text_.assign(obscured_text_length, kPasswordReplacementChar); | 956 layout_text_.assign(obscured_text_length, kPasswordReplacementChar); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1027 cursor_bounds_ += delta_offset; | 1028 cursor_bounds_ += delta_offset; |
| 1028 } | 1029 } |
| 1029 | 1030 |
| 1030 void RenderText::DrawSelection(Canvas* canvas) { | 1031 void RenderText::DrawSelection(Canvas* canvas) { |
| 1031 const std::vector<Rect> sel = GetSubstringBounds(selection()); | 1032 const std::vector<Rect> sel = GetSubstringBounds(selection()); |
| 1032 for (std::vector<Rect>::const_iterator i = sel.begin(); i < sel.end(); ++i) | 1033 for (std::vector<Rect>::const_iterator i = sel.begin(); i < sel.end(); ++i) |
| 1033 canvas->FillRect(*i, selection_background_focused_color_); | 1034 canvas->FillRect(*i, selection_background_focused_color_); |
| 1034 } | 1035 } |
| 1035 | 1036 |
| 1036 } // namespace gfx | 1037 } // namespace gfx |
| OLD | NEW |