summaryrefslogtreecommitdiffstats
path: root/ui/base
diff options
context:
space:
mode:
authorbartfab@chromium.org <bartfab@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-14 20:11:00 +0000
committerbartfab@chromium.org <bartfab@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-14 20:11:00 +0000
commita2ac2864d48491b47068d5c30922329dfd135d0c (patch)
tree4b379492310e34b9c1e0b1a59caa4928ad4b6598 /ui/base
parent14efc6d257c73271ae0b70d2e71571b335827570 (diff)
downloadchromium_src-a2ac2864d48491b47068d5c30922329dfd135d0c.zip
chromium_src-a2ac2864d48491b47068d5c30922329dfd135d0c.tar.gz
chromium_src-a2ac2864d48491b47068d5c30922329dfd135d0c.tar.bz2
Make ElideRectangleText() report horizontal truncation as well
This CL modifies ElideRectangleText() so that instead of a single bool, it returns a combination of flags indicating whether the text had to be truncated horizontally and/or vertically. BUG=None Review URL: https://chromiumcodereview.appspot.com/11361259 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@167720 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/base')
-rw-r--r--ui/base/text/text_elider.cc34
-rw-r--r--ui/base/text/text_elider.h24
-rw-r--r--ui/base/text/text_elider_unittest.cc78
3 files changed, 78 insertions, 58 deletions
diff --git a/ui/base/text/text_elider.cc b/ui/base/text/text_elider.cc
index 5f1593e..4388c07 100644
--- a/ui/base/text/text_elider.cc
+++ b/ui/base/text/text_elider.cc
@@ -795,7 +795,8 @@ class RectangleText {
current_height_(0),
last_line_ended_in_lf_(false),
lines_(lines),
- full_(false) {}
+ insufficient_width_(false),
+ insufficient_height_(false) {}
// Perform deferred initializions following creation. Must be called
// before any input can be added via AddString().
@@ -808,9 +809,10 @@ class RectangleText {
void AddString(const string16& input);
// Perform any deferred output processing. Must be called after the last
- // AddString() call has occured. Returns |true| if the text had to be
- // truncated to fit the available height.
- bool Finalize();
+ // AddString() call has occured. Returns a combination of
+ // |ReformattingResultFlags| indicating whether the given width or height was
+ // insufficient, leading to elision or truncation.
+ int Finalize();
private:
// Add a line to the rectangular region at the current position,
@@ -867,8 +869,12 @@ class RectangleText {
// The output vector of lines.
std::vector<string16>* lines_;
+ // Indicates whether a word was so long that it had to be truncated or elided
+ // to fit the available width.
+ bool insufficient_width_;
+
// Indicates whether there were too many lines for the available height.
- bool full_;
+ bool insufficient_height_;
DISALLOW_COPY_AND_ASSIGN(RectangleText);
};
@@ -877,7 +883,7 @@ void RectangleText::AddString(const string16& input) {
base::i18n::BreakIterator lines(input,
base::i18n::BreakIterator::BREAK_NEWLINE);
if (lines.Init()) {
- while (!full_ && lines.Advance()) {
+ while (!insufficient_height_ && lines.Advance()) {
string16 line = lines.GetString();
// The BREAK_NEWLINE iterator will keep the trailing newline character,
// except in the case of the last line, which may not have one. Remove
@@ -892,17 +898,18 @@ void RectangleText::AddString(const string16& input) {
}
}
-bool RectangleText::Finalize() {
+int RectangleText::Finalize() {
// Remove trailing whitespace from the last line or remove the last line
// completely, if it's just whitespace.
- if (!full_ && !lines_->empty()) {
+ if (!insufficient_height_ && !lines_->empty()) {
TrimWhitespace(lines_->back(), TRIM_TRAILING, &lines_->back());
if (lines_->back().empty() && !last_line_ended_in_lf_)
lines_->pop_back();
}
if (last_line_ended_in_lf_)
lines_->push_back(string16());
- return full_;
+ return (insufficient_width_ ? ui::INSUFFICIENT_SPACE_HORIZONTAL : 0) |
+ (insufficient_height_ ? ui::INSUFFICIENT_SPACE_VERTICAL : 0);
}
void RectangleText::AddLine(const string16& line) {
@@ -945,7 +952,7 @@ int RectangleText::WrapWord(const string16& word) {
string16 text = word;
int lines_added = 0;
bool first_fragment = true;
- while (!full_ && !text.empty()) {
+ while (!insufficient_height_ && !text.empty()) {
const string16 fragment =
ui::ElideText(text, font_, available_pixel_width_, ui::TRUNCATE_AT_END);
if (!first_fragment && NewLine())
@@ -979,6 +986,7 @@ int RectangleText::AddWordOverflow(const string16& word) {
const string16 elided_word =
ui::ElideText(word, font_, available_pixel_width_, elide_behavior);
AddToCurrentLine(elided_word);
+ insufficient_width_ = true;
}
return lines_added;
@@ -1009,7 +1017,7 @@ void RectangleText::AddToCurrentLine(const string16& text) {
void RectangleText::AddToCurrentLineWithWidth(const string16& text,
int text_width) {
if (current_height_ >= available_pixel_height_) {
- full_ = true;
+ insufficient_height_ = true;
return;
}
current_line_.append(text);
@@ -1023,7 +1031,7 @@ bool RectangleText::NewLine() {
current_line_.clear();
line_added = true;
} else {
- full_ = true;
+ insufficient_height_ = true;
}
current_height_ += line_height_;
current_width_ = 0;
@@ -1042,7 +1050,7 @@ bool ElideRectangleString(const string16& input, size_t max_rows,
return rect.Finalize();
}
-bool ElideRectangleText(const string16& input,
+int ElideRectangleText(const string16& input,
const gfx::Font& font,
int available_pixel_width,
int available_pixel_height,
diff --git a/ui/base/text/text_elider.h b/ui/base/text/text_elider.h
index 20e202d..39249ad 100644
--- a/ui/base/text/text_elider.h
+++ b/ui/base/text/text_elider.h
@@ -167,18 +167,28 @@ enum WordWrapBehavior {
WRAP_LONG_WORDS,
};
+// Indicates whether the |available_pixel_width| by |available_pixel_height|
+// rectangle passed to |ElideRectangleText()| had insufficient space to
+// accommodate the given |text|, leading to elision or truncation.
+enum ReformattingResultFlags {
+ INSUFFICIENT_SPACE_HORIZONTAL = 1 << 0,
+ INSUFFICIENT_SPACE_VERTICAL = 1 << 1,
+};
+
// Reformats |text| into output vector |lines| so that the resulting text fits
// into an |available_pixel_width| by |available_pixel_height| rectangle with
// the specified |font|. Input newlines are respected, but lines that are too
// long are broken into pieces. For words that are too wide to fit on a single
// line, the wrapping behavior can be specified with the |wrap_behavior| param.
-// Returns |true| if the input had to be truncated (and not just reformatted).
-UI_EXPORT bool ElideRectangleText(const string16& text,
- const gfx::Font& font,
- int available_pixel_width,
- int available_pixel_height,
- WordWrapBehavior wrap_behavior,
- std::vector<string16>* lines);
+// Returns a combination of |ReformattingResultFlags| that indicate whether the
+// given rectangle had insufficient space to accommodate |texŧ|, leading to
+// elision or truncation (and not just reformatting).
+UI_EXPORT int ElideRectangleText(const string16& text,
+ const gfx::Font& font,
+ int available_pixel_width,
+ int available_pixel_height,
+ WordWrapBehavior wrap_behavior,
+ std::vector<string16>* lines);
// Truncates the string to length characters. This breaks the string at
// the first word break before length, adding the horizontal ellipsis
diff --git a/ui/base/text/text_elider_unittest.cc b/ui/base/text/text_elider_unittest.cc
index e21b33c..8f9aa9c 100644
--- a/ui/base/text/text_elider_unittest.cc
+++ b/ui/base/text/text_elider_unittest.cc
@@ -524,7 +524,7 @@ TEST(TextEliderTest, ElideRectangleText) {
const char* input;
int available_pixel_width;
int available_pixel_height;
- bool truncated;
+ bool truncated_y;
const char* output;
} cases[] = {
{ "", 0, 0, false, NULL },
@@ -556,7 +556,7 @@ TEST(TextEliderTest, ElideRectangleText) {
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
std::vector<string16> lines;
- EXPECT_EQ(cases[i].truncated,
+ EXPECT_EQ(cases[i].truncated_y ? INSUFFICIENT_SPACE_VERTICAL : 0,
ElideRectangleText(UTF8ToUTF16(cases[i].input),
font,
cases[i].available_pixel_width,
@@ -583,12 +583,12 @@ TEST(TextEliderTest, ElideRectangleTextPunctuation) {
int available_pixel_width;
int available_pixel_height;
bool wrap_words;
- bool truncated;
+ bool truncated_x;
const char* output;
} cases[] = {
{ "Test T.", test_t_width, line_height * 2, false, false, "Test|T." },
{ "Test T ?", test_t_width, line_height * 2, false, false, "Test|T ?" },
- { "Test. Test", test_width, line_height * 3, false, false, "Test|Test" },
+ { "Test. Test", test_width, line_height * 3, false, true, "Test|Test" },
{ "Test. Test", test_width, line_height * 3, true, false, "Test|.|Test" },
};
@@ -596,7 +596,7 @@ TEST(TextEliderTest, ElideRectangleTextPunctuation) {
std::vector<string16> lines;
const WordWrapBehavior wrap_behavior =
(cases[i].wrap_words ? WRAP_LONG_WORDS : TRUNCATE_LONG_WORDS);
- EXPECT_EQ(cases[i].truncated,
+ EXPECT_EQ(cases[i].truncated_x ? INSUFFICIENT_SPACE_HORIZONTAL : 0,
ElideRectangleText(UTF8ToUTF16(cases[i].input),
font,
cases[i].available_pixel_width,
@@ -623,45 +623,47 @@ TEST(TextEliderTest, ElideRectangleTextLongWords) {
const char* input;
int available_pixel_width;
WordWrapBehavior wrap_behavior;
+ bool truncated_x;
const char* output;
} cases[] = {
- { "Testing", test_width, IGNORE_LONG_WORDS, "Testing" },
- { "X Testing", test_width, IGNORE_LONG_WORDS, "X|Testing" },
- { "Test Testing", test_width, IGNORE_LONG_WORDS, "Test|Testing" },
- { "Test\nTesting", test_width, IGNORE_LONG_WORDS, "Test|Testing" },
- { "Test Tests ", test_width, IGNORE_LONG_WORDS, "Test|Tests" },
- { "Test Tests T", test_width, IGNORE_LONG_WORDS, "Test|Tests|T" },
-
- { "Testing", elided_width, ELIDE_LONG_WORDS, "Tes..." },
- { "X Testing", elided_width, ELIDE_LONG_WORDS, "X|Tes..." },
- { "Test Testing", elided_width, ELIDE_LONG_WORDS, "Test|Tes..." },
- { "Test\nTesting", elided_width, ELIDE_LONG_WORDS, "Test|Tes..." },
-
- { "Testing", test_width, TRUNCATE_LONG_WORDS, "Test" },
- { "X Testing", test_width, TRUNCATE_LONG_WORDS, "X|Test" },
- { "Test Testing", test_width, TRUNCATE_LONG_WORDS, "Test|Test" },
- { "Test\nTesting", test_width, TRUNCATE_LONG_WORDS, "Test|Test" },
- { "Test Tests ", test_width, TRUNCATE_LONG_WORDS, "Test|Test" },
- { "Test Tests T", test_width, TRUNCATE_LONG_WORDS, "Test|Test|T" },
-
- { "Testing", test_width, WRAP_LONG_WORDS, "Test|ing" },
- { "X Testing", test_width, WRAP_LONG_WORDS, "X|Test|ing" },
- { "Test Testing", test_width, WRAP_LONG_WORDS, "Test|Test|ing" },
- { "Test\nTesting", test_width, WRAP_LONG_WORDS, "Test|Test|ing" },
- { "Test Tests ", test_width, WRAP_LONG_WORDS, "Test|Test|s" },
- { "Test Tests T", test_width, WRAP_LONG_WORDS, "Test|Test|s T" },
- { "TestTestTest", test_width, WRAP_LONG_WORDS, "Test|Test|Test" },
- { "TestTestTestT", test_width, WRAP_LONG_WORDS, "Test|Test|Test|T" },
+ { "Testing", test_width, IGNORE_LONG_WORDS, false, "Testing" },
+ { "X Testing", test_width, IGNORE_LONG_WORDS, false, "X|Testing" },
+ { "Test Testing", test_width, IGNORE_LONG_WORDS, false, "Test|Testing" },
+ { "Test\nTesting", test_width, IGNORE_LONG_WORDS, false, "Test|Testing" },
+ { "Test Tests ", test_width, IGNORE_LONG_WORDS, false, "Test|Tests" },
+ { "Test Tests T", test_width, IGNORE_LONG_WORDS, false, "Test|Tests|T" },
+
+ { "Testing", elided_width, ELIDE_LONG_WORDS, true, "Tes..." },
+ { "X Testing", elided_width, ELIDE_LONG_WORDS, true, "X|Tes..." },
+ { "Test Testing", elided_width, ELIDE_LONG_WORDS, true, "Test|Tes..." },
+ { "Test\nTesting", elided_width, ELIDE_LONG_WORDS, true, "Test|Tes..." },
+
+ { "Testing", test_width, TRUNCATE_LONG_WORDS, true, "Test" },
+ { "X Testing", test_width, TRUNCATE_LONG_WORDS, true, "X|Test" },
+ { "Test Testing", test_width, TRUNCATE_LONG_WORDS, true, "Test|Test" },
+ { "Test\nTesting", test_width, TRUNCATE_LONG_WORDS, true, "Test|Test" },
+ { "Test Tests ", test_width, TRUNCATE_LONG_WORDS, true, "Test|Test" },
+ { "Test Tests T", test_width, TRUNCATE_LONG_WORDS, true, "Test|Test|T" },
+
+ { "Testing", test_width, WRAP_LONG_WORDS, false, "Test|ing" },
+ { "X Testing", test_width, WRAP_LONG_WORDS, false, "X|Test|ing" },
+ { "Test Testing", test_width, WRAP_LONG_WORDS, false, "Test|Test|ing" },
+ { "Test\nTesting", test_width, WRAP_LONG_WORDS, false, "Test|Test|ing" },
+ { "Test Tests ", test_width, WRAP_LONG_WORDS, false, "Test|Test|s" },
+ { "Test Tests T", test_width, WRAP_LONG_WORDS, false, "Test|Test|s T" },
+ { "TestTestTest", test_width, WRAP_LONG_WORDS, false, "Test|Test|Test" },
+ { "TestTestTestT", test_width, WRAP_LONG_WORDS, false, "Test|Test|Test|T" },
};
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
std::vector<string16> lines;
- ElideRectangleText(UTF8ToUTF16(cases[i].input),
- font,
- cases[i].available_pixel_width,
- kAvailableHeight,
- cases[i].wrap_behavior,
- &lines);
+ EXPECT_EQ(cases[i].truncated_x ? INSUFFICIENT_SPACE_HORIZONTAL : 0,
+ ElideRectangleText(UTF8ToUTF16(cases[i].input),
+ font,
+ cases[i].available_pixel_width,
+ kAvailableHeight,
+ cases[i].wrap_behavior,
+ &lines));
std::string expected_output(cases[i].output);
ReplaceSubstringsAfterOffset(&expected_output, 0, "...", kEllipsis);
const std::string result = UTF16ToUTF8(JoinString(lines, '|'));