Add line height setting to views::Label & use it for notifications.

This fixes the line spacing of notification so it's 18px on all
platforms (instead of the previous 17px on Chrome OS and 15px on
Windows).

To do this, support for a line height property was added to the
BoundedLabel that NotificationView uses, to the Label that BoundedLabel
uses, and to the Canvas that Label uses.

BUG=225871
R=mukai@chromium.org,msw@chromium.org

Review URL: https://chromiumcodereview.appspot.com/14322007

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@195076 0039d316-1c4b-4281-b951-d872f2087c98
parent a1c0601d
...@@ -89,7 +89,7 @@ void Canvas::RecreateBackingCanvas(const gfx::Size& size, ...@@ -89,7 +89,7 @@ void Canvas::RecreateBackingCanvas(const gfx::Size& size,
// static // static
int Canvas::GetStringWidth(const string16& text, const gfx::Font& font) { int Canvas::GetStringWidth(const string16& text, const gfx::Font& font) {
int width = 0, height = 0; int width = 0, height = 0;
Canvas::SizeStringInt(text, font, &width, &height, NO_ELLIPSIS); Canvas::SizeStringInt(text, font, &width, &height, 0, NO_ELLIPSIS);
return width; return width;
} }
...@@ -433,6 +433,7 @@ void Canvas::DrawStringInt(const string16& text, ...@@ -433,6 +433,7 @@ void Canvas::DrawStringInt(const string16& text,
font, font,
color, color,
gfx::Rect(x, y, w, h), gfx::Rect(x, y, w, h),
0,
flags, flags,
ShadowValues()); ShadowValues());
} }
......
...@@ -124,10 +124,12 @@ class UI_EXPORT Canvas { ...@@ -124,10 +124,12 @@ class UI_EXPORT Canvas {
// Compute the size required to draw some text with the provided font. // Compute the size required to draw some text with the provided font.
// Attempts to fit the text with the provided width and height. Increases // Attempts to fit the text with the provided width and height. Increases
// height and then width as needed to make the text fit. This method // height and then width as needed to make the text fit. This method
// supports multiple lines. // supports multiple lines. On Skia only a line_height can be specified and
// specifying a 0 value for it will cause the default height to be used.
static void SizeStringInt(const string16& text, static void SizeStringInt(const string16& text,
const gfx::Font& font, const gfx::Font& font,
int* width, int* height, int* width, int* height,
int line_height,
int flags); int flags);
// Returns the number of horizontal pixels needed to display the specified // Returns the number of horizontal pixels needed to display the specified
...@@ -322,11 +324,13 @@ class UI_EXPORT Canvas { ...@@ -322,11 +324,13 @@ class UI_EXPORT Canvas {
int flags); int flags);
// Similar to above DrawStringInt method but with text shadows support. // Similar to above DrawStringInt method but with text shadows support.
// Currently it's only implemented for canvas skia. // Currently it's only implemented for canvas skia. Specifying a 0 line_height
// will cause the default height to be used.
void DrawStringWithShadows(const string16& text, void DrawStringWithShadows(const string16& text,
const gfx::Font& font, const gfx::Font& font,
SkColor color, SkColor color,
const gfx::Rect& text_bounds, const gfx::Rect& text_bounds,
int line_height,
int flags, int flags,
const ShadowValues& shadows); const ShadowValues& shadows);
......
...@@ -12,7 +12,10 @@ namespace gfx { ...@@ -12,7 +12,10 @@ namespace gfx {
// static // static
void Canvas::SizeStringInt(const string16& text, void Canvas::SizeStringInt(const string16& text,
const gfx::Font& font, const gfx::Font& font,
int* width, int* height, int flags) { int* width,
int* height,
int line_height,
int flags) {
NOTIMPLEMENTED(); NOTIMPLEMENTED();
} }
...@@ -20,6 +23,7 @@ void Canvas::DrawStringWithShadows(const string16& text, ...@@ -20,6 +23,7 @@ void Canvas::DrawStringWithShadows(const string16& text,
const gfx::Font& font, const gfx::Font& font,
SkColor color, SkColor color,
const gfx::Rect& text_bounds, const gfx::Rect& text_bounds,
int line_height,
int flags, int flags,
const ShadowValues& shadows) { const ShadowValues& shadows) {
NOTIMPLEMENTED(); NOTIMPLEMENTED();
......
...@@ -13,11 +13,10 @@ ...@@ -13,11 +13,10 @@
#include "ui/gfx/rect.h" #include "ui/gfx/rect.h"
// Note: This is a temporary Skia-based implementation of the ui/gfx text // Note: This is a temporary Skia-based implementation of the ui/gfx text
// rendering routines for views/aura. It replaces the stale Cocoa-based // rendering routines for views/aura. It replaces the stale Cocoa-based
// implementation. A future |canvas_skia.cc| implementation will supersede // implementation. A future |canvas_skia.cc| implementation will supersede
// this and the other platform-specific implmenentations. // this and the other platform-specific implmenentations. Most drawing options,
// Most drawing options, such as alignment and multi-line, are not implemented // such as alignment, multi-line, and line heights are not implemented here.
// here.
namespace { namespace {
...@@ -40,7 +39,11 @@ void Canvas::SizeStringInt(const string16& text, ...@@ -40,7 +39,11 @@ void Canvas::SizeStringInt(const string16& text,
const gfx::Font& font, const gfx::Font& font,
int* width, int* width,
int* height, int* height,
int line_height,
int flags) { int flags) {
DLOG_IF(WARNING, line_height != 0) << "Line heights not implemented.";
DLOG_IF(WARNING, flags & Canvas::MULTI_LINE) << "Multi-line not implemented.";
NSFont* native_font = font.GetNativeFont(); NSFont* native_font = font.GetNativeFont();
NSString* ns_string = base::SysUTF16ToNSString(text); NSString* ns_string = base::SysUTF16ToNSString(text);
NSDictionary* attributes = NSDictionary* attributes =
...@@ -55,9 +58,12 @@ void Canvas::DrawStringWithShadows(const string16& text, ...@@ -55,9 +58,12 @@ void Canvas::DrawStringWithShadows(const string16& text,
const gfx::Font& font, const gfx::Font& font,
SkColor color, SkColor color,
const gfx::Rect& text_bounds, const gfx::Rect& text_bounds,
int line_height,
int flags, int flags,
const ShadowValues& shadows) { const ShadowValues& shadows) {
DLOG_IF(WARNING, !shadows.empty()) << "Text shadow not implemented."; DLOG_IF(WARNING, line_height != 0) << "Line heights not implemented.";
DLOG_IF(WARNING, flags & Canvas::MULTI_LINE) << "Multi-line not implemented.";
DLOG_IF(WARNING, !shadows.empty()) << "Text shadows not implemented.";
skia::RefPtr<SkTypeface> typeface = skia::AdoptRef( skia::RefPtr<SkTypeface> typeface = skia::AdoptRef(
SkTypeface::CreateFromName( SkTypeface::CreateFromName(
......
...@@ -169,6 +169,7 @@ int AdjustPlatformSpecificFlags(const string16& text, int flags) { ...@@ -169,6 +169,7 @@ int AdjustPlatformSpecificFlags(const string16& text, int flags) {
void Canvas::SizeStringInt(const string16& text, void Canvas::SizeStringInt(const string16& text,
const Font& font, const Font& font,
int* width, int* height, int* width, int* height,
int line_height,
int flags) { int flags) {
DCHECK_GE(*width, 0); DCHECK_GE(*width, 0);
DCHECK_GE(*height, 0); DCHECK_GE(*height, 0);
...@@ -201,7 +202,7 @@ void Canvas::SizeStringInt(const string16& text, ...@@ -201,7 +202,7 @@ void Canvas::SizeStringInt(const string16& text,
render_text->SetText(strings[i]); render_text->SetText(strings[i]);
const Size string_size = render_text->GetStringSize(); const Size string_size = render_text->GetStringSize();
w = std::max(w, string_size.width()); w = std::max(w, string_size.width());
h += string_size.height(); h += (i > 0 && line_height > 0) ? line_height : string_size.height();
} }
*width = w; *width = w;
*height = h; *height = h;
...@@ -228,6 +229,7 @@ void Canvas::DrawStringWithShadows(const string16& text, ...@@ -228,6 +229,7 @@ void Canvas::DrawStringWithShadows(const string16& text,
const Font& font, const Font& font,
SkColor color, SkColor color,
const Rect& text_bounds, const Rect& text_bounds,
int line_height,
int flags, int flags,
const ShadowValues& shadows) { const ShadowValues& shadows) {
if (!IntersectsClipRect(text_bounds)) if (!IntersectsClipRect(text_bounds))
...@@ -268,18 +270,22 @@ void Canvas::DrawStringWithShadows(const string16& text, ...@@ -268,18 +270,22 @@ void Canvas::DrawStringWithShadows(const string16& text,
for (size_t i = 0; i < strings.size(); i++) { for (size_t i = 0; i < strings.size(); i++) {
ui::Range range = StripAcceleratorChars(flags, &strings[i]); ui::Range range = StripAcceleratorChars(flags, &strings[i]);
UpdateRenderText(rect, strings[i], font, flags, color, render_text.get()); UpdateRenderText(rect, strings[i], font, flags, color, render_text.get());
const int line_height = render_text->GetStringSize().height(); int line_padding = 0;
if (line_height > 0)
line_padding = line_height - render_text->GetStringSize().height();
else
line_height = render_text->GetStringSize().height();
// TODO(msw|asvitkine): Center Windows multi-line text: crbug.com/107357 // TODO(msw|asvitkine): Center Windows multi-line text: crbug.com/107357
#if !defined(OS_WIN) #if !defined(OS_WIN)
if (i == 0) { if (i == 0) {
// TODO(msw|asvitkine): Support multi-line text with varied heights. // TODO(msw|asvitkine): Support multi-line text with varied heights.
const int aggregate_height = strings.size() * line_height; const int text_height = strings.size() * line_height - line_padding;
rect += Vector2d(0, (text_bounds.height() - aggregate_height) / 2); rect += Vector2d(0, (text_bounds.height() - text_height) / 2);
} }
#endif #endif
rect.set_height(line_height); rect.set_height(line_height - line_padding);
if (range.IsValid()) if (range.IsValid())
render_text->ApplyStyle(UNDERLINE, true, range); render_text->ApplyStyle(UNDERLINE, true, range);
...@@ -313,10 +319,10 @@ void Canvas::DrawStringWithShadows(const string16& text, ...@@ -313,10 +319,10 @@ void Canvas::DrawStringWithShadows(const string16& text,
UpdateRenderText(rect, adjusted_text, font, flags, color, UpdateRenderText(rect, adjusted_text, font, flags, color,
render_text.get()); render_text.get());
const int line_height = render_text->GetStringSize().height(); const int text_height = render_text->GetStringSize().height();
// Center the text vertically. // Center the text vertically.
rect += Vector2d(0, (text_bounds.height() - line_height) / 2); rect += Vector2d(0, (text_bounds.height() - text_height) / 2);
rect.set_height(line_height); rect.set_height(text_height);
render_text->SetDisplayRect(rect); render_text->SetDisplayRect(rect);
if (range.IsValid()) if (range.IsValid())
render_text->ApplyStyle(UNDERLINE, true, range); render_text->ApplyStyle(UNDERLINE, true, range);
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include <limits>
#include "base/utf_string_conversions.h" #include "base/utf_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/canvas.h" #include "ui/gfx/canvas.h"
...@@ -9,29 +11,50 @@ ...@@ -9,29 +11,50 @@
namespace gfx { namespace gfx {
TEST(CanvasTest, StringWidth) { class CanvasTest : public testing::Test {
const string16 text = UTF8ToUTF16("Test"); protected:
const int width = Canvas::GetStringWidth(text, Font()); int GetStringWidth(const char *text) {
return Canvas::GetStringWidth(UTF8ToUTF16(text), font_);
EXPECT_GT(width, 0); }
gfx::Size SizeStringInt(const char *text, int width, int line_height) {
string16 text16 = UTF8ToUTF16(text);
int height = 0;
int flags = (text16.find('\n') != string16::npos) ? Canvas::MULTI_LINE : 0;
Canvas::SizeStringInt(text16, font_, &width, &height, line_height, flags);
return gfx::Size(width, height);
}
private:
gfx::Font font_;
};
TEST_F(CanvasTest, StringWidth) {
EXPECT_GT(GetStringWidth("Test"), 0);
} }
TEST(CanvasTest, StringWidthEmptyString) { TEST_F(CanvasTest, StringWidthEmptyString) {
const string16 text = UTF8ToUTF16(""); EXPECT_EQ(0, GetStringWidth(""));
const int width = Canvas::GetStringWidth(text, Font());
EXPECT_EQ(0, width);
} }
TEST(CanvasTest, StringSizeEmptyString) { TEST_F(CanvasTest, StringSizeEmptyString) {
const Font font; gfx::Size size = SizeStringInt("", 0, 0);
const string16 text = UTF8ToUTF16(""); EXPECT_EQ(0, size.width());
int width = 0; EXPECT_GT(size.height(), 0);
int height = 0; }
Canvas::SizeStringInt(text, font, &width, &height, 0);
EXPECT_EQ(0, width); // Line height is only supported on Skia.
EXPECT_GT(height, 0); #if defined(OS_MACOSX) || defined(OS_ANDROID)
#define MAYBE_StringSizeWithLineHeight DISABLED_StringSizeWithLineHeight
#else
#define MAYBE_StringSizeWithLineHeight StringSizeWithLineHeight
#endif
TEST_F(CanvasTest, MAYBE_StringSizeWithLineHeight) {
gfx::Size one_line_size = SizeStringInt("Q", 0, 0);
gfx::Size four_line_size = SizeStringInt("Q\nQ\nQ\nQ", 1000000, 1000);
EXPECT_EQ(one_line_size.width(), four_line_size.width());
EXPECT_EQ(3 * 1000 + one_line_size.height(), four_line_size.height());
} }
} // namespace gfx } // namespace gfx
...@@ -25,6 +25,7 @@ const int kTextTopPadding = 12; ...@@ -25,6 +25,7 @@ const int kTextTopPadding = 12;
// Text sizes. // Text sizes.
const int kTitleFontSize = 14; const int kTitleFontSize = 14;
const int kMessageFontSize = 12; const int kMessageFontSize = 12;
const int kMessageLineHeight = 18;
// Colors. // Colors.
const SkColor kNotificationBackgroundColor = SkColorSetRGB(255, 255, 255); const SkColor kNotificationBackgroundColor = SkColorSetRGB(255, 255, 255);
......
...@@ -28,8 +28,9 @@ extern const int kIconToTextPadding; // H space between icon & title/message. ...@@ -28,8 +28,9 @@ extern const int kIconToTextPadding; // H space between icon & title/message.
extern const int kTextTopPadding; // V space between text elements. extern const int kTextTopPadding; // V space between text elements.
// Text sizes. // Text sizes.
extern const int kTitleFontSize; // For title only. extern const int kTitleFontSize; // For title only.
extern const int kMessageFontSize; // For everything but title. extern const int kMessageFontSize; // For everything but title.
extern const int kMessageLineHeight; // In pixels.
// Colors. // Colors.
extern const SkColor kNotificationBackgroundColor; // Background of the card. extern const SkColor kNotificationBackgroundColor; // Background of the card.
......
...@@ -113,7 +113,9 @@ gfx::Size InnerBoundedLabel::GetSizeForWidthAndLines(int width, int lines) { ...@@ -113,7 +113,9 @@ gfx::Size InnerBoundedLabel::GetSizeForWidthAndLines(int width, int lines) {
int text_height = std::numeric_limits<int>::max(); int text_height = std::numeric_limits<int>::max();
std::vector<string16> wrapped = GetWrappedText(text_width, lines); std::vector<string16> wrapped = GetWrappedText(text_width, lines);
gfx::Canvas::SizeStringInt(JoinString(wrapped, '\n'), font(), gfx::Canvas::SizeStringInt(JoinString(wrapped, '\n'), font(),
&text_width, &text_height, GetTextFlags()); &text_width, &text_height,
owner_->GetLineHeight(),
GetTextFlags());
size.set_width(text_width + insets.width()); size.set_width(text_width + insets.width());
size.set_height(text_height + insets.height()); size.set_height(text_height + insets.height());
SetCachedSize(key, size); SetCachedSize(key, size);
...@@ -167,7 +169,7 @@ void InnerBoundedLabel::OnPaint(gfx::Canvas* canvas) { ...@@ -167,7 +169,7 @@ void InnerBoundedLabel::OnPaint(gfx::Canvas* canvas) {
views::Label::OnPaintBackground(canvas); views::Label::OnPaintBackground(canvas);
views::Label::OnPaintFocusBorder(canvas); views::Label::OnPaintFocusBorder(canvas);
views::Label::OnPaintBorder(canvas); views::Label::OnPaintBorder(canvas);
int lines = owner_->line_limit(); int lines = owner_->GetLineLimit();
int height = GetSizeForWidthAndLines(width(), lines).height(); int height = GetSizeForWidthAndLines(width(), lines).height();
if (height > 0) { if (height > 0) {
gfx::Rect bounds(width(), height); gfx::Rect bounds(width(), height);
...@@ -275,10 +277,22 @@ void BoundedLabel::SetColors(SkColor textColor, SkColor backgroundColor) { ...@@ -275,10 +277,22 @@ void BoundedLabel::SetColors(SkColor textColor, SkColor backgroundColor) {
label_->SetBackgroundColor(backgroundColor); label_->SetBackgroundColor(backgroundColor);
} }
void BoundedLabel::SetLineHeight(int height) {
label_->SetLineHeight(height);
}
void BoundedLabel::SetLineLimit(int lines) { void BoundedLabel::SetLineLimit(int lines) {
line_limit_ = std::max(lines, -1); line_limit_ = std::max(lines, -1);
} }
int BoundedLabel::GetLineHeight() const {
return label_->line_height();
}
int BoundedLabel::GetLineLimit() const {
return line_limit_;
}
int BoundedLabel::GetLinesForWidthAndLimit(int width, int limit) { int BoundedLabel::GetLinesForWidthAndLimit(int width, int limit) {
return visible() ? label_->GetLinesForWidthAndLimit(width, limit) : 0; return visible() ? label_->GetLinesForWidthAndLimit(width, limit) : 0;
} }
......
...@@ -38,9 +38,11 @@ class MESSAGE_CENTER_EXPORT BoundedLabel : public views::View { ...@@ -38,9 +38,11 @@ class MESSAGE_CENTER_EXPORT BoundedLabel : public views::View {
virtual ~BoundedLabel(); virtual ~BoundedLabel();
void SetColors(SkColor textColor, SkColor backgroundColor); void SetColors(SkColor textColor, SkColor backgroundColor);
void SetLineHeight(int height); // Pass in 0 for default height.
void SetLineLimit(int lines); // Pass in -1 for no limit. void SetLineLimit(int lines); // Pass in -1 for no limit.
int line_limit() const { return line_limit_; } int GetLineHeight() const;
int GetLineLimit() const;
// Pass in a -1 width to use the preferred width, a -1 limit to skip limits. // Pass in a -1 width to use the preferred width, a -1 limit to skip limits.
int GetLinesForWidthAndLimit(int width, int limit); int GetLinesForWidthAndLimit(int width, int limit);
......
...@@ -412,6 +412,7 @@ NotificationView::NotificationView(const Notification& notification, ...@@ -412,6 +412,7 @@ NotificationView::NotificationView(const Notification& notification,
if (!notification.message().empty()) { if (!notification.message().empty()) {
message_view_ = new BoundedLabel( message_view_ = new BoundedLabel(
ui::TruncateString(notification.message(), kMessageCharacterLimit)); ui::TruncateString(notification.message(), kMessageCharacterLimit));
message_view_->SetLineHeight(kMessageLineHeight);
message_view_->SetVisible(!is_expanded() || !notification.items().size()); message_view_->SetVisible(!is_expanded() || !notification.items().size());
message_view_->SetColors(kDimTextColor, kDimTextBackgroundColor); message_view_->SetColors(kDimTextColor, kDimTextBackgroundColor);
message_view_->set_border(MakeTextBorder(4, 1)); message_view_->set_border(MakeTextBorder(4, 1));
...@@ -507,7 +508,7 @@ int NotificationView::GetHeightForWidth(int width) { ...@@ -507,7 +508,7 @@ int NotificationView::GetHeightForWidth(int width) {
// line limit would be different for the specified width than it currently is. // line limit would be different for the specified width than it currently is.
// TODO(dharcourt): Avoid BoxLayout and directly compute the correct height. // TODO(dharcourt): Avoid BoxLayout and directly compute the correct height.
if (message_view_ && title_view_) { if (message_view_ && title_view_) {
int used_limit = message_view_->line_limit(); int used_limit = message_view_->GetLineLimit();
int correct_limit = GetMessageLineLimit(width); int correct_limit = GetMessageLineLimit(width);
if (used_limit != correct_limit) { if (used_limit != correct_limit) {
total_height -= GetMessageHeight(content_width, used_limit); total_height -= GetMessageHeight(content_width, used_limit);
......
...@@ -376,7 +376,7 @@ void TextButtonBase::CalculateTextSize(gfx::Size* text_size, int max_width) { ...@@ -376,7 +376,7 @@ void TextButtonBase::CalculateTextSize(gfx::Size* text_size, int max_width) {
if (!multi_line_) if (!multi_line_)
flags |= gfx::Canvas::NO_ELLIPSIS; flags |= gfx::Canvas::NO_ELLIPSIS;
gfx::Canvas::SizeStringInt(text_, font_, &w, &h, flags); gfx::Canvas::SizeStringInt(text_, font_, &w, &h, 0, flags);
text_size->SetSize(w, h); text_size->SetSize(w, h);
} }
...@@ -498,7 +498,7 @@ void TextButtonBase::PaintButton(gfx::Canvas* canvas, PaintButtonMode mode) { ...@@ -498,7 +498,7 @@ void TextButtonBase::PaintButton(gfx::Canvas* canvas, PaintButtonMode mode) {
shadows.push_back(gfx::ShadowValue(text_shadow_offset_, 0, color)); shadows.push_back(gfx::ShadowValue(text_shadow_offset_, 0, color));
} }
canvas->DrawStringWithShadows(text_, font_, text_color, text_bounds, canvas->DrawStringWithShadows(text_, font_, text_color, text_bounds,
draw_string_flags, shadows); 0, draw_string_flags, shadows);
} }
} }
} }
......
...@@ -121,6 +121,15 @@ void Label::SetHorizontalAlignment(gfx::HorizontalAlignment alignment) { ...@@ -121,6 +121,15 @@ void Label::SetHorizontalAlignment(gfx::HorizontalAlignment alignment) {
} }
} }
void Label::SetLineHeight(int height) {
if (height != line_height_) {
line_height_ = height;
ResetCachedSize();
PreferredSizeChanged();
SchedulePaint();
}
}
void Label::SetMultiLine(bool multi_line) { void Label::SetMultiLine(bool multi_line) {
DCHECK(!multi_line || elide_behavior_ != ELIDE_IN_MIDDLE); DCHECK(!multi_line || elide_behavior_ != ELIDE_IN_MIDDLE);
if (multi_line != is_multi_line_) { if (multi_line != is_multi_line_) {
...@@ -226,7 +235,8 @@ int Label::GetHeightForWidth(int w) { ...@@ -226,7 +235,8 @@ int Label::GetHeightForWidth(int w) {
int cache_width = w; int cache_width = w;
int h = font_.GetHeight(); int h = font_.GetHeight();
gfx::Canvas::SizeStringInt(text_, font_, &w, &h, ComputeDrawStringFlags()); const int flags = ComputeDrawStringFlags();
gfx::Canvas::SizeStringInt(text_, font_, &w, &h, line_height_, flags);
cached_heights_[cached_heights_cursor_] = gfx::Size(cache_width, h); cached_heights_[cached_heights_cursor_] = gfx::Size(cache_width, h);
cached_heights_cursor_ = (cached_heights_cursor_ + 1) % kCachedSizeLimit; cached_heights_cursor_ = (cached_heights_cursor_ + 1) % kCachedSizeLimit;
return h + GetInsets().height(); return h + GetInsets().height();
...@@ -274,7 +284,7 @@ void Label::PaintText(gfx::Canvas* canvas, ...@@ -274,7 +284,7 @@ void Label::PaintText(gfx::Canvas* canvas,
enabled() ? enabled_shadow_color_ : disabled_shadow_color_)); enabled() ? enabled_shadow_color_ : disabled_shadow_color_));
canvas->DrawStringWithShadows(text, font_, canvas->DrawStringWithShadows(text, font_,
enabled() ? actual_enabled_color_ : actual_disabled_color_, enabled() ? actual_enabled_color_ : actual_disabled_color_,
text_bounds, flags, shadows); text_bounds, line_height_, flags, shadows);
if (HasFocus()) { if (HasFocus()) {
gfx::Rect focus_bounds = text_bounds; gfx::Rect focus_bounds = text_bounds;
...@@ -297,7 +307,7 @@ gfx::Size Label::GetTextSize() const { ...@@ -297,7 +307,7 @@ gfx::Size Label::GetTextSize() const {
int flags = ComputeDrawStringFlags(); int flags = ComputeDrawStringFlags();
if (!is_multi_line_) if (!is_multi_line_)
flags |= gfx::Canvas::NO_ELLIPSIS; flags |= gfx::Canvas::NO_ELLIPSIS;
gfx::Canvas::SizeStringInt(text_, font_, &w, &h, flags); gfx::Canvas::SizeStringInt(text_, font_, &w, &h, line_height_, flags);
text_size_.SetSize(w, h); text_size_.SetSize(w, h);
text_size_valid_ = true; text_size_valid_ = true;
} }
...@@ -338,6 +348,7 @@ void Label::Init(const string16& text, const gfx::Font& font) { ...@@ -338,6 +348,7 @@ void Label::Init(const string16& text, const gfx::Font& font) {
auto_color_readability_ = true; auto_color_readability_ = true;
UpdateColorsFromTheme(ui::NativeTheme::instance()); UpdateColorsFromTheme(ui::NativeTheme::instance());
horizontal_alignment_ = gfx::ALIGN_CENTER; horizontal_alignment_ = gfx::ALIGN_CENTER;
line_height_ = 0;
is_multi_line_ = false; is_multi_line_ = false;
allow_character_break_ = false; allow_character_break_ = false;
elide_behavior_ = NO_ELIDE; elide_behavior_ = NO_ELIDE;
......
...@@ -117,6 +117,12 @@ class VIEWS_EXPORT Label : public View { ...@@ -117,6 +117,12 @@ class VIEWS_EXPORT Label : public View {
return directionality_mode_; return directionality_mode_;
} }
// Get or set the distance in pixels between baselines of multi-line text.
// Default is 0, indicating the distance between lines should be the standard
// one for the label's text, font, and platform.
int line_height() const { return line_height_; }
void SetLineHeight(int height);
// Get or set if the label text can wrap on multiple lines; default is false. // Get or set if the label text can wrap on multiple lines; default is false.
bool is_multi_line() const { return is_multi_line_; } bool is_multi_line() const { return is_multi_line_; }
void SetMultiLine(bool multi_line); void SetMultiLine(bool multi_line);
...@@ -242,6 +248,7 @@ class VIEWS_EXPORT Label : public View { ...@@ -242,6 +248,7 @@ class VIEWS_EXPORT Label : public View {
bool auto_color_readability_; bool auto_color_readability_;
mutable gfx::Size text_size_; mutable gfx::Size text_size_;
mutable bool text_size_valid_; mutable bool text_size_valid_;
int line_height_;
bool is_multi_line_; bool is_multi_line_;
bool allow_character_break_; bool allow_character_break_;
ElideBehavior elide_behavior_; ElideBehavior elide_behavior_;
......
...@@ -659,8 +659,8 @@ void TreeView::ConfigureInternalNode(TreeModelNode* model_node, ...@@ -659,8 +659,8 @@ void TreeView::ConfigureInternalNode(TreeModelNode* model_node,
void TreeView::UpdateNodeTextWidth(InternalNode* node) { void TreeView::UpdateNodeTextWidth(InternalNode* node) {
int width = 0, height = 0; int width = 0, height = 0;
gfx::Canvas::SizeStringInt(node->model_node()->GetTitle(), gfx::Canvas::SizeStringInt(node->model_node()->GetTitle(), font_,
font_, &width, &height, gfx::Canvas::NO_ELLIPSIS); &width, &height, 0, gfx::Canvas::NO_ELLIPSIS);
node->set_text_width(width); node->set_text_width(width);
} }
......
...@@ -111,7 +111,7 @@ void DrawTextStartingFrom(gfx::Canvas* canvas, ...@@ -111,7 +111,7 @@ void DrawTextStartingFrom(gfx::Canvas* canvas,
word = text; // Draw the whole text at once. word = text; // Draw the whole text at once.
int w = 0, h = 0; int w = 0, h = 0;
gfx::Canvas::SizeStringInt(word, font, &w, &h, flags); gfx::Canvas::SizeStringInt(word, font, &w, &h, 0, flags);
// If we exceed the boundaries, we need to wrap. // If we exceed the boundaries, we need to wrap.
WrapIfWordDoesntFit(w, font.GetHeight(), position, bounds); WrapIfWordDoesntFit(w, font.GetHeight(), position, bounds);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment