Chromium Code Reviews| Index: app/text_elider.cc |
| =================================================================== |
| --- app/text_elider.cc (revision 69878) |
| +++ app/text_elider.cc (working copy) |
| @@ -6,6 +6,8 @@ |
| #include "app/text_elider.h" |
| #include "base/file_path.h" |
| +#include "base/i18n/break_iterator.h" |
| +#include "base/i18n/char_iterator.h" |
| #include "base/i18n/rtl.h" |
| #include "base/string_split.h" |
| #include "base/string_util.h" |
| @@ -498,3 +500,127 @@ |
| } |
| } // namespace gfx |
| + |
| +namespace { |
| + |
| +class RectangleString { |
|
Evan Martin
2010/12/21 23:39:18
Can you add a comment describing this class?
|
| + public: |
| + RectangleString(size_t max_rows, size_t max_cols, string16 *output) |
| + : max_rows_(max_rows), |
| + max_cols_(max_cols), |
| + current_row_(0), |
| + current_col_(0), |
| + suppressed_(false), |
| + output_(output) {} |
| + |
| + void Init() { output_->clear(); } |
| + void AddString(const string16& input); |
|
Evan Martin
2010/12/21 23:39:18
typo: double space
|
| + bool Finalize(); |
|
Evan Martin
2010/12/21 23:39:18
Please add comment docs to all functions and membe
|
| + |
| + private: |
| + void AddLine(const string16& line); |
| + void AddWord(const string16& word); |
| + void Append(const string16& string); |
| + void NewLine(); |
| + |
| + size_t max_rows_; |
| + size_t max_cols_; |
| + size_t current_row_; |
| + size_t current_col_; |
| + bool suppressed_; |
| + string16 *output_; |
| +}; |
| + |
| +void RectangleString::AddString(const string16& input) { |
| + base::BreakIterator lines(&input, base::BreakIterator::BREAK_NEWLINE); |
| + if (lines.Init()) { |
| + while (lines.Advance()) |
| + AddLine(lines.GetString()); |
| + } else { |
| + NOTREACHED() << "BreakIterator (lines) init failed"; |
| + } |
| +} |
| + |
| +bool RectangleString::Finalize() { |
| + if (suppressed_) { |
| + output_->append(WideToUTF16(L"...")); |
|
Evan Martin
2010/12/21 23:39:18
ASCIIToUTF16("...")
Elsewhere we use a Unicode el
|
| + return true; |
| + } |
| + return false; |
| +} |
| + |
| +void RectangleString::AddLine(const string16& line) { |
| + if (line.length() < max_cols_) { |
| + Append(line); |
| + } else { |
| + base::BreakIterator words(&line, base::BreakIterator::BREAK_SPACE); |
| + if (words.Init()) { |
| + while (words.Advance()) |
| + AddWord(words.GetString()); |
| + } else { |
| + NOTREACHED() << "BreakIterator (words) init failed"; |
| + } |
| + } |
| + // Account for naturally-occuring newlines. |
| + ++current_row_; |
| + current_col_ = 0; |
| +} |
| + |
| +void RectangleString::AddWord(const string16& word) { |
| + if (word.length() < max_cols_) { |
| + // Word can be made to fit, no need to fragment it. |
| + if (current_col_ + word.length() >= max_cols_) |
| + NewLine(); |
| + Append(word); |
| + } else { |
| + // Word is so big that it must be fragmented. |
| + int array_start = 0; |
| + int char_start = 0; |
| + base::UTF16CharIterator chars(&word); |
| + while (!chars.end()) { |
| + // When boundary is hit, add as much as will fit on this line. |
| + if (current_col_ + (chars.char_pos() - char_start) >= max_cols_) { |
| + Append(word.substr(array_start, chars.array_pos() - array_start)); |
| + NewLine(); |
| + array_start = chars.array_pos(); |
| + char_start = chars.char_pos(); |
| + } |
| + chars.Advance(); |
| + } |
| + // add last remaining fragment, if any. |
| + if (array_start != chars.array_pos()) |
| + Append(word.substr(array_start, chars.array_pos() - array_start)); |
| + } |
| +} |
| + |
| +void RectangleString::Append(const string16& string) { |
| + if (current_row_ < max_rows_) |
| + output_->append(string); |
| + else |
| + suppressed_ = true; |
| + current_col_ += string.length(); |
| +} |
| + |
| +void RectangleString::NewLine() { |
| + if (current_row_ < max_rows_) |
| + output_->append(WideToUTF16(L"\n")); |
|
Evan Martin
2010/12/21 23:39:18
ASCIIToUTF16("\n")
|
| + else |
| + suppressed_ = true; |
| + ++current_row_; |
| + current_col_ = 0; |
| +} |
| + |
| +} // namespace |
| + |
| +namespace gfx { |
| + |
| +bool ElideRectangleString(const string16& input, size_t max_rows, |
| + size_t max_cols, string16* output) { |
| + RectangleString rect(max_rows, max_cols, output); |
| + rect.Init(); |
| + rect.AddString(input); |
| + return rect.Finalize(); |
| +} |
| + |
| +} // namespace gfx |
| + |