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

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: GetClusterAt() 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') | ui/gfx/render_text_unittest.cc » ('J')
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>
msw 2015/03/25 20:25:16 nit: remove
Jun Mukai 2015/03/25 21:50:05 Done.
8 9
9 #include "base/i18n/bidi_line_iterator.h" 10 #include "base/i18n/bidi_line_iterator.h"
10 #include "base/i18n/break_iterator.h" 11 #include "base/i18n/break_iterator.h"
11 #include "base/i18n/char_iterator.h" 12 #include "base/i18n/char_iterator.h"
12 #include "base/profiler/scoped_tracker.h" 13 #include "base/profiler/scoped_tracker.h"
13 #include "base/strings/utf_string_conversions.h" 14 #include "base/strings/utf_string_conversions.h"
14 #include "base/trace_event/trace_event.h" 15 #include "base/trace_event/trace_event.h"
15 #include "third_party/harfbuzz-ng/src/hb.h" 16 #include "third_party/harfbuzz-ng/src/hb.h"
16 #include "third_party/icu/source/common/unicode/ubidi.h" 17 #include "third_party/icu/source/common/unicode/ubidi.h"
17 #include "third_party/skia/include/core/SkColor.h" 18 #include "third_party/skia/include/core/SkColor.h"
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 AdvanceLine(); 292 AdvanceLine();
292 } 293 }
293 } 294 }
294 295
295 // 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
296 // 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
297 // 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
298 // |*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
299 // lines). 300 // lines).
300 // Returns whether to skip the line before |*next_char|. 301 // Returns whether to skip the line before |*next_char|.
301 // TODO(ckocagil): Check clusters to avoid breaking ligatures and diacritics.
302 // TODO(ckocagil): We might have to reshape after breaking at ligatures. 302 // TODO(ckocagil): We might have to reshape after breaking at ligatures.
303 // See whether resolving the TODO above resolves this too. 303 // See whether resolving the TODO above resolves this too.
304 // 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.
305 bool BreakRunAtWidth(const internal::TextRunHarfBuzz& run, 305 bool BreakRunAtWidth(const internal::TextRunHarfBuzz& run,
306 size_t start_char, 306 size_t start_char,
307 SkScalar* width, 307 SkScalar* width,
308 size_t* next_char) { 308 size_t* next_char) {
309 DCHECK(words_); 309 DCHECK(words_);
310 DCHECK(run.range.Contains(Range(start_char, start_char + 1))); 310 DCHECK(run.range.Contains(Range(start_char, start_char + 1)));
311 SkScalar available_width = max_width_ - line_x_; 311 SkScalar available_width = max_width_ - line_x_;
312 BreakList<size_t>::const_iterator word = words_->GetBreak(start_char); 312 BreakList<size_t>::const_iterator word = words_->GetBreak(start_char);
313 BreakList<size_t>::const_iterator next_word = word + 1; 313 BreakList<size_t>::const_iterator next_word = word + 1;
314 // 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.
315 SkScalar word_width = 0; 315 SkScalar word_width = 0;
316 *width = 0; 316 *width = 0;
317 317
318 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()) {
319 // |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
320 // 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|
321 // when |i| reaches |next_word|. 322 // when |i| reaches |next_word|.
322 if (next_word != words_->breaks().end() && i >= next_word->first) { 323 if (next_word != words_->breaks().end() && i >= next_word->first) {
323 word = next_word++; 324 word = next_word++;
324 word_width = 0; 325 word_width = 0;
325 } 326 }
326 327
327 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
328 SkScalar char_width = ((glyph_range.end() >= run.glyph_count) 332 SkScalar char_width = ((glyph_range.end() >= run.glyph_count)
329 ? SkFloatToScalar(run.width) 333 ? SkFloatToScalar(run.width)
330 : run.positions[glyph_range.end()].x()) - 334 : run.positions[glyph_range.end()].x()) -
331 run.positions[glyph_range.start()].x(); 335 run.positions[glyph_range.start()].x();
332 336
333 *width += char_width; 337 *width += char_width;
334 word_width += char_width; 338 word_width += char_width;
335 339
336 if (*width > available_width) { 340 if (*width > available_width) {
337 if (line_x_ != 0 || word_width < *width) { 341 if (line_x_ != 0 || word_width < *width) {
338 // Roll back one word. 342 // Roll back one word.
339 *width -= word_width; 343 *width -= word_width;
340 *next_char = std::max(word->first, start_char); 344 *next_char = std::max(word->first, start_char);
341 } else if (char_width < *width) { 345 } else if (char_width < *width) {
342 // Roll back one character. 346 // Roll back one character.
343 *width -= char_width; 347 *width -= char_width;
344 *next_char = i; 348 *next_char = i;
345 } else { 349 } else {
346 // Continue from the next character. 350 // Continue from the next character.
347 *next_char = i + 1; 351 *next_char = i + char_range.length();
348 } 352 }
349 return true; 353 return true;
350 } 354 }
351 } 355 }
352 356
353 *next_char = run.range.end(); 357 *next_char = run.range.end();
354 return false; 358 return false;
355 } 359 }
356 360
357 // 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 1157 matching lines...) Expand 10 before | Expand all | Expand 10 after
1515 DCHECK(!update_layout_run_list_); 1519 DCHECK(!update_layout_run_list_);
1516 DCHECK(!update_display_run_list_); 1520 DCHECK(!update_display_run_list_);
1517 return text_elided() ? display_run_list_.get() : &layout_run_list_; 1521 return text_elided() ? display_run_list_.get() : &layout_run_list_;
1518 } 1522 }
1519 1523
1520 const internal::TextRunList* RenderTextHarfBuzz::GetRunList() const { 1524 const internal::TextRunList* RenderTextHarfBuzz::GetRunList() const {
1521 return const_cast<RenderTextHarfBuzz*>(this)->GetRunList(); 1525 return const_cast<RenderTextHarfBuzz*>(this)->GetRunList();
1522 } 1526 }
1523 1527
1524 } // namespace gfx 1528 } // namespace gfx
OLDNEW
« no previous file with comments | « no previous file | ui/gfx/render_text_unittest.cc » ('j') | ui/gfx/render_text_unittest.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698