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/base/text/text_elider.h" | 10 #include "ui/gfx/text_elider.h" |
11 | 11 |
12 #include <string> | 12 #include <string> |
13 #include <vector> | 13 #include <vector> |
14 | 14 |
15 #include "base/files/file_path.h" | 15 #include "base/files/file_path.h" |
16 #include "base/i18n/break_iterator.h" | 16 #include "base/i18n/break_iterator.h" |
17 #include "base/i18n/char_iterator.h" | 17 #include "base/i18n/char_iterator.h" |
18 #include "base/i18n/rtl.h" | 18 #include "base/i18n/rtl.h" |
19 #include "base/memory/scoped_ptr.h" | 19 #include "base/memory/scoped_ptr.h" |
20 #include "base/strings/string_split.h" | 20 #include "base/strings/string_split.h" |
(...skipping 786 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
807 } | 807 } |
808 | 808 |
809 // Internal class used to track progress of a rectangular text elide | 809 // Internal class used to track progress of a rectangular text elide |
810 // operation. Exists so the top-level ElideRectangleText() function | 810 // operation. Exists so the top-level ElideRectangleText() function |
811 // can be broken into smaller methods sharing this state. | 811 // can be broken into smaller methods sharing this state. |
812 class RectangleText { | 812 class RectangleText { |
813 public: | 813 public: |
814 RectangleText(const gfx::FontList& font_list, | 814 RectangleText(const gfx::FontList& font_list, |
815 int available_pixel_width, | 815 int available_pixel_width, |
816 int available_pixel_height, | 816 int available_pixel_height, |
817 ui::WordWrapBehavior wrap_behavior, | 817 gfx::WordWrapBehavior wrap_behavior, |
818 std::vector<string16>* lines) | 818 std::vector<string16>* lines) |
819 : font_list_(font_list), | 819 : font_list_(font_list), |
820 line_height_(font_list.GetHeight()), | 820 line_height_(font_list.GetHeight()), |
821 available_pixel_width_(available_pixel_width), | 821 available_pixel_width_(available_pixel_width), |
822 available_pixel_height_(available_pixel_height), | 822 available_pixel_height_(available_pixel_height), |
823 wrap_behavior_(wrap_behavior), | 823 wrap_behavior_(wrap_behavior), |
824 current_width_(0), | 824 current_width_(0), |
825 current_height_(0), | 825 current_height_(0), |
826 last_line_ended_in_lf_(false), | 826 last_line_ended_in_lf_(false), |
827 lines_(lines), | 827 lines_(lines), |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
875 // The height of each line of text. | 875 // The height of each line of text. |
876 const int line_height_; | 876 const int line_height_; |
877 | 877 |
878 // The number of pixels of available width in the rectangle. | 878 // The number of pixels of available width in the rectangle. |
879 const int available_pixel_width_; | 879 const int available_pixel_width_; |
880 | 880 |
881 // The number of pixels of available height in the rectangle. | 881 // The number of pixels of available height in the rectangle. |
882 const int available_pixel_height_; | 882 const int available_pixel_height_; |
883 | 883 |
884 // The wrap behavior for words that are too long to fit on a single line. | 884 // The wrap behavior for words that are too long to fit on a single line. |
885 const ui::WordWrapBehavior wrap_behavior_; | 885 const gfx::WordWrapBehavior wrap_behavior_; |
886 | 886 |
887 // The current running width. | 887 // The current running width. |
888 int current_width_; | 888 int current_width_; |
889 | 889 |
890 // The current running height. | 890 // The current running height. |
891 int current_height_; | 891 int current_height_; |
892 | 892 |
893 // The current line of text. | 893 // The current line of text. |
894 string16 current_line_; | 894 string16 current_line_; |
895 | 895 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
931 int RectangleText::Finalize() { | 931 int RectangleText::Finalize() { |
932 // Remove trailing whitespace from the last line or remove the last line | 932 // Remove trailing whitespace from the last line or remove the last line |
933 // completely, if it's just whitespace. | 933 // completely, if it's just whitespace. |
934 if (!insufficient_height_ && !lines_->empty()) { | 934 if (!insufficient_height_ && !lines_->empty()) { |
935 TrimWhitespace(lines_->back(), TRIM_TRAILING, &lines_->back()); | 935 TrimWhitespace(lines_->back(), TRIM_TRAILING, &lines_->back()); |
936 if (lines_->back().empty() && !last_line_ended_in_lf_) | 936 if (lines_->back().empty() && !last_line_ended_in_lf_) |
937 lines_->pop_back(); | 937 lines_->pop_back(); |
938 } | 938 } |
939 if (last_line_ended_in_lf_) | 939 if (last_line_ended_in_lf_) |
940 lines_->push_back(string16()); | 940 lines_->push_back(string16()); |
941 return (insufficient_width_ ? ui::INSUFFICIENT_SPACE_HORIZONTAL : 0) | | 941 return (insufficient_width_ ? gfx::INSUFFICIENT_SPACE_HORIZONTAL : 0) | |
942 (insufficient_height_ ? ui::INSUFFICIENT_SPACE_VERTICAL : 0); | 942 (insufficient_height_ ? gfx::INSUFFICIENT_SPACE_VERTICAL : 0); |
943 } | 943 } |
944 | 944 |
945 void RectangleText::AddLine(const string16& line) { | 945 void RectangleText::AddLine(const string16& line) { |
946 const int line_width = gfx::GetStringWidth(line, font_list_); | 946 const int line_width = gfx::GetStringWidth(line, font_list_); |
947 if (line_width <= available_pixel_width_) { | 947 if (line_width <= available_pixel_width_) { |
948 AddToCurrentLineWithWidth(line, line_width); | 948 AddToCurrentLineWithWidth(line, line_width); |
949 } else { | 949 } else { |
950 // Iterate over positions that are valid to break the line at. In general, | 950 // Iterate over positions that are valid to break the line at. In general, |
951 // these are word boundaries but after any punctuation following the word. | 951 // these are word boundaries but after any punctuation following the word. |
952 base::i18n::BreakIterator words(line, | 952 base::i18n::BreakIterator words(line, |
(...skipping 24 matching lines...) Expand all Loading... |
977 NewLine(); | 977 NewLine(); |
978 } | 978 } |
979 | 979 |
980 int RectangleText::WrapWord(const string16& word) { | 980 int RectangleText::WrapWord(const string16& word) { |
981 // Word is so wide that it must be fragmented. | 981 // Word is so wide that it must be fragmented. |
982 string16 text = word; | 982 string16 text = word; |
983 int lines_added = 0; | 983 int lines_added = 0; |
984 bool first_fragment = true; | 984 bool first_fragment = true; |
985 while (!insufficient_height_ && !text.empty()) { | 985 while (!insufficient_height_ && !text.empty()) { |
986 string16 fragment = | 986 string16 fragment = |
987 ui::ElideText(text, font_list_, available_pixel_width_, | 987 gfx::ElideText(text, font_list_, available_pixel_width_, |
988 ui::TRUNCATE_AT_END); | 988 gfx::TRUNCATE_AT_END); |
989 // At least one character has to be added at every line, even if the | 989 // At least one character has to be added at every line, even if the |
990 // available space is too small. | 990 // available space is too small. |
991 if(fragment.empty()) | 991 if(fragment.empty()) |
992 fragment = text.substr(0, 1); | 992 fragment = text.substr(0, 1); |
993 if (!first_fragment && NewLine()) | 993 if (!first_fragment && NewLine()) |
994 lines_added++; | 994 lines_added++; |
995 AddToCurrentLine(fragment); | 995 AddToCurrentLine(fragment); |
996 text = text.substr(fragment.length()); | 996 text = text.substr(fragment.length()); |
997 first_fragment = false; | 997 first_fragment = false; |
998 } | 998 } |
999 return lines_added; | 999 return lines_added; |
1000 } | 1000 } |
1001 | 1001 |
1002 int RectangleText::AddWordOverflow(const string16& word) { | 1002 int RectangleText::AddWordOverflow(const string16& word) { |
1003 int lines_added = 0; | 1003 int lines_added = 0; |
1004 | 1004 |
1005 // Unless this is the very first word, put it on a new line. | 1005 // Unless this is the very first word, put it on a new line. |
1006 if (!current_line_.empty()) { | 1006 if (!current_line_.empty()) { |
1007 if (!NewLine()) | 1007 if (!NewLine()) |
1008 return 0; | 1008 return 0; |
1009 lines_added++; | 1009 lines_added++; |
1010 } | 1010 } |
1011 | 1011 |
1012 if (wrap_behavior_ == ui::IGNORE_LONG_WORDS) { | 1012 if (wrap_behavior_ == gfx::IGNORE_LONG_WORDS) { |
1013 current_line_ = word; | 1013 current_line_ = word; |
1014 current_width_ = available_pixel_width_; | 1014 current_width_ = available_pixel_width_; |
1015 } else if (wrap_behavior_ == ui::WRAP_LONG_WORDS) { | 1015 } else if (wrap_behavior_ == gfx::WRAP_LONG_WORDS) { |
1016 lines_added += WrapWord(word); | 1016 lines_added += WrapWord(word); |
1017 } else { | 1017 } else { |
1018 const ui::ElideBehavior elide_behavior = | 1018 const gfx::ElideBehavior elide_behavior = |
1019 (wrap_behavior_ == ui::ELIDE_LONG_WORDS ? ui::ELIDE_AT_END : | 1019 (wrap_behavior_ == gfx::ELIDE_LONG_WORDS ? gfx::ELIDE_AT_END : |
1020 ui::TRUNCATE_AT_END); | 1020 gfx::TRUNCATE_AT_END); |
1021 const string16 elided_word = | 1021 const string16 elided_word = |
1022 ui::ElideText(word, font_list_, available_pixel_width_, elide_behavior); | 1022 gfx::ElideText(word, font_list_, available_pixel_width_, elide_behavior)
; |
1023 AddToCurrentLine(elided_word); | 1023 AddToCurrentLine(elided_word); |
1024 insufficient_width_ = true; | 1024 insufficient_width_ = true; |
1025 } | 1025 } |
1026 | 1026 |
1027 return lines_added; | 1027 return lines_added; |
1028 } | 1028 } |
1029 | 1029 |
1030 int RectangleText::AddWord(const string16& word) { | 1030 int RectangleText::AddWord(const string16& word) { |
1031 int lines_added = 0; | 1031 int lines_added = 0; |
1032 string16 trimmed; | 1032 string16 trimmed; |
1033 TrimWhitespace(word, TRIM_TRAILING, &trimmed); | 1033 TrimWhitespace(word, TRIM_TRAILING, &trimmed); |
1034 const int trimmed_width = gfx::GetStringWidth(trimmed, font_list_); | 1034 const int trimmed_width = gfx::GetStringWidth(trimmed, font_list_); |
1035 if (trimmed_width <= available_pixel_width_) { | 1035 if (trimmed_width <= available_pixel_width_) { |
1036 // Word can be made to fit, no need to fragment it. | 1036 // Word can be made to fit, no need to fragment it. |
1037 if ((current_width_ + trimmed_width > available_pixel_width_) && NewLine()) | 1037 if ((current_width_ + trimmed_width > available_pixel_width_) && NewLine()) |
1038 lines_added++; | 1038 lines_added++; |
1039 // Append the non-trimmed word, in case more words are added after. | 1039 // Append the non-trimmed word, in case more words are added after. |
1040 AddToCurrentLine(word); | 1040 AddToCurrentLine(word); |
1041 } else { | 1041 } else { |
1042 lines_added = AddWordOverflow(wrap_behavior_ == ui::IGNORE_LONG_WORDS ? | 1042 lines_added = AddWordOverflow(wrap_behavior_ == gfx::IGNORE_LONG_WORDS ? |
1043 trimmed : word); | 1043 trimmed : word); |
1044 } | 1044 } |
1045 return lines_added; | 1045 return lines_added; |
1046 } | 1046 } |
1047 | 1047 |
1048 void RectangleText::AddToCurrentLine(const string16& text) { | 1048 void RectangleText::AddToCurrentLine(const string16& text) { |
1049 AddToCurrentLineWithWidth(text, gfx::GetStringWidth(text, font_list_)); | 1049 AddToCurrentLineWithWidth(text, gfx::GetStringWidth(text, font_list_)); |
1050 } | 1050 } |
1051 | 1051 |
1052 void RectangleText::AddToCurrentLineWithWidth(const string16& text, | 1052 void RectangleText::AddToCurrentLineWithWidth(const string16& text, |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1168 index = char_iterator.getIndex(); | 1168 index = char_iterator.getIndex(); |
1169 } else { | 1169 } else { |
1170 // String has leading whitespace, return the elide string. | 1170 // String has leading whitespace, return the elide string. |
1171 return kElideString; | 1171 return kElideString; |
1172 } | 1172 } |
1173 } | 1173 } |
1174 return string.substr(0, index) + kElideString; | 1174 return string.substr(0, index) + kElideString; |
1175 } | 1175 } |
1176 | 1176 |
1177 } // namespace ui | 1177 } // namespace ui |
OLD | NEW |