Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 // This file implements utility functions for eliding and formatting UI text. | 5 // This file implements utility functions for eliding and formatting UI text. |
| 6 // | 6 // |
| 7 // Note that several of the functions declared in text_elider.h are implemented | 7 // Note that several of the functions declared in text_elider.h are implemented |
| 8 // in this file using helper classes in an unnamed namespace. | 8 // in this file using helper classes in an unnamed namespace. |
| 9 | 9 |
| 10 #include "ui/gfx/text_elider.h" | 10 #include "ui/gfx/text_elider.h" |
| (...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 464 | 464 |
| 465 // Internal class used to track progress of a rectangular text elide | 465 // Internal class used to track progress of a rectangular text elide |
| 466 // operation. Exists so the top-level ElideRectangleText() function | 466 // operation. Exists so the top-level ElideRectangleText() function |
| 467 // can be broken into smaller methods sharing this state. | 467 // can be broken into smaller methods sharing this state. |
| 468 class RectangleText { | 468 class RectangleText { |
| 469 public: | 469 public: |
| 470 RectangleText(const FontList& font_list, | 470 RectangleText(const FontList& font_list, |
| 471 float available_pixel_width, | 471 float available_pixel_width, |
| 472 int available_pixel_height, | 472 int available_pixel_height, |
| 473 WordWrapBehavior wrap_behavior, | 473 WordWrapBehavior wrap_behavior, |
| 474 std::vector<base::string16>* lines) | 474 std::vector<base::string16>* lines, |
| 475 float* max_width) | |
| 475 : font_list_(font_list), | 476 : font_list_(font_list), |
| 476 line_height_(font_list.GetHeight()), | 477 line_height_(font_list.GetHeight()), |
| 477 available_pixel_width_(available_pixel_width), | 478 available_pixel_width_(available_pixel_width), |
| 478 available_pixel_height_(available_pixel_height), | 479 available_pixel_height_(available_pixel_height), |
| 479 wrap_behavior_(wrap_behavior), | 480 wrap_behavior_(wrap_behavior), |
| 480 current_width_(0), | 481 current_width_(0), |
| 481 current_height_(0), | 482 current_height_(0), |
| 482 last_line_ended_in_lf_(false), | 483 last_line_ended_in_lf_(false), |
| 483 lines_(lines), | 484 lines_(lines), |
| 484 insufficient_width_(false), | 485 insufficient_width_(false), |
| 485 insufficient_height_(false) {} | 486 insufficient_height_(false), |
| 487 max_width_(max_width) {} | |
| 486 | 488 |
| 487 // Perform deferred initializions following creation. Must be called | 489 // Perform deferred initializions following creation. Must be called |
| 488 // before any input can be added via AddString(). | 490 // before any input can be added via AddString(). |
| 489 void Init() { lines_->clear(); } | 491 void Init() { lines_->clear(); } |
| 490 | 492 |
| 491 // Add an input string, reformatting to fit the desired dimensions. | 493 // Add an input string, reformatting to fit the desired dimensions. |
| 492 // AddString() may be called multiple times to concatenate together | 494 // AddString() may be called multiple times to concatenate together |
| 493 // multiple strings into the region (the current caller doesn't do | 495 // multiple strings into the region (the current caller doesn't do |
| 494 // this, however). | 496 // this, however). |
| 495 void AddString(const base::string16& input); | 497 void AddString(const base::string16& input); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 555 // The output vector of lines. | 557 // The output vector of lines. |
| 556 std::vector<base::string16>* lines_; | 558 std::vector<base::string16>* lines_; |
| 557 | 559 |
| 558 // Indicates whether a word was so long that it had to be truncated or elided | 560 // Indicates whether a word was so long that it had to be truncated or elided |
| 559 // to fit the available width. | 561 // to fit the available width. |
| 560 bool insufficient_width_; | 562 bool insufficient_width_; |
| 561 | 563 |
| 562 // Indicates whether there were too many lines for the available height. | 564 // Indicates whether there were too many lines for the available height. |
| 563 bool insufficient_height_; | 565 bool insufficient_height_; |
| 564 | 566 |
| 567 float* max_width_; | |
|
Alexei Svitkine (slow)
2014/10/02 16:59:37
I suggest not making this a pointer, but rather a
| |
| 568 | |
| 565 DISALLOW_COPY_AND_ASSIGN(RectangleText); | 569 DISALLOW_COPY_AND_ASSIGN(RectangleText); |
| 566 }; | 570 }; |
| 567 | 571 |
| 568 void RectangleText::AddString(const base::string16& input) { | 572 void RectangleText::AddString(const base::string16& input) { |
| 569 base::i18n::BreakIterator lines(input, | 573 base::i18n::BreakIterator lines(input, |
| 570 base::i18n::BreakIterator::BREAK_NEWLINE); | 574 base::i18n::BreakIterator::BREAK_NEWLINE); |
| 571 if (lines.Init()) { | 575 if (lines.Init()) { |
| 572 while (!insufficient_height_ && lines.Advance()) { | 576 while (!insufficient_height_ && lines.Advance()) { |
| 573 base::string16 line = lines.GetString(); | 577 base::string16 line = lines.GetString(); |
| 574 // The BREAK_NEWLINE iterator will keep the trailing newline character, | 578 // The BREAK_NEWLINE iterator will keep the trailing newline character, |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 684 | 688 |
| 685 int RectangleText::AddWord(const base::string16& word) { | 689 int RectangleText::AddWord(const base::string16& word) { |
| 686 int lines_added = 0; | 690 int lines_added = 0; |
| 687 base::string16 trimmed; | 691 base::string16 trimmed; |
| 688 base::TrimWhitespace(word, base::TRIM_TRAILING, &trimmed); | 692 base::TrimWhitespace(word, base::TRIM_TRAILING, &trimmed); |
| 689 const float trimmed_width = GetStringWidthF(trimmed, font_list_); | 693 const float trimmed_width = GetStringWidthF(trimmed, font_list_); |
| 690 if (trimmed_width <= available_pixel_width_) { | 694 if (trimmed_width <= available_pixel_width_) { |
| 691 // Word can be made to fit, no need to fragment it. | 695 // Word can be made to fit, no need to fragment it. |
| 692 if ((current_width_ + trimmed_width > available_pixel_width_) && NewLine()) | 696 if ((current_width_ + trimmed_width > available_pixel_width_) && NewLine()) |
| 693 lines_added++; | 697 lines_added++; |
| 698 if (max_width_) | |
| 699 *max_width_ = std::max(*max_width_, current_width_ + trimmed_width); | |
| 694 // Append the non-trimmed word, in case more words are added after. | 700 // Append the non-trimmed word, in case more words are added after. |
| 695 AddToCurrentLine(word); | 701 AddToCurrentLine(word); |
| 696 } else { | 702 } else { |
| 697 lines_added = AddWordOverflow(wrap_behavior_ == IGNORE_LONG_WORDS ? | 703 lines_added = AddWordOverflow(wrap_behavior_ == IGNORE_LONG_WORDS ? |
| 698 trimmed : word); | 704 trimmed : word); |
| 699 } | 705 } |
| 700 return lines_added; | 706 return lines_added; |
| 701 } | 707 } |
| 702 | 708 |
| 703 void RectangleText::AddToCurrentLine(const base::string16& text) { | 709 void RectangleText::AddToCurrentLine(const base::string16& text) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 737 rect.Init(); | 743 rect.Init(); |
| 738 rect.AddString(input); | 744 rect.AddString(input); |
| 739 return rect.Finalize(); | 745 return rect.Finalize(); |
| 740 } | 746 } |
| 741 | 747 |
| 742 int ElideRectangleText(const base::string16& input, | 748 int ElideRectangleText(const base::string16& input, |
| 743 const FontList& font_list, | 749 const FontList& font_list, |
| 744 float available_pixel_width, | 750 float available_pixel_width, |
| 745 int available_pixel_height, | 751 int available_pixel_height, |
| 746 WordWrapBehavior wrap_behavior, | 752 WordWrapBehavior wrap_behavior, |
| 747 std::vector<base::string16>* lines) { | 753 std::vector<base::string16>* lines, |
| 754 float* max_width) { | |
| 748 RectangleText rect(font_list, | 755 RectangleText rect(font_list, |
| 749 available_pixel_width, | 756 available_pixel_width, |
| 750 available_pixel_height, | 757 available_pixel_height, |
| 751 wrap_behavior, | 758 wrap_behavior, |
| 752 lines); | 759 lines, |
| 760 max_width); | |
| 753 rect.Init(); | 761 rect.Init(); |
| 754 rect.AddString(input); | 762 rect.AddString(input); |
| 755 return rect.Finalize(); | 763 return rect.Finalize(); |
| 756 } | 764 } |
| 757 | 765 |
| 758 base::string16 TruncateString(const base::string16& string, | 766 base::string16 TruncateString(const base::string16& string, |
| 759 size_t length, | 767 size_t length, |
| 760 BreakType break_type) { | 768 BreakType break_type) { |
| 761 DCHECK(break_type == CHARACTER_BREAK || break_type == WORD_BREAK); | 769 DCHECK(break_type == CHARACTER_BREAK || break_type == WORD_BREAK); |
| 762 | 770 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 815 index = char_iterator.getIndex(); | 823 index = char_iterator.getIndex(); |
| 816 } else { | 824 } else { |
| 817 // String has leading whitespace, return the elide string. | 825 // String has leading whitespace, return the elide string. |
| 818 return kElideString; | 826 return kElideString; |
| 819 } | 827 } |
| 820 | 828 |
| 821 return string.substr(0, index) + kElideString; | 829 return string.substr(0, index) + kElideString; |
| 822 } | 830 } |
| 823 | 831 |
| 824 } // namespace gfx | 832 } // namespace gfx |
| OLD | NEW |