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

Unified Diff: ui/gfx/text_elider.cc

Issue 312233003: Add fade eliding for Views Labels; related cleanup. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Refine alignment check; minor additional cleanup. Created 6 years, 6 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/gfx/text_elider.h ('k') | ui/gfx/text_elider_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/gfx/text_elider.cc
diff --git a/ui/gfx/text_elider.cc b/ui/gfx/text_elider.cc
index 7a7524acf22ba1ca6b3ce064ed9a68bac8f6521c..8c07bdecd5f581d2e88b3bf20f1947bd94fe1c6b 100644
--- a/ui/gfx/text_elider.cc
+++ b/ui/gfx/text_elider.cc
@@ -32,57 +32,18 @@ using base::WideToUTF16;
namespace gfx {
-// U+2026 in utf8
-const char kEllipsis[] = "\xE2\x80\xA6";
-const base::char16 kEllipsisUTF16[] = { 0x2026, 0 };
-const base::char16 kForwardSlash = '/';
-
-StringSlicer::StringSlicer(const base::string16& text,
- const base::string16& ellipsis,
- bool elide_in_middle,
- bool elide_at_beginning)
- : text_(text),
- ellipsis_(ellipsis),
- elide_in_middle_(elide_in_middle),
- elide_at_beginning_(elide_at_beginning) {
-}
-
-base::string16 StringSlicer::CutString(size_t length, bool insert_ellipsis) {
- const base::string16 ellipsis_text = insert_ellipsis ? ellipsis_
- : base::string16();
-
- if (elide_at_beginning_)
- return ellipsis_text +
- text_.substr(FindValidBoundaryBefore(text_.length() - length));
-
- if (!elide_in_middle_)
- return text_.substr(0, FindValidBoundaryBefore(length)) + ellipsis_text;
-
- // We put the extra character, if any, before the cut.
- const size_t half_length = length / 2;
- const size_t prefix_length = FindValidBoundaryBefore(length - half_length);
- const size_t suffix_start_guess = text_.length() - half_length;
- const size_t suffix_start = FindValidBoundaryAfter(suffix_start_guess);
- const size_t suffix_length =
- half_length - (suffix_start_guess - suffix_start);
- return text_.substr(0, prefix_length) + ellipsis_text +
- text_.substr(suffix_start, suffix_length);
-}
-
-size_t StringSlicer::FindValidBoundaryBefore(size_t index) const {
- DCHECK_LE(index, text_.length());
- if (index != text_.length())
- U16_SET_CP_START(text_.data(), 0, index);
- return index;
-}
-
-size_t StringSlicer::FindValidBoundaryAfter(size_t index) const {
- DCHECK_LE(index, text_.length());
- if (index != text_.length())
- U16_SET_CP_LIMIT(text_.data(), 0, index, text_.length());
- return index;
-}
+namespace {
+// Elides a well-formed email address (e.g. username@domain.com) to fit into
+// |available_pixel_width| using the specified |font_list|.
+// This function guarantees that the string returned will contain at least one
+// character, other than the ellipses, on either side of the '@'. If it is
+// impossible to achieve these requirements: only an ellipsis will be returned.
+// If possible: this elides only the username portion of the |email|. Otherwise,
+// the domain is elided in the middle so that it splits the available width
+// equally with the elided username (should the username be short enough that it
+// doesn't need half the available width: the elided domain will occupy that
+// extra width).
base::string16 ElideEmail(const base::string16& email,
const FontList& font_list,
float available_pixel_width) {
@@ -124,8 +85,7 @@ base::string16 ElideEmail(const base::string16& email,
std::min(available_domain_width,
std::max(available_pixel_width - full_username_width,
available_pixel_width / 2));
- domain = ElideText(domain, font_list, desired_domain_width,
- ELIDE_IN_MIDDLE);
+ domain = ElideText(domain, font_list, desired_domain_width, ELIDE_MIDDLE);
// Failing to elide the domain such that at least one character remains
// (other than the ellipsis itself) remains: return a single ellipsis.
if (domain.length() <= 1U)
@@ -136,12 +96,63 @@ base::string16 ElideEmail(const base::string16& email,
// is guaranteed to fit with at least one character remaining given all the
// precautions taken earlier).
available_pixel_width -= GetStringWidthF(domain, font_list);
- username = ElideText(username, font_list, available_pixel_width,
- ELIDE_AT_END);
-
+ username = ElideText(username, font_list, available_pixel_width, ELIDE_TAIL);
return username + kAtSignUTF16 + domain;
}
+} // namespace
+
+// U+2026 in utf8
+const char kEllipsis[] = "\xE2\x80\xA6";
+const base::char16 kEllipsisUTF16[] = { 0x2026, 0 };
+const base::char16 kForwardSlash = '/';
+
+StringSlicer::StringSlicer(const base::string16& text,
+ const base::string16& ellipsis,
+ bool elide_in_middle,
+ bool elide_at_beginning)
+ : text_(text),
+ ellipsis_(ellipsis),
+ elide_in_middle_(elide_in_middle),
+ elide_at_beginning_(elide_at_beginning) {
+}
+
+base::string16 StringSlicer::CutString(size_t length, bool insert_ellipsis) {
+ const base::string16 ellipsis_text = insert_ellipsis ? ellipsis_
+ : base::string16();
+
+ if (elide_at_beginning_)
+ return ellipsis_text +
+ text_.substr(FindValidBoundaryBefore(text_.length() - length));
+
+ if (!elide_in_middle_)
+ return text_.substr(0, FindValidBoundaryBefore(length)) + ellipsis_text;
+
+ // We put the extra character, if any, before the cut.
+ const size_t half_length = length / 2;
+ const size_t prefix_length = FindValidBoundaryBefore(length - half_length);
+ const size_t suffix_start_guess = text_.length() - half_length;
+ const size_t suffix_start = FindValidBoundaryAfter(suffix_start_guess);
+ const size_t suffix_length =
+ half_length - (suffix_start_guess - suffix_start);
+ return text_.substr(0, prefix_length) + ellipsis_text +
+ text_.substr(suffix_start, suffix_length);
+}
+
+size_t StringSlicer::FindValidBoundaryBefore(size_t index) const {
+ DCHECK_LE(index, text_.length());
+ if (index != text_.length())
+ U16_SET_CP_START(text_.data(), 0, index);
+ return index;
+}
+
+size_t StringSlicer::FindValidBoundaryAfter(size_t index) const {
+ DCHECK_LE(index, text_.length());
+ if (index != text_.length())
+ U16_SET_CP_LIMIT(text_.data(), 0, index, text_.length());
+ return index;
+}
+
base::string16 ElideFilename(const base::FilePath& filename,
const FontList& font_list,
float available_pixel_width) {
@@ -163,8 +174,8 @@ base::string16 ElideFilename(const base::FilePath& filename,
return base::i18n::GetDisplayStringInLTRDirectionality(filename_utf16);
if (rootname.empty() || extension.empty()) {
- const base::string16 elided_name = ElideText(filename_utf16, font_list,
- available_pixel_width, ELIDE_AT_END);
+ const base::string16 elided_name =
+ ElideText(filename_utf16, font_list, available_pixel_width, ELIDE_TAIL);
return base::i18n::GetDisplayStringInLTRDirectionality(elided_name);
}
@@ -179,14 +190,13 @@ base::string16 ElideFilename(const base::FilePath& filename,
if (ext_width >= available_pixel_width) {
const base::string16 elided_name = ElideText(
- rootname + extension, font_list, available_pixel_width,
- ELIDE_IN_MIDDLE);
+ rootname + extension, font_list, available_pixel_width, ELIDE_MIDDLE);
return base::i18n::GetDisplayStringInLTRDirectionality(elided_name);
}
float available_root_width = available_pixel_width - ext_width;
base::string16 elided_name =
- ElideText(rootname, font_list, available_root_width, ELIDE_AT_END);
+ ElideText(rootname, font_list, available_root_width, ELIDE_TAIL);
elided_name += extension;
return base::i18n::GetDisplayStringInLTRDirectionality(elided_name);
}
@@ -194,15 +204,17 @@ base::string16 ElideFilename(const base::FilePath& filename,
base::string16 ElideText(const base::string16& text,
const FontList& font_list,
float available_pixel_width,
- ElideBehavior elide_behavior) {
- if (text.empty())
+ ElideBehavior behavior) {
+ DCHECK_NE(behavior, FADE_TAIL);
+ if (text.empty() || behavior == FADE_TAIL)
return text;
+ if (behavior == ELIDE_EMAIL)
+ return ElideEmail(text, font_list, available_pixel_width);
const float current_text_pixel_width = GetStringWidthF(text, font_list);
- const bool elide_in_middle = (elide_behavior == ELIDE_IN_MIDDLE);
- const bool elide_at_beginning = (elide_behavior == ELIDE_AT_BEGINNING);
- const bool insert_ellipsis = (elide_behavior != TRUNCATE_AT_END);
-
+ const bool elide_in_middle = (behavior == ELIDE_MIDDLE);
+ const bool elide_at_beginning = (behavior == ELIDE_HEAD);
+ const bool insert_ellipsis = (behavior != TRUNCATE);
const base::string16 ellipsis = base::string16(kEllipsisUTF16);
StringSlicer slicer(text, ellipsis, elide_in_middle, elide_at_beginning);
@@ -214,10 +226,10 @@ base::string16 ElideText(const base::string16& text,
// return positive numbers again. Detecting that is probably not worth it
// (eliding way too much from a ridiculous string is probably still
// ridiculous), but we should check other widths for bogus values as well.
- if (current_text_pixel_width <= 0 && !text.empty()) {
+ if (current_text_pixel_width <= 0) {
const base::string16 cut =
slicer.CutString(text.length() / 2, insert_ellipsis);
- return ElideText(cut, font_list, available_pixel_width, elide_behavior);
+ return ElideText(cut, font_list, available_pixel_width, behavior);
}
if (current_text_pixel_width <= available_pixel_width)
@@ -254,7 +266,8 @@ base::string16 ElideText(const base::string16& text,
return slicer.CutString(guess, insert_ellipsis);
}
-bool ElideString(const base::string16& input, int max_len,
+bool ElideString(const base::string16& input,
+ int max_len,
base::string16* output) {
DCHECK_GE(max_len, 0);
if (static_cast<int>(input.length()) <= max_len) {
@@ -633,11 +646,10 @@ int RectangleText::WrapWord(const base::string16& word) {
bool first_fragment = true;
while (!insufficient_height_ && !text.empty()) {
base::string16 fragment =
- ElideText(text, font_list_, available_pixel_width_,
- TRUNCATE_AT_END);
+ ElideText(text, font_list_, available_pixel_width_, TRUNCATE);
// At least one character has to be added at every line, even if the
// available space is too small.
- if(fragment.empty())
+ if (fragment.empty())
fragment = text.substr(0, 1);
if (!first_fragment && NewLine())
lines_added++;
@@ -665,7 +677,7 @@ int RectangleText::AddWordOverflow(const base::string16& word) {
lines_added += WrapWord(word);
} else {
const ElideBehavior elide_behavior =
- (wrap_behavior_ == ELIDE_LONG_WORDS ? ELIDE_AT_END : TRUNCATE_AT_END);
+ (wrap_behavior_ == ELIDE_LONG_WORDS ? ELIDE_TAIL : TRUNCATE);
const base::string16 elided_word =
ElideText(word, font_list_, available_pixel_width_, elide_behavior);
AddToCurrentLine(elided_word);
« no previous file with comments | « ui/gfx/text_elider.h ('k') | ui/gfx/text_elider_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698