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

Unified Diff: ui/gfx/render_text_harfbuzz.cc

Issue 1070223004: Stop combining text runs which are connected by 'COMMON' blocks. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Make sure multiline breaker behavior is correct. Created 5 years, 8 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 side-by-side diff with in-line comments
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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/gfx/render_text_harfbuzz.cc
diff --git a/ui/gfx/render_text_harfbuzz.cc b/ui/gfx/render_text_harfbuzz.cc
index 32a9e554f60b47127cef9d426aef71a9f410adfa..2442daf466f324e8acb37e6db3bd15f0b4094033 100644
--- a/ui/gfx/render_text_harfbuzz.cc
+++ b/ui/gfx/render_text_harfbuzz.cc
@@ -90,15 +90,12 @@ size_t FindRunBreakingCharacter(const base::string16& text,
return run_break;
}
-// If the given scripts match, returns the one that isn't USCRIPT_COMMON or
-// USCRIPT_INHERITED, i.e. the more specific one. Otherwise returns
-// USCRIPT_INVALID_CODE.
+// If the given scripts match, returns the one that isn't USCRIPT_INHERITED,
+// i.e. the more specific one. Otherwise returns USCRIPT_INVALID_CODE.
UScriptCode ScriptIntersect(UScriptCode first, UScriptCode second) {
- if (first == second ||
- (second > USCRIPT_INVALID_CODE && second <= USCRIPT_INHERITED)) {
+ if (first == second || second == USCRIPT_INHERITED)
return first;
- }
- if (first > USCRIPT_INVALID_CODE && first <= USCRIPT_INHERITED)
+ if (first == USCRIPT_INHERITED)
return second;
return USCRIPT_INVALID_CODE;
}
@@ -167,6 +164,12 @@ int ScriptInterval(const base::string16& text,
while (char_iterator.Advance()) {
ScriptSetIntersect(char_iterator.get(), scripts, &scripts_size);
+ // Special handling for white space. White space should be merged into the
msw 2015/04/23 00:00:38 nit: "Special handling to merge white space into t
xdai1 2015/04/23 22:59:42 Done.
+ // previous run.
+ if (u_isUWhiteSpace(char_iterator.get())) {
msw 2015/04/23 00:00:38 Just "continue;" instead of faking out |scripts| a
xdai1 2015/04/23 22:59:42 Actually this is depending on how we want to break
+ scripts[0] = *script;
+ scripts_size = 1U;
+ }
if (scripts_size == 0U)
return char_iterator.array_pos();
*script = scripts[0];
@@ -318,7 +321,8 @@ class HarfBuzzLineBreaker {
BreakList<size_t>::const_iterator word = words_->GetBreak(start_char);
BreakList<size_t>::const_iterator next_word = word + 1;
// Width from |std::max(word->first, start_char)| to the current character.
- SkScalar word_width = 0;
+ SkScalar word_width =
msw 2015/04/23 00:00:38 Is this necessary for the run breaking change? Can
xdai1 2015/04/23 22:59:42 Yes, it has to be modified as described in the CL
+ start_char == 0 ? 0 : GetGlyphWidth(word->first, start_char - 1);
*width = 0;
Range char_range;
@@ -355,7 +359,8 @@ class HarfBuzzLineBreaker {
// TODO(mukai): implement ELIDE_LONG_WORDS.
if (*width > available_width) {
- if (line_x_ != 0 || word_width < *width) {
+ if ((line_x_ != 0 && word_width <= *width) ||
+ (line_x_ == 0 && word_width < *width)) {
// Roll back one word.
*width -= word_width;
*next_char = std::max(word->first, start_char);
@@ -470,6 +475,65 @@ class HarfBuzzLineBreaker {
line_x_ += SkFloatToScalar(width);
}
+ // Returns the index for the run that contains text_[pos] using binary search.
+ size_t GetRunIndexAt(size_t pos) const {
+ pos = (pos < text_.size()) ? pos : text_.size() - 1;
+ size_t low = 0, high = run_list_.size() - 1;
+ while (low <= high) {
+ size_t mid = low + (high - low) / 2;
+ if (run_list_.runs()[mid]->range.start() <= pos &&
+ run_list_.runs()[mid]->range.end() > pos)
+ return mid;
+ else if (run_list_.runs()[mid]->range.start() > pos)
+ high = mid - 1;
+ else
+ low = mid + 1;
+ }
+ return 0;
+ }
+
+ // Returns the glyph width for |text_| between [start_pos, end_pos].
+ SkScalar GetGlyphWidth(size_t start_pos, size_t end_pos) const {
+ end_pos = (end_pos < text_.size()) ? end_pos : text_.size() - 1;
+ if (start_pos > end_pos)
+ return 0;
+
+ // Finding the runs that containing |start_char| and |end_char|.
+ size_t start_run_idx = GetRunIndexAt(start_pos);
+ size_t end_run_idx = GetRunIndexAt(end_pos);
+ const internal::TextRunHarfBuzz* start_run =
+ run_list_.runs()[start_run_idx];
+ const internal::TextRunHarfBuzz* end_run = run_list_.runs()[end_run_idx];
+
+ SkScalar width = 0;
+ for (size_t i = start_run_idx; i <= end_run_idx; ++i) {
+ width += run_list_.runs()[i]->width;
+ }
+
+ Range char_range;
+ Range glyph_range;
+ for (size_t pos = start_run->range.start(); pos < start_pos; ++pos) {
+ start_run->GetClusterAt(pos, &char_range, &glyph_range);
+ SkScalar char_width =
+ ((glyph_range.end() >= start_run->glyph_count)
+ ? SkFloatToScalar(start_run->width)
+ : start_run->positions[glyph_range.end()].x()) -
+ start_run->positions[glyph_range.start()].x();
+ width -= char_width;
+ }
+
+ for (size_t pos = end_pos + 1; pos < end_run->range.end(); ++pos) {
+ end_run->GetClusterAt(pos, &char_range, &glyph_range);
+ SkScalar char_width = ((glyph_range.end() >= end_run->glyph_count)
+ ? SkFloatToScalar(end_run->width)
+ : end_run->positions[glyph_range.end()].x()) -
+ end_run->positions[glyph_range.start()].x();
+ width -= char_width;
+ }
+
+ return width;
+ }
+
const SkScalar max_width_;
const int min_baseline_;
const float min_height_;
« 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