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

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

Issue 2379033004: Optimize some code in RenderTextHarfbuzz. (Closed)
Patch Set: . 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
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 628 matching lines...) Expand 10 before | Expand all | Expand 10 after
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(
649 base::i18n::BreakIterator* grapheme_iterator, 649 RenderTextHarfBuzz* render_text,
msw 2016/09/30 19:10:17 nit: fits on line above (git cl format)
Alexei Svitkine (slow) 2016/09/30 19:14:16 Done.
650 size_t text_index) { 650 size_t text_index) {
651 DCHECK_LT(text_index, range.end()); 651 DCHECK_LT(text_index, range.end());
652 if (glyph_count == 0) 652 if (glyph_count == 0)
653 return RangeF(preceding_run_widths, preceding_run_widths + width); 653 return RangeF(preceding_run_widths, preceding_run_widths + width);
654 654
655 Range chars; 655 Range chars;
656 Range glyphs; 656 Range glyphs;
657 GetClusterAt(text_index, &chars, &glyphs); 657 GetClusterAt(text_index, &chars, &glyphs);
658 const float cluster_begin_x = positions[glyphs.start()].x(); 658 const float cluster_begin_x = positions[glyphs.start()].x();
659 const float cluster_end_x = glyphs.end() < glyph_count ? 659 const float cluster_end_x = glyphs.end() < glyph_count ?
660 positions[glyphs.end()].x() : SkFloatToScalar(width); 660 positions[glyphs.end()].x() : SkFloatToScalar(width);
661 661
662 // A cluster consists of a number of code points and corresponds to a number 662 // 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 663 // 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 664 // 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. 665 // cluster, we simply divide the cluster width by the number of graphemes.
666 if (chars.length() > 1 && grapheme_iterator) { 666 // Note: The first call to GetGraphemeIterator() can be expensive, so avoid
667 // doing it unless it's actually needed (when length > 1).
668 if (chars.length() > 1 && render_text->GetGraphemeIterator()) {
667 int before = 0; 669 int before = 0;
668 int total = 0; 670 int total = 0;
671 base::i18n::BreakIterator* grapheme_iterator =
672 render_text->GetGraphemeIterator();
669 for (size_t i = chars.start(); i < chars.end(); ++i) { 673 for (size_t i = chars.start(); i < chars.end(); ++i) {
670 if (grapheme_iterator->IsGraphemeBoundary(i)) { 674 if (grapheme_iterator->IsGraphemeBoundary(i)) {
671 if (i < text_index) 675 if (i < text_index)
672 ++before; 676 ++before;
673 ++total; 677 ++total;
674 } 678 }
675 } 679 }
676 DCHECK_GT(total, 0); 680 DCHECK_GT(total, 0);
677 if (total > 1) { 681 if (total > 1) {
678 if (is_rtl) 682 if (is_rtl)
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
862 Range RenderTextHarfBuzz::GetGlyphBounds(size_t index) { 866 Range RenderTextHarfBuzz::GetGlyphBounds(size_t index) {
863 EnsureLayout(); 867 EnsureLayout();
864 const size_t run_index = 868 const size_t run_index =
865 GetRunContainingCaret(SelectionModel(index, CURSOR_FORWARD)); 869 GetRunContainingCaret(SelectionModel(index, CURSOR_FORWARD));
866 internal::TextRunList* run_list = GetRunList(); 870 internal::TextRunList* run_list = GetRunList();
867 // Return edge bounds if the index is invalid or beyond the layout text size. 871 // Return edge bounds if the index is invalid or beyond the layout text size.
868 if (run_index >= run_list->size()) 872 if (run_index >= run_list->size())
869 return Range(GetStringSize().width()); 873 return Range(GetStringSize().width());
870 const size_t layout_index = TextIndexToDisplayIndex(index); 874 const size_t layout_index = TextIndexToDisplayIndex(index);
871 internal::TextRunHarfBuzz* run = run_list->runs()[run_index]; 875 internal::TextRunHarfBuzz* run = run_list->runs()[run_index];
872 RangeF bounds = 876 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 877 // If cursor is enabled, extend the last glyph up to the rightmost cursor
875 // position since clients expect them to be contiguous. 878 // position since clients expect them to be contiguous.
876 if (cursor_enabled() && run_index == run_list->size() - 1 && 879 if (cursor_enabled() && run_index == run_list->size() - 1 &&
877 index == (run->is_rtl ? run->range.start() : run->range.end() - 1)) 880 index == (run->is_rtl ? run->range.start() : run->range.end() - 1))
878 bounds.set_end(std::ceil(bounds.end())); 881 bounds.set_end(std::ceil(bounds.end()));
879 return run->is_rtl ? RangeF(bounds.end(), bounds.start()).Round() 882 return run->is_rtl ? RangeF(bounds.end(), bounds.start()).Round()
880 : bounds.Round(); 883 : bounds.Round();
881 } 884 }
882 885
886 base::i18n::BreakIterator* RenderTextHarfBuzz::GetGraphemeIterator() {
887 if (update_grapheme_iterator_) {
888 update_grapheme_iterator_ = false;
889 grapheme_iterator_.reset(new base::i18n::BreakIterator(
890 GetDisplayText(),
891 base::i18n::BreakIterator::BREAK_CHARACTER));
892 if (!grapheme_iterator_->Init())
893 grapheme_iterator_.reset();
894 }
895 return grapheme_iterator_.get();
896 }
897
883 int RenderTextHarfBuzz::GetDisplayTextBaseline() { 898 int RenderTextHarfBuzz::GetDisplayTextBaseline() {
884 EnsureLayout(); 899 EnsureLayout();
885 return lines()[0].baseline; 900 return lines()[0].baseline;
886 } 901 }
887 902
888 SelectionModel RenderTextHarfBuzz::AdjacentCharSelectionModel( 903 SelectionModel RenderTextHarfBuzz::AdjacentCharSelectionModel(
889 const SelectionModel& selection, 904 const SelectionModel& selection,
890 VisualCursorDirection direction) { 905 VisualCursorDirection direction) {
891 DCHECK(!update_display_run_list_); 906 DCHECK(!update_display_run_list_);
892 907
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1012 for (size_t i = 0; i < run_list->size(); ++i) { 1027 for (size_t i = 0; i < run_list->size(); ++i) {
1013 internal::TextRunHarfBuzz* run = 1028 internal::TextRunHarfBuzz* run =
1014 run_list->runs()[run_list->visual_to_logical(i)]; 1029 run_list->runs()[run_list->visual_to_logical(i)];
1015 Range intersection = run->range.Intersect(layout_range); 1030 Range intersection = run->range.Intersect(layout_range);
1016 if (!intersection.IsValid()) 1031 if (!intersection.IsValid())
1017 continue; 1032 continue;
1018 DCHECK(!intersection.is_reversed()); 1033 DCHECK(!intersection.is_reversed());
1019 const size_t left_index = 1034 const size_t left_index =
1020 run->is_rtl ? intersection.end() - 1 : intersection.start(); 1035 run->is_rtl ? intersection.end() - 1 : intersection.start();
1021 const Range leftmost_character_x = 1036 const Range leftmost_character_x =
1022 run->GetGraphemeBounds(GetGraphemeIterator(), left_index).Round(); 1037 run->GetGraphemeBounds(this, left_index).Round();
1023 const size_t right_index = 1038 const size_t right_index =
1024 run->is_rtl ? intersection.start() : intersection.end() - 1; 1039 run->is_rtl ? intersection.start() : intersection.end() - 1;
1025 const Range rightmost_character_x = 1040 const Range rightmost_character_x =
1026 run->GetGraphemeBounds(GetGraphemeIterator(), right_index).Round(); 1041 run->GetGraphemeBounds(this, right_index).Round();
1027 Range range_x(leftmost_character_x.start(), rightmost_character_x.end()); 1042 Range range_x(leftmost_character_x.start(), rightmost_character_x.end());
1028 DCHECK(!range_x.is_reversed()); 1043 DCHECK(!range_x.is_reversed());
1029 if (range_x.is_empty()) 1044 if (range_x.is_empty())
1030 continue; 1045 continue;
1031 1046
1032 // Union this with the last range if they're adjacent. 1047 // Union this with the last range if they're adjacent.
1033 DCHECK(bounds.empty() || bounds.back().GetMax() <= range_x.GetMin()); 1048 DCHECK(bounds.empty() || bounds.back().GetMax() <= range_x.GetMin());
1034 if (!bounds.empty() && bounds.back().GetMax() == range_x.GetMin()) { 1049 if (!bounds.empty() && bounds.back().GetMax() == range_x.GetMin()) {
1035 range_x = Range(bounds.back().GetMin(), range_x.GetMax()); 1050 range_x = Range(bounds.back().GetMin(), range_x.GetMax());
1036 bounds.pop_back(); 1051 bounds.pop_back();
(...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after
1561 update_display_text_ = true; 1576 update_display_text_ = true;
1562 update_layout_run_list_ = false; 1577 update_layout_run_list_ = false;
1563 } 1578 }
1564 if (update_display_text_) { 1579 if (update_display_text_) {
1565 UpdateDisplayText(multiline() ? 0 : layout_run_list_.width()); 1580 UpdateDisplayText(multiline() ? 0 : layout_run_list_.width());
1566 update_display_text_ = false; 1581 update_display_text_ = false;
1567 update_display_run_list_ = text_elided(); 1582 update_display_run_list_ = text_elided();
1568 } 1583 }
1569 } 1584 }
1570 1585
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() { 1586 internal::TextRunList* RenderTextHarfBuzz::GetRunList() {
1584 DCHECK(!update_layout_run_list_); 1587 DCHECK(!update_layout_run_list_);
1585 DCHECK(!update_display_run_list_); 1588 DCHECK(!update_display_run_list_);
1586 return text_elided() ? display_run_list_.get() : &layout_run_list_; 1589 return text_elided() ? display_run_list_.get() : &layout_run_list_;
1587 } 1590 }
1588 1591
1589 const internal::TextRunList* RenderTextHarfBuzz::GetRunList() const { 1592 const internal::TextRunList* RenderTextHarfBuzz::GetRunList() const {
1590 return const_cast<RenderTextHarfBuzz*>(this)->GetRunList(); 1593 return const_cast<RenderTextHarfBuzz*>(this)->GetRunList();
1591 } 1594 }
1592 1595
1593 } // namespace gfx 1596 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698