Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(294)

Side by Side Diff: ui/gfx/render_text_harfbuzz.cc

Issue 2379033004: Optimize some code in RenderTextHarfbuzz. (Closed)
Patch Set: Nits & git cl format Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/gfx/render_text_harfbuzz.h ('k') | ui/gfx/render_text_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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_harfbuzz.h" 5 #include "ui/gfx/render_text_harfbuzz.h"
6 6
7 #include <limits> 7 #include <limits>
8 #include <set> 8 #include <set>
9 9
10 #include "base/i18n/bidi_line_iterator.h" 10 #include "base/i18n/bidi_line_iterator.h"
(...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after
638 if (is_rtl) { 638 if (is_rtl) {
639 GetClusterAtImpl(pos, range, glyph_to_char.rbegin(), glyph_to_char.rend(), 639 GetClusterAtImpl(pos, range, glyph_to_char.rbegin(), glyph_to_char.rend(),
640 true, chars, glyphs); 640 true, chars, glyphs);
641 return; 641 return;
642 } 642 }
643 643
644 GetClusterAtImpl(pos, range, glyph_to_char.begin(), glyph_to_char.end(), 644 GetClusterAtImpl(pos, range, glyph_to_char.begin(), glyph_to_char.end(),
645 false, chars, glyphs); 645 false, chars, glyphs);
646 } 646 }
647 647
648 RangeF TextRunHarfBuzz::GetGraphemeBounds( 648 RangeF TextRunHarfBuzz::GetGraphemeBounds(RenderTextHarfBuzz* render_text,
649 base::i18n::BreakIterator* grapheme_iterator, 649 size_t text_index) {
650 size_t text_index) {
651 DCHECK_LT(text_index, range.end()); 650 DCHECK_LT(text_index, range.end());
652 if (glyph_count == 0) 651 if (glyph_count == 0)
653 return RangeF(preceding_run_widths, preceding_run_widths + width); 652 return RangeF(preceding_run_widths, preceding_run_widths + width);
654 653
655 Range chars; 654 Range chars;
656 Range glyphs; 655 Range glyphs;
657 GetClusterAt(text_index, &chars, &glyphs); 656 GetClusterAt(text_index, &chars, &glyphs);
658 const float cluster_begin_x = positions[glyphs.start()].x(); 657 const float cluster_begin_x = positions[glyphs.start()].x();
659 const float cluster_end_x = glyphs.end() < glyph_count ? 658 const float cluster_end_x = glyphs.end() < glyph_count ?
660 positions[glyphs.end()].x() : SkFloatToScalar(width); 659 positions[glyphs.end()].x() : SkFloatToScalar(width);
661 660
662 // A cluster consists of a number of code points and corresponds to a number 661 // A cluster consists of a number of code points and corresponds to a number
663 // of glyphs that should be drawn together. A cluster can contain multiple 662 // of glyphs that should be drawn together. A cluster can contain multiple
664 // graphemes. In order to place the cursor at a grapheme boundary inside the 663 // graphemes. In order to place the cursor at a grapheme boundary inside the
665 // cluster, we simply divide the cluster width by the number of graphemes. 664 // cluster, we simply divide the cluster width by the number of graphemes.
666 if (chars.length() > 1 && grapheme_iterator) { 665 // Note: The first call to GetGraphemeIterator() can be expensive, so avoid
666 // doing it unless it's actually needed (when length > 1).
667 if (chars.length() > 1 && render_text->GetGraphemeIterator()) {
667 int before = 0; 668 int before = 0;
668 int total = 0; 669 int total = 0;
670 base::i18n::BreakIterator* grapheme_iterator =
671 render_text->GetGraphemeIterator();
669 for (size_t i = chars.start(); i < chars.end(); ++i) { 672 for (size_t i = chars.start(); i < chars.end(); ++i) {
670 if (grapheme_iterator->IsGraphemeBoundary(i)) { 673 if (grapheme_iterator->IsGraphemeBoundary(i)) {
671 if (i < text_index) 674 if (i < text_index)
672 ++before; 675 ++before;
673 ++total; 676 ++total;
674 } 677 }
675 } 678 }
676 DCHECK_GT(total, 0); 679 DCHECK_GT(total, 0);
677 if (total > 1) { 680 if (total > 1) {
678 if (is_rtl) 681 if (is_rtl)
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
862 Range RenderTextHarfBuzz::GetGlyphBounds(size_t index) { 865 Range RenderTextHarfBuzz::GetGlyphBounds(size_t index) {
863 EnsureLayout(); 866 EnsureLayout();
864 const size_t run_index = 867 const size_t run_index =
865 GetRunContainingCaret(SelectionModel(index, CURSOR_FORWARD)); 868 GetRunContainingCaret(SelectionModel(index, CURSOR_FORWARD));
866 internal::TextRunList* run_list = GetRunList(); 869 internal::TextRunList* run_list = GetRunList();
867 // Return edge bounds if the index is invalid or beyond the layout text size. 870 // Return edge bounds if the index is invalid or beyond the layout text size.
868 if (run_index >= run_list->size()) 871 if (run_index >= run_list->size())
869 return Range(GetStringSize().width()); 872 return Range(GetStringSize().width());
870 const size_t layout_index = TextIndexToDisplayIndex(index); 873 const size_t layout_index = TextIndexToDisplayIndex(index);
871 internal::TextRunHarfBuzz* run = run_list->runs()[run_index]; 874 internal::TextRunHarfBuzz* run = run_list->runs()[run_index];
872 RangeF bounds = 875 RangeF bounds = run->GetGraphemeBounds(this, layout_index);
873 run->GetGraphemeBounds(GetGraphemeIterator(), layout_index);
874 // If cursor is enabled, extend the last glyph up to the rightmost cursor 876 // If cursor is enabled, extend the last glyph up to the rightmost cursor
875 // position since clients expect them to be contiguous. 877 // position since clients expect them to be contiguous.
876 if (cursor_enabled() && run_index == run_list->size() - 1 && 878 if (cursor_enabled() && run_index == run_list->size() - 1 &&
877 index == (run->is_rtl ? run->range.start() : run->range.end() - 1)) 879 index == (run->is_rtl ? run->range.start() : run->range.end() - 1))
878 bounds.set_end(std::ceil(bounds.end())); 880 bounds.set_end(std::ceil(bounds.end()));
879 return run->is_rtl ? RangeF(bounds.end(), bounds.start()).Round() 881 return run->is_rtl ? RangeF(bounds.end(), bounds.start()).Round()
880 : bounds.Round(); 882 : bounds.Round();
881 } 883 }
882 884
885 base::i18n::BreakIterator* RenderTextHarfBuzz::GetGraphemeIterator() {
886 if (update_grapheme_iterator_) {
887 update_grapheme_iterator_ = false;
888 grapheme_iterator_.reset(new base::i18n::BreakIterator(
889 GetDisplayText(), base::i18n::BreakIterator::BREAK_CHARACTER));
890 if (!grapheme_iterator_->Init())
891 grapheme_iterator_.reset();
892 }
893 return grapheme_iterator_.get();
894 }
895
883 int RenderTextHarfBuzz::GetDisplayTextBaseline() { 896 int RenderTextHarfBuzz::GetDisplayTextBaseline() {
884 EnsureLayout(); 897 EnsureLayout();
885 return lines()[0].baseline; 898 return lines()[0].baseline;
886 } 899 }
887 900
888 SelectionModel RenderTextHarfBuzz::AdjacentCharSelectionModel( 901 SelectionModel RenderTextHarfBuzz::AdjacentCharSelectionModel(
889 const SelectionModel& selection, 902 const SelectionModel& selection,
890 VisualCursorDirection direction) { 903 VisualCursorDirection direction) {
891 DCHECK(!update_display_run_list_); 904 DCHECK(!update_display_run_list_);
892 905
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1012 for (size_t i = 0; i < run_list->size(); ++i) { 1025 for (size_t i = 0; i < run_list->size(); ++i) {
1013 internal::TextRunHarfBuzz* run = 1026 internal::TextRunHarfBuzz* run =
1014 run_list->runs()[run_list->visual_to_logical(i)]; 1027 run_list->runs()[run_list->visual_to_logical(i)];
1015 Range intersection = run->range.Intersect(layout_range); 1028 Range intersection = run->range.Intersect(layout_range);
1016 if (!intersection.IsValid()) 1029 if (!intersection.IsValid())
1017 continue; 1030 continue;
1018 DCHECK(!intersection.is_reversed()); 1031 DCHECK(!intersection.is_reversed());
1019 const size_t left_index = 1032 const size_t left_index =
1020 run->is_rtl ? intersection.end() - 1 : intersection.start(); 1033 run->is_rtl ? intersection.end() - 1 : intersection.start();
1021 const Range leftmost_character_x = 1034 const Range leftmost_character_x =
1022 run->GetGraphemeBounds(GetGraphemeIterator(), left_index).Round(); 1035 run->GetGraphemeBounds(this, left_index).Round();
1023 const size_t right_index = 1036 const size_t right_index =
1024 run->is_rtl ? intersection.start() : intersection.end() - 1; 1037 run->is_rtl ? intersection.start() : intersection.end() - 1;
1025 const Range rightmost_character_x = 1038 const Range rightmost_character_x =
1026 run->GetGraphemeBounds(GetGraphemeIterator(), right_index).Round(); 1039 run->GetGraphemeBounds(this, right_index).Round();
1027 Range range_x(leftmost_character_x.start(), rightmost_character_x.end()); 1040 Range range_x(leftmost_character_x.start(), rightmost_character_x.end());
1028 DCHECK(!range_x.is_reversed()); 1041 DCHECK(!range_x.is_reversed());
1029 if (range_x.is_empty()) 1042 if (range_x.is_empty())
1030 continue; 1043 continue;
1031 1044
1032 // Union this with the last range if they're adjacent. 1045 // Union this with the last range if they're adjacent.
1033 DCHECK(bounds.empty() || bounds.back().GetMax() <= range_x.GetMin()); 1046 DCHECK(bounds.empty() || bounds.back().GetMax() <= range_x.GetMin());
1034 if (!bounds.empty() && bounds.back().GetMax() == range_x.GetMin()) { 1047 if (!bounds.empty() && bounds.back().GetMax() == range_x.GetMin()) {
1035 range_x = Range(bounds.back().GetMin(), range_x.GetMax()); 1048 range_x = Range(bounds.back().GetMin(), range_x.GetMax());
1036 bounds.pop_back(); 1049 bounds.pop_back();
(...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after
1561 update_display_text_ = true; 1574 update_display_text_ = true;
1562 update_layout_run_list_ = false; 1575 update_layout_run_list_ = false;
1563 } 1576 }
1564 if (update_display_text_) { 1577 if (update_display_text_) {
1565 UpdateDisplayText(multiline() ? 0 : layout_run_list_.width()); 1578 UpdateDisplayText(multiline() ? 0 : layout_run_list_.width());
1566 update_display_text_ = false; 1579 update_display_text_ = false;
1567 update_display_run_list_ = text_elided(); 1580 update_display_run_list_ = text_elided();
1568 } 1581 }
1569 } 1582 }
1570 1583
1571 base::i18n::BreakIterator* RenderTextHarfBuzz::GetGraphemeIterator() {
1572 if (update_grapheme_iterator_) {
1573 update_grapheme_iterator_ = false;
1574 grapheme_iterator_.reset(new base::i18n::BreakIterator(
1575 GetDisplayText(),
1576 base::i18n::BreakIterator::BREAK_CHARACTER));
1577 if (!grapheme_iterator_->Init())
1578 grapheme_iterator_.reset();
1579 }
1580 return grapheme_iterator_.get();
1581 }
1582
1583 internal::TextRunList* RenderTextHarfBuzz::GetRunList() { 1584 internal::TextRunList* RenderTextHarfBuzz::GetRunList() {
1584 DCHECK(!update_layout_run_list_); 1585 DCHECK(!update_layout_run_list_);
1585 DCHECK(!update_display_run_list_); 1586 DCHECK(!update_display_run_list_);
1586 return text_elided() ? display_run_list_.get() : &layout_run_list_; 1587 return text_elided() ? display_run_list_.get() : &layout_run_list_;
1587 } 1588 }
1588 1589
1589 const internal::TextRunList* RenderTextHarfBuzz::GetRunList() const { 1590 const internal::TextRunList* RenderTextHarfBuzz::GetRunList() const {
1590 return const_cast<RenderTextHarfBuzz*>(this)->GetRunList(); 1591 return const_cast<RenderTextHarfBuzz*>(this)->GetRunList();
1591 } 1592 }
1592 1593
1593 } // namespace gfx 1594 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gfx/render_text_harfbuzz.h ('k') | ui/gfx/render_text_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698