summaryrefslogtreecommitdiffstats
path: root/ui/base
diff options
context:
space:
mode:
Diffstat (limited to 'ui/base')
-rw-r--r--ui/base/text/text_elider.cc34
-rw-r--r--ui/base/text/text_elider.h14
-rw-r--r--ui/base/text/text_elider_unittest.cc90
3 files changed, 115 insertions, 23 deletions
diff --git a/ui/base/text/text_elider.cc b/ui/base/text/text_elider.cc
index 4b18619..e6aaa26 100644
--- a/ui/base/text/text_elider.cc
+++ b/ui/base/text/text_elider.cc
@@ -507,11 +507,13 @@ namespace {
// can be broken into smaller methods sharing this state.
class RectangleString {
public:
- RectangleString(size_t max_rows, size_t max_cols, string16 *output)
+ RectangleString(size_t max_rows, size_t max_cols,
+ bool strict, string16 *output)
: max_rows_(max_rows),
max_cols_(max_cols),
current_row_(0),
current_col_(0),
+ strict_(strict),
suppressed_(false),
output_(output) {}
@@ -542,10 +544,11 @@ class RectangleString {
// have not been exceeded, advancing the current position.
void Append(const string16& string);
- // Add a newline to the output string if the rectangular boundaries
- // have not been exceeded, resetting the current position to the
- // beginning of the next line.
- void NewLine();
+ // Set the current position to the beginning of the next line. If
+ // |output| is true, add a newline to the output string if the rectangular
+ // boundaries have not been exceeded. If |output| is false, we assume
+ // some other mechanism will (likely) do similar breaking after the fact.
+ void NewLine(bool output);
// Maximum number of rows allowed in the output string.
size_t max_rows_;
@@ -564,6 +567,9 @@ class RectangleString {
// Current character position, should never exceed max_cols_.
size_t current_col_;
+ // True when we do whitespace to newline conversions ourselves.
+ bool strict_;
+
// True when some of the input has been truncated.
bool suppressed_;
@@ -610,7 +616,7 @@ 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();
+ NewLine(strict_);
Append(word);
} else {
// Word is so big that it must be fragmented.
@@ -621,7 +627,7 @@ void RectangleString::AddWord(const string16& word) {
// 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();
+ NewLine(true);
array_start = chars.array_pos();
char_start = chars.char_pos();
}
@@ -641,11 +647,13 @@ void RectangleString::Append(const string16& string) {
current_col_ += string.length();
}
-void RectangleString::NewLine() {
- if (current_row_ < max_rows_)
- output_->append(ASCIIToUTF16("\n"));
- else
+void RectangleString::NewLine(bool output) {
+ if (current_row_ < max_rows_) {
+ if (output)
+ output_->append(ASCIIToUTF16("\n"));
+ } else {
suppressed_ = true;
+ }
++current_row_;
current_col_ = 0;
}
@@ -655,8 +663,8 @@ void RectangleString::NewLine() {
namespace ui {
bool ElideRectangleString(const string16& input, size_t max_rows,
- size_t max_cols, string16* output) {
- RectangleString rect(max_rows, max_cols, output);
+ size_t max_cols, bool strict, string16* output) {
+ RectangleString rect(max_rows, max_cols, strict, output);
rect.Init();
rect.AddString(input);
return rect.Finalize();
diff --git a/ui/base/text/text_elider.h b/ui/base/text/text_elider.h
index f010712..5dd3dc5 100644
--- a/ui/base/text/text_elider.h
+++ b/ui/base/text/text_elider.h
@@ -106,13 +106,15 @@ bool ElideString(const string16& input, int max_len, string16* output);
// Reformat |input| into |output| so that it fits into a |max_rows| by
// |max_cols| rectangle of characters. Input newlines are respected, but
-// lines that are too long are broken into pieces, first at naturally
-// occuring whitespace boundaries, and then intra-word (respecting UTF-16
-// surrogate pairs) as necssary. Truncation (indicated by an added 3 dots)
-// occurs if the result is still too long. Returns true if the input had
-// to be truncated (and not just reformatted).
+// lines that are too long are broken into pieces. If |strict| is true,
+// we break first at naturally occuring whitespace boundaries, otherwise
+// we assume some other mechanism will do this in approximately the same
+// spot after the fact. If the word itself is too long, we always break
+// intra-word (respecting UTF-16 surrogate pairs) as necssary. Truncation
+// (indicated by an added 3 dots) occurs if the result is still too long.
+// Returns true if the input had to be truncated (and not just reformatted).
bool ElideRectangleString(const string16& input, size_t max_rows,
- size_t max_cols, string16* output);
+ size_t max_cols, bool strict, string16* output);
} // namespace ui
diff --git a/ui/base/text/text_elider_unittest.cc b/ui/base/text/text_elider_unittest.cc
index 083d9f2..69cf0c1 100644
--- a/ui/base/text/text_elider_unittest.cc
+++ b/ui/base/text/text_elider_unittest.cc
@@ -401,7 +401,89 @@ TEST(TextEliderTest, ElideRectangleString) {
EXPECT_EQ(cases[i].result,
ui::ElideRectangleString(UTF8ToUTF16(cases[i].input),
cases[i].max_rows, cases[i].max_cols,
- &output));
+ true, &output));
+ EXPECT_EQ(cases[i].output, UTF16ToUTF8(output));
+ }
+}
+
+TEST(TextEliderTest, ElideRectangleStringNotStrict) {
+ struct TestData {
+ const char* input;
+ int max_rows;
+ int max_cols;
+ bool result;
+ const char* output;
+ } cases[] = {
+ { "", 0, 0, false, "" },
+ { "", 1, 1, false, "" },
+ { "Hi, my name_is\nDick", 0, 0, true, "..." },
+ { "Hi, my name_is\nDick", 1, 0, true, "\n..." },
+ { "Hi, my name_is\nDick", 0, 1, true, "..." },
+ { "Hi, my name_is\nDick", 1, 1, true, "H\n..." },
+ { "Hi, my name_is\nDick", 2, 1, true, "H\ni\n..." },
+ { "Hi, my name_is\nDick", 3, 1, true, "H\ni\n,\n..." },
+ { "Hi, my name_is\nDick", 4, 1, true, "H\ni\n,\n \n..." },
+ { "Hi, my name_is\nDick", 5, 1, true, "H\ni\n,\n \nm\n..." },
+ { "Hi, my name_is\nDick", 0, 2, true, "..." },
+ { "Hi, my name_is\nDick", 1, 2, true, "Hi\n..." },
+ { "Hi, my name_is\nDick", 2, 2, true, "Hi\n, \n..." },
+ { "Hi, my name_is\nDick", 3, 2, true, "Hi\n, \nmy\n..." },
+ { "Hi, my name_is\nDick", 4, 2, true, "Hi\n, \nmy\n n\n..." },
+ { "Hi, my name_is\nDick", 5, 2, true, "Hi\n, \nmy\n n\nam\n..." },
+ { "Hi, my name_is\nDick", 0, 3, true, "..." },
+ { "Hi, my name_is\nDick", 1, 3, true, "Hi,\n..." },
+ { "Hi, my name_is\nDick", 2, 3, true, "Hi,\n my\n..." },
+ { "Hi, my name_is\nDick", 3, 3, true, "Hi,\n my\n na\n..." },
+ { "Hi, my name_is\nDick", 4, 3, true, "Hi,\n my\n na\nme_\n..." },
+ { "Hi, my name_is\nDick", 5, 3, true, "Hi,\n my\n na\nme_\nis\n..." },
+ { "Hi, my name_is\nDick", 1, 4, true, "Hi, ..." },
+ { "Hi, my name_is\nDick", 2, 4, true, "Hi, my n\n..." },
+ { "Hi, my name_is\nDick", 3, 4, true, "Hi, my n\name_\n..." },
+ { "Hi, my name_is\nDick", 4, 4, true, "Hi, my n\name_\nis\n..." },
+ { "Hi, my name_is\nDick", 5, 4, false, "Hi, my n\name_\nis\nDick" },
+ { "Hi, my name_is\nDick", 1, 5, true, "Hi, ..." },
+ { "Hi, my name_is\nDick", 2, 5, true, "Hi, my na\n..." },
+ { "Hi, my name_is\nDick", 3, 5, true, "Hi, my na\nme_is\n..." },
+ { "Hi, my name_is\nDick", 4, 5, true, "Hi, my na\nme_is\n\n..." },
+ { "Hi, my name_is\nDick", 5, 5, false, "Hi, my na\nme_is\n\nDick" },
+ { "Hi, my name_is\nDick", 1, 6, true, "Hi, ..." },
+ { "Hi, my name_is\nDick", 2, 6, true, "Hi, my nam\n..." },
+ { "Hi, my name_is\nDick", 3, 6, true, "Hi, my nam\ne_is\n..." },
+ { "Hi, my name_is\nDick", 4, 6, false, "Hi, my nam\ne_is\nDick" },
+ { "Hi, my name_is\nDick", 5, 6, false, "Hi, my nam\ne_is\nDick" },
+ { "Hi, my name_is\nDick", 1, 7, true, "Hi, ..." },
+ { "Hi, my name_is\nDick", 2, 7, true, "Hi, my name\n..." },
+ { "Hi, my name_is\nDick", 3, 7, true, "Hi, my name\n_is\n..." },
+ { "Hi, my name_is\nDick", 4, 7, false, "Hi, my name\n_is\nDick" },
+ { "Hi, my name_is\nDick", 5, 7, false, "Hi, my name\n_is\nDick" },
+ { "Hi, my name_is\nDick", 1, 8, true, "Hi, my n\n..." },
+ { "Hi, my name_is\nDick", 2, 8, true, "Hi, my n\name_is\n..." },
+ { "Hi, my name_is\nDick", 3, 8, false, "Hi, my n\name_is\nDick" },
+ { "Hi, my name_is\nDick", 1, 9, true, "Hi, my ..." },
+ { "Hi, my name_is\nDick", 2, 9, true, "Hi, my name_is\n..." },
+ { "Hi, my name_is\nDick", 3, 9, false, "Hi, my name_is\nDick" },
+ { "Hi, my name_is\nDick", 1, 10, true, "Hi, my ..." },
+ { "Hi, my name_is\nDick", 2, 10, true, "Hi, my name_is\n..." },
+ { "Hi, my name_is\nDick", 3, 10, false, "Hi, my name_is\nDick" },
+ { "Hi, my name_is\nDick", 1, 11, true, "Hi, my ..." },
+ { "Hi, my name_is\nDick", 2, 11, true, "Hi, my name_is\n..." },
+ { "Hi, my name_is\nDick", 3, 11, false, "Hi, my name_is\nDick" },
+ { "Hi, my name_is\nDick", 1, 12, true, "Hi, my ..." },
+ { "Hi, my name_is\nDick", 2, 12, true, "Hi, my name_is\n..." },
+ { "Hi, my name_is\nDick", 3, 12, false, "Hi, my name_is\nDick" },
+ { "Hi, my name_is\nDick", 1, 13, true, "Hi, my ..." },
+ { "Hi, my name_is\nDick", 2, 13, true, "Hi, my name_is\n..." },
+ { "Hi, my name_is\nDick", 3, 13, false, "Hi, my name_is\nDick" },
+ { "Hi, my name_is\nDick", 1, 20, true, "Hi, my name_is\n..." },
+ { "Hi, my name_is\nDick", 2, 20, false, "Hi, my name_is\nDick" },
+ { "Hi, my name_is Dick", 1, 40, false, "Hi, my name_is Dick" },
+ };
+ string16 output;
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
+ EXPECT_EQ(cases[i].result,
+ ui::ElideRectangleString(UTF8ToUTF16(cases[i].input),
+ cases[i].max_rows, cases[i].max_cols,
+ false, &output));
EXPECT_EQ(cases[i].output, UTF16ToUTF8(output));
}
}
@@ -419,9 +501,9 @@ TEST(TextEliderTest, ElideRectangleWide16) {
L"\x03a0\x03b1\x03b3\x03ba\x03cc\x03c3\x03bc\x03b9\x03bf\x03c2\x0020\n"
L"\x0399\x03c3\x03c4\x03cc\x03c2"));
string16 output;
- EXPECT_TRUE(ui::ElideRectangleString(str, 2, 4, &output));
+ EXPECT_TRUE(ui::ElideRectangleString(str, 2, 4, true, &output));
EXPECT_EQ(out1, output);
- EXPECT_FALSE(ui::ElideRectangleString(str, 2, 12, &output));
+ EXPECT_FALSE(ui::ElideRectangleString(str, 2, 12, true, &output));
EXPECT_EQ(out2, output);
}
@@ -434,7 +516,7 @@ TEST(TextEliderTest, ElideRectangleWide32) {
"\xF0\x9D\x92\x9C\xF0\x9D\x92\x9C\xF0\x9D\x92\x9C\n"
"\xF0\x9D\x92\x9C \naaa\n..."));
string16 output;
- EXPECT_TRUE(ui::ElideRectangleString(str, 3, 3, &output));
+ EXPECT_TRUE(ui::ElideRectangleString(str, 3, 3, true, &output));
EXPECT_EQ(out, output);
}