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