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 |