Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(195)

Side by Side Diff: ui/base/text/text_elider.cc

Issue 10386016: Modify ui::ElideRectangleText() to honor trailing newlines. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 the anonymous namespace. 8 // in this file using helper classes in the anonymous namespace.
9 9
10 #include "ui/base/text/text_elider.h" 10 #include "ui/base/text/text_elider.h"
(...skipping 775 matching lines...) Expand 10 before | Expand all | Expand 10 after
786 int available_pixel_height, 786 int available_pixel_height,
787 ui::WordWrapBehavior wrap_behavior, 787 ui::WordWrapBehavior wrap_behavior,
788 std::vector<string16>* lines) 788 std::vector<string16>* lines)
789 : font_(font), 789 : font_(font),
790 line_height_(font.GetHeight()), 790 line_height_(font.GetHeight()),
791 available_pixel_width_(available_pixel_width), 791 available_pixel_width_(available_pixel_width),
792 available_pixel_height_(available_pixel_height), 792 available_pixel_height_(available_pixel_height),
793 wrap_behavior_(wrap_behavior), 793 wrap_behavior_(wrap_behavior),
794 current_width_(0), 794 current_width_(0),
795 current_height_(0), 795 current_height_(0),
796 last_line_ended_in_lf_(false),
796 lines_(lines), 797 lines_(lines),
797 full_(false) {} 798 full_(false) {}
798 799
799 // Perform deferred initializions following creation. Must be called 800 // Perform deferred initializions following creation. Must be called
800 // before any input can be added via AddString(). 801 // before any input can be added via AddString().
801 void Init() { lines_->clear(); } 802 void Init() { lines_->clear(); }
802 803
803 // Add an input string, reformatting to fit the desired dimensions. 804 // Add an input string, reformatting to fit the desired dimensions.
804 // AddString() may be called multiple times to concatenate together 805 // AddString() may be called multiple times to concatenate together
805 // multiple strings into the region (the current caller doesn't do 806 // multiple strings into the region (the current caller doesn't do
806 // this, however). 807 // this, however).
807 void AddString(const string16& input); 808 void AddString(const string16& input);
808 809
809 // Perform any deferred output processing. Must be called after the last 810 // Perform any deferred output processing. Must be called after the last
810 // AddString() call has occured. Returns |true| if the text had to be 811 // AddString() call has occured. Returns |true| if the text had to be
811 // truncated to fit the available height. 812 // truncated to fit the available height.
812 bool Finalize(); 813 bool Finalize();
813 814
814 private: 815 private:
815 // Returns |true| if |text| is entirely composed of whitespace.
816 bool IsWhitespaceString(const string16& text) const;
817
818 // Add a line to the rectangular region at the current position, 816 // Add a line to the rectangular region at the current position,
819 // either by itself or by breaking it into words. 817 // either by itself or by breaking it into words.
820 void AddLine(const string16& line); 818 void AddLine(const string16& line);
821 819
822 // Wrap the specified word across multiple lines. 820 // Wrap the specified word across multiple lines.
823 int WrapWord(const string16& word); 821 int WrapWord(const string16& word);
824 822
825 // Add a long word - wrapping, eliding or truncating per the wrap behavior. 823 // Add a long word - wrapping, eliding or truncating per the wrap behavior.
826 int AddWordOverflow(const string16& word); 824 int AddWordOverflow(const string16& word);
827 825
(...skipping 28 matching lines...) Expand all
856 854
857 // The current running width. 855 // The current running width.
858 int current_width_; 856 int current_width_;
859 857
860 // The current running height. 858 // The current running height.
861 int current_height_; 859 int current_height_;
862 860
863 // The current line of text. 861 // The current line of text.
864 string16 current_line_; 862 string16 current_line_;
865 863
864 // Indicates whether the last line ended with \n.
865 bool last_line_ended_in_lf_;
866
866 // The output vector of lines. 867 // The output vector of lines.
867 std::vector<string16>* lines_; 868 std::vector<string16>* lines_;
868 869
869 // Indicates whether there were too many lines for the available height. 870 // Indicates whether there were too many lines for the available height.
870 bool full_; 871 bool full_;
871 872
872 DISALLOW_COPY_AND_ASSIGN(RectangleText); 873 DISALLOW_COPY_AND_ASSIGN(RectangleText);
873 }; 874 };
874 875
875 void RectangleText::AddString(const string16& input) { 876 void RectangleText::AddString(const string16& input) {
876 base::i18n::BreakIterator lines(input, 877 base::i18n::BreakIterator lines(input,
877 base::i18n::BreakIterator::BREAK_NEWLINE); 878 base::i18n::BreakIterator::BREAK_NEWLINE);
878 if (lines.Init()) { 879 if (lines.Init()) {
879 while (!full_ && lines.Advance()) { 880 while (!full_ && lines.Advance()) {
880 string16 line = lines.GetString(); 881 string16 line = lines.GetString();
881 // The BREAK_NEWLINE iterator will keep the trailing newline character, 882 // The BREAK_NEWLINE iterator will keep the trailing newline character,
882 // except in the case of the last line, which may not have one. Remove 883 // except in the case of the last line, which may not have one. Remove
883 // the newline character, if it exists. 884 // the newline character, if it exists.
884 if (!line.empty() && line[line.length() - 1] == '\n') 885 last_line_ended_in_lf_ = !line.empty() && line[line.length() - 1] == '\n';
886 if (last_line_ended_in_lf_)
885 line.resize(line.length() - 1); 887 line.resize(line.length() - 1);
886 AddLine(line); 888 AddLine(line);
887 } 889 }
888 } else { 890 } else {
889 NOTREACHED() << "BreakIterator (lines) init failed"; 891 NOTREACHED() << "BreakIterator (lines) init failed";
890 } 892 }
891 } 893 }
892 894
893 bool RectangleText::Finalize() { 895 bool RectangleText::Finalize() {
894 // Remove trailing whitespace from the last line or remove the last line 896 // Remove trailing whitespace from the last line or remove the last line
895 // completely, if it's just whitespace. 897 // completely, if it's just whitespace.
896 if (!full_ && !lines_->empty()) { 898 if (!full_ && !lines_->empty()) {
897 TrimWhitespace(lines_->back(), TRIM_TRAILING, &lines_->back()); 899 TrimWhitespace(lines_->back(), TRIM_TRAILING, &lines_->back());
898 if (lines_->back().empty()) 900 if (lines_->back().empty() && !last_line_ended_in_lf_)
899 lines_->pop_back(); 901 lines_->pop_back();
900 } 902 }
903 if (last_line_ended_in_lf_)
904 lines_->push_back(string16());
901 return full_; 905 return full_;
902 } 906 }
903 907
904 bool RectangleText::IsWhitespaceString(const string16& text) const {
905 return text.find_first_not_of(kWhitespaceUTF16) == string16::npos;
906 }
907
908 void RectangleText::AddLine(const string16& line) { 908 void RectangleText::AddLine(const string16& line) {
909 const int line_width = font_.GetStringWidth(line); 909 const int line_width = font_.GetStringWidth(line);
910 if (line_width < available_pixel_width_) { 910 if (line_width < available_pixel_width_) {
911 AddToCurrentLineWithWidth(line, line_width); 911 AddToCurrentLineWithWidth(line, line_width);
912 } else { 912 } else {
913 // Iterate over positions that are valid to break the line at. In general, 913 // Iterate over positions that are valid to break the line at. In general,
914 // these are word boundaries but after any punctuation following the word. 914 // these are word boundaries but after any punctuation following the word.
915 base::i18n::BreakIterator words(line, 915 base::i18n::BreakIterator words(line,
916 base::i18n::BreakIterator::BREAK_LINE); 916 base::i18n::BreakIterator::BREAK_LINE);
917 if (words.Init()) { 917 if (words.Init()) {
918 while (words.Advance()) { 918 while (words.Advance()) {
919 const bool truncate = !current_line_.empty(); 919 const bool truncate = !current_line_.empty();
920 const string16& word = words.GetString(); 920 const string16& word = words.GetString();
921 const int lines_added = AddWord(word); 921 const int lines_added = AddWord(word);
922 if (lines_added) { 922 if (lines_added) {
923 if (truncate) { 923 if (truncate) {
924 // Trim trailing whitespace from the line that was added. 924 // Trim trailing whitespace from the line that was added.
925 const int line = lines_->size() - lines_added; 925 const int line = lines_->size() - lines_added;
926 TrimWhitespace(lines_->at(line), TRIM_TRAILING, &lines_->at(line)); 926 TrimWhitespace(lines_->at(line), TRIM_TRAILING, &lines_->at(line));
927 } 927 }
928 if (IsWhitespaceString(word)) { 928 if (ContainsOnlyWhitespace(word)) {
929 // Skip the first space if the previous line was carried over. 929 // Skip the first space if the previous line was carried over.
930 current_width_ = 0; 930 current_width_ = 0;
931 current_line_.clear(); 931 current_line_.clear();
932 } 932 }
933 } 933 }
934 } 934 }
935 } else { 935 } else {
936 NOTREACHED() << "BreakIterator (words) init failed"; 936 NOTREACHED() << "BreakIterator (words) init failed";
937 } 937 }
938 } 938 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
989 string16 trimmed; 989 string16 trimmed;
990 TrimWhitespace(word, TRIM_TRAILING, &trimmed); 990 TrimWhitespace(word, TRIM_TRAILING, &trimmed);
991 const int trimmed_width = font_.GetStringWidth(trimmed); 991 const int trimmed_width = font_.GetStringWidth(trimmed);
992 if (trimmed_width <= available_pixel_width_) { 992 if (trimmed_width <= available_pixel_width_) {
993 // Word can be made to fit, no need to fragment it. 993 // Word can be made to fit, no need to fragment it.
994 if ((current_width_ + trimmed_width > available_pixel_width_) && NewLine()) 994 if ((current_width_ + trimmed_width > available_pixel_width_) && NewLine())
995 lines_added++; 995 lines_added++;
996 // Append the non-trimmed word, in case more words are added after. 996 // Append the non-trimmed word, in case more words are added after.
997 AddToCurrentLine(word); 997 AddToCurrentLine(word);
998 } else { 998 } else {
999 lines_added = AddWordOverflow(word); 999 lines_added = AddWordOverflow(wrap_behavior_ == ui::IGNORE_LONG_WORDS ?
1000 trimmed : word);
1000 } 1001 }
1001 return lines_added; 1002 return lines_added;
1002 } 1003 }
1003 1004
1004 void RectangleText::AddToCurrentLine(const string16& text) { 1005 void RectangleText::AddToCurrentLine(const string16& text) {
1005 AddToCurrentLineWithWidth(text, font_.GetStringWidth(text)); 1006 AddToCurrentLineWithWidth(text, font_.GetStringWidth(text));
1006 } 1007 }
1007 1008
1008 void RectangleText::AddToCurrentLineWithWidth(const string16& text, 1009 void RectangleText::AddToCurrentLineWithWidth(const string16& text,
1009 int text_width) { 1010 int text_width) {
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1113 index = char_iterator.getIndex(); 1114 index = char_iterator.getIndex();
1114 } else { 1115 } else {
1115 // String has leading whitespace, return the elide string. 1116 // String has leading whitespace, return the elide string.
1116 return kElideString; 1117 return kElideString;
1117 } 1118 }
1118 } 1119 }
1119 return string.substr(0, index) + kElideString; 1120 return string.substr(0, index) + kElideString;
1120 } 1121 }
1121 1122
1122 } // namespace ui 1123 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698