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 |