- add sources.
[platform/framework/web/crosswalk.git] / src / ui / views / controls / label_unittest.cc
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.
4
5 #include "base/i18n/rtl.h"
6 #include "base/strings/utf_string_conversions.h"
7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "ui/base/accessibility/accessible_view_state.h"
9 #include "ui/base/l10n/l10n_util.h"
10 #include "ui/gfx/canvas.h"
11 #include "ui/views/border.h"
12 #include "ui/views/controls/label.h"
13
14 namespace views {
15
16 // All text sizing measurements (width and height) should be greater than this.
17 const int kMinTextDimension = 4;
18
19 TEST(LabelTest, FontPropertySymbol) {
20   Label label;
21   std::string font_name("symbol");
22   gfx::Font font(font_name, 26);
23   label.SetFontList(gfx::FontList(font));
24   gfx::Font font_used = label.font_list().GetPrimaryFont();
25   EXPECT_EQ(font_name, font_used.GetFontName());
26   EXPECT_EQ(26, font_used.GetFontSize());
27 }
28
29 TEST(LabelTest, FontPropertyArial) {
30   Label label;
31   std::string font_name("arial");
32   gfx::Font font(font_name, 30);
33   label.SetFontList(gfx::FontList(font));
34   gfx::Font font_used = label.font_list().GetPrimaryFont();
35   EXPECT_EQ(font_name, font_used.GetFontName());
36   EXPECT_EQ(30, font_used.GetFontSize());
37 }
38
39 TEST(LabelTest, TextProperty) {
40   Label label;
41   string16 test_text(ASCIIToUTF16("A random string."));
42   label.SetText(test_text);
43   EXPECT_EQ(test_text, label.text());
44 }
45
46 TEST(LabelTest, ColorProperty) {
47   Label label;
48   SkColor color = SkColorSetARGB(20, 40, 10, 5);
49   label.SetAutoColorReadabilityEnabled(false);
50   label.SetEnabledColor(color);
51   EXPECT_EQ(color, label.enabled_color());
52 }
53
54 TEST(LabelTest, AlignmentProperty) {
55   Label label;
56   bool reverse_alignment = base::i18n::IsRTL();
57
58   label.SetHorizontalAlignment(gfx::ALIGN_RIGHT);
59   EXPECT_EQ(reverse_alignment ? gfx::ALIGN_LEFT : gfx::ALIGN_RIGHT,
60             label.horizontal_alignment());
61   label.SetHorizontalAlignment(gfx::ALIGN_LEFT);
62   EXPECT_EQ(reverse_alignment ? gfx::ALIGN_RIGHT : gfx::ALIGN_LEFT,
63             label.horizontal_alignment());
64   label.SetHorizontalAlignment(gfx::ALIGN_CENTER);
65   EXPECT_EQ(gfx::ALIGN_CENTER, label.horizontal_alignment());
66
67   // The label's alignment should not be flipped if the directionality mode is
68   // AUTO_DETECT_DIRECTIONALITY.
69   label.set_directionality_mode(Label::AUTO_DETECT_DIRECTIONALITY);
70   label.SetHorizontalAlignment(gfx::ALIGN_RIGHT);
71   EXPECT_EQ(gfx::ALIGN_RIGHT, label.horizontal_alignment());
72   label.SetHorizontalAlignment(gfx::ALIGN_LEFT);
73   EXPECT_EQ(gfx::ALIGN_LEFT, label.horizontal_alignment());
74   label.SetHorizontalAlignment(gfx::ALIGN_CENTER);
75   EXPECT_EQ(gfx::ALIGN_CENTER, label.horizontal_alignment());
76 }
77
78 TEST(LabelTest, DirectionalityModeProperty) {
79   Label label;
80   EXPECT_EQ(Label::USE_UI_DIRECTIONALITY, label.directionality_mode());
81
82   label.set_directionality_mode(Label::AUTO_DETECT_DIRECTIONALITY);
83   EXPECT_EQ(Label::AUTO_DETECT_DIRECTIONALITY, label.directionality_mode());
84
85   label.set_directionality_mode(Label::USE_UI_DIRECTIONALITY);
86   EXPECT_EQ(Label::USE_UI_DIRECTIONALITY, label.directionality_mode());
87 }
88
89 TEST(LabelTest, MultiLineProperty) {
90   Label label;
91   EXPECT_FALSE(label.is_multi_line());
92   label.SetMultiLine(true);
93   EXPECT_TRUE(label.is_multi_line());
94   label.SetMultiLine(false);
95   EXPECT_FALSE(label.is_multi_line());
96 }
97
98 TEST(LabelTest, TooltipProperty) {
99   Label label;
100   string16 test_text(ASCIIToUTF16("My cool string."));
101   label.SetText(test_text);
102
103   string16 tooltip;
104   EXPECT_TRUE(label.GetTooltipText(gfx::Point(), &tooltip));
105   EXPECT_EQ(test_text, tooltip);
106
107   string16 tooltip_text(ASCIIToUTF16("The tooltip!"));
108   label.SetTooltipText(tooltip_text);
109   EXPECT_TRUE(label.GetTooltipText(gfx::Point(), &tooltip));
110   EXPECT_EQ(tooltip_text, tooltip);
111
112   string16 empty_text;
113   label.SetTooltipText(empty_text);
114   EXPECT_TRUE(label.GetTooltipText(gfx::Point(), &tooltip));
115   EXPECT_EQ(test_text, tooltip);
116
117   // Make the label big enough to hold the text
118   // and expect there to be no tooltip.
119   label.SetBounds(0, 0, 1000, 40);
120   EXPECT_FALSE(label.GetTooltipText(gfx::Point(), &tooltip));
121
122   // Verify that setting the tooltip still shows it.
123   label.SetTooltipText(tooltip_text);
124   EXPECT_TRUE(label.GetTooltipText(gfx::Point(), &tooltip));
125   EXPECT_EQ(tooltip_text, tooltip);
126   // Clear out the tooltip.
127   label.SetTooltipText(empty_text);
128
129   // Shrink the bounds and the tooltip should come back.
130   label.SetBounds(0, 0, 1, 1);
131   EXPECT_TRUE(label.GetTooltipText(gfx::Point(), &tooltip));
132
133   // Make the label multiline and there is no tooltip again.
134   label.SetMultiLine(true);
135   EXPECT_FALSE(label.GetTooltipText(gfx::Point(), &tooltip));
136
137   // Verify that setting the tooltip still shows it.
138   label.SetTooltipText(tooltip_text);
139   EXPECT_TRUE(label.GetTooltipText(gfx::Point(), &tooltip));
140   EXPECT_EQ(tooltip_text, tooltip);
141   // Clear out the tooltip.
142   label.SetTooltipText(empty_text);
143 }
144
145 TEST(LabelTest, Accessibility) {
146   Label label;
147   string16 test_text(ASCIIToUTF16("My special text."));
148   label.SetText(test_text);
149
150   ui::AccessibleViewState state;
151   label.GetAccessibleState(&state);
152   EXPECT_EQ(ui::AccessibilityTypes::ROLE_STATICTEXT, state.role);
153   EXPECT_EQ(test_text, state.name);
154   EXPECT_TRUE(ui::AccessibilityTypes::STATE_READONLY & state.state);
155 }
156
157 TEST(LabelTest, SingleLineSizing) {
158   Label label;
159   string16 test_text(ASCIIToUTF16("A not so random string in one line."));
160   label.SetText(test_text);
161
162   // GetPreferredSize
163   gfx::Size required_size = label.GetPreferredSize();
164   EXPECT_GT(required_size.height(), kMinTextDimension);
165   EXPECT_GT(required_size.width(), kMinTextDimension);
166
167   // Test everything with borders.
168   gfx::Insets border(10, 20, 30, 40);
169   label.set_border(Border::CreateEmptyBorder(border.top(),
170                                              border.left(),
171                                              border.bottom(),
172                                              border.right()));
173
174   // GetPreferredSize and borders.
175   label.SetBounds(0, 0, 0, 0);
176   gfx::Size required_size_with_border = label.GetPreferredSize();
177   EXPECT_EQ(required_size_with_border.height(),
178             required_size.height() + border.height());
179   EXPECT_EQ(required_size_with_border.width(),
180             required_size.width() + border.width());
181 }
182
183 TEST(LabelTest, MultilineSmallAvailableWidthSizing) {
184   Label label;
185   string16 test_text(ASCIIToUTF16("Too Wide."));
186
187   label.SetMultiLine(true);
188   label.SetAllowCharacterBreak(true);
189   label.SetElideBehavior(Label::ELIDE_AT_END);
190   label.SetText(test_text);
191
192   // Check that Label can be laid out at a variety of small sizes,
193   // splitting the words into up to one character per line if necessary.
194   // Incorrect word splitting may cause infinite loops in text layout.
195   gfx::Size required_size = label.GetPreferredSize();
196   for (int i = 1; i < required_size.width(); ++i) {
197     EXPECT_GT(label.GetHeightForWidth(i), 0);
198   }
199 }
200
201 TEST(LabelTest, MultiLineSizing) {
202   Label label;
203   label.set_focusable(false);
204   string16 test_text(
205       ASCIIToUTF16("A random string\nwith multiple lines\nand returns!"));
206   label.SetText(test_text);
207   label.SetMultiLine(true);
208
209   // GetPreferredSize
210   gfx::Size required_size = label.GetPreferredSize();
211   EXPECT_GT(required_size.height(), kMinTextDimension);
212   EXPECT_GT(required_size.width(), kMinTextDimension);
213
214   // SizeToFit with unlimited width.
215   label.SizeToFit(0);
216   int required_width = label.GetLocalBounds().width();
217   EXPECT_GT(required_width, kMinTextDimension);
218
219   // SizeToFit with limited width.
220   label.SizeToFit(required_width - 1);
221   int constrained_width = label.GetLocalBounds().width();
222 #if defined(OS_WIN)
223   // Canvas::SizeStringInt (in ui/gfx/canvas_linux.cc)
224   // has to be fixed to return the size that fits to given width/height.
225   EXPECT_LT(constrained_width, required_width);
226 #endif
227   EXPECT_GT(constrained_width, kMinTextDimension);
228
229   // Change the width back to the desire width.
230   label.SizeToFit(required_width);
231   EXPECT_EQ(required_width, label.GetLocalBounds().width());
232
233   // General tests for GetHeightForWidth.
234   int required_height = label.GetHeightForWidth(required_width);
235   EXPECT_GT(required_height, kMinTextDimension);
236   int height_for_constrained_width = label.GetHeightForWidth(constrained_width);
237 #if defined(OS_WIN)
238   // Canvas::SizeStringInt (in ui/gfx/canvas_linux.cc)
239   // has to be fixed to return the size that fits to given width/height.
240   EXPECT_GT(height_for_constrained_width, required_height);
241 #endif
242   // Using the constrained width or the required_width - 1 should give the
243   // same result for the height because the constrainted width is the tight
244   // width when given "required_width - 1" as the max width.
245   EXPECT_EQ(height_for_constrained_width,
246             label.GetHeightForWidth(required_width - 1));
247
248   // Test everything with borders.
249   gfx::Insets border(10, 20, 30, 40);
250   label.set_border(Border::CreateEmptyBorder(border.top(),
251                                              border.left(),
252                                              border.bottom(),
253                                              border.right()));
254
255   // SizeToFit and borders.
256   label.SizeToFit(0);
257   int required_width_with_border = label.GetLocalBounds().width();
258   EXPECT_EQ(required_width_with_border, required_width + border.width());
259
260   // GetHeightForWidth and borders.
261   int required_height_with_border =
262       label.GetHeightForWidth(required_width_with_border);
263   EXPECT_EQ(required_height_with_border, required_height + border.height());
264
265   // Test that the border width is subtracted before doing the height
266   // calculation.  If it is, then the height will grow when width
267   // is shrunk.
268   int height1 = label.GetHeightForWidth(required_width_with_border - 1);
269 #if defined(OS_WIN)
270   // Canvas::SizeStringInt (in ui/gfx/canvas_linux.cc)
271   // has to be fixed to return the size that fits to given width/height.
272   EXPECT_GT(height1, required_height_with_border);
273 #endif
274   EXPECT_EQ(height1, height_for_constrained_width + border.height());
275
276   // GetPreferredSize and borders.
277   label.SetBounds(0, 0, 0, 0);
278   gfx::Size required_size_with_border = label.GetPreferredSize();
279   EXPECT_EQ(required_size_with_border.height(),
280             required_size.height() + border.height());
281   EXPECT_EQ(required_size_with_border.width(),
282             required_size.width() + border.width());
283 }
284
285 TEST(LabelTest, AutoDetectDirectionality) {
286   Label label;
287   label.set_directionality_mode(Label::AUTO_DETECT_DIRECTIONALITY);
288
289   // Test text starts with RTL character.
290   string16 test_text(WideToUTF16(L"  \x5d0\x5d1\x5d2 abc"));
291   label.SetText(test_text);
292   gfx::Size required_size(label.GetPreferredSize());
293   gfx::Size extra(22, 8);
294   label.SetBounds(0,
295                   0,
296                   required_size.width() + extra.width(),
297                   required_size.height() + extra.height());
298
299   string16 paint_text;
300   gfx::Rect text_bounds;
301   int flags;
302   label.CalculateDrawStringParams(&paint_text, &text_bounds, &flags);
303   EXPECT_EQ(gfx::Canvas::FORCE_RTL_DIRECTIONALITY,
304             flags & (gfx::Canvas::FORCE_RTL_DIRECTIONALITY |
305                      gfx::Canvas::FORCE_LTR_DIRECTIONALITY));
306
307   // Test text starts with LTR character.
308   test_text = (WideToUTF16(L"ltr \x5d0\x5d1\x5d2 abc"));
309   label.SetText(test_text);
310   required_size = label.GetPreferredSize();
311   label.SetBounds(0,
312                   0,
313                   required_size.width() + extra.width(),
314                   required_size.height() + extra.height());
315
316   label.CalculateDrawStringParams(&paint_text, &text_bounds, &flags);
317   EXPECT_EQ(gfx::Canvas::FORCE_LTR_DIRECTIONALITY,
318             flags & (gfx::Canvas::FORCE_RTL_DIRECTIONALITY |
319                      gfx::Canvas::FORCE_LTR_DIRECTIONALITY));
320 }
321
322 TEST(LabelTest, DrawSingleLineString) {
323   Label label;
324   label.set_focusable(false);
325
326   // Turn off mirroring so that we don't need to figure out if
327   // align right really means align left.
328   label.set_directionality_mode(Label::AUTO_DETECT_DIRECTIONALITY);
329
330   string16 test_text(ASCIIToUTF16("Here's a string with no returns."));
331   label.SetText(test_text);
332   gfx::Size required_size(label.GetPreferredSize());
333   gfx::Size extra(22, 8);
334   label.SetBounds(0,
335                   0,
336                   required_size.width() + extra.width(),
337                   required_size.height() + extra.height());
338
339   // Do some basic verifications for all three alignments.
340   string16 paint_text;
341   gfx::Rect text_bounds;
342   int flags;
343
344   // Centered text.
345   label.CalculateDrawStringParams(&paint_text, &text_bounds, &flags);
346   EXPECT_EQ(test_text, paint_text);
347   // The text should be centered horizontally and vertically.
348   EXPECT_EQ(extra.width() / 2, text_bounds.x());
349   EXPECT_EQ(extra.height() / 2 , text_bounds.y());
350   EXPECT_EQ(required_size.width(), text_bounds.width());
351   EXPECT_EQ(required_size.height(), text_bounds.height());
352   EXPECT_EQ(gfx::Canvas::TEXT_ALIGN_CENTER,
353             flags & (gfx::Canvas::TEXT_ALIGN_LEFT |
354                      gfx::Canvas::TEXT_ALIGN_CENTER |
355                      gfx::Canvas::TEXT_ALIGN_RIGHT));
356
357   // Left aligned text.
358   label.SetHorizontalAlignment(gfx::ALIGN_LEFT);
359   paint_text.clear();
360   text_bounds.SetRect(0, 0, 0, 0);
361   label.CalculateDrawStringParams(&paint_text, &text_bounds, &flags);
362   EXPECT_EQ(test_text, paint_text);
363   // The text should be left aligned horizontally and centered vertically.
364   EXPECT_EQ(0, text_bounds.x());
365   EXPECT_EQ(extra.height() / 2 , text_bounds.y());
366   EXPECT_EQ(required_size.width(), text_bounds.width());
367   EXPECT_EQ(required_size.height(), text_bounds.height());
368   EXPECT_EQ(gfx::Canvas::TEXT_ALIGN_LEFT,
369             flags & (gfx::Canvas::TEXT_ALIGN_LEFT |
370                      gfx::Canvas::TEXT_ALIGN_CENTER |
371                      gfx::Canvas::TEXT_ALIGN_RIGHT));
372
373   // Right aligned text.
374   label.SetHorizontalAlignment(gfx::ALIGN_RIGHT);
375   paint_text.clear();
376   text_bounds.SetRect(0, 0, 0, 0);
377   label.CalculateDrawStringParams(&paint_text, &text_bounds, &flags);
378   EXPECT_EQ(test_text, paint_text);
379   // The text should be right aligned horizontally and centered vertically.
380   EXPECT_EQ(extra.width(), text_bounds.x());
381   EXPECT_EQ(extra.height() / 2 , text_bounds.y());
382   EXPECT_EQ(required_size.width(), text_bounds.width());
383   EXPECT_EQ(required_size.height(), text_bounds.height());
384   EXPECT_EQ(gfx::Canvas::TEXT_ALIGN_RIGHT,
385             flags & (gfx::Canvas::TEXT_ALIGN_LEFT |
386                      gfx::Canvas::TEXT_ALIGN_CENTER |
387                      gfx::Canvas::TEXT_ALIGN_RIGHT));
388
389   // Test single line drawing with a border.
390   gfx::Insets border(39, 34, 8, 96);
391   label.set_border(Border::CreateEmptyBorder(border.top(),
392                                              border.left(),
393                                              border.bottom(),
394                                              border.right()));
395
396   gfx::Size required_size_with_border(label.GetPreferredSize());
397   EXPECT_EQ(required_size.width() + border.width(),
398             required_size_with_border.width());
399   EXPECT_EQ(required_size.height() + border.height(),
400             required_size_with_border.height());
401   label.SetBounds(0,
402                   0,
403                   required_size_with_border.width() + extra.width(),
404                   required_size_with_border.height() + extra.height());
405
406   // Centered text with border.
407   label.SetHorizontalAlignment(gfx::ALIGN_CENTER);
408   paint_text.clear();
409   text_bounds.SetRect(0, 0, 0, 0);
410   label.CalculateDrawStringParams(&paint_text, &text_bounds, &flags);
411   EXPECT_EQ(test_text, paint_text);
412   // The text should be centered horizontally and vertically within the border.
413   EXPECT_EQ(border.left() + extra.width() / 2, text_bounds.x());
414   EXPECT_EQ(border.top() + extra.height() / 2 , text_bounds.y());
415   EXPECT_EQ(required_size.width(), text_bounds.width());
416   EXPECT_EQ(required_size.height(), text_bounds.height());
417   EXPECT_EQ(gfx::Canvas::TEXT_ALIGN_CENTER,
418             flags & (gfx::Canvas::TEXT_ALIGN_LEFT |
419                      gfx::Canvas::TEXT_ALIGN_CENTER |
420                      gfx::Canvas::TEXT_ALIGN_RIGHT));
421
422   // Left aligned text with border.
423   label.SetHorizontalAlignment(gfx::ALIGN_LEFT);
424   paint_text.clear();
425   text_bounds.SetRect(0, 0, 0, 0);
426   label.CalculateDrawStringParams(&paint_text, &text_bounds, &flags);
427   EXPECT_EQ(test_text, paint_text);
428   // The text should be left aligned horizontally and centered vertically.
429   EXPECT_EQ(border.left(), text_bounds.x());
430   EXPECT_EQ(border.top() + extra.height() / 2 , text_bounds.y());
431   EXPECT_EQ(required_size.width(), text_bounds.width());
432   EXPECT_EQ(required_size.height(), text_bounds.height());
433   EXPECT_EQ(gfx::Canvas::TEXT_ALIGN_LEFT,
434             flags & (gfx::Canvas::TEXT_ALIGN_LEFT |
435                      gfx::Canvas::TEXT_ALIGN_CENTER |
436                      gfx::Canvas::TEXT_ALIGN_RIGHT));
437
438   // Right aligned text.
439   label.SetHorizontalAlignment(gfx::ALIGN_RIGHT);
440   paint_text.clear();
441   text_bounds.SetRect(0, 0, 0, 0);
442   label.CalculateDrawStringParams(&paint_text, &text_bounds, &flags);
443   EXPECT_EQ(test_text, paint_text);
444   // The text should be right aligned horizontally and centered vertically.
445   EXPECT_EQ(border.left() + extra.width(), text_bounds.x());
446   EXPECT_EQ(border.top() + extra.height() / 2 , text_bounds.y());
447   EXPECT_EQ(required_size.width(), text_bounds.width());
448   EXPECT_EQ(required_size.height(), text_bounds.height());
449   EXPECT_EQ(gfx::Canvas::TEXT_ALIGN_RIGHT,
450             flags & (gfx::Canvas::TEXT_ALIGN_LEFT |
451                      gfx::Canvas::TEXT_ALIGN_CENTER |
452                      gfx::Canvas::TEXT_ALIGN_RIGHT));
453 }
454
455 // On Linux the underlying pango routines require a max height in order to
456 // ellide multiline text. So until that can be resolved, we set all
457 // multiline lables to not ellide in Linux only.
458 TEST(LabelTest, DrawMultiLineString) {
459   Label label;
460   label.set_focusable(false);
461
462   // Turn off mirroring so that we don't need to figure out if
463   // align right really means align left.
464   label.set_directionality_mode(Label::AUTO_DETECT_DIRECTIONALITY);
465
466   string16 test_text(ASCIIToUTF16("Another string\nwith returns\n\n!"));
467   label.SetText(test_text);
468   label.SetMultiLine(true);
469   label.SizeToFit(0);
470   gfx::Size extra(50, 10);
471   label.SetBounds(label.x(),
472                   label.y(),
473                   label.width() + extra.width(),
474                   label.height() + extra.height());
475
476   // Do some basic verifications for all three alignments.
477   string16 paint_text;
478   gfx::Rect text_bounds;
479   int flags;
480   label.CalculateDrawStringParams(&paint_text, &text_bounds, &flags);
481   EXPECT_EQ(test_text, paint_text);
482   EXPECT_EQ(extra.width() / 2, text_bounds.x());
483   EXPECT_EQ(extra.height() / 2, text_bounds.y());
484   EXPECT_GT(text_bounds.width(), kMinTextDimension);
485   EXPECT_GT(text_bounds.height(), kMinTextDimension);
486   int expected_flags = gfx::Canvas::MULTI_LINE |
487                        gfx::Canvas::TEXT_ALIGN_CENTER |
488                        gfx::Canvas::FORCE_LTR_DIRECTIONALITY;
489 #if defined(OS_WIN)
490   EXPECT_EQ(expected_flags, flags);
491 #else
492   EXPECT_EQ(expected_flags | gfx::Canvas::NO_ELLIPSIS, flags);
493 #endif
494   gfx::Rect center_bounds(text_bounds);
495
496   label.SetHorizontalAlignment(gfx::ALIGN_LEFT);
497   paint_text.clear();
498   text_bounds.SetRect(0, 0, 0, 0);
499   label.CalculateDrawStringParams(&paint_text, &text_bounds, &flags);
500   EXPECT_EQ(test_text, paint_text);
501   EXPECT_EQ(0, text_bounds.x());
502   EXPECT_EQ(extra.height() / 2, text_bounds.y());
503   EXPECT_GT(text_bounds.width(), kMinTextDimension);
504   EXPECT_GT(text_bounds.height(), kMinTextDimension);
505   expected_flags = gfx::Canvas::MULTI_LINE |
506                    gfx::Canvas::TEXT_ALIGN_LEFT |
507                    gfx::Canvas::FORCE_LTR_DIRECTIONALITY;
508 #if defined(OS_WIN)
509   EXPECT_EQ(expected_flags, flags);
510 #else
511   EXPECT_EQ(expected_flags | gfx::Canvas::NO_ELLIPSIS, flags);
512 #endif
513
514   label.SetHorizontalAlignment(gfx::ALIGN_RIGHT);
515   paint_text.clear();
516   text_bounds.SetRect(0, 0, 0, 0);
517   label.CalculateDrawStringParams(&paint_text, &text_bounds, &flags);
518   EXPECT_EQ(test_text, paint_text);
519   EXPECT_EQ(extra.width(), text_bounds.x());
520   EXPECT_EQ(extra.height() / 2, text_bounds.y());
521   EXPECT_GT(text_bounds.width(), kMinTextDimension);
522   EXPECT_GT(text_bounds.height(), kMinTextDimension);
523   expected_flags = gfx::Canvas::MULTI_LINE |
524                    gfx::Canvas::TEXT_ALIGN_RIGHT |
525                    gfx::Canvas::FORCE_LTR_DIRECTIONALITY;
526 #if defined(OS_WIN)
527   EXPECT_EQ(expected_flags, flags);
528 #else
529   EXPECT_EQ(expected_flags | gfx::Canvas::NO_ELLIPSIS, flags);
530 #endif
531
532   // Test multiline drawing with a border.
533   gfx::Insets border(19, 92, 23, 2);
534   label.set_border(Border::CreateEmptyBorder(border.top(),
535                                              border.left(),
536                                              border.bottom(),
537                                              border.right()));
538   label.SizeToFit(0);
539   label.SetBounds(label.x(),
540                   label.y(),
541                   label.width() + extra.width(),
542                   label.height() + extra.height());
543
544   label.SetHorizontalAlignment(gfx::ALIGN_CENTER);
545   paint_text.clear();
546   text_bounds.SetRect(0, 0, 0, 0);
547   label.CalculateDrawStringParams(&paint_text, &text_bounds, &flags);
548   EXPECT_EQ(test_text, paint_text);
549   EXPECT_EQ(border.left() + extra.width() / 2, text_bounds.x());
550   EXPECT_EQ(border.top() + extra.height() / 2, text_bounds.y());
551   EXPECT_EQ(center_bounds.width(), text_bounds.width());
552   EXPECT_EQ(center_bounds.height(), text_bounds.height());
553   expected_flags = gfx::Canvas::MULTI_LINE |
554                    gfx::Canvas::TEXT_ALIGN_CENTER |
555                    gfx::Canvas::FORCE_LTR_DIRECTIONALITY;
556 #if defined(OS_WIN)
557   EXPECT_EQ(expected_flags, flags);
558 #else
559   EXPECT_EQ(expected_flags | gfx::Canvas::NO_ELLIPSIS, flags);
560 #endif
561
562   label.SetHorizontalAlignment(gfx::ALIGN_LEFT);
563   paint_text.clear();
564   text_bounds.SetRect(0, 0, 0, 0);
565   label.CalculateDrawStringParams(&paint_text, &text_bounds, &flags);
566   EXPECT_EQ(test_text, paint_text);
567   EXPECT_EQ(border.left(), text_bounds.x());
568   EXPECT_EQ(border.top() + extra.height() / 2, text_bounds.y());
569   EXPECT_EQ(center_bounds.width(), text_bounds.width());
570   EXPECT_EQ(center_bounds.height(), text_bounds.height());
571   expected_flags = gfx::Canvas::MULTI_LINE |
572                    gfx::Canvas::TEXT_ALIGN_LEFT |
573                    gfx::Canvas::FORCE_LTR_DIRECTIONALITY;
574 #if defined(OS_WIN)
575   EXPECT_EQ(expected_flags, flags);
576 #else
577   EXPECT_EQ(expected_flags | gfx::Canvas::NO_ELLIPSIS, flags);
578 #endif
579
580   label.SetHorizontalAlignment(gfx::ALIGN_RIGHT);
581   paint_text.clear();
582   text_bounds.SetRect(0, 0, 0, 0);
583   label.CalculateDrawStringParams(&paint_text, &text_bounds, &flags);
584   EXPECT_EQ(test_text, paint_text);
585   EXPECT_EQ(extra.width() + border.left(), text_bounds.x());
586   EXPECT_EQ(border.top() + extra.height() / 2, text_bounds.y());
587   EXPECT_EQ(center_bounds.width(), text_bounds.width());
588   EXPECT_EQ(center_bounds.height(), text_bounds.height());
589   expected_flags = gfx::Canvas::MULTI_LINE |
590                    gfx::Canvas::TEXT_ALIGN_RIGHT |
591                    gfx::Canvas::FORCE_LTR_DIRECTIONALITY;
592 #if defined(OS_WIN)
593   EXPECT_EQ(expected_flags, flags);
594 #else
595   EXPECT_EQ(expected_flags | gfx::Canvas::NO_ELLIPSIS, flags);
596 #endif
597 }
598
599 TEST(LabelTest, DrawSingleLineStringInRTL) {
600   Label label;
601   label.set_focusable(false);
602
603   std::string locale = l10n_util::GetApplicationLocale("");
604   base::i18n::SetICUDefaultLocale("he");
605
606   string16 test_text(ASCIIToUTF16("Here's a string with no returns."));
607   label.SetText(test_text);
608   gfx::Size required_size(label.GetPreferredSize());
609   gfx::Size extra(22, 8);
610   label.SetBounds(0,
611                   0,
612                   required_size.width() + extra.width(),
613                   required_size.height() + extra.height());
614
615   // Do some basic verifications for all three alignments.
616   string16 paint_text;
617   gfx::Rect text_bounds;
618   int flags;
619
620   // Centered text.
621   label.CalculateDrawStringParams(&paint_text, &text_bounds, &flags);
622   EXPECT_EQ(test_text, paint_text);
623   // The text should be centered horizontally and vertically.
624   EXPECT_EQ(extra.width() / 2, text_bounds.x());
625   EXPECT_EQ(extra.height() / 2 , text_bounds.y());
626   EXPECT_EQ(required_size.width(), text_bounds.width());
627   EXPECT_EQ(required_size.height(), text_bounds.height());
628   EXPECT_EQ(gfx::Canvas::TEXT_ALIGN_CENTER,
629             flags & (gfx::Canvas::TEXT_ALIGN_LEFT |
630                      gfx::Canvas::TEXT_ALIGN_CENTER |
631                      gfx::Canvas::TEXT_ALIGN_RIGHT));
632
633   // ALIGN_LEFT label.
634   label.SetHorizontalAlignment(gfx::ALIGN_LEFT);
635   paint_text.clear();
636   text_bounds.SetRect(0, 0, 0, 0);
637   label.CalculateDrawStringParams(&paint_text, &text_bounds, &flags);
638   EXPECT_EQ(test_text, paint_text);
639   // The text should be right aligned horizontally and centered vertically.
640   EXPECT_EQ(extra.width(), text_bounds.x());
641   EXPECT_EQ(extra.height() / 2 , text_bounds.y());
642   EXPECT_EQ(required_size.width(), text_bounds.width());
643   EXPECT_EQ(required_size.height(), text_bounds.height());
644   EXPECT_EQ(gfx::Canvas::TEXT_ALIGN_RIGHT,
645             flags & (gfx::Canvas::TEXT_ALIGN_LEFT |
646                      gfx::Canvas::TEXT_ALIGN_CENTER |
647                      gfx::Canvas::TEXT_ALIGN_RIGHT));
648
649   // ALIGN_RIGHT label.
650   label.SetHorizontalAlignment(gfx::ALIGN_RIGHT);
651   paint_text.clear();
652   text_bounds.SetRect(0, 0, 0, 0);
653   label.CalculateDrawStringParams(&paint_text, &text_bounds, &flags);
654   EXPECT_EQ(test_text, paint_text);
655   // The text should be left aligned horizontally and centered vertically.
656   EXPECT_EQ(0, text_bounds.x());
657   EXPECT_EQ(extra.height() / 2 , text_bounds.y());
658   EXPECT_EQ(required_size.width(), text_bounds.width());
659   EXPECT_EQ(required_size.height(), text_bounds.height());
660   EXPECT_EQ(gfx::Canvas::TEXT_ALIGN_LEFT,
661             flags & (gfx::Canvas::TEXT_ALIGN_LEFT |
662                      gfx::Canvas::TEXT_ALIGN_CENTER |
663                      gfx::Canvas::TEXT_ALIGN_RIGHT));
664
665
666   // Test single line drawing with a border.
667   gfx::Insets border(39, 34, 8, 96);
668   label.set_border(Border::CreateEmptyBorder(border.top(),
669                                              border.left(),
670                                              border.bottom(),
671                                              border.right()));
672
673   gfx::Size required_size_with_border(label.GetPreferredSize());
674   EXPECT_EQ(required_size.width() + border.width(),
675             required_size_with_border.width());
676   EXPECT_EQ(required_size.height() + border.height(),
677             required_size_with_border.height());
678   label.SetBounds(0,
679                   0,
680                   required_size_with_border.width() + extra.width(),
681                   required_size_with_border.height() + extra.height());
682
683   // Centered text with border.
684   label.SetHorizontalAlignment(gfx::ALIGN_CENTER);
685   paint_text.clear();
686   text_bounds.SetRect(0, 0, 0, 0);
687   label.CalculateDrawStringParams(&paint_text, &text_bounds, &flags);
688   EXPECT_EQ(test_text, paint_text);
689   // The text should be centered horizontally and vertically within the border.
690   EXPECT_EQ(border.left() + extra.width() / 2, text_bounds.x());
691   EXPECT_EQ(border.top() + extra.height() / 2 , text_bounds.y());
692   EXPECT_EQ(required_size.width(), text_bounds.width());
693   EXPECT_EQ(required_size.height(), text_bounds.height());
694   EXPECT_EQ(gfx::Canvas::TEXT_ALIGN_CENTER,
695             flags & (gfx::Canvas::TEXT_ALIGN_LEFT |
696                      gfx::Canvas::TEXT_ALIGN_CENTER |
697                      gfx::Canvas::TEXT_ALIGN_RIGHT));
698
699   // ALIGN_LEFT text with border.
700   label.SetHorizontalAlignment(gfx::ALIGN_LEFT);
701   paint_text.clear();
702   text_bounds.SetRect(0, 0, 0, 0);
703   label.CalculateDrawStringParams(&paint_text, &text_bounds, &flags);
704   EXPECT_EQ(test_text, paint_text);
705   // The text should be right aligned horizontally and centered vertically.
706   EXPECT_EQ(border.left() + extra.width(), text_bounds.x());
707   EXPECT_EQ(border.top() + extra.height() / 2 , text_bounds.y());
708   EXPECT_EQ(required_size.width(), text_bounds.width());
709   EXPECT_EQ(required_size.height(), text_bounds.height());
710   EXPECT_EQ(gfx::Canvas::TEXT_ALIGN_RIGHT,
711             flags & (gfx::Canvas::TEXT_ALIGN_LEFT |
712                      gfx::Canvas::TEXT_ALIGN_CENTER |
713                      gfx::Canvas::TEXT_ALIGN_RIGHT));
714
715   // ALIGN_RIGHT text.
716   label.SetHorizontalAlignment(gfx::ALIGN_RIGHT);
717   paint_text.clear();
718   text_bounds.SetRect(0, 0, 0, 0);
719   label.CalculateDrawStringParams(&paint_text, &text_bounds, &flags);
720   EXPECT_EQ(test_text, paint_text);
721   // The text should be left aligned horizontally and centered vertically.
722   EXPECT_EQ(border.left(), text_bounds.x());
723   EXPECT_EQ(border.top() + extra.height() / 2 , text_bounds.y());
724   EXPECT_EQ(required_size.width(), text_bounds.width());
725   EXPECT_EQ(required_size.height(), text_bounds.height());
726   EXPECT_EQ(gfx::Canvas::TEXT_ALIGN_LEFT,
727             flags & (gfx::Canvas::TEXT_ALIGN_LEFT |
728                      gfx::Canvas::TEXT_ALIGN_CENTER |
729                      gfx::Canvas::TEXT_ALIGN_RIGHT));
730
731   // Reset locale.
732   base::i18n::SetICUDefaultLocale(locale);
733 }
734
735 // On Linux the underlying pango routines require a max height in order to
736 // ellide multiline text. So until that can be resolved, we set all
737 // multiline lables to not ellide in Linux only.
738 TEST(LabelTest, DrawMultiLineStringInRTL) {
739   Label label;
740   label.set_focusable(false);
741
742   // Test for RTL.
743   std::string locale = l10n_util::GetApplicationLocale("");
744   base::i18n::SetICUDefaultLocale("he");
745
746   string16 test_text(ASCIIToUTF16("Another string\nwith returns\n\n!"));
747   label.SetText(test_text);
748   label.SetMultiLine(true);
749   label.SizeToFit(0);
750   gfx::Size extra(50, 10);
751   label.SetBounds(label.x(),
752                   label.y(),
753                   label.width() + extra.width(),
754                   label.height() + extra.height());
755
756   // Do some basic verifications for all three alignments.
757   string16 paint_text;
758   gfx::Rect text_bounds;
759   int flags;
760   label.CalculateDrawStringParams(&paint_text, &text_bounds, &flags);
761   EXPECT_EQ(test_text, paint_text);
762   EXPECT_EQ(extra.width() / 2, text_bounds.x());
763   EXPECT_EQ(extra.height() / 2, text_bounds.y());
764   EXPECT_GT(text_bounds.width(), kMinTextDimension);
765   EXPECT_GT(text_bounds.height(), kMinTextDimension);
766 #if defined(OS_WIN)
767   EXPECT_EQ(gfx::Canvas::MULTI_LINE | gfx::Canvas::TEXT_ALIGN_CENTER, flags);
768 #else
769   EXPECT_EQ(
770       gfx::Canvas::MULTI_LINE |
771       gfx::Canvas::TEXT_ALIGN_CENTER |
772       gfx::Canvas::NO_ELLIPSIS,
773       flags);
774 #endif
775   gfx::Rect center_bounds(text_bounds);
776
777   label.SetHorizontalAlignment(gfx::ALIGN_LEFT);
778   paint_text.clear();
779   text_bounds.SetRect(0, 0, 0, 0);
780   label.CalculateDrawStringParams(&paint_text, &text_bounds, &flags);
781   EXPECT_EQ(test_text, paint_text);
782   EXPECT_EQ(extra.width(), text_bounds.x());
783   EXPECT_EQ(extra.height() / 2, text_bounds.y());
784   EXPECT_GT(text_bounds.width(), kMinTextDimension);
785   EXPECT_GT(text_bounds.height(), kMinTextDimension);
786 #if defined(OS_WIN)
787   EXPECT_EQ(gfx::Canvas::MULTI_LINE | gfx::Canvas::TEXT_ALIGN_RIGHT, flags);
788 #else
789   EXPECT_EQ(
790       gfx::Canvas::MULTI_LINE |
791       gfx::Canvas::TEXT_ALIGN_RIGHT |
792       gfx::Canvas::NO_ELLIPSIS,
793       flags);
794 #endif
795
796   label.SetHorizontalAlignment(gfx::ALIGN_RIGHT);
797   paint_text.clear();
798   text_bounds.SetRect(0, 0, 0, 0);
799   label.CalculateDrawStringParams(&paint_text, &text_bounds, &flags);
800   EXPECT_EQ(test_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 #if defined(OS_WIN)
806   EXPECT_EQ(gfx::Canvas::MULTI_LINE | gfx::Canvas::TEXT_ALIGN_LEFT, flags);
807 #else
808   EXPECT_EQ(
809       gfx::Canvas::MULTI_LINE |
810       gfx::Canvas::TEXT_ALIGN_LEFT |
811       gfx::Canvas::NO_ELLIPSIS,
812       flags);
813 #endif
814
815   // Test multiline drawing with a border.
816   gfx::Insets border(19, 92, 23, 2);
817   label.set_border(Border::CreateEmptyBorder(border.top(),
818                                              border.left(),
819                                              border.bottom(),
820                                              border.right()));
821   label.SizeToFit(0);
822   label.SetBounds(label.x(),
823                   label.y(),
824                   label.width() + extra.width(),
825                   label.height() + extra.height());
826
827   label.SetHorizontalAlignment(gfx::ALIGN_CENTER);
828   paint_text.clear();
829   text_bounds.SetRect(0, 0, 0, 0);
830   label.CalculateDrawStringParams(&paint_text, &text_bounds, &flags);
831   EXPECT_EQ(test_text, paint_text);
832   EXPECT_EQ(border.left() + extra.width() / 2, text_bounds.x());
833   EXPECT_EQ(border.top() + extra.height() / 2, text_bounds.y());
834   EXPECT_EQ(center_bounds.width(), text_bounds.width());
835   EXPECT_EQ(center_bounds.height(), text_bounds.height());
836 #if defined(OS_WIN)
837   EXPECT_EQ(gfx::Canvas::MULTI_LINE | gfx::Canvas::TEXT_ALIGN_CENTER, flags);
838 #else
839   EXPECT_EQ(
840       gfx::Canvas::MULTI_LINE |
841       gfx::Canvas::TEXT_ALIGN_CENTER |
842       gfx::Canvas::NO_ELLIPSIS,
843       flags);
844 #endif
845
846   label.SetHorizontalAlignment(gfx::ALIGN_LEFT);
847   paint_text.clear();
848   text_bounds.SetRect(0, 0, 0, 0);
849   label.CalculateDrawStringParams(&paint_text, &text_bounds, &flags);
850   EXPECT_EQ(test_text, paint_text);
851   EXPECT_EQ(border.left() + extra.width(), text_bounds.x());
852   EXPECT_EQ(border.top() + extra.height() / 2, text_bounds.y());
853   EXPECT_EQ(center_bounds.width(), text_bounds.width());
854   EXPECT_EQ(center_bounds.height(), text_bounds.height());
855 #if defined(OS_WIN)
856   EXPECT_EQ(gfx::Canvas::MULTI_LINE | gfx::Canvas::TEXT_ALIGN_RIGHT, flags);
857 #else
858   EXPECT_EQ(
859       gfx::Canvas::MULTI_LINE |
860       gfx::Canvas::TEXT_ALIGN_RIGHT |
861       gfx::Canvas::NO_ELLIPSIS,
862       flags);
863 #endif
864
865   label.SetHorizontalAlignment(gfx::ALIGN_RIGHT);
866   paint_text.clear();
867   text_bounds.SetRect(0, 0, 0, 0);
868   label.CalculateDrawStringParams(&paint_text, &text_bounds, &flags);
869   EXPECT_EQ(test_text, paint_text);
870   EXPECT_EQ(border.left(), text_bounds.x());
871   EXPECT_EQ(border.top() + extra.height() / 2, text_bounds.y());
872   EXPECT_EQ(center_bounds.width(), text_bounds.width());
873   EXPECT_EQ(center_bounds.height(), text_bounds.height());
874 #if defined(OS_WIN)
875   EXPECT_EQ(gfx::Canvas::MULTI_LINE | gfx::Canvas::TEXT_ALIGN_LEFT, flags);
876 #else
877   EXPECT_EQ(
878       gfx::Canvas::MULTI_LINE |
879       gfx::Canvas::TEXT_ALIGN_LEFT |
880       gfx::Canvas::NO_ELLIPSIS,
881       flags);
882 #endif
883
884   // Reset Locale
885   base::i18n::SetICUDefaultLocale(locale);
886 }
887
888 // Check that we disable subpixel rendering when a transparent background is
889 // being used.
890 TEST(LabelTest, DisableSubpixelRendering) {
891   Label label;
892   label.SetBackgroundColor(SK_ColorWHITE);
893   EXPECT_EQ(
894       0, label.ComputeDrawStringFlags() & gfx::Canvas::NO_SUBPIXEL_RENDERING);
895
896   label.SetBackgroundColor(SkColorSetARGB(64, 255, 255, 255));
897   EXPECT_EQ(
898       gfx::Canvas::NO_SUBPIXEL_RENDERING,
899       label.ComputeDrawStringFlags() & gfx::Canvas::NO_SUBPIXEL_RENDERING);
900 }
901
902 // Check that labels support GetTooltipHandlerForPoint.
903 TEST(LabelTest, GetTooltipHandlerForPoint) {
904   Label label;
905   label.SetText(
906       ASCIIToUTF16("A string that's long enough to exceed the bounds"));
907   label.SetBounds(0, 0, 10, 10);
908   // There's a default tooltip if the text is too big to fit.
909   EXPECT_EQ(&label, label.GetTooltipHandlerForPoint(gfx::Point(2, 2)));
910
911   // If there's no default tooltip, this should return NULL.
912   label.SetBounds(0, 0, 500, 50);
913   EXPECT_FALSE(label.GetTooltipHandlerForPoint(gfx::Point(2, 2)));
914
915   label.SetTooltipText(ASCIIToUTF16("a tooltip"));
916   // If the point hits the label, and tooltip is set, the label should be
917   // returned as its tooltip handler.
918   EXPECT_EQ(&label, label.GetTooltipHandlerForPoint(gfx::Point(2, 2)));
919
920   // Additionally, GetTooltipHandlerForPoint should verify that the label
921   // actually contains the point.
922   EXPECT_FALSE(label.GetTooltipHandlerForPoint(gfx::Point(2, 51)));
923   EXPECT_FALSE(label.GetTooltipHandlerForPoint(gfx::Point(-1, 20)));
924
925   // GetTooltipHandlerForPoint works should work in child bounds.
926   label.SetBounds(2, 2, 10, 10);
927   EXPECT_EQ(&label, label.GetTooltipHandlerForPoint(gfx::Point(1, 5)));
928   EXPECT_FALSE(label.GetTooltipHandlerForPoint(gfx::Point(3, 11)));
929 }
930
931 }  // namespace views