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

Unified Diff: ui/gfx/text_elider.cc

Issue 354963003: Move gfx::ElideText functionality to RenderText. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Exclude unreachable code by platform. 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
Index: ui/gfx/text_elider.cc
diff --git a/ui/gfx/text_elider.cc b/ui/gfx/text_elider.cc
index 8c07bdecd5f581d2e88b3bf20f1947bd94fe1c6b..947027887b02c92791a3296fcfb23ddb0f949b12 100644
--- a/ui/gfx/text_elider.cc
+++ b/ui/gfx/text_elider.cc
@@ -24,6 +24,7 @@
#include "third_party/icu/source/common/unicode/rbbi.h"
#include "third_party/icu/source/common/unicode/uloc.h"
#include "ui/gfx/font_list.h"
+#include "ui/gfx/render_text.h"
#include "ui/gfx/text_utils.h"
using base::ASCIIToUTF16;
@@ -34,16 +35,13 @@ namespace gfx {
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).
+#if !defined(OS_WIN) && !defined(OS_LINUX)
+// The returned string will have at least one character besides the ellipsis
+// on either side of '@'; if that's impossible, a single ellipsis is returned.
+// If possible, only the username is elided. Otherwise, the domain is elided
+// in the middle, splitting available width equally with the elided username.
+// If the username is 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) {
@@ -51,10 +49,8 @@ base::string16 ElideEmail(const base::string16& email,
return email;
// Split the email into its local-part (username) and domain-part. The email
- // spec technically allows for @ symbols in the local-part (username) of the
- // email under some special requirements. It is guaranteed that there is no @
- // symbol in the domain part of the email however so splitting at the last @
- // symbol is safe.
+ // spec allows for @ symbols in the username under some special requirements,
+ // but not in the domain part, so splitting at the last @ symbol is safe.
const size_t split_index = email.find_last_of('@');
DCHECK_NE(split_index, base::string16::npos);
base::string16 username = email.substr(0, split_index);
@@ -99,6 +95,7 @@ base::string16 ElideEmail(const base::string16& email,
username = ElideText(username, font_list, available_pixel_width, ELIDE_TAIL);
return username + kAtSignUTF16 + domain;
}
+#endif
} // namespace
@@ -205,36 +202,32 @@ base::string16 ElideText(const base::string16& text,
const FontList& font_list,
float available_pixel_width,
ElideBehavior behavior) {
+#if defined(OS_WIN) || defined(OS_LINUX)
Alexei Svitkine (slow) 2014/07/03 20:12:34 I understand why it wouldn't work on platforms tha
msw 2014/07/08 19:07:36 RenderText doesn't support RectF values for the di
+ DCHECK_NE(behavior, FADE_TAIL);
+ scoped_ptr<RenderText> render_text(RenderText::CreateInstance());
+ render_text->SetCursorEnabled(false);
+ // Do not bother accurately sizing strings over 5000 characters here, for
+ // performance purposes. This matches the behavior of Canvas::SizeStringFloat.
+ render_text->set_truncate_length(5000);
+ render_text->SetFontList(font_list);
+ render_text->SetDisplayRect(gfx::Rect(gfx::Size(available_pixel_width, 1)));
+ render_text->SetElideBehavior(behavior);
+ render_text->SetText(text);
+ return render_text->layout_text();
+#else
DCHECK_NE(behavior, FADE_TAIL);
- if (text.empty() || behavior == FADE_TAIL)
+ if (text.empty() || behavior == FADE_TAIL || behavior == NO_ELIDE ||
+ GetStringWidthF(text, font_list) <= available_pixel_width)
Alexei Svitkine (slow) 2014/07/03 20:12:34 Nit: {}'s
msw 2014/07/08 19:07:36 Done.
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 = (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);
- // Pango will return 0 width for absurdly long strings. Cut the string in
- // half and try again.
- // This is caused by an int overflow in Pango (specifically, in
- // pango_glyph_string_extents_range). It's actually more subtle than just
- // returning 0, since on super absurdly long strings, the int can wrap and
- // 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) {
- const base::string16 cut =
- slicer.CutString(text.length() / 2, insert_ellipsis);
- return ElideText(cut, font_list, available_pixel_width, behavior);
- }
-
- if (current_text_pixel_width <= available_pixel_width)
- return text;
-
if (insert_ellipsis &&
GetStringWidthF(ellipsis, font_list) > available_pixel_width)
return base::string16();
@@ -254,8 +247,7 @@ base::string16 ElideText(const base::string16& text,
break;
if (guess_width > available_pixel_width) {
hi = guess - 1;
- // Move back if we are on loop terminating condition, and guess is wider
- // than available.
+ // Move back on the loop terminating condition when the guess is too wide.
if (hi < lo)
lo = hi;
} else {
@@ -264,6 +256,7 @@ base::string16 ElideText(const base::string16& text,
}
return slicer.CutString(guess, insert_ellipsis);
+#endif
}
bool ElideString(const base::string16& input,

Powered by Google App Engine
This is Rietveld 408576698