Chromium Code Reviews| 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 | 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 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 216 // the given runs. |min_baseline| and |min_height| are the minimum baseline and | 216 // the given runs. |min_baseline| and |min_height| are the minimum baseline and |
| 217 // height for each line. | 217 // height for each line. |
| 218 // TODO(ckocagil): Expose the interface of this class in the header and test | 218 // TODO(ckocagil): Expose the interface of this class in the header and test |
| 219 // this class directly. | 219 // this class directly. |
| 220 class HarfBuzzLineBreaker { | 220 class HarfBuzzLineBreaker { |
| 221 public: | 221 public: |
| 222 HarfBuzzLineBreaker(size_t max_width, | 222 HarfBuzzLineBreaker(size_t max_width, |
| 223 int min_baseline, | 223 int min_baseline, |
| 224 float min_height, | 224 float min_height, |
| 225 bool multiline, | 225 bool multiline, |
| 226 bool allow_character_break, | |
| 226 const base::string16& text, | 227 const base::string16& text, |
| 227 const BreakList<size_t>* words, | 228 const BreakList<size_t>* words, |
| 228 const internal::TextRunList& run_list) | 229 const internal::TextRunList& run_list) |
| 229 : max_width_((max_width == 0) ? SK_ScalarMax : SkIntToScalar(max_width)), | 230 : max_width_((max_width == 0) ? SK_ScalarMax : SkIntToScalar(max_width)), |
| 230 min_baseline_(min_baseline), | 231 min_baseline_(min_baseline), |
| 231 min_height_(min_height), | 232 min_height_(min_height), |
| 232 multiline_(multiline), | 233 multiline_(multiline), |
| 234 allow_character_break_(allow_character_break), | |
| 233 text_(text), | 235 text_(text), |
| 234 words_(words), | 236 words_(words), |
| 235 run_list_(run_list), | 237 run_list_(run_list), |
| 236 text_x_(0), | 238 text_x_(0), |
| 237 line_x_(0), | 239 line_x_(0), |
| 238 max_descent_(0), | 240 max_descent_(0), |
| 239 max_ascent_(0) { | 241 max_ascent_(0) { |
| 240 DCHECK_EQ(multiline_, (words_ != nullptr)); | 242 DCHECK_EQ(multiline_, (words_ != nullptr)); |
| 241 AdvanceLine(); | 243 AdvanceLine(); |
| 242 } | 244 } |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 328 Range glyph_range = run.CharRangeToGlyphRange(Range(i, i + 1)); | 330 Range glyph_range = run.CharRangeToGlyphRange(Range(i, i + 1)); |
| 329 SkScalar char_width = ((glyph_range.end() >= run.glyph_count) | 331 SkScalar char_width = ((glyph_range.end() >= run.glyph_count) |
| 330 ? SkFloatToScalar(run.width) | 332 ? SkFloatToScalar(run.width) |
| 331 : run.positions[glyph_range.end()].x()) - | 333 : run.positions[glyph_range.end()].x()) - |
| 332 run.positions[glyph_range.start()].x(); | 334 run.positions[glyph_range.start()].x(); |
| 333 | 335 |
| 334 *width += char_width; | 336 *width += char_width; |
| 335 word_width += char_width; | 337 word_width += char_width; |
| 336 | 338 |
| 337 if (*width > available_width) { | 339 if (*width > available_width) { |
| 338 if (line_x_ != 0 || word_width < *width) { | 340 if (!allow_character_break_ && (line_x_ != 0 || word_width < *width)) { |
|
msw
2015/03/25 20:54:15
I don't think this matches the current Label behav
Jun Mukai
2015/03/26 01:35:08
Rewritten the logic, and enriched the tests. PTAL.
| |
| 339 // Roll back one word. | 341 // Roll back one word. |
| 340 *width -= word_width; | 342 *width -= word_width; |
| 341 *next_char = std::max(word->first, start_char); | 343 *next_char = std::max(word->first, start_char); |
| 342 } else if (char_width < *width) { | 344 } else if (char_width < *width) { |
| 343 // Roll back one character. | 345 // Roll back one character. |
| 344 *width -= char_width; | 346 *width -= char_width; |
| 345 *next_char = i; | 347 *next_char = i; |
| 346 } else { | 348 } else { |
| 347 // Continue from the next character. | 349 // Continue from the next character. |
| 348 *next_char = i + 1; | 350 *next_char = i + 1; |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 437 UpdateRTLSegmentRanges(); | 439 UpdateRTLSegmentRanges(); |
| 438 } | 440 } |
| 439 text_x_ += SkFloatToScalar(width); | 441 text_x_ += SkFloatToScalar(width); |
| 440 line_x_ += SkFloatToScalar(width); | 442 line_x_ += SkFloatToScalar(width); |
| 441 } | 443 } |
| 442 | 444 |
| 443 const SkScalar max_width_; | 445 const SkScalar max_width_; |
| 444 const int min_baseline_; | 446 const int min_baseline_; |
| 445 const float min_height_; | 447 const float min_height_; |
| 446 const bool multiline_; | 448 const bool multiline_; |
| 449 const bool allow_character_break_; | |
| 447 const base::string16& text_; | 450 const base::string16& text_; |
| 448 const BreakList<size_t>* const words_; | 451 const BreakList<size_t>* const words_; |
| 449 const internal::TextRunList& run_list_; | 452 const internal::TextRunList& run_list_; |
| 450 | 453 |
| 451 // Stores the resulting lines. | 454 // Stores the resulting lines. |
| 452 std::vector<internal::Line> lines_; | 455 std::vector<internal::Line> lines_; |
| 453 | 456 |
| 454 // Text space and line space x coordinates of the next segment to be added. | 457 // Text space and line space x coordinates of the next segment to be added. |
| 455 SkScalar text_x_; | 458 SkScalar text_x_; |
| 456 SkScalar line_x_; | 459 SkScalar line_x_; |
| (...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 979 if (lines().empty()) { | 982 if (lines().empty()) { |
| 980 // TODO(vadimt): Remove ScopedTracker below once crbug.com/431326 is fixed. | 983 // TODO(vadimt): Remove ScopedTracker below once crbug.com/431326 is fixed. |
| 981 tracked_objects::ScopedTracker tracking_profile2( | 984 tracked_objects::ScopedTracker tracking_profile2( |
| 982 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 985 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 983 "431326 RenderTextHarfBuzz::EnsureLayout2")); | 986 "431326 RenderTextHarfBuzz::EnsureLayout2")); |
| 984 | 987 |
| 985 internal::TextRunList* run_list = GetRunList(); | 988 internal::TextRunList* run_list = GetRunList(); |
| 986 HarfBuzzLineBreaker line_breaker( | 989 HarfBuzzLineBreaker line_breaker( |
| 987 display_rect().width(), font_list().GetBaseline(), | 990 display_rect().width(), font_list().GetBaseline(), |
| 988 std::max(font_list().GetHeight(), min_line_height()), multiline(), | 991 std::max(font_list().GetHeight(), min_line_height()), multiline(), |
| 989 GetDisplayText(), multiline() ? &GetLineBreaks() : nullptr, *run_list); | 992 allow_character_break(), GetDisplayText(), |
| 993 multiline() ? &GetLineBreaks() : nullptr, *run_list); | |
| 990 | 994 |
| 991 // TODO(vadimt): Remove ScopedTracker below once crbug.com/431326 is fixed. | 995 // TODO(vadimt): Remove ScopedTracker below once crbug.com/431326 is fixed. |
| 992 tracked_objects::ScopedTracker tracking_profile3( | 996 tracked_objects::ScopedTracker tracking_profile3( |
| 993 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 997 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 994 "431326 RenderTextHarfBuzz::EnsureLayout3")); | 998 "431326 RenderTextHarfBuzz::EnsureLayout3")); |
| 995 | 999 |
| 996 for (size_t i = 0; i < run_list->size(); ++i) | 1000 for (size_t i = 0; i < run_list->size(); ++i) |
| 997 line_breaker.AddRun(i); | 1001 line_breaker.AddRun(i); |
| 998 std::vector<internal::Line> lines; | 1002 std::vector<internal::Line> lines; |
| 999 line_breaker.Finalize(&lines, &total_size_); | 1003 line_breaker.Finalize(&lines, &total_size_); |
| (...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1519 DCHECK(!update_layout_run_list_); | 1523 DCHECK(!update_layout_run_list_); |
| 1520 DCHECK(!update_display_run_list_); | 1524 DCHECK(!update_display_run_list_); |
| 1521 return text_elided() ? display_run_list_.get() : &layout_run_list_; | 1525 return text_elided() ? display_run_list_.get() : &layout_run_list_; |
| 1522 } | 1526 } |
| 1523 | 1527 |
| 1524 const internal::TextRunList* RenderTextHarfBuzz::GetRunList() const { | 1528 const internal::TextRunList* RenderTextHarfBuzz::GetRunList() const { |
| 1525 return const_cast<RenderTextHarfBuzz*>(this)->GetRunList(); | 1529 return const_cast<RenderTextHarfBuzz*>(this)->GetRunList(); |
| 1526 } | 1530 } |
| 1527 | 1531 |
| 1528 } // namespace gfx | 1532 } // namespace gfx |
| OLD | NEW |