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> | |
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 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
307 SkScalar* width, | 308 SkScalar* width, |
308 size_t* next_char) { | 309 size_t* next_char) { |
309 DCHECK(words_); | 310 DCHECK(words_); |
310 DCHECK(run.range.Contains(Range(start_char, start_char + 1))); | 311 DCHECK(run.range.Contains(Range(start_char, start_char + 1))); |
311 SkScalar available_width = max_width_ - line_x_; | 312 SkScalar available_width = max_width_ - line_x_; |
312 BreakList<size_t>::const_iterator word = words_->GetBreak(start_char); | 313 BreakList<size_t>::const_iterator word = words_->GetBreak(start_char); |
313 BreakList<size_t>::const_iterator next_word = word + 1; | 314 BreakList<size_t>::const_iterator next_word = word + 1; |
314 // Width from |std::max(word->first, start_char)| to the current character. | 315 // Width from |std::max(word->first, start_char)| to the current character. |
315 SkScalar word_width = 0; | 316 SkScalar word_width = 0; |
316 *width = 0; | 317 *width = 0; |
318 std::set<size_t> used_glyphs; | |
317 | 319 |
318 for (size_t i = start_char; i < run.range.end(); ++i) { | 320 for (size_t i = start_char; i < run.range.end(); ++i) { |
319 // |word| holds the word boundary at or before |i|, and |next_word| holds | 321 // |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| | 322 // the word boundary right after |i|. Advance both |word| and |next_word| |
321 // when |i| reaches |next_word|. | 323 // when |i| reaches |next_word|. |
322 if (next_word != words_->breaks().end() && i >= next_word->first) { | 324 if (next_word != words_->breaks().end() && i >= next_word->first) { |
323 word = next_word++; | 325 word = next_word++; |
324 word_width = 0; | 326 word_width = 0; |
325 } | 327 } |
326 | 328 |
327 Range glyph_range = run.CharRangeToGlyphRange(Range(i, i + 1)); | 329 Range glyph_range = run.CharRangeToGlyphRange(Range(i, i + 1)); |
330 | |
331 // Sometimes multiple code points can point to the same glyph (e.g. | |
msw
2015/03/24 22:52:45
This fix seems odd/wrong. Shouldn't the line above
Jun Mukai
2015/03/25 00:23:15
This is inside of EnsureLayout(), which is called
| |
332 // diacritic marks). We need to skip in that case to avoid adding | |
333 // the width of the same glyph multiple times. | |
334 bool already_used = false; | |
335 for (size_t i = glyph_range.start(); i < glyph_range.end(); ++i) { | |
336 if (used_glyphs.find(i) != used_glyphs.end()) | |
337 already_used = true; | |
338 used_glyphs.insert(i); | |
339 } | |
340 if (already_used) | |
341 continue; | |
342 | |
328 SkScalar char_width = ((glyph_range.end() >= run.glyph_count) | 343 SkScalar char_width = ((glyph_range.end() >= run.glyph_count) |
329 ? SkFloatToScalar(run.width) | 344 ? SkFloatToScalar(run.width) |
330 : run.positions[glyph_range.end()].x()) - | 345 : run.positions[glyph_range.end()].x()) - |
331 run.positions[glyph_range.start()].x(); | 346 run.positions[glyph_range.start()].x(); |
332 | 347 |
333 *width += char_width; | 348 *width += char_width; |
334 word_width += char_width; | 349 word_width += char_width; |
335 | 350 |
336 if (*width > available_width) { | 351 if (*width > available_width) { |
337 if (line_x_ != 0 || word_width < *width) { | 352 if (line_x_ != 0 || word_width < *width) { |
(...skipping 1177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1515 DCHECK(!update_layout_run_list_); | 1530 DCHECK(!update_layout_run_list_); |
1516 DCHECK(!update_display_run_list_); | 1531 DCHECK(!update_display_run_list_); |
1517 return text_elided() ? display_run_list_.get() : &layout_run_list_; | 1532 return text_elided() ? display_run_list_.get() : &layout_run_list_; |
1518 } | 1533 } |
1519 | 1534 |
1520 const internal::TextRunList* RenderTextHarfBuzz::GetRunList() const { | 1535 const internal::TextRunList* RenderTextHarfBuzz::GetRunList() const { |
1521 return const_cast<RenderTextHarfBuzz*>(this)->GetRunList(); | 1536 return const_cast<RenderTextHarfBuzz*>(this)->GetRunList(); |
1522 } | 1537 } |
1523 | 1538 |
1524 } // namespace gfx | 1539 } // namespace gfx |
OLD | NEW |