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

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

Issue 1036663003: Break runs by clusters rather than iteration over code points (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: win/mac test fix Created 5 years, 9 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 | « no previous file | 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 8
9 #include "base/i18n/bidi_line_iterator.h" 9 #include "base/i18n/bidi_line_iterator.h"
10 #include "base/i18n/break_iterator.h" 10 #include "base/i18n/break_iterator.h"
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 AdvanceLine(); 292 AdvanceLine();
293 } 293 }
294 } 294 }
295 295
296 // Starting from |start_char|, finds a suitable line break position at or 296 // Starting from |start_char|, finds a suitable line break position at or
297 // before available width using word break. If the current position is at the 297 // before available width using word break. If the current position is at the
298 // beginning of a line, this function will not roll back to |start_char| and 298 // beginning of a line, this function will not roll back to |start_char| and
299 // |*next_char| will be greater than |start_char| (to avoid constructing empty 299 // |*next_char| will be greater than |start_char| (to avoid constructing empty
300 // lines). 300 // lines).
301 // Returns whether to skip the line before |*next_char|. 301 // Returns whether to skip the line before |*next_char|.
302 // TODO(ckocagil): Check clusters to avoid breaking ligatures and diacritics.
303 // TODO(ckocagil): We might have to reshape after breaking at ligatures. 302 // TODO(ckocagil): We might have to reshape after breaking at ligatures.
304 // See whether resolving the TODO above resolves this too. 303 // See whether resolving the TODO above resolves this too.
305 // TODO(ckocagil): Do not reserve width for whitespace at the end of lines. 304 // TODO(ckocagil): Do not reserve width for whitespace at the end of lines.
306 bool BreakRunAtWidth(const internal::TextRunHarfBuzz& run, 305 bool BreakRunAtWidth(const internal::TextRunHarfBuzz& run,
307 size_t start_char, 306 size_t start_char,
308 SkScalar* width, 307 SkScalar* width,
309 size_t* next_char) { 308 size_t* next_char) {
310 DCHECK(words_); 309 DCHECK(words_);
311 DCHECK(run.range.Contains(Range(start_char, start_char + 1))); 310 DCHECK(run.range.Contains(Range(start_char, start_char + 1)));
312 SkScalar available_width = max_width_ - line_x_; 311 SkScalar available_width = max_width_ - line_x_;
313 BreakList<size_t>::const_iterator word = words_->GetBreak(start_char); 312 BreakList<size_t>::const_iterator word = words_->GetBreak(start_char);
314 BreakList<size_t>::const_iterator next_word = word + 1; 313 BreakList<size_t>::const_iterator next_word = word + 1;
315 // Width from |std::max(word->first, start_char)| to the current character. 314 // Width from |std::max(word->first, start_char)| to the current character.
316 SkScalar word_width = 0; 315 SkScalar word_width = 0;
317 *width = 0; 316 *width = 0;
318 317
319 for (size_t i = start_char; i < run.range.end(); ++i) { 318 Range char_range;
319 for (size_t i = start_char; i < run.range.end(); i += char_range.length()) {
320 // |word| holds the word boundary at or before |i|, and |next_word| holds 320 // |word| holds the word boundary at or before |i|, and |next_word| holds
321 // the word boundary right after |i|. Advance both |word| and |next_word| 321 // the word boundary right after |i|. Advance both |word| and |next_word|
322 // when |i| reaches |next_word|. 322 // when |i| reaches |next_word|.
323 if (next_word != words_->breaks().end() && i >= next_word->first) { 323 if (next_word != words_->breaks().end() && i >= next_word->first) {
324 word = next_word++; 324 word = next_word++;
325 word_width = 0; 325 word_width = 0;
326 } 326 }
327 327
328 Range glyph_range = run.CharRangeToGlyphRange(Range(i, i + 1)); 328 Range glyph_range;
329 run.GetClusterAt(i, &char_range, &glyph_range);
330 DCHECK_LT(0U, char_range.length());
331
329 SkScalar char_width = ((glyph_range.end() >= run.glyph_count) 332 SkScalar char_width = ((glyph_range.end() >= run.glyph_count)
330 ? SkFloatToScalar(run.width) 333 ? SkFloatToScalar(run.width)
331 : run.positions[glyph_range.end()].x()) - 334 : run.positions[glyph_range.end()].x()) -
332 run.positions[glyph_range.start()].x(); 335 run.positions[glyph_range.start()].x();
333 336
334 *width += char_width; 337 *width += char_width;
335 word_width += char_width; 338 word_width += char_width;
336 339
337 if (*width > available_width) { 340 if (*width > available_width) {
338 if (line_x_ != 0 || word_width < *width) { 341 if (line_x_ != 0 || word_width < *width) {
339 // Roll back one word. 342 // Roll back one word.
340 *width -= word_width; 343 *width -= word_width;
341 *next_char = std::max(word->first, start_char); 344 *next_char = std::max(word->first, start_char);
342 } else if (char_width < *width) { 345 } else if (char_width < *width) {
343 // Roll back one character. 346 // Roll back one character.
344 *width -= char_width; 347 *width -= char_width;
345 *next_char = i; 348 *next_char = i;
346 } else { 349 } else {
347 // Continue from the next character. 350 // Continue from the next character.
348 *next_char = i + 1; 351 *next_char = i + char_range.length();
349 } 352 }
350 return true; 353 return true;
351 } 354 }
352 } 355 }
353 356
354 *next_char = run.range.end(); 357 *next_char = run.range.end();
355 return false; 358 return false;
356 } 359 }
357 360
358 // RTL runs are broken in logical order but displayed in visual order. To find 361 // RTL runs are broken in logical order but displayed in visual order. To find
(...skipping 1160 matching lines...) Expand 10 before | Expand all | Expand 10 after
1519 DCHECK(!update_layout_run_list_); 1522 DCHECK(!update_layout_run_list_);
1520 DCHECK(!update_display_run_list_); 1523 DCHECK(!update_display_run_list_);
1521 return text_elided() ? display_run_list_.get() : &layout_run_list_; 1524 return text_elided() ? display_run_list_.get() : &layout_run_list_;
1522 } 1525 }
1523 1526
1524 const internal::TextRunList* RenderTextHarfBuzz::GetRunList() const { 1527 const internal::TextRunList* RenderTextHarfBuzz::GetRunList() const {
1525 return const_cast<RenderTextHarfBuzz*>(this)->GetRunList(); 1528 return const_cast<RenderTextHarfBuzz*>(this)->GetRunList();
1526 } 1529 }
1527 1530
1528 } // namespace gfx 1531 } // namespace gfx
OLDNEW
« no previous file with comments | « no previous file | ui/gfx/render_text_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698