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