1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/views/controls/label.h"
7 #include "base/i18n/rtl.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10 #include "ui/accessibility/ax_view_state.h"
11 #include "ui/base/l10n/l10n_util.h"
12 #include "ui/gfx/canvas.h"
13 #include "ui/views/border.h"
14 #include "ui/views/test/views_test_base.h"
15 #include "ui/views/widget/widget.h"
17 using base::ASCIIToUTF16
;
21 typedef ViewsTestBase LabelTest
;
23 // All text sizing measurements (width and height) should be greater than this.
24 const int kMinTextDimension
= 4;
26 // A test utility function to set the application default text direction.
27 void SetRTL(bool rtl
) {
28 // Override the current locale/direction.
29 base::i18n::SetICUDefaultLocale(rtl
? "he" : "en");
30 EXPECT_EQ(rtl
, base::i18n::IsRTL());
33 TEST_F(LabelTest
, FontPropertySymbol
) {
35 std::string
font_name("symbol");
36 gfx::Font
font(font_name
, 26);
37 label
.SetFontList(gfx::FontList(font
));
38 gfx::Font font_used
= label
.font_list().GetPrimaryFont();
39 EXPECT_EQ(font_name
, font_used
.GetFontName());
40 EXPECT_EQ(26, font_used
.GetFontSize());
43 TEST_F(LabelTest
, FontPropertyArial
) {
45 std::string
font_name("arial");
46 gfx::Font
font(font_name
, 30);
47 label
.SetFontList(gfx::FontList(font
));
48 gfx::Font font_used
= label
.font_list().GetPrimaryFont();
49 EXPECT_EQ(font_name
, font_used
.GetFontName());
50 EXPECT_EQ(30, font_used
.GetFontSize());
53 TEST_F(LabelTest
, TextProperty
) {
55 base::string16
test_text(ASCIIToUTF16("A random string."));
56 label
.SetText(test_text
);
57 EXPECT_EQ(test_text
, label
.text());
60 TEST_F(LabelTest
, ColorProperty
) {
62 SkColor color
= SkColorSetARGB(20, 40, 10, 5);
63 label
.SetAutoColorReadabilityEnabled(false);
64 label
.SetEnabledColor(color
);
65 EXPECT_EQ(color
, label
.enabled_color());
68 TEST_F(LabelTest
, AlignmentProperty
) {
69 const bool was_rtl
= base::i18n::IsRTL();
72 for (size_t i
= 0; i
< 2; ++i
) {
73 // Toggle the application default text direction (to try each direction).
74 SetRTL(!base::i18n::IsRTL());
75 bool reverse_alignment
= base::i18n::IsRTL();
77 // The alignment should be flipped in RTL UI.
78 label
.SetHorizontalAlignment(gfx::ALIGN_RIGHT
);
79 EXPECT_EQ(reverse_alignment
? gfx::ALIGN_LEFT
: gfx::ALIGN_RIGHT
,
80 label
.GetHorizontalAlignment());
81 label
.SetHorizontalAlignment(gfx::ALIGN_LEFT
);
82 EXPECT_EQ(reverse_alignment
? gfx::ALIGN_RIGHT
: gfx::ALIGN_LEFT
,
83 label
.GetHorizontalAlignment());
84 label
.SetHorizontalAlignment(gfx::ALIGN_CENTER
);
85 EXPECT_EQ(gfx::ALIGN_CENTER
, label
.GetHorizontalAlignment());
87 for (size_t j
= 0; j
< 2; ++j
) {
88 label
.SetHorizontalAlignment(gfx::ALIGN_TO_HEAD
);
89 const bool rtl
= j
== 0;
90 label
.SetText(rtl
? base::WideToUTF16(L
"\x5d0") : ASCIIToUTF16("A"));
91 EXPECT_EQ(rtl
? gfx::ALIGN_RIGHT
: gfx::ALIGN_LEFT
,
92 label
.GetHorizontalAlignment());
96 EXPECT_EQ(was_rtl
, base::i18n::IsRTL());
99 TEST_F(LabelTest
, DirectionalityModeProperty
) {
101 EXPECT_EQ(gfx::DIRECTIONALITY_FROM_UI
, label
.directionality_mode());
103 label
.set_directionality_mode(gfx::DIRECTIONALITY_FROM_TEXT
);
104 EXPECT_EQ(gfx::DIRECTIONALITY_FROM_TEXT
, label
.directionality_mode());
106 label
.set_directionality_mode(gfx::DIRECTIONALITY_FROM_UI
);
107 EXPECT_EQ(gfx::DIRECTIONALITY_FROM_UI
, label
.directionality_mode());
110 TEST_F(LabelTest
, MultiLineProperty
) {
112 EXPECT_FALSE(label
.is_multi_line());
113 label
.SetMultiLine(true);
114 EXPECT_TRUE(label
.is_multi_line());
115 label
.SetMultiLine(false);
116 EXPECT_FALSE(label
.is_multi_line());
119 TEST_F(LabelTest
, ObscuredProperty
) {
121 base::string16
test_text(ASCIIToUTF16("Password!"));
122 label
.SetText(test_text
);
124 // Should be false by default...
125 EXPECT_FALSE(label
.is_obscured());
126 EXPECT_EQ(test_text
, label
.layout_text());
127 EXPECT_EQ(test_text
, label
.text());
129 label
.SetObscured(true);
130 EXPECT_TRUE(label
.is_obscured());
131 EXPECT_EQ(ASCIIToUTF16("*********"), label
.layout_text());
132 EXPECT_EQ(test_text
, label
.text());
134 label
.SetText(test_text
+ test_text
);
135 EXPECT_EQ(ASCIIToUTF16("******************"), label
.layout_text());
136 EXPECT_EQ(test_text
+ test_text
, label
.text());
138 label
.SetObscured(false);
139 EXPECT_FALSE(label
.is_obscured());
140 EXPECT_EQ(test_text
+ test_text
, label
.layout_text());
141 EXPECT_EQ(test_text
+ test_text
, label
.text());
144 TEST_F(LabelTest
, ObscuredSurrogatePair
) {
145 // 'MUSICAL SYMBOL G CLEF': represented in UTF-16 as two characters
146 // forming the surrogate pair 0x0001D11E.
148 base::string16 test_text
= base::UTF8ToUTF16("\xF0\x9D\x84\x9E");
149 label
.SetText(test_text
);
151 label
.SetObscured(true);
152 EXPECT_EQ(ASCIIToUTF16("*"), label
.layout_text());
153 EXPECT_EQ(test_text
, label
.text());
156 TEST_F(LabelTest
, TooltipProperty
) {
158 label
.SetText(ASCIIToUTF16("My cool string."));
160 base::string16 tooltip
;
161 EXPECT_TRUE(label
.GetTooltipText(gfx::Point(), &tooltip
));
162 EXPECT_EQ(label
.text(), tooltip
);
164 base::string16
tooltip_text(ASCIIToUTF16("The tooltip!"));
165 label
.SetTooltipText(tooltip_text
);
166 EXPECT_TRUE(label
.GetTooltipText(gfx::Point(), &tooltip
));
167 EXPECT_EQ(tooltip_text
, tooltip
);
169 label
.SetTooltipText(base::string16());
170 EXPECT_TRUE(label
.GetTooltipText(gfx::Point(), &tooltip
));
171 EXPECT_EQ(label
.text(), tooltip
);
173 // Make the label big enough to hold the text
174 // and expect there to be no tooltip.
175 label
.SetBounds(0, 0, 1000, 40);
176 EXPECT_FALSE(label
.GetTooltipText(gfx::Point(), &tooltip
));
178 // Verify that setting the tooltip still shows it.
179 label
.SetTooltipText(tooltip_text
);
180 EXPECT_TRUE(label
.GetTooltipText(gfx::Point(), &tooltip
));
181 EXPECT_EQ(tooltip_text
, tooltip
);
182 // Clear out the tooltip.
183 label
.SetTooltipText(base::string16());
185 // Shrink the bounds and the tooltip should come back.
186 label
.SetBounds(0, 0, 1, 1);
187 EXPECT_TRUE(label
.GetTooltipText(gfx::Point(), &tooltip
));
189 // Make the label obscured and there is no tooltip.
190 label
.SetObscured(true);
191 EXPECT_FALSE(label
.GetTooltipText(gfx::Point(), &tooltip
));
193 // Obscuring the text shouldn't permanently clobber the tooltip.
194 label
.SetObscured(false);
195 EXPECT_TRUE(label
.GetTooltipText(gfx::Point(), &tooltip
));
197 // Make the label multiline and there is no tooltip.
198 label
.SetMultiLine(true);
199 EXPECT_FALSE(label
.GetTooltipText(gfx::Point(), &tooltip
));
201 // Verify that setting the tooltip still shows it.
202 label
.SetTooltipText(tooltip_text
);
203 EXPECT_TRUE(label
.GetTooltipText(gfx::Point(), &tooltip
));
204 EXPECT_EQ(tooltip_text
, tooltip
);
205 // Clear out the tooltip.
206 label
.SetTooltipText(base::string16());
209 TEST_F(LabelTest
, Accessibility
) {
211 label
.SetText(ASCIIToUTF16("My special text."));
213 ui::AXViewState state
;
214 label
.GetAccessibleState(&state
);
215 EXPECT_EQ(ui::AX_ROLE_STATIC_TEXT
, state
.role
);
216 EXPECT_EQ(label
.text(), state
.name
);
217 EXPECT_TRUE(state
.HasStateFlag(ui::AX_STATE_READ_ONLY
));
220 TEST_F(LabelTest
, SingleLineSizing
) {
222 label
.SetText(ASCIIToUTF16("A not so random string in one line."));
225 gfx::Size required_size
= label
.GetPreferredSize();
226 EXPECT_GT(required_size
.height(), kMinTextDimension
);
227 EXPECT_GT(required_size
.width(), kMinTextDimension
);
229 // Test everything with borders.
230 gfx::Insets
border(10, 20, 30, 40);
231 label
.SetBorder(Border::CreateEmptyBorder(
232 border
.top(), border
.left(), border
.bottom(), border
.right()));
234 // GetPreferredSize and borders.
235 label
.SetBounds(0, 0, 0, 0);
236 gfx::Size required_size_with_border
= label
.GetPreferredSize();
237 EXPECT_EQ(required_size_with_border
.height(),
238 required_size
.height() + border
.height());
239 EXPECT_EQ(required_size_with_border
.width(),
240 required_size
.width() + border
.width());
243 TEST_F(LabelTest
, MultilineSmallAvailableWidthSizing
) {
245 label
.SetMultiLine(true);
246 label
.SetAllowCharacterBreak(true);
247 label
.SetText(ASCIIToUTF16("Too Wide."));
249 // Check that Label can be laid out at a variety of small sizes,
250 // splitting the words into up to one character per line if necessary.
251 // Incorrect word splitting may cause infinite loops in text layout.
252 gfx::Size required_size
= label
.GetPreferredSize();
253 for (int i
= 1; i
< required_size
.width(); ++i
)
254 EXPECT_GT(label
.GetHeightForWidth(i
), 0);
257 TEST_F(LabelTest
, MultiLineSizing
) {
259 label
.SetFocusable(false);
261 ASCIIToUTF16("A random string\nwith multiple lines\nand returns!"));
262 label
.SetMultiLine(true);
265 gfx::Size required_size
= label
.GetPreferredSize();
266 EXPECT_GT(required_size
.height(), kMinTextDimension
);
267 EXPECT_GT(required_size
.width(), kMinTextDimension
);
269 // SizeToFit with unlimited width.
271 int required_width
= label
.GetLocalBounds().width();
272 EXPECT_GT(required_width
, kMinTextDimension
);
274 // SizeToFit with limited width.
275 label
.SizeToFit(required_width
- 1);
276 int constrained_width
= label
.GetLocalBounds().width();
278 // Canvas::SizeStringInt (in ui/gfx/canvas_linux.cc)
279 // has to be fixed to return the size that fits to given width/height.
280 EXPECT_LT(constrained_width
, required_width
);
282 EXPECT_GT(constrained_width
, kMinTextDimension
);
284 // Change the width back to the desire width.
285 label
.SizeToFit(required_width
);
286 EXPECT_EQ(required_width
, label
.GetLocalBounds().width());
288 // General tests for GetHeightForWidth.
289 int required_height
= label
.GetHeightForWidth(required_width
);
290 EXPECT_GT(required_height
, kMinTextDimension
);
291 int height_for_constrained_width
= label
.GetHeightForWidth(constrained_width
);
293 // Canvas::SizeStringInt (in ui/gfx/canvas_linux.cc)
294 // has to be fixed to return the size that fits to given width/height.
295 EXPECT_GT(height_for_constrained_width
, required_height
);
297 // Using the constrained width or the required_width - 1 should give the
298 // same result for the height because the constrainted width is the tight
299 // width when given "required_width - 1" as the max width.
300 EXPECT_EQ(height_for_constrained_width
,
301 label
.GetHeightForWidth(required_width
- 1));
303 // Test everything with borders.
304 gfx::Insets
border(10, 20, 30, 40);
305 label
.SetBorder(Border::CreateEmptyBorder(
306 border
.top(), border
.left(), border
.bottom(), border
.right()));
308 // SizeToFit and borders.
310 int required_width_with_border
= label
.GetLocalBounds().width();
311 EXPECT_EQ(required_width_with_border
, required_width
+ border
.width());
313 // GetHeightForWidth and borders.
314 int required_height_with_border
=
315 label
.GetHeightForWidth(required_width_with_border
);
316 EXPECT_EQ(required_height_with_border
, required_height
+ border
.height());
318 // Test that the border width is subtracted before doing the height
319 // calculation. If it is, then the height will grow when width
321 int height1
= label
.GetHeightForWidth(required_width_with_border
- 1);
323 // Canvas::SizeStringInt (in ui/gfx/canvas_linux.cc)
324 // has to be fixed to return the size that fits to given width/height.
325 EXPECT_GT(height1
, required_height_with_border
);
327 EXPECT_EQ(height1
, height_for_constrained_width
+ border
.height());
329 // GetPreferredSize and borders.
330 label
.SetBounds(0, 0, 0, 0);
331 gfx::Size required_size_with_border
= label
.GetPreferredSize();
332 EXPECT_EQ(required_size_with_border
.height(),
333 required_size
.height() + border
.height());
334 EXPECT_EQ(required_size_with_border
.width(),
335 required_size
.width() + border
.width());
338 TEST_F(LabelTest
, DirectionalityFromText
) {
340 label
.set_directionality_mode(gfx::DIRECTIONALITY_FROM_TEXT
);
341 label
.SetBounds(0, 0, 1000, 1000);
342 base::string16 paint_text
;
343 gfx::Rect text_bounds
;
346 // Test text starts with RTL character.
347 label
.SetText(base::WideToUTF16(L
" \x5d0\x5d1\x5d2 abc"));
348 label
.CalculateDrawStringParams(&paint_text
, &text_bounds
, &flags
);
349 EXPECT_EQ(gfx::Canvas::FORCE_RTL_DIRECTIONALITY
,
350 flags
& (gfx::Canvas::FORCE_RTL_DIRECTIONALITY
|
351 gfx::Canvas::FORCE_LTR_DIRECTIONALITY
));
353 // Test text starts with LTR character.
354 label
.SetText(base::WideToUTF16(L
"ltr \x5d0\x5d1\x5d2 abc"));
355 label
.CalculateDrawStringParams(&paint_text
, &text_bounds
, &flags
);
356 EXPECT_EQ(gfx::Canvas::FORCE_LTR_DIRECTIONALITY
,
357 flags
& (gfx::Canvas::FORCE_RTL_DIRECTIONALITY
|
358 gfx::Canvas::FORCE_LTR_DIRECTIONALITY
));
361 TEST_F(LabelTest
, DrawSingleLineString
) {
363 label
.SetFocusable(false);
364 // Force a directionality to simplify alignment value testing.
365 label
.set_directionality_mode(gfx::DIRECTIONALITY_FORCE_LTR
);
367 label
.SetText(ASCIIToUTF16("Here's a string with no returns."));
368 gfx::Size
required_size(label
.GetPreferredSize());
369 gfx::Size
extra(22, 8);
370 label
.SetBounds(0, 0, required_size
.width() + extra
.width(),
371 required_size
.height() + extra
.height());
373 // Do some basic verifications for all three alignments.
374 base::string16 paint_text
;
375 gfx::Rect text_bounds
;
379 label
.CalculateDrawStringParams(&paint_text
, &text_bounds
, &flags
);
380 EXPECT_EQ(label
.text(), paint_text
);
381 // The text should be centered horizontally and vertically.
382 EXPECT_EQ(extra
.width() / 2, text_bounds
.x());
383 EXPECT_EQ(extra
.height() / 2 , text_bounds
.y());
384 EXPECT_EQ(required_size
.width(), text_bounds
.width());
385 EXPECT_EQ(required_size
.height(), text_bounds
.height());
386 EXPECT_EQ(gfx::Canvas::TEXT_ALIGN_CENTER
,
387 flags
& (gfx::Canvas::TEXT_ALIGN_LEFT
|
388 gfx::Canvas::TEXT_ALIGN_CENTER
|
389 gfx::Canvas::TEXT_ALIGN_RIGHT
));
391 // Left aligned text.
392 label
.SetHorizontalAlignment(gfx::ALIGN_LEFT
);
394 text_bounds
.SetRect(0, 0, 0, 0);
395 label
.CalculateDrawStringParams(&paint_text
, &text_bounds
, &flags
);
396 EXPECT_EQ(label
.text(), paint_text
);
397 // The text should be left aligned horizontally and centered vertically.
398 EXPECT_EQ(0, text_bounds
.x());
399 EXPECT_EQ(extra
.height() / 2 , text_bounds
.y());
400 EXPECT_EQ(required_size
.width(), text_bounds
.width());
401 EXPECT_EQ(required_size
.height(), text_bounds
.height());
402 EXPECT_EQ(gfx::Canvas::TEXT_ALIGN_LEFT
,
403 flags
& (gfx::Canvas::TEXT_ALIGN_LEFT
|
404 gfx::Canvas::TEXT_ALIGN_CENTER
|
405 gfx::Canvas::TEXT_ALIGN_RIGHT
));
407 // Right aligned text.
408 label
.SetHorizontalAlignment(gfx::ALIGN_RIGHT
);
410 text_bounds
.SetRect(0, 0, 0, 0);
411 label
.CalculateDrawStringParams(&paint_text
, &text_bounds
, &flags
);
412 EXPECT_EQ(label
.text(), paint_text
);
413 // The text should be right aligned horizontally and centered vertically.
414 EXPECT_EQ(extra
.width(), text_bounds
.x());
415 EXPECT_EQ(extra
.height() / 2 , text_bounds
.y());
416 EXPECT_EQ(required_size
.width(), text_bounds
.width());
417 EXPECT_EQ(required_size
.height(), text_bounds
.height());
418 EXPECT_EQ(gfx::Canvas::TEXT_ALIGN_RIGHT
,
419 flags
& (gfx::Canvas::TEXT_ALIGN_LEFT
|
420 gfx::Canvas::TEXT_ALIGN_CENTER
|
421 gfx::Canvas::TEXT_ALIGN_RIGHT
));
423 // Test single line drawing with a border.
424 gfx::Insets
border(39, 34, 8, 96);
425 label
.SetBorder(Border::CreateEmptyBorder(
426 border
.top(), border
.left(), border
.bottom(), border
.right()));
428 gfx::Size
required_size_with_border(label
.GetPreferredSize());
429 EXPECT_EQ(required_size
.width() + border
.width(),
430 required_size_with_border
.width());
431 EXPECT_EQ(required_size
.height() + border
.height(),
432 required_size_with_border
.height());
433 label
.SetBounds(0, 0, required_size_with_border
.width() + extra
.width(),
434 required_size_with_border
.height() + extra
.height());
436 // Centered text with border.
437 label
.SetHorizontalAlignment(gfx::ALIGN_CENTER
);
439 text_bounds
.SetRect(0, 0, 0, 0);
440 label
.CalculateDrawStringParams(&paint_text
, &text_bounds
, &flags
);
441 EXPECT_EQ(label
.text(), paint_text
);
442 // The text should be centered horizontally and vertically within the border.
443 EXPECT_EQ(border
.left() + extra
.width() / 2, text_bounds
.x());
444 EXPECT_EQ(border
.top() + extra
.height() / 2 , text_bounds
.y());
445 EXPECT_EQ(required_size
.width(), text_bounds
.width());
446 EXPECT_EQ(required_size
.height(), text_bounds
.height());
447 EXPECT_EQ(gfx::Canvas::TEXT_ALIGN_CENTER
,
448 flags
& (gfx::Canvas::TEXT_ALIGN_LEFT
|
449 gfx::Canvas::TEXT_ALIGN_CENTER
|
450 gfx::Canvas::TEXT_ALIGN_RIGHT
));
452 // Left aligned text with border.
453 label
.SetHorizontalAlignment(gfx::ALIGN_LEFT
);
455 text_bounds
.SetRect(0, 0, 0, 0);
456 label
.CalculateDrawStringParams(&paint_text
, &text_bounds
, &flags
);
457 EXPECT_EQ(label
.text(), paint_text
);
458 // The text should be left aligned horizontally and centered vertically.
459 EXPECT_EQ(border
.left(), text_bounds
.x());
460 EXPECT_EQ(border
.top() + extra
.height() / 2 , text_bounds
.y());
461 EXPECT_EQ(required_size
.width(), text_bounds
.width());
462 EXPECT_EQ(required_size
.height(), text_bounds
.height());
463 EXPECT_EQ(gfx::Canvas::TEXT_ALIGN_LEFT
,
464 flags
& (gfx::Canvas::TEXT_ALIGN_LEFT
|
465 gfx::Canvas::TEXT_ALIGN_CENTER
|
466 gfx::Canvas::TEXT_ALIGN_RIGHT
));
468 // Right aligned text.
469 label
.SetHorizontalAlignment(gfx::ALIGN_RIGHT
);
471 text_bounds
.SetRect(0, 0, 0, 0);
472 label
.CalculateDrawStringParams(&paint_text
, &text_bounds
, &flags
);
473 EXPECT_EQ(label
.text(), paint_text
);
474 // The text should be right aligned horizontally and centered vertically.
475 EXPECT_EQ(border
.left() + extra
.width(), text_bounds
.x());
476 EXPECT_EQ(border
.top() + extra
.height() / 2 , text_bounds
.y());
477 EXPECT_EQ(required_size
.width(), text_bounds
.width());
478 EXPECT_EQ(required_size
.height(), text_bounds
.height());
479 EXPECT_EQ(gfx::Canvas::TEXT_ALIGN_RIGHT
,
480 flags
& (gfx::Canvas::TEXT_ALIGN_LEFT
|
481 gfx::Canvas::TEXT_ALIGN_CENTER
|
482 gfx::Canvas::TEXT_ALIGN_RIGHT
));
485 // Pango needs a max height to elide multiline text; that is not supported here.
486 TEST_F(LabelTest
, DrawMultiLineString
) {
488 label
.SetFocusable(false);
489 // Force a directionality to simplify alignment value testing.
490 label
.set_directionality_mode(gfx::DIRECTIONALITY_FORCE_LTR
);
491 // Set a background color to prevent gfx::Canvas::NO_SUBPIXEL_RENDERING flags.
492 label
.SetBackgroundColor(SK_ColorWHITE
);
494 label
.SetText(ASCIIToUTF16("Another string\nwith returns\n\n!"));
495 label
.SetMultiLine(true);
497 gfx::Size
extra(50, 10);
498 label
.SetBounds(label
.x(), label
.y(),
499 label
.width() + extra
.width(),
500 label
.height() + extra
.height());
502 // Do some basic verifications for all three alignments.
503 base::string16 paint_text
;
504 gfx::Rect text_bounds
;
506 label
.CalculateDrawStringParams(&paint_text
, &text_bounds
, &flags
);
507 EXPECT_EQ(label
.text(), paint_text
);
508 EXPECT_EQ(extra
.width() / 2, text_bounds
.x());
509 EXPECT_EQ(extra
.height() / 2, text_bounds
.y());
510 EXPECT_GT(text_bounds
.width(), kMinTextDimension
);
511 EXPECT_GT(text_bounds
.height(), kMinTextDimension
);
512 int expected_flags
= gfx::Canvas::MULTI_LINE
|
513 gfx::Canvas::TEXT_ALIGN_CENTER
|
514 gfx::Canvas::FORCE_LTR_DIRECTIONALITY
;
516 expected_flags
|= gfx::Canvas::NO_ELLIPSIS
;
518 EXPECT_EQ(expected_flags
, expected_flags
);
519 gfx::Rect
center_bounds(text_bounds
);
521 label
.SetHorizontalAlignment(gfx::ALIGN_LEFT
);
523 text_bounds
.SetRect(0, 0, 0, 0);
524 label
.CalculateDrawStringParams(&paint_text
, &text_bounds
, &flags
);
525 EXPECT_EQ(label
.text(), paint_text
);
526 EXPECT_EQ(0, text_bounds
.x());
527 EXPECT_EQ(extra
.height() / 2, text_bounds
.y());
528 EXPECT_GT(text_bounds
.width(), kMinTextDimension
);
529 EXPECT_GT(text_bounds
.height(), kMinTextDimension
);
530 expected_flags
= gfx::Canvas::MULTI_LINE
|
531 gfx::Canvas::TEXT_ALIGN_LEFT
|
532 gfx::Canvas::FORCE_LTR_DIRECTIONALITY
;
534 expected_flags
|= gfx::Canvas::NO_ELLIPSIS
;
536 EXPECT_EQ(expected_flags
, expected_flags
);
538 label
.SetHorizontalAlignment(gfx::ALIGN_RIGHT
);
540 text_bounds
.SetRect(0, 0, 0, 0);
541 label
.CalculateDrawStringParams(&paint_text
, &text_bounds
, &flags
);
542 EXPECT_EQ(label
.text(), paint_text
);
543 EXPECT_EQ(extra
.width(), text_bounds
.x());
544 EXPECT_EQ(extra
.height() / 2, text_bounds
.y());
545 EXPECT_GT(text_bounds
.width(), kMinTextDimension
);
546 EXPECT_GT(text_bounds
.height(), kMinTextDimension
);
547 expected_flags
= gfx::Canvas::MULTI_LINE
|
548 gfx::Canvas::TEXT_ALIGN_RIGHT
|
549 gfx::Canvas::FORCE_LTR_DIRECTIONALITY
;
551 expected_flags
|= gfx::Canvas::NO_ELLIPSIS
;
553 EXPECT_EQ(expected_flags
, expected_flags
);
555 // Test multiline drawing with a border.
556 gfx::Insets
border(19, 92, 23, 2);
557 label
.SetBorder(Border::CreateEmptyBorder(
558 border
.top(), border
.left(), border
.bottom(), border
.right()));
560 label
.SetBounds(label
.x(), label
.y(),
561 label
.width() + extra
.width(),
562 label
.height() + extra
.height());
564 label
.SetHorizontalAlignment(gfx::ALIGN_CENTER
);
566 text_bounds
.SetRect(0, 0, 0, 0);
567 label
.CalculateDrawStringParams(&paint_text
, &text_bounds
, &flags
);
568 EXPECT_EQ(label
.text(), paint_text
);
569 EXPECT_EQ(border
.left() + extra
.width() / 2, text_bounds
.x());
570 EXPECT_EQ(border
.top() + extra
.height() / 2, text_bounds
.y());
571 EXPECT_EQ(center_bounds
.width(), text_bounds
.width());
572 EXPECT_EQ(center_bounds
.height(), text_bounds
.height());
573 expected_flags
= gfx::Canvas::MULTI_LINE
|
574 gfx::Canvas::TEXT_ALIGN_CENTER
|
575 gfx::Canvas::FORCE_LTR_DIRECTIONALITY
;
577 expected_flags
|= gfx::Canvas::NO_ELLIPSIS
;
579 EXPECT_EQ(expected_flags
, expected_flags
);
581 label
.SetHorizontalAlignment(gfx::ALIGN_LEFT
);
583 text_bounds
.SetRect(0, 0, 0, 0);
584 label
.CalculateDrawStringParams(&paint_text
, &text_bounds
, &flags
);
585 EXPECT_EQ(label
.text(), paint_text
);
586 EXPECT_EQ(border
.left(), text_bounds
.x());
587 EXPECT_EQ(border
.top() + extra
.height() / 2, text_bounds
.y());
588 EXPECT_EQ(center_bounds
.width(), text_bounds
.width());
589 EXPECT_EQ(center_bounds
.height(), text_bounds
.height());
590 expected_flags
= gfx::Canvas::MULTI_LINE
|
591 gfx::Canvas::TEXT_ALIGN_LEFT
|
592 gfx::Canvas::FORCE_LTR_DIRECTIONALITY
;
594 expected_flags
|= gfx::Canvas::NO_ELLIPSIS
;
596 EXPECT_EQ(expected_flags
, expected_flags
);
598 label
.SetHorizontalAlignment(gfx::ALIGN_RIGHT
);
600 text_bounds
.SetRect(0, 0, 0, 0);
601 label
.CalculateDrawStringParams(&paint_text
, &text_bounds
, &flags
);
602 EXPECT_EQ(label
.text(), paint_text
);
603 EXPECT_EQ(extra
.width() + border
.left(), text_bounds
.x());
604 EXPECT_EQ(border
.top() + extra
.height() / 2, text_bounds
.y());
605 EXPECT_EQ(center_bounds
.width(), text_bounds
.width());
606 EXPECT_EQ(center_bounds
.height(), text_bounds
.height());
607 expected_flags
= gfx::Canvas::MULTI_LINE
|
608 gfx::Canvas::TEXT_ALIGN_RIGHT
|
609 gfx::Canvas::FORCE_LTR_DIRECTIONALITY
;
611 expected_flags
|= gfx::Canvas::NO_ELLIPSIS
;
613 EXPECT_EQ(expected_flags
, expected_flags
);
616 TEST_F(LabelTest
, DrawSingleLineStringInRTL
) {
618 label
.SetFocusable(false);
620 std::string locale
= l10n_util::GetApplicationLocale("");
621 base::i18n::SetICUDefaultLocale("he");
623 label
.SetText(ASCIIToUTF16("Here's a string with no returns."));
624 gfx::Size
required_size(label
.GetPreferredSize());
625 gfx::Size
extra(22, 8);
626 label
.SetBounds(0, 0, required_size
.width() + extra
.width(),
627 required_size
.height() + extra
.height());
629 // Do some basic verifications for all three alignments.
630 base::string16 paint_text
;
631 gfx::Rect text_bounds
;
635 label
.CalculateDrawStringParams(&paint_text
, &text_bounds
, &flags
);
636 EXPECT_EQ(label
.text(), paint_text
);
637 // The text should be centered horizontally and vertically.
638 EXPECT_EQ(extra
.width() / 2, text_bounds
.x());
639 EXPECT_EQ(extra
.height() / 2 , text_bounds
.y());
640 EXPECT_EQ(required_size
.width(), text_bounds
.width());
641 EXPECT_EQ(required_size
.height(), text_bounds
.height());
642 EXPECT_EQ(gfx::Canvas::TEXT_ALIGN_CENTER
,
643 flags
& (gfx::Canvas::TEXT_ALIGN_LEFT
|
644 gfx::Canvas::TEXT_ALIGN_CENTER
|
645 gfx::Canvas::TEXT_ALIGN_RIGHT
));
648 label
.SetHorizontalAlignment(gfx::ALIGN_LEFT
);
650 text_bounds
.SetRect(0, 0, 0, 0);
651 label
.CalculateDrawStringParams(&paint_text
, &text_bounds
, &flags
);
652 EXPECT_EQ(label
.text(), paint_text
);
653 // The text should be right aligned horizontally and centered vertically.
654 EXPECT_EQ(extra
.width(), text_bounds
.x());
655 EXPECT_EQ(extra
.height() / 2 , text_bounds
.y());
656 EXPECT_EQ(required_size
.width(), text_bounds
.width());
657 EXPECT_EQ(required_size
.height(), text_bounds
.height());
658 EXPECT_EQ(gfx::Canvas::TEXT_ALIGN_RIGHT
,
659 flags
& (gfx::Canvas::TEXT_ALIGN_LEFT
|
660 gfx::Canvas::TEXT_ALIGN_CENTER
|
661 gfx::Canvas::TEXT_ALIGN_RIGHT
));
663 // ALIGN_RIGHT label.
664 label
.SetHorizontalAlignment(gfx::ALIGN_RIGHT
);
666 text_bounds
.SetRect(0, 0, 0, 0);
667 label
.CalculateDrawStringParams(&paint_text
, &text_bounds
, &flags
);
668 EXPECT_EQ(label
.text(), paint_text
);
669 // The text should be left aligned horizontally and centered vertically.
670 EXPECT_EQ(0, text_bounds
.x());
671 EXPECT_EQ(extra
.height() / 2 , text_bounds
.y());
672 EXPECT_EQ(required_size
.width(), text_bounds
.width());
673 EXPECT_EQ(required_size
.height(), text_bounds
.height());
674 EXPECT_EQ(gfx::Canvas::TEXT_ALIGN_LEFT
,
675 flags
& (gfx::Canvas::TEXT_ALIGN_LEFT
|
676 gfx::Canvas::TEXT_ALIGN_CENTER
|
677 gfx::Canvas::TEXT_ALIGN_RIGHT
));
680 // Test single line drawing with a border.
681 gfx::Insets
border(39, 34, 8, 96);
682 label
.SetBorder(Border::CreateEmptyBorder(
683 border
.top(), border
.left(), border
.bottom(), border
.right()));
685 gfx::Size
required_size_with_border(label
.GetPreferredSize());
686 EXPECT_EQ(required_size
.width() + border
.width(),
687 required_size_with_border
.width());
688 EXPECT_EQ(required_size
.height() + border
.height(),
689 required_size_with_border
.height());
690 label
.SetBounds(0, 0, required_size_with_border
.width() + extra
.width(),
691 required_size_with_border
.height() + extra
.height());
693 // Centered text with border.
694 label
.SetHorizontalAlignment(gfx::ALIGN_CENTER
);
696 text_bounds
.SetRect(0, 0, 0, 0);
697 label
.CalculateDrawStringParams(&paint_text
, &text_bounds
, &flags
);
698 EXPECT_EQ(label
.text(), paint_text
);
699 // The text should be centered horizontally and vertically within the border.
700 EXPECT_EQ(border
.left() + extra
.width() / 2, text_bounds
.x());
701 EXPECT_EQ(border
.top() + extra
.height() / 2 , text_bounds
.y());
702 EXPECT_EQ(required_size
.width(), text_bounds
.width());
703 EXPECT_EQ(required_size
.height(), text_bounds
.height());
704 EXPECT_EQ(gfx::Canvas::TEXT_ALIGN_CENTER
,
705 flags
& (gfx::Canvas::TEXT_ALIGN_LEFT
|
706 gfx::Canvas::TEXT_ALIGN_CENTER
|
707 gfx::Canvas::TEXT_ALIGN_RIGHT
));
709 // ALIGN_LEFT text with border.
710 label
.SetHorizontalAlignment(gfx::ALIGN_LEFT
);
712 text_bounds
.SetRect(0, 0, 0, 0);
713 label
.CalculateDrawStringParams(&paint_text
, &text_bounds
, &flags
);
714 EXPECT_EQ(label
.text(), paint_text
);
715 // The text should be right aligned horizontally and centered vertically.
716 EXPECT_EQ(border
.left() + extra
.width(), text_bounds
.x());
717 EXPECT_EQ(border
.top() + extra
.height() / 2 , text_bounds
.y());
718 EXPECT_EQ(required_size
.width(), text_bounds
.width());
719 EXPECT_EQ(required_size
.height(), text_bounds
.height());
720 EXPECT_EQ(gfx::Canvas::TEXT_ALIGN_RIGHT
,
721 flags
& (gfx::Canvas::TEXT_ALIGN_LEFT
|
722 gfx::Canvas::TEXT_ALIGN_CENTER
|
723 gfx::Canvas::TEXT_ALIGN_RIGHT
));
726 label
.SetHorizontalAlignment(gfx::ALIGN_RIGHT
);
728 text_bounds
.SetRect(0, 0, 0, 0);
729 label
.CalculateDrawStringParams(&paint_text
, &text_bounds
, &flags
);
730 EXPECT_EQ(label
.text(), paint_text
);
731 // The text should be left aligned horizontally and centered vertically.
732 EXPECT_EQ(border
.left(), text_bounds
.x());
733 EXPECT_EQ(border
.top() + extra
.height() / 2 , text_bounds
.y());
734 EXPECT_EQ(required_size
.width(), text_bounds
.width());
735 EXPECT_EQ(required_size
.height(), text_bounds
.height());
736 EXPECT_EQ(gfx::Canvas::TEXT_ALIGN_LEFT
,
737 flags
& (gfx::Canvas::TEXT_ALIGN_LEFT
|
738 gfx::Canvas::TEXT_ALIGN_CENTER
|
739 gfx::Canvas::TEXT_ALIGN_RIGHT
));
742 base::i18n::SetICUDefaultLocale(locale
);
745 // On Linux the underlying pango routines require a max height in order to
746 // ellide multiline text. So until that can be resolved, we set all
747 // multiline lables to not ellide in Linux only.
748 TEST_F(LabelTest
, DrawMultiLineStringInRTL
) {
750 label
.SetFocusable(false);
753 std::string locale
= l10n_util::GetApplicationLocale("");
754 base::i18n::SetICUDefaultLocale("he");
756 label
.SetText(ASCIIToUTF16("Another string\nwith returns\n\n!"));
757 label
.SetMultiLine(true);
759 gfx::Size
extra(50, 10);
760 label
.SetBounds(label
.x(), label
.y(),
761 label
.width() + extra
.width(),
762 label
.height() + extra
.height());
764 // Do some basic verifications for all three alignments.
765 base::string16 paint_text
;
766 gfx::Rect text_bounds
;
768 label
.CalculateDrawStringParams(&paint_text
, &text_bounds
, &flags
);
769 EXPECT_EQ(label
.text(), paint_text
);
770 EXPECT_EQ(extra
.width() / 2, text_bounds
.x());
771 EXPECT_EQ(extra
.height() / 2, text_bounds
.y());
772 EXPECT_GT(text_bounds
.width(), kMinTextDimension
);
773 EXPECT_GT(text_bounds
.height(), kMinTextDimension
);
774 EXPECT_TRUE(gfx::Canvas::MULTI_LINE
& flags
);
775 EXPECT_TRUE(gfx::Canvas::TEXT_ALIGN_CENTER
& flags
);
777 EXPECT_TRUE(gfx::Canvas::NO_ELLIPSIS
& flags
);
779 gfx::Rect
center_bounds(text_bounds
);
781 label
.SetHorizontalAlignment(gfx::ALIGN_LEFT
);
783 text_bounds
.SetRect(0, 0, 0, 0);
784 label
.CalculateDrawStringParams(&paint_text
, &text_bounds
, &flags
);
785 EXPECT_EQ(label
.text(), paint_text
);
786 EXPECT_EQ(extra
.width(), text_bounds
.x());
787 EXPECT_EQ(extra
.height() / 2, text_bounds
.y());
788 EXPECT_GT(text_bounds
.width(), kMinTextDimension
);
789 EXPECT_GT(text_bounds
.height(), kMinTextDimension
);
790 EXPECT_TRUE(gfx::Canvas::MULTI_LINE
& flags
);
791 EXPECT_TRUE(gfx::Canvas::TEXT_ALIGN_RIGHT
& flags
);
793 EXPECT_TRUE(gfx::Canvas::NO_ELLIPSIS
& flags
);
796 label
.SetHorizontalAlignment(gfx::ALIGN_RIGHT
);
798 text_bounds
.SetRect(0, 0, 0, 0);
799 label
.CalculateDrawStringParams(&paint_text
, &text_bounds
, &flags
);
800 EXPECT_EQ(label
.text(), paint_text
);
801 EXPECT_EQ(0, text_bounds
.x());
802 EXPECT_EQ(extra
.height() / 2, text_bounds
.y());
803 EXPECT_GT(text_bounds
.width(), kMinTextDimension
);
804 EXPECT_GT(text_bounds
.height(), kMinTextDimension
);
805 EXPECT_TRUE(gfx::Canvas::MULTI_LINE
& flags
);
806 EXPECT_TRUE(gfx::Canvas::TEXT_ALIGN_LEFT
& flags
);
808 EXPECT_TRUE(gfx::Canvas::NO_ELLIPSIS
& flags
);
811 // Test multiline drawing with a border.
812 gfx::Insets
border(19, 92, 23, 2);
813 label
.SetBorder(Border::CreateEmptyBorder(
814 border
.top(), border
.left(), border
.bottom(), border
.right()));
816 label
.SetBounds(label
.x(), label
.y(),
817 label
.width() + extra
.width(),
818 label
.height() + extra
.height());
820 label
.SetHorizontalAlignment(gfx::ALIGN_CENTER
);
822 text_bounds
.SetRect(0, 0, 0, 0);
823 label
.CalculateDrawStringParams(&paint_text
, &text_bounds
, &flags
);
824 EXPECT_EQ(label
.text(), paint_text
);
825 EXPECT_EQ(border
.left() + extra
.width() / 2, text_bounds
.x());
826 EXPECT_EQ(border
.top() + extra
.height() / 2, text_bounds
.y());
827 EXPECT_EQ(center_bounds
.width(), text_bounds
.width());
828 EXPECT_EQ(center_bounds
.height(), text_bounds
.height());
829 EXPECT_TRUE(gfx::Canvas::MULTI_LINE
& flags
);
830 EXPECT_TRUE(gfx::Canvas::TEXT_ALIGN_CENTER
& flags
);
832 EXPECT_TRUE(gfx::Canvas::NO_ELLIPSIS
& flags
);
835 label
.SetHorizontalAlignment(gfx::ALIGN_LEFT
);
837 text_bounds
.SetRect(0, 0, 0, 0);
838 label
.CalculateDrawStringParams(&paint_text
, &text_bounds
, &flags
);
839 EXPECT_EQ(label
.text(), paint_text
);
840 EXPECT_EQ(border
.left() + extra
.width(), text_bounds
.x());
841 EXPECT_EQ(border
.top() + extra
.height() / 2, text_bounds
.y());
842 EXPECT_EQ(center_bounds
.width(), text_bounds
.width());
843 EXPECT_EQ(center_bounds
.height(), text_bounds
.height());
844 EXPECT_TRUE(gfx::Canvas::MULTI_LINE
& flags
);
845 EXPECT_TRUE(gfx::Canvas::TEXT_ALIGN_RIGHT
& flags
);
847 EXPECT_TRUE(gfx::Canvas::NO_ELLIPSIS
& flags
);
850 label
.SetHorizontalAlignment(gfx::ALIGN_RIGHT
);
852 text_bounds
.SetRect(0, 0, 0, 0);
853 label
.CalculateDrawStringParams(&paint_text
, &text_bounds
, &flags
);
854 EXPECT_EQ(label
.text(), paint_text
);
855 EXPECT_EQ(border
.left(), text_bounds
.x());
856 EXPECT_EQ(border
.top() + extra
.height() / 2, text_bounds
.y());
857 EXPECT_EQ(center_bounds
.width(), text_bounds
.width());
858 EXPECT_EQ(center_bounds
.height(), text_bounds
.height());
859 EXPECT_TRUE(gfx::Canvas::MULTI_LINE
& flags
);
860 EXPECT_TRUE(gfx::Canvas::TEXT_ALIGN_LEFT
& flags
);
862 EXPECT_TRUE(gfx::Canvas::NO_ELLIPSIS
& flags
);
866 base::i18n::SetICUDefaultLocale(locale
);
869 // Ensure the subpixel rendering flag and background color alpha are respected.
870 TEST_F(LabelTest
, DisableSubpixelRendering
) {
872 label
.SetBackgroundColor(SK_ColorWHITE
);
873 const int flag
= gfx::Canvas::NO_SUBPIXEL_RENDERING
;
874 EXPECT_EQ(0, label
.ComputeDrawStringFlags() & flag
);
875 label
.set_subpixel_rendering_enabled(false);
876 EXPECT_EQ(flag
, label
.ComputeDrawStringFlags() & flag
);
877 label
.set_subpixel_rendering_enabled(true);
878 EXPECT_EQ(0, label
.ComputeDrawStringFlags() & flag
);
879 // Text cannot be drawn with subpixel rendering on transparent backgrounds.
880 label
.SetBackgroundColor(SkColorSetARGB(64, 255, 255, 255));
881 EXPECT_EQ(flag
, label
.ComputeDrawStringFlags() & flag
);
884 // Check that labels support GetTooltipHandlerForPoint.
885 TEST_F(LabelTest
, GetTooltipHandlerForPoint
) {
886 // A root view must be defined for this test because the hit-testing
887 // behaviour used by GetTooltipHandlerForPoint() is defined by
888 // the ViewTargeter installed on the root view.
890 Widget::InitParams init_params
=
891 CreateParams(Widget::InitParams::TYPE_POPUP
);
892 init_params
.ownership
= Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET
;
893 init_params
.bounds
= gfx::Rect(0, 0, 200, 200);
894 widget
.Init(init_params
);
898 ASCIIToUTF16("A string that's long enough to exceed the bounds"));
899 label
.SetBounds(0, 0, 10, 10);
900 widget
.SetContentsView(&label
);
902 // There's a default tooltip if the text is too big to fit.
903 EXPECT_EQ(&label
, label
.GetTooltipHandlerForPoint(gfx::Point(2, 2)));
905 // If there's no default tooltip, this should return NULL.
906 label
.SetBounds(0, 0, 500, 50);
907 EXPECT_FALSE(label
.GetTooltipHandlerForPoint(gfx::Point(2, 2)));
909 label
.SetTooltipText(ASCIIToUTF16("a tooltip"));
910 // If the point hits the label, and tooltip is set, the label should be
911 // returned as its tooltip handler.
912 EXPECT_EQ(&label
, label
.GetTooltipHandlerForPoint(gfx::Point(2, 2)));
914 // Additionally, GetTooltipHandlerForPoint should verify that the label
915 // actually contains the point.
916 EXPECT_FALSE(label
.GetTooltipHandlerForPoint(gfx::Point(2, 51)));
917 EXPECT_FALSE(label
.GetTooltipHandlerForPoint(gfx::Point(-1, 20)));
919 // GetTooltipHandlerForPoint works should work in child bounds.
920 label
.SetBounds(2, 2, 10, 10);
921 EXPECT_EQ(&label
, label
.GetTooltipHandlerForPoint(gfx::Point(1, 5)));
922 EXPECT_FALSE(label
.GetTooltipHandlerForPoint(gfx::Point(3, 11)));