OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |