OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/gfx/render_text.h" | 5 #include "ui/gfx/render_text.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/format_macros.h" | 9 #include "base/format_macros.h" |
10 #include "base/i18n/break_iterator.h" | 10 #include "base/i18n/break_iterator.h" |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 | 243 |
244 TEST_F(RenderTextTest, ObscuredText) { | 244 TEST_F(RenderTextTest, ObscuredText) { |
245 const base::string16 seuss = ASCIIToUTF16("hop on pop"); | 245 const base::string16 seuss = ASCIIToUTF16("hop on pop"); |
246 const base::string16 no_seuss = ASCIIToUTF16("**********"); | 246 const base::string16 no_seuss = ASCIIToUTF16("**********"); |
247 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); | 247 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); |
248 | 248 |
249 // GetLayoutText() returns asterisks when the obscured bit is set. | 249 // GetLayoutText() returns asterisks when the obscured bit is set. |
250 render_text->SetText(seuss); | 250 render_text->SetText(seuss); |
251 render_text->SetObscured(true); | 251 render_text->SetObscured(true); |
252 EXPECT_EQ(seuss, render_text->text()); | 252 EXPECT_EQ(seuss, render_text->text()); |
253 EXPECT_EQ(no_seuss, render_text->GetLayoutText()); | 253 EXPECT_EQ(no_seuss, render_text->GetDisplayText()); |
254 render_text->SetObscured(false); | 254 render_text->SetObscured(false); |
255 EXPECT_EQ(seuss, render_text->text()); | 255 EXPECT_EQ(seuss, render_text->text()); |
256 EXPECT_EQ(seuss, render_text->GetLayoutText()); | 256 EXPECT_EQ(seuss, render_text->GetDisplayText()); |
257 | 257 |
258 render_text->SetObscured(true); | 258 render_text->SetObscured(true); |
259 | 259 |
260 // Surrogate pairs are counted as one code point. | 260 // Surrogate pairs are counted as one code point. |
261 const base::char16 invalid_surrogates[] = {0xDC00, 0xD800, 0}; | 261 const base::char16 invalid_surrogates[] = {0xDC00, 0xD800, 0}; |
262 render_text->SetText(invalid_surrogates); | 262 render_text->SetText(invalid_surrogates); |
263 EXPECT_EQ(ASCIIToUTF16("**"), render_text->GetLayoutText()); | 263 EXPECT_EQ(ASCIIToUTF16("**"), render_text->GetDisplayText()); |
264 const base::char16 valid_surrogates[] = {0xD800, 0xDC00, 0}; | 264 const base::char16 valid_surrogates[] = {0xD800, 0xDC00, 0}; |
265 render_text->SetText(valid_surrogates); | 265 render_text->SetText(valid_surrogates); |
266 EXPECT_EQ(ASCIIToUTF16("*"), render_text->GetLayoutText()); | 266 EXPECT_EQ(ASCIIToUTF16("*"), render_text->GetDisplayText()); |
267 EXPECT_EQ(0U, render_text->cursor_position()); | 267 EXPECT_EQ(0U, render_text->cursor_position()); |
268 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, false); | 268 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, false); |
269 EXPECT_EQ(2U, render_text->cursor_position()); | 269 EXPECT_EQ(2U, render_text->cursor_position()); |
270 | 270 |
271 // Test index conversion and cursor validity with a valid surrogate pair. | 271 // Test index conversion and cursor validity with a valid surrogate pair. |
272 EXPECT_EQ(0U, render_text->TextIndexToLayoutIndex(0U)); | 272 EXPECT_EQ(0U, render_text->TextIndexToDisplayIndex(0U)); |
273 EXPECT_EQ(1U, render_text->TextIndexToLayoutIndex(1U)); | 273 EXPECT_EQ(1U, render_text->TextIndexToDisplayIndex(1U)); |
274 EXPECT_EQ(1U, render_text->TextIndexToLayoutIndex(2U)); | 274 EXPECT_EQ(1U, render_text->TextIndexToDisplayIndex(2U)); |
275 EXPECT_EQ(0U, render_text->LayoutIndexToTextIndex(0U)); | 275 EXPECT_EQ(0U, render_text->DisplayIndexToTextIndex(0U)); |
276 EXPECT_EQ(2U, render_text->LayoutIndexToTextIndex(1U)); | 276 EXPECT_EQ(2U, render_text->DisplayIndexToTextIndex(1U)); |
277 EXPECT_TRUE(render_text->IsValidCursorIndex(0U)); | 277 EXPECT_TRUE(render_text->IsValidCursorIndex(0U)); |
278 EXPECT_FALSE(render_text->IsValidCursorIndex(1U)); | 278 EXPECT_FALSE(render_text->IsValidCursorIndex(1U)); |
279 EXPECT_TRUE(render_text->IsValidCursorIndex(2U)); | 279 EXPECT_TRUE(render_text->IsValidCursorIndex(2U)); |
280 | 280 |
281 // FindCursorPosition() should not return positions between a surrogate pair. | 281 // FindCursorPosition() should not return positions between a surrogate pair. |
282 render_text->SetDisplayRect(Rect(0, 0, 20, 20)); | 282 render_text->SetDisplayRect(Rect(0, 0, 20, 20)); |
283 EXPECT_EQ(render_text->FindCursorPosition(Point(0, 0)).caret_pos(), 0U); | 283 EXPECT_EQ(render_text->FindCursorPosition(Point(0, 0)).caret_pos(), 0U); |
284 EXPECT_EQ(render_text->FindCursorPosition(Point(20, 0)).caret_pos(), 2U); | 284 EXPECT_EQ(render_text->FindCursorPosition(Point(20, 0)).caret_pos(), 2U); |
285 for (int x = -1; x <= 20; ++x) { | 285 for (int x = -1; x <= 20; ++x) { |
286 SelectionModel selection = render_text->FindCursorPosition(Point(x, 0)); | 286 SelectionModel selection = render_text->FindCursorPosition(Point(x, 0)); |
(...skipping 18 matching lines...) Expand all Loading... |
305 } | 305 } |
306 | 306 |
307 TEST_F(RenderTextTest, RevealObscuredText) { | 307 TEST_F(RenderTextTest, RevealObscuredText) { |
308 const base::string16 seuss = ASCIIToUTF16("hop on pop"); | 308 const base::string16 seuss = ASCIIToUTF16("hop on pop"); |
309 const base::string16 no_seuss = ASCIIToUTF16("**********"); | 309 const base::string16 no_seuss = ASCIIToUTF16("**********"); |
310 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); | 310 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); |
311 | 311 |
312 render_text->SetText(seuss); | 312 render_text->SetText(seuss); |
313 render_text->SetObscured(true); | 313 render_text->SetObscured(true); |
314 EXPECT_EQ(seuss, render_text->text()); | 314 EXPECT_EQ(seuss, render_text->text()); |
315 EXPECT_EQ(no_seuss, render_text->GetLayoutText()); | 315 EXPECT_EQ(no_seuss, render_text->GetDisplayText()); |
316 | 316 |
317 // Valid reveal index and new revealed index clears previous one. | 317 // Valid reveal index and new revealed index clears previous one. |
318 render_text->RenderText::SetObscuredRevealIndex(0); | 318 render_text->RenderText::SetObscuredRevealIndex(0); |
319 EXPECT_EQ(ASCIIToUTF16("h*********"), render_text->GetLayoutText()); | 319 EXPECT_EQ(ASCIIToUTF16("h*********"), render_text->GetDisplayText()); |
320 render_text->RenderText::SetObscuredRevealIndex(1); | 320 render_text->RenderText::SetObscuredRevealIndex(1); |
321 EXPECT_EQ(ASCIIToUTF16("*o********"), render_text->GetLayoutText()); | 321 EXPECT_EQ(ASCIIToUTF16("*o********"), render_text->GetDisplayText()); |
322 render_text->RenderText::SetObscuredRevealIndex(2); | 322 render_text->RenderText::SetObscuredRevealIndex(2); |
323 EXPECT_EQ(ASCIIToUTF16("**p*******"), render_text->GetLayoutText()); | 323 EXPECT_EQ(ASCIIToUTF16("**p*******"), render_text->GetDisplayText()); |
324 | 324 |
325 // Invalid reveal index. | 325 // Invalid reveal index. |
326 render_text->RenderText::SetObscuredRevealIndex(-1); | 326 render_text->RenderText::SetObscuredRevealIndex(-1); |
327 EXPECT_EQ(no_seuss, render_text->GetLayoutText()); | 327 EXPECT_EQ(no_seuss, render_text->GetDisplayText()); |
328 render_text->RenderText::SetObscuredRevealIndex(seuss.length() + 1); | 328 render_text->RenderText::SetObscuredRevealIndex(seuss.length() + 1); |
329 EXPECT_EQ(no_seuss, render_text->GetLayoutText()); | 329 EXPECT_EQ(no_seuss, render_text->GetDisplayText()); |
330 | 330 |
331 // SetObscured clears the revealed index. | 331 // SetObscured clears the revealed index. |
332 render_text->RenderText::SetObscuredRevealIndex(0); | 332 render_text->RenderText::SetObscuredRevealIndex(0); |
333 EXPECT_EQ(ASCIIToUTF16("h*********"), render_text->GetLayoutText()); | 333 EXPECT_EQ(ASCIIToUTF16("h*********"), render_text->GetDisplayText()); |
334 render_text->SetObscured(false); | 334 render_text->SetObscured(false); |
335 EXPECT_EQ(seuss, render_text->GetLayoutText()); | 335 EXPECT_EQ(seuss, render_text->GetDisplayText()); |
336 render_text->SetObscured(true); | 336 render_text->SetObscured(true); |
337 EXPECT_EQ(no_seuss, render_text->GetLayoutText()); | 337 EXPECT_EQ(no_seuss, render_text->GetDisplayText()); |
338 | 338 |
339 // SetText clears the revealed index. | 339 // SetText clears the revealed index. |
340 render_text->SetText(ASCIIToUTF16("new")); | 340 render_text->SetText(ASCIIToUTF16("new")); |
341 EXPECT_EQ(ASCIIToUTF16("***"), render_text->GetLayoutText()); | 341 EXPECT_EQ(ASCIIToUTF16("***"), render_text->GetDisplayText()); |
342 render_text->RenderText::SetObscuredRevealIndex(2); | 342 render_text->RenderText::SetObscuredRevealIndex(2); |
343 EXPECT_EQ(ASCIIToUTF16("**w"), render_text->GetLayoutText()); | 343 EXPECT_EQ(ASCIIToUTF16("**w"), render_text->GetDisplayText()); |
344 render_text->SetText(ASCIIToUTF16("new longer")); | 344 render_text->SetText(ASCIIToUTF16("new longer")); |
345 EXPECT_EQ(ASCIIToUTF16("**********"), render_text->GetLayoutText()); | 345 EXPECT_EQ(ASCIIToUTF16("**********"), render_text->GetDisplayText()); |
346 | 346 |
347 // Text with invalid surrogates. | 347 // Text with invalid surrogates. |
348 const base::char16 invalid_surrogates[] = {0xDC00, 0xD800, 'h', 'o', 'p', 0}; | 348 const base::char16 invalid_surrogates[] = {0xDC00, 0xD800, 'h', 'o', 'p', 0}; |
349 render_text->SetText(invalid_surrogates); | 349 render_text->SetText(invalid_surrogates); |
350 EXPECT_EQ(ASCIIToUTF16("*****"), render_text->GetLayoutText()); | 350 EXPECT_EQ(ASCIIToUTF16("*****"), render_text->GetDisplayText()); |
351 render_text->RenderText::SetObscuredRevealIndex(0); | 351 render_text->RenderText::SetObscuredRevealIndex(0); |
352 const base::char16 invalid_expect_0[] = {0xDC00, '*', '*', '*', '*', 0}; | 352 const base::char16 invalid_expect_0[] = {0xDC00, '*', '*', '*', '*', 0}; |
353 EXPECT_EQ(invalid_expect_0, render_text->GetLayoutText()); | 353 EXPECT_EQ(invalid_expect_0, render_text->GetDisplayText()); |
354 render_text->RenderText::SetObscuredRevealIndex(1); | 354 render_text->RenderText::SetObscuredRevealIndex(1); |
355 const base::char16 invalid_expect_1[] = {'*', 0xD800, '*', '*', '*', 0}; | 355 const base::char16 invalid_expect_1[] = {'*', 0xD800, '*', '*', '*', 0}; |
356 EXPECT_EQ(invalid_expect_1, render_text->GetLayoutText()); | 356 EXPECT_EQ(invalid_expect_1, render_text->GetDisplayText()); |
357 render_text->RenderText::SetObscuredRevealIndex(2); | 357 render_text->RenderText::SetObscuredRevealIndex(2); |
358 EXPECT_EQ(ASCIIToUTF16("**h**"), render_text->GetLayoutText()); | 358 EXPECT_EQ(ASCIIToUTF16("**h**"), render_text->GetDisplayText()); |
359 | 359 |
360 // Text with valid surrogates before and after the reveal index. | 360 // Text with valid surrogates before and after the reveal index. |
361 const base::char16 valid_surrogates[] = | 361 const base::char16 valid_surrogates[] = |
362 {0xD800, 0xDC00, 'h', 'o', 'p', 0xD800, 0xDC00, 0}; | 362 {0xD800, 0xDC00, 'h', 'o', 'p', 0xD800, 0xDC00, 0}; |
363 render_text->SetText(valid_surrogates); | 363 render_text->SetText(valid_surrogates); |
364 EXPECT_EQ(ASCIIToUTF16("*****"), render_text->GetLayoutText()); | 364 EXPECT_EQ(ASCIIToUTF16("*****"), render_text->GetDisplayText()); |
365 render_text->RenderText::SetObscuredRevealIndex(0); | 365 render_text->RenderText::SetObscuredRevealIndex(0); |
366 const base::char16 valid_expect_0_and_1[] = | 366 const base::char16 valid_expect_0_and_1[] = |
367 {0xD800, 0xDC00, '*', '*', '*', '*', 0}; | 367 {0xD800, 0xDC00, '*', '*', '*', '*', 0}; |
368 EXPECT_EQ(valid_expect_0_and_1, render_text->GetLayoutText()); | 368 EXPECT_EQ(valid_expect_0_and_1, render_text->GetDisplayText()); |
369 render_text->RenderText::SetObscuredRevealIndex(1); | 369 render_text->RenderText::SetObscuredRevealIndex(1); |
370 EXPECT_EQ(valid_expect_0_and_1, render_text->GetLayoutText()); | 370 EXPECT_EQ(valid_expect_0_and_1, render_text->GetDisplayText()); |
371 render_text->RenderText::SetObscuredRevealIndex(2); | 371 render_text->RenderText::SetObscuredRevealIndex(2); |
372 EXPECT_EQ(ASCIIToUTF16("*h***"), render_text->GetLayoutText()); | 372 EXPECT_EQ(ASCIIToUTF16("*h***"), render_text->GetDisplayText()); |
373 render_text->RenderText::SetObscuredRevealIndex(5); | 373 render_text->RenderText::SetObscuredRevealIndex(5); |
374 const base::char16 valid_expect_5_and_6[] = | 374 const base::char16 valid_expect_5_and_6[] = |
375 {'*', '*', '*', '*', 0xD800, 0xDC00, 0}; | 375 {'*', '*', '*', '*', 0xD800, 0xDC00, 0}; |
376 EXPECT_EQ(valid_expect_5_and_6, render_text->GetLayoutText()); | 376 EXPECT_EQ(valid_expect_5_and_6, render_text->GetDisplayText()); |
377 render_text->RenderText::SetObscuredRevealIndex(6); | 377 render_text->RenderText::SetObscuredRevealIndex(6); |
378 EXPECT_EQ(valid_expect_5_and_6, render_text->GetLayoutText()); | 378 EXPECT_EQ(valid_expect_5_and_6, render_text->GetDisplayText()); |
379 } | 379 } |
380 | 380 |
381 TEST_F(RenderTextTest, ElidedText) { | 381 TEST_F(RenderTextTest, ElidedText) { |
382 // TODO(skanuj) : Add more test cases for following | 382 // TODO(skanuj) : Add more test cases for following |
383 // - RenderText styles. | 383 // - RenderText styles. |
384 // - Cross interaction of truncate, elide and obscure. | 384 // - Cross interaction of truncate, elide and obscure. |
385 // - ElideText tests from text_elider.cc. | 385 // - ElideText tests from text_elider.cc. |
386 struct { | 386 struct { |
387 const wchar_t* text; | 387 const wchar_t* text; |
388 const wchar_t* layout_text; | 388 const wchar_t* display_text; |
389 const bool elision_expected; | 389 const bool elision_expected; |
390 } cases[] = { | 390 } cases[] = { |
391 // Strings shorter than the elision width should be laid out in full. | 391 // Strings shorter than the elision width should be laid out in full. |
392 { L"", L"" , false }, | 392 { L"", L"" , false }, |
393 { L"M", L"" , false }, | 393 { L"M", L"" , false }, |
394 { L" . ", L" . " , false }, | 394 { L" . ", L" . " , false }, |
395 { kWeak, kWeak , false }, | 395 { kWeak, kWeak , false }, |
396 { kLtr, kLtr , false }, | 396 { kLtr, kLtr , false }, |
397 { kLtrRtl, kLtrRtl , false }, | 397 { kLtrRtl, kLtrRtl , false }, |
398 { kLtrRtlLtr, kLtrRtlLtr, false }, | 398 { kLtrRtlLtr, kLtrRtlLtr, false }, |
(...skipping 23 matching lines...) Expand all Loading... |
422 | 422 |
423 scoped_ptr<RenderText> expected_render_text(RenderText::CreateInstance()); | 423 scoped_ptr<RenderText> expected_render_text(RenderText::CreateInstance()); |
424 expected_render_text->SetFontList(FontList("serif, Sans serif, 12px")); | 424 expected_render_text->SetFontList(FontList("serif, Sans serif, 12px")); |
425 expected_render_text->SetDisplayRect(Rect(0, 0, 9999, 100)); | 425 expected_render_text->SetDisplayRect(Rect(0, 0, 9999, 100)); |
426 | 426 |
427 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); | 427 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); |
428 render_text->SetFontList(FontList("serif, Sans serif, 12px")); | 428 render_text->SetFontList(FontList("serif, Sans serif, 12px")); |
429 render_text->SetElideBehavior(ELIDE_TAIL); | 429 render_text->SetElideBehavior(ELIDE_TAIL); |
430 | 430 |
431 for (size_t i = 0; i < arraysize(cases); i++) { | 431 for (size_t i = 0; i < arraysize(cases); i++) { |
| 432 SCOPED_TRACE(base::StringPrintf("Testing cases[%" PRIuS "] '%ls'", i, |
| 433 cases[i].text)); |
| 434 |
432 // Compute expected width | 435 // Compute expected width |
433 expected_render_text->SetText(WideToUTF16(cases[i].layout_text)); | 436 expected_render_text->SetText(WideToUTF16(cases[i].display_text)); |
434 int expected_width = expected_render_text->GetContentWidth(); | 437 int expected_width = expected_render_text->GetContentWidth(); |
435 | 438 |
436 base::string16 input = WideToUTF16(cases[i].text); | 439 base::string16 input = WideToUTF16(cases[i].text); |
437 // Extend the input text to ensure that it is wider than the layout_text, | 440 // Extend the input text to ensure that it is wider than the display_text, |
438 // and so it will get elided. | 441 // and so it will get elided. |
439 if (cases[i].elision_expected) | 442 if (cases[i].elision_expected) |
440 input.append(WideToUTF16(L" MMMMMMMMMMM")); | 443 input.append(WideToUTF16(L" MMMMMMMMMMM")); |
441 | |
442 render_text->SetText(input); | 444 render_text->SetText(input); |
443 render_text->SetDisplayRect(Rect(0, 0, expected_width, 100)); | 445 render_text->SetDisplayRect(Rect(0, 0, expected_width, 100)); |
444 EXPECT_EQ(input, render_text->text()) | 446 EXPECT_EQ(input, render_text->text()); |
445 << "->For case " << i << ": " << cases[i].text << "\n"; | 447 EXPECT_EQ(WideToUTF16(cases[i].display_text), |
446 EXPECT_EQ(WideToUTF16(cases[i].layout_text), render_text->GetLayoutText()) | 448 render_text->GetDisplayText()); |
447 << "->For case " << i << ": " << cases[i].text << "\n"; | |
448 expected_render_text->SetText(base::string16()); | 449 expected_render_text->SetText(base::string16()); |
449 } | 450 } |
450 } | 451 } |
451 | 452 |
452 TEST_F(RenderTextTest, ElidedObscuredText) { | 453 TEST_F(RenderTextTest, ElidedObscuredText) { |
453 scoped_ptr<RenderText> expected_render_text(RenderText::CreateInstance()); | 454 scoped_ptr<RenderText> expected_render_text(RenderText::CreateInstance()); |
454 expected_render_text->SetFontList(FontList("serif, Sans serif, 12px")); | 455 expected_render_text->SetFontList(FontList("serif, Sans serif, 12px")); |
455 expected_render_text->SetDisplayRect(Rect(0, 0, 9999, 100)); | 456 expected_render_text->SetDisplayRect(Rect(0, 0, 9999, 100)); |
456 expected_render_text->SetText(WideToUTF16(L"**\x2026")); | 457 expected_render_text->SetText(WideToUTF16(L"**\x2026")); |
457 | 458 |
458 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); | 459 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); |
459 render_text->SetFontList(FontList("serif, Sans serif, 12px")); | 460 render_text->SetFontList(FontList("serif, Sans serif, 12px")); |
460 render_text->SetElideBehavior(ELIDE_TAIL); | 461 render_text->SetElideBehavior(ELIDE_TAIL); |
461 render_text->SetDisplayRect( | 462 render_text->SetDisplayRect( |
462 Rect(0, 0, expected_render_text->GetContentWidth(), 100)); | 463 Rect(0, 0, expected_render_text->GetContentWidth(), 100)); |
463 render_text->SetObscured(true); | 464 render_text->SetObscured(true); |
464 render_text->SetText(WideToUTF16(L"abcdef")); | 465 render_text->SetText(WideToUTF16(L"abcdef")); |
465 EXPECT_EQ(WideToUTF16(L"abcdef"), render_text->text()); | 466 EXPECT_EQ(WideToUTF16(L"abcdef"), render_text->text()); |
466 EXPECT_EQ(WideToUTF16(L"**\x2026"), render_text->GetLayoutText()); | 467 EXPECT_EQ(WideToUTF16(L"**\x2026"), render_text->GetDisplayText()); |
467 } | 468 } |
468 | 469 |
469 TEST_F(RenderTextTest, TruncatedText) { | 470 TEST_F(RenderTextTest, TruncatedText) { |
470 struct { | 471 struct { |
471 const wchar_t* text; | 472 const wchar_t* text; |
472 const wchar_t* layout_text; | 473 const wchar_t* display_text; |
473 } cases[] = { | 474 } cases[] = { |
474 // Strings shorter than the truncation length should be laid out in full. | 475 // Strings shorter than the truncation length should be laid out in full. |
475 { L"", L"" }, | 476 { L"", L"" }, |
476 { kWeak, kWeak }, | 477 { kWeak, kWeak }, |
477 { kLtr, kLtr }, | 478 { kLtr, kLtr }, |
478 { kLtrRtl, kLtrRtl }, | 479 { kLtrRtl, kLtrRtl }, |
479 { kLtrRtlLtr, kLtrRtlLtr }, | 480 { kLtrRtlLtr, kLtrRtlLtr }, |
480 { kRtl, kRtl }, | 481 { kRtl, kRtl }, |
481 { kRtlLtr, kRtlLtr }, | 482 { kRtlLtr, kRtlLtr }, |
482 { kRtlLtrRtl, kRtlLtrRtl }, | 483 { kRtlLtrRtl, kRtlLtrRtl }, |
(...skipping 16 matching lines...) Expand all Loading... |
499 { L"0123\x05e9\x05bc\x05c1\x05b8", L"0123\x2026" }, | 500 { L"0123\x05e9\x05bc\x05c1\x05b8", L"0123\x2026" }, |
500 { L"01234\x05e9\x05bc\x05c1\x05b8", L"0123\x2026" }, | 501 { L"01234\x05e9\x05bc\x05c1\x05b8", L"0123\x2026" }, |
501 { L"012\xF0\x9D\x84\x9E", L"012\xF0\x2026" }, | 502 { L"012\xF0\x9D\x84\x9E", L"012\xF0\x2026" }, |
502 }; | 503 }; |
503 | 504 |
504 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); | 505 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); |
505 render_text->set_truncate_length(5); | 506 render_text->set_truncate_length(5); |
506 for (size_t i = 0; i < arraysize(cases); i++) { | 507 for (size_t i = 0; i < arraysize(cases); i++) { |
507 render_text->SetText(WideToUTF16(cases[i].text)); | 508 render_text->SetText(WideToUTF16(cases[i].text)); |
508 EXPECT_EQ(WideToUTF16(cases[i].text), render_text->text()); | 509 EXPECT_EQ(WideToUTF16(cases[i].text), render_text->text()); |
509 EXPECT_EQ(WideToUTF16(cases[i].layout_text), render_text->GetLayoutText()) | 510 EXPECT_EQ(WideToUTF16(cases[i].display_text), render_text->GetDisplayText()) |
510 << "For case " << i << ": " << cases[i].text; | 511 << "For case " << i << ": " << cases[i].text; |
511 } | 512 } |
512 } | 513 } |
513 | 514 |
514 TEST_F(RenderTextTest, TruncatedObscuredText) { | 515 TEST_F(RenderTextTest, TruncatedObscuredText) { |
515 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); | 516 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); |
516 render_text->set_truncate_length(3); | 517 render_text->set_truncate_length(3); |
517 render_text->SetObscured(true); | 518 render_text->SetObscured(true); |
518 render_text->SetText(WideToUTF16(L"abcdef")); | 519 render_text->SetText(WideToUTF16(L"abcdef")); |
519 EXPECT_EQ(WideToUTF16(L"abcdef"), render_text->text()); | 520 EXPECT_EQ(WideToUTF16(L"abcdef"), render_text->text()); |
520 EXPECT_EQ(WideToUTF16(L"**\x2026"), render_text->GetLayoutText()); | 521 EXPECT_EQ(WideToUTF16(L"**\x2026"), render_text->GetDisplayText()); |
521 } | 522 } |
522 | 523 |
523 TEST_F(RenderTextTest, TruncatedCursorMovementLTR) { | 524 TEST_F(RenderTextTest, TruncatedCursorMovementLTR) { |
524 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); | 525 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); |
525 render_text->set_truncate_length(2); | 526 render_text->set_truncate_length(2); |
526 render_text->SetText(WideToUTF16(L"abcd")); | 527 render_text->SetText(WideToUTF16(L"abcd")); |
527 | 528 |
528 EXPECT_EQ(SelectionModel(0, CURSOR_BACKWARD), render_text->selection_model()); | 529 EXPECT_EQ(SelectionModel(0, CURSOR_BACKWARD), render_text->selection_model()); |
529 render_text->MoveCursor(LINE_BREAK, CURSOR_RIGHT, false); | 530 render_text->MoveCursor(LINE_BREAK, CURSOR_RIGHT, false); |
530 EXPECT_EQ(SelectionModel(4, CURSOR_FORWARD), render_text->selection_model()); | 531 EXPECT_EQ(SelectionModel(4, CURSOR_FORWARD), render_text->selection_model()); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
569 | 570 |
570 expected.clear(); | 571 expected.clear(); |
571 expected.push_back(SelectionModel(4, CURSOR_FORWARD)); | 572 expected.push_back(SelectionModel(4, CURSOR_FORWARD)); |
572 // The cursor hops over the elided text to preceeding text. | 573 // The cursor hops over the elided text to preceeding text. |
573 expected.push_back(SelectionModel(1, CURSOR_FORWARD)); | 574 expected.push_back(SelectionModel(1, CURSOR_FORWARD)); |
574 expected.push_back(SelectionModel(0, CURSOR_FORWARD)); | 575 expected.push_back(SelectionModel(0, CURSOR_FORWARD)); |
575 expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); | 576 expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); |
576 RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_RIGHT); | 577 RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_RIGHT); |
577 } | 578 } |
578 | 579 |
579 TEST_F(RenderTextTest, GetTextDirection) { | 580 TEST_F(RenderTextTest, GetDisplayTextDirection) { |
580 struct { | 581 struct { |
581 const wchar_t* text; | 582 const wchar_t* text; |
582 const base::i18n::TextDirection text_direction; | 583 const base::i18n::TextDirection text_direction; |
583 } cases[] = { | 584 } cases[] = { |
584 // Blank strings and those with no/weak directionality default to LTR. | 585 // Blank strings and those with no/weak directionality default to LTR. |
585 { L"", base::i18n::LEFT_TO_RIGHT }, | 586 { L"", base::i18n::LEFT_TO_RIGHT }, |
586 { kWeak, base::i18n::LEFT_TO_RIGHT }, | 587 { kWeak, base::i18n::LEFT_TO_RIGHT }, |
587 // Strings that begin with strong LTR characters. | 588 // Strings that begin with strong LTR characters. |
588 { kLtr, base::i18n::LEFT_TO_RIGHT }, | 589 { kLtr, base::i18n::LEFT_TO_RIGHT }, |
589 { kLtrRtl, base::i18n::LEFT_TO_RIGHT }, | 590 { kLtrRtl, base::i18n::LEFT_TO_RIGHT }, |
(...skipping 10 matching lines...) Expand all Loading... |
600 for (size_t i = 0; i < 2; ++i) { | 601 for (size_t i = 0; i < 2; ++i) { |
601 // Toggle the application default text direction (to try each direction). | 602 // Toggle the application default text direction (to try each direction). |
602 SetRTL(!base::i18n::IsRTL()); | 603 SetRTL(!base::i18n::IsRTL()); |
603 const base::i18n::TextDirection ui_direction = base::i18n::IsRTL() ? | 604 const base::i18n::TextDirection ui_direction = base::i18n::IsRTL() ? |
604 base::i18n::RIGHT_TO_LEFT : base::i18n::LEFT_TO_RIGHT; | 605 base::i18n::RIGHT_TO_LEFT : base::i18n::LEFT_TO_RIGHT; |
605 | 606 |
606 // Ensure that directionality modes yield the correct text directions. | 607 // Ensure that directionality modes yield the correct text directions. |
607 for (size_t j = 0; j < arraysize(cases); j++) { | 608 for (size_t j = 0; j < arraysize(cases); j++) { |
608 render_text->SetText(WideToUTF16(cases[j].text)); | 609 render_text->SetText(WideToUTF16(cases[j].text)); |
609 render_text->SetDirectionalityMode(DIRECTIONALITY_FROM_TEXT); | 610 render_text->SetDirectionalityMode(DIRECTIONALITY_FROM_TEXT); |
610 EXPECT_EQ(render_text->GetTextDirection(), cases[j].text_direction); | 611 EXPECT_EQ(render_text->GetDisplayTextDirection(),cases[j].text_direction); |
611 render_text->SetDirectionalityMode(DIRECTIONALITY_FROM_UI); | 612 render_text->SetDirectionalityMode(DIRECTIONALITY_FROM_UI); |
612 EXPECT_EQ(render_text->GetTextDirection(), ui_direction); | 613 EXPECT_EQ(render_text->GetDisplayTextDirection(), ui_direction); |
613 render_text->SetDirectionalityMode(DIRECTIONALITY_FORCE_LTR); | 614 render_text->SetDirectionalityMode(DIRECTIONALITY_FORCE_LTR); |
614 EXPECT_EQ(render_text->GetTextDirection(), base::i18n::LEFT_TO_RIGHT); | 615 EXPECT_EQ(render_text->GetDisplayTextDirection(), |
| 616 base::i18n::LEFT_TO_RIGHT); |
615 render_text->SetDirectionalityMode(DIRECTIONALITY_FORCE_RTL); | 617 render_text->SetDirectionalityMode(DIRECTIONALITY_FORCE_RTL); |
616 EXPECT_EQ(render_text->GetTextDirection(), base::i18n::RIGHT_TO_LEFT); | 618 EXPECT_EQ(render_text->GetDisplayTextDirection(), |
| 619 base::i18n::RIGHT_TO_LEFT); |
617 } | 620 } |
618 } | 621 } |
619 | 622 |
620 EXPECT_EQ(was_rtl, base::i18n::IsRTL()); | 623 EXPECT_EQ(was_rtl, base::i18n::IsRTL()); |
621 | 624 |
622 // Ensure that text changes update the direction for DIRECTIONALITY_FROM_TEXT. | 625 // Ensure that text changes update the direction for DIRECTIONALITY_FROM_TEXT. |
623 render_text->SetDirectionalityMode(DIRECTIONALITY_FROM_TEXT); | 626 render_text->SetDirectionalityMode(DIRECTIONALITY_FROM_TEXT); |
624 render_text->SetText(WideToUTF16(kLtr)); | 627 render_text->SetText(WideToUTF16(kLtr)); |
625 EXPECT_EQ(render_text->GetTextDirection(), base::i18n::LEFT_TO_RIGHT); | 628 EXPECT_EQ(render_text->GetDisplayTextDirection(), base::i18n::LEFT_TO_RIGHT); |
626 render_text->SetText(WideToUTF16(kRtl)); | 629 render_text->SetText(WideToUTF16(kRtl)); |
627 EXPECT_EQ(render_text->GetTextDirection(), base::i18n::RIGHT_TO_LEFT); | 630 EXPECT_EQ(render_text->GetDisplayTextDirection(), base::i18n::RIGHT_TO_LEFT); |
628 } | 631 } |
629 | 632 |
630 TEST_F(RenderTextTest, MoveCursorLeftRightInLtr) { | 633 TEST_F(RenderTextTest, MoveCursorLeftRightInLtr) { |
631 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); | 634 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); |
632 | 635 |
633 // Pure LTR. | 636 // Pure LTR. |
634 render_text->SetText(ASCIIToUTF16("abc")); | 637 render_text->SetText(ASCIIToUTF16("abc")); |
635 // |expected| saves the expected SelectionModel when moving cursor from left | 638 // |expected| saves the expected SelectionModel when moving cursor from left |
636 // to right. | 639 // to right. |
637 std::vector<SelectionModel> expected; | 640 std::vector<SelectionModel> expected; |
(...skipping 722 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1360 | 1363 |
1361 TEST_F(RenderTextTest, MinLineHeight) { | 1364 TEST_F(RenderTextTest, MinLineHeight) { |
1362 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); | 1365 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); |
1363 | 1366 |
1364 render_text->SetText(ASCIIToUTF16("Hello!")); | 1367 render_text->SetText(ASCIIToUTF16("Hello!")); |
1365 SizeF default_size = render_text->GetStringSizeF(); | 1368 SizeF default_size = render_text->GetStringSizeF(); |
1366 ASSERT_NE(0, default_size.height()); | 1369 ASSERT_NE(0, default_size.height()); |
1367 ASSERT_NE(0, default_size.width()); | 1370 ASSERT_NE(0, default_size.width()); |
1368 | 1371 |
1369 render_text->SetMinLineHeight(default_size.height() / 2); | 1372 render_text->SetMinLineHeight(default_size.height() / 2); |
1370 // MacOSX does not recompute the bounds properly, so invoke ResetLayout() | |
1371 // explicitly. | |
1372 // TODO(mukai): fix this. | |
1373 render_text->ResetLayout(); | |
1374 EXPECT_EQ(default_size.ToString(), render_text->GetStringSizeF().ToString()); | 1373 EXPECT_EQ(default_size.ToString(), render_text->GetStringSizeF().ToString()); |
1375 | 1374 |
1376 render_text->SetMinLineHeight(default_size.height() * 2); | 1375 render_text->SetMinLineHeight(default_size.height() * 2); |
1377 render_text->ResetLayout(); | |
1378 SizeF taller_size = render_text->GetStringSizeF(); | 1376 SizeF taller_size = render_text->GetStringSizeF(); |
1379 EXPECT_EQ(default_size.height() * 2, taller_size.height()); | 1377 EXPECT_EQ(default_size.height() * 2, taller_size.height()); |
1380 EXPECT_EQ(default_size.width(), taller_size.width()); | 1378 EXPECT_EQ(default_size.width(), taller_size.width()); |
1381 } | 1379 } |
1382 | 1380 |
1383 TEST_F(RenderTextTest, SetFontList) { | 1381 TEST_F(RenderTextTest, SetFontList) { |
1384 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); | 1382 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); |
1385 render_text->SetFontList(FontList("Arial,Symbol, 13px")); | 1383 render_text->SetFontList(FontList("Arial,Symbol, 13px")); |
1386 const std::vector<Font>& fonts = render_text->font_list().GetFonts(); | 1384 const std::vector<Font>& fonts = render_text->font_list().GetFonts(); |
1387 ASSERT_EQ(2U, fonts.size()); | 1385 ASSERT_EQ(2U, fonts.size()); |
(...skipping 608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1996 continue; | 1994 continue; |
1997 | 1995 |
1998 for (size_t j = 0; j < kTestStrings[i].lines_count; ++j) { | 1996 for (size_t j = 0; j < kTestStrings[i].lines_count; ++j) { |
1999 SCOPED_TRACE(base::StringPrintf("Line %" PRIuS "", j)); | 1997 SCOPED_TRACE(base::StringPrintf("Line %" PRIuS "", j)); |
2000 VerifyLineSegments(kTestStrings[i].line_char_ranges[j], | 1998 VerifyLineSegments(kTestStrings[i].line_char_ranges[j], |
2001 render_text.lines_[j].segments); | 1999 render_text.lines_[j].segments); |
2002 } | 2000 } |
2003 } | 2001 } |
2004 } | 2002 } |
2005 | 2003 |
| 2004 // Make sure that multiline mode ignores elide behavior. |
| 2005 TEST_F(RenderTextTest, Multiline_IgnoreElide) { |
| 2006 const wchar_t kTestString[] = |
| 2007 L"very very very long string xxxxxxxxxxxxxxxxxxxxxxxxxx"; |
| 2008 const wchar_t kEllipsis[] = L"\x2026"; |
| 2009 |
| 2010 RenderTextHarfBuzz render_text; |
| 2011 render_text.SetElideBehavior(ELIDE_TAIL); |
| 2012 render_text.SetDisplayRect(Rect(20, 1000)); |
| 2013 render_text.SetText(base::WideToUTF16(kTestString)); |
| 2014 EXPECT_NE(base::string16::npos, |
| 2015 render_text.GetDisplayText().find(base::WideToUTF16(kEllipsis))); |
| 2016 |
| 2017 render_text.SetMultiline(true); |
| 2018 EXPECT_EQ(base::string16::npos, |
| 2019 render_text.GetDisplayText().find(base::WideToUTF16(kEllipsis))); |
| 2020 } |
| 2021 |
2006 TEST_F(RenderTextTest, NewlineWithoutMultilineFlag) { | 2022 TEST_F(RenderTextTest, NewlineWithoutMultilineFlag) { |
2007 const wchar_t* kTestStrings[] = { | 2023 const wchar_t* kTestStrings[] = { |
2008 L"abc\ndef", L"a \n b ", L"ab\n", L"a\n\nb", L"\nab", L"\n", | 2024 L"abc\ndef", L"a \n b ", L"ab\n", L"a\n\nb", L"\nab", L"\n", |
2009 }; | 2025 }; |
2010 | 2026 |
2011 RenderTextHarfBuzz render_text; | 2027 RenderTextHarfBuzz render_text; |
2012 render_text.SetDisplayRect(Rect(200, 1000)); | 2028 render_text.SetDisplayRect(Rect(200, 1000)); |
2013 Canvas canvas; | 2029 Canvas canvas; |
2014 | 2030 |
2015 for (size_t i = 0; i < arraysize(kTestStrings); ++i) { | 2031 for (size_t i = 0; i < arraysize(kTestStrings); ++i) { |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2090 }; | 2106 }; |
2091 | 2107 |
2092 RenderTextHarfBuzz render_text; | 2108 RenderTextHarfBuzz render_text; |
2093 | 2109 |
2094 for (size_t i = 0; i < arraysize(cases); ++i) { | 2110 for (size_t i = 0; i < arraysize(cases); ++i) { |
2095 SCOPED_TRACE(base::StringPrintf("Case %" PRIuS, i)); | 2111 SCOPED_TRACE(base::StringPrintf("Case %" PRIuS, i)); |
2096 | 2112 |
2097 base::string16 text = WideToUTF16(cases[i]); | 2113 base::string16 text = WideToUTF16(cases[i]); |
2098 render_text.SetText(text); | 2114 render_text.SetText(text); |
2099 render_text.EnsureLayout(); | 2115 render_text.EnsureLayout(); |
2100 ASSERT_EQ(1U, render_text.runs_.size()); | 2116 internal::TextRunList* run_list = render_text.GetRunList(); |
2101 internal::TextRunHarfBuzz* run = render_text.runs_[0]; | 2117 ASSERT_EQ(1U, run_list->size()); |
| 2118 internal::TextRunHarfBuzz* run = run_list->runs()[0]; |
2102 | 2119 |
2103 base::i18n::BreakIterator* iter = render_text.grapheme_iterator_.get(); | 2120 base::i18n::BreakIterator* iter = render_text.grapheme_iterator_.get(); |
2104 auto first_grapheme_bounds = run->GetGraphemeBounds(iter, 0); | 2121 auto first_grapheme_bounds = run->GetGraphemeBounds(iter, 0); |
2105 EXPECT_EQ(first_grapheme_bounds, run->GetGraphemeBounds(iter, 1)); | 2122 EXPECT_EQ(first_grapheme_bounds, run->GetGraphemeBounds(iter, 1)); |
2106 auto second_grapheme_bounds = run->GetGraphemeBounds(iter, 2); | 2123 auto second_grapheme_bounds = run->GetGraphemeBounds(iter, 2); |
2107 EXPECT_EQ(first_grapheme_bounds.second, second_grapheme_bounds.first); | 2124 EXPECT_EQ(first_grapheme_bounds.second, second_grapheme_bounds.first); |
2108 } | 2125 } |
2109 } | 2126 } |
2110 | 2127 |
2111 // Test the partition of a multi-grapheme cluster into grapheme ranges. | 2128 // Test the partition of a multi-grapheme cluster into grapheme ranges. |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2163 } | 2180 } |
2164 } | 2181 } |
2165 } | 2182 } |
2166 | 2183 |
2167 TEST_F(RenderTextTest, HarfBuzz_RunDirection) { | 2184 TEST_F(RenderTextTest, HarfBuzz_RunDirection) { |
2168 RenderTextHarfBuzz render_text; | 2185 RenderTextHarfBuzz render_text; |
2169 const base::string16 mixed = | 2186 const base::string16 mixed = |
2170 WideToUTF16(L"\x05D0\x05D1" L"1234" L"\x05D2\x05D3"); | 2187 WideToUTF16(L"\x05D0\x05D1" L"1234" L"\x05D2\x05D3"); |
2171 render_text.SetText(mixed); | 2188 render_text.SetText(mixed); |
2172 render_text.EnsureLayout(); | 2189 render_text.EnsureLayout(); |
2173 ASSERT_EQ(3U, render_text.runs_.size()); | 2190 internal::TextRunList* run_list = render_text.GetRunList(); |
2174 EXPECT_TRUE(render_text.runs_[0]->is_rtl); | 2191 ASSERT_EQ(3U, run_list->size()); |
2175 EXPECT_FALSE(render_text.runs_[1]->is_rtl); | 2192 EXPECT_TRUE(run_list->runs()[0]->is_rtl); |
2176 EXPECT_TRUE(render_text.runs_[2]->is_rtl); | 2193 EXPECT_FALSE(run_list->runs()[1]->is_rtl); |
| 2194 EXPECT_TRUE(run_list->runs()[2]->is_rtl); |
2177 } | 2195 } |
2178 | 2196 |
2179 TEST_F(RenderTextTest, HarfBuzz_BreakRunsByUnicodeBlocks) { | 2197 TEST_F(RenderTextTest, HarfBuzz_BreakRunsByUnicodeBlocks) { |
2180 RenderTextHarfBuzz render_text; | 2198 RenderTextHarfBuzz render_text; |
2181 | 2199 |
2182 // The '\x25B6' "play character" should break runs. http://crbug.com/278913 | 2200 // The '\x25B6' "play character" should break runs. http://crbug.com/278913 |
2183 render_text.SetText(WideToUTF16(L"x\x25B6y")); | 2201 render_text.SetText(WideToUTF16(L"x\x25B6y")); |
2184 render_text.EnsureLayout(); | 2202 render_text.EnsureLayout(); |
2185 ASSERT_EQ(3U, render_text.runs_.size()); | 2203 internal::TextRunList* run_list = render_text.GetRunList(); |
2186 EXPECT_EQ(Range(0, 1), render_text.runs_[0]->range); | 2204 ASSERT_EQ(3U, run_list->size()); |
2187 EXPECT_EQ(Range(1, 2), render_text.runs_[1]->range); | 2205 EXPECT_EQ(Range(0, 1), run_list->runs()[0]->range); |
2188 EXPECT_EQ(Range(2, 3), render_text.runs_[2]->range); | 2206 EXPECT_EQ(Range(1, 2), run_list->runs()[1]->range); |
| 2207 EXPECT_EQ(Range(2, 3), run_list->runs()[2]->range); |
2189 | 2208 |
2190 render_text.SetText(WideToUTF16(L"x \x25B6 y")); | 2209 render_text.SetText(WideToUTF16(L"x \x25B6 y")); |
2191 render_text.EnsureLayout(); | 2210 render_text.EnsureLayout(); |
2192 ASSERT_EQ(3U, render_text.runs_.size()); | 2211 run_list = render_text.GetRunList(); |
2193 EXPECT_EQ(Range(0, 2), render_text.runs_[0]->range); | 2212 ASSERT_EQ(3U, run_list->size()); |
2194 EXPECT_EQ(Range(2, 3), render_text.runs_[1]->range); | 2213 EXPECT_EQ(Range(0, 2), run_list->runs()[0]->range); |
2195 EXPECT_EQ(Range(3, 5), render_text.runs_[2]->range); | 2214 EXPECT_EQ(Range(2, 3), run_list->runs()[1]->range); |
| 2215 EXPECT_EQ(Range(3, 5), run_list->runs()[2]->range); |
2196 } | 2216 } |
2197 | 2217 |
2198 TEST_F(RenderTextTest, HarfBuzz_BreakRunsByEmoji) { | 2218 TEST_F(RenderTextTest, HarfBuzz_BreakRunsByEmoji) { |
2199 RenderTextHarfBuzz render_text; | 2219 RenderTextHarfBuzz render_text; |
2200 | 2220 |
2201 // \xF0\x9F\x98\x81 (U+1F601) is smile icon emoji. \xE2\x9C\xA8 (U+2728) is | 2221 // \xF0\x9F\x98\x81 (U+1F601) is smile icon emoji. \xE2\x9C\xA8 (U+2728) is |
2202 // a sparkle icon. Both can be drawn with color emoji fonts, so runs should be | 2222 // a sparkle icon. Both can be drawn with color emoji fonts, so runs should be |
2203 // separated. See crbug.com/448909 | 2223 // separated. See crbug.com/448909 |
2204 render_text.SetText(UTF8ToUTF16("x\xF0\x9F\x98\x81y\xE2\x9C\xA8")); | 2224 render_text.SetText(UTF8ToUTF16("x\xF0\x9F\x98\x81y\xE2\x9C\xA8")); |
2205 render_text.EnsureLayout(); | 2225 render_text.EnsureLayout(); |
2206 ASSERT_EQ(4U, render_text.runs_.size()); | 2226 internal::TextRunList* run_list = render_text.GetRunList(); |
2207 EXPECT_EQ(Range(0, 1), render_text.runs_[0]->range); | 2227 ASSERT_EQ(4U, run_list->size()); |
| 2228 EXPECT_EQ(Range(0, 1), run_list->runs()[0]->range); |
2208 // The length is 2 since U+1F601 is represented as a surrogate pair in UTF16. | 2229 // The length is 2 since U+1F601 is represented as a surrogate pair in UTF16. |
2209 EXPECT_EQ(Range(1, 3), render_text.runs_[1]->range); | 2230 EXPECT_EQ(Range(1, 3), run_list->runs()[1]->range); |
2210 EXPECT_EQ(Range(3, 4), render_text.runs_[2]->range); | 2231 EXPECT_EQ(Range(3, 4), run_list->runs()[2]->range); |
2211 EXPECT_EQ(Range(4, 5), render_text.runs_[3]->range); | 2232 EXPECT_EQ(Range(4, 5), run_list->runs()[3]->range); |
2212 } | 2233 } |
2213 | 2234 |
2214 TEST_F(RenderTextTest, GlyphBounds) { | 2235 TEST_F(RenderTextTest, GlyphBounds) { |
2215 const wchar_t* kTestStrings[] = { | 2236 const wchar_t* kTestStrings[] = { |
2216 L"asdf 1234 qwer", L"\x0647\x0654", L"\x0645\x0631\x062D\x0628\x0627" | 2237 L"asdf 1234 qwer", L"\x0647\x0654", L"\x0645\x0631\x062D\x0628\x0627" |
2217 }; | 2238 }; |
2218 scoped_ptr<RenderText> render_text(new RenderTextHarfBuzz); | 2239 scoped_ptr<RenderText> render_text(new RenderTextHarfBuzz); |
2219 | 2240 |
2220 for (size_t i = 0; i < arraysize(kTestStrings); ++i) { | 2241 for (size_t i = 0; i < arraysize(kTestStrings); ++i) { |
2221 render_text->SetText(WideToUTF16(kTestStrings[i])); | 2242 render_text->SetText(WideToUTF16(kTestStrings[i])); |
2222 render_text->EnsureLayout(); | 2243 render_text->EnsureLayout(); |
2223 | 2244 |
2224 for (size_t j = 0; j < render_text->text().length(); ++j) | 2245 for (size_t j = 0; j < render_text->text().length(); ++j) |
2225 EXPECT_FALSE(render_text->GetGlyphBounds(j).is_empty()); | 2246 EXPECT_FALSE(render_text->GetGlyphBounds(j).is_empty()); |
2226 } | 2247 } |
2227 } | 2248 } |
2228 | 2249 |
2229 // Ensure that shaping with a non-existent font does not cause a crash. | 2250 // Ensure that shaping with a non-existent font does not cause a crash. |
2230 TEST_F(RenderTextTest, HarfBuzz_NonExistentFont) { | 2251 TEST_F(RenderTextTest, HarfBuzz_NonExistentFont) { |
2231 RenderTextHarfBuzz render_text; | 2252 RenderTextHarfBuzz render_text; |
2232 render_text.SetText(ASCIIToUTF16("test")); | 2253 render_text.SetText(ASCIIToUTF16("test")); |
2233 render_text.EnsureLayout(); | 2254 render_text.EnsureLayout(); |
2234 ASSERT_EQ(1U, render_text.runs_.size()); | 2255 internal::TextRunList* run_list = render_text.GetRunList(); |
2235 internal::TextRunHarfBuzz* run = render_text.runs_[0]; | 2256 ASSERT_EQ(1U, run_list->size()); |
| 2257 internal::TextRunHarfBuzz* run = run_list->runs()[0]; |
2236 render_text.ShapeRunWithFont( | 2258 render_text.ShapeRunWithFont( |
2237 run, "TheFontThatDoesntExist", FontRenderParams()); | 2259 render_text.text(), "TheFontThatDoesntExist", FontRenderParams(), run); |
2238 } | 2260 } |
2239 | 2261 |
2240 // Ensure an empty run returns sane values to queries. | 2262 // Ensure an empty run returns sane values to queries. |
2241 TEST_F(RenderTextTest, HarfBuzz_EmptyRun) { | 2263 TEST_F(RenderTextTest, HarfBuzz_EmptyRun) { |
2242 internal::TextRunHarfBuzz run; | 2264 internal::TextRunHarfBuzz run; |
2243 const base::string16 kString = ASCIIToUTF16("abcdefgh"); | 2265 const base::string16 kString = ASCIIToUTF16("abcdefgh"); |
2244 scoped_ptr<base::i18n::BreakIterator> iter(new base::i18n::BreakIterator( | 2266 scoped_ptr<base::i18n::BreakIterator> iter(new base::i18n::BreakIterator( |
2245 kString, base::i18n::BreakIterator::BREAK_CHARACTER)); | 2267 kString, base::i18n::BreakIterator::BREAK_CHARACTER)); |
2246 ASSERT_TRUE(iter->Init()); | 2268 ASSERT_TRUE(iter->Init()); |
2247 | 2269 |
(...skipping 12 matching lines...) Expand all Loading... |
2260 // Ensure a string fits in a display rect with a width equal to the string's. | 2282 // Ensure a string fits in a display rect with a width equal to the string's. |
2261 TEST_F(RenderTextTest, StringFitsOwnWidth) { | 2283 TEST_F(RenderTextTest, StringFitsOwnWidth) { |
2262 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); | 2284 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); |
2263 const base::string16 kString = ASCIIToUTF16("www.example.com"); | 2285 const base::string16 kString = ASCIIToUTF16("www.example.com"); |
2264 | 2286 |
2265 render_text->SetText(kString); | 2287 render_text->SetText(kString); |
2266 render_text->ApplyStyle(BOLD, true, Range(0, 3)); | 2288 render_text->ApplyStyle(BOLD, true, Range(0, 3)); |
2267 render_text->SetElideBehavior(ELIDE_TAIL); | 2289 render_text->SetElideBehavior(ELIDE_TAIL); |
2268 | 2290 |
2269 render_text->SetDisplayRect(Rect(0, 0, 500, 100)); | 2291 render_text->SetDisplayRect(Rect(0, 0, 500, 100)); |
2270 EXPECT_EQ(kString, render_text->GetLayoutText()); | 2292 EXPECT_EQ(kString, render_text->GetDisplayText()); |
2271 render_text->SetDisplayRect(Rect(0, 0, render_text->GetContentWidth(), 100)); | 2293 render_text->SetDisplayRect(Rect(0, 0, render_text->GetContentWidth(), 100)); |
2272 EXPECT_EQ(kString, render_text->GetLayoutText()); | 2294 EXPECT_EQ(kString, render_text->GetDisplayText()); |
2273 } | 2295 } |
2274 | 2296 |
2275 // TODO(derat): Figure out why this fails on Windows: http://crbug.com/427184 | 2297 // TODO(derat): Figure out why this fails on Windows: http://crbug.com/427184 |
2276 #if !defined(OS_WIN) | 2298 #if !defined(OS_WIN) |
2277 // Ensure that RenderText examines all of the fonts in its FontList before | 2299 // Ensure that RenderText examines all of the fonts in its FontList before |
2278 // falling back to other fonts. | 2300 // falling back to other fonts. |
2279 TEST_F(RenderTextTest, HarfBuzz_FontListFallback) { | 2301 TEST_F(RenderTextTest, HarfBuzz_FontListFallback) { |
2280 // Double-check that the requested fonts are present. | 2302 // Double-check that the requested fonts are present. |
2281 FontList font_list("Arial, Symbol, 12px"); | 2303 FontList font_list("Arial, Symbol, 12px"); |
2282 const std::vector<Font>& fonts = font_list.GetFonts(); | 2304 const std::vector<Font>& fonts = font_list.GetFonts(); |
(...skipping 22 matching lines...) Expand all Loading... |
2305 PlatformFontWin* font_win = new PlatformFontWin("Meiryo", 12); | 2327 PlatformFontWin* font_win = new PlatformFontWin("Meiryo", 12); |
2306 // Japanese name for Meiryo. This name won't be found in the system's linked | 2328 // Japanese name for Meiryo. This name won't be found in the system's linked |
2307 // fonts, forcing RTHB to try the Uniscribe font and its fallbacks. | 2329 // fonts, forcing RTHB to try the Uniscribe font and its fallbacks. |
2308 font_win->font_ref_->font_name_ = WideToUTF8(L"\x30e1\x30a4\x30ea\x30aa"); | 2330 font_win->font_ref_->font_name_ = WideToUTF8(L"\x30e1\x30a4\x30ea\x30aa"); |
2309 FontList font_list((Font(font_win))); | 2331 FontList font_list((Font(font_win))); |
2310 | 2332 |
2311 render_text.SetFontList(font_list); | 2333 render_text.SetFontList(font_list); |
2312 // Korean character "han". | 2334 // Korean character "han". |
2313 render_text.SetText(WideToUTF16(L"\xd55c")); | 2335 render_text.SetText(WideToUTF16(L"\xd55c")); |
2314 render_text.EnsureLayout(); | 2336 render_text.EnsureLayout(); |
2315 ASSERT_EQ(1U, render_text.runs_.size()); | 2337 internal::TextRunList* run_list = render_text.GetRunList(); |
2316 EXPECT_EQ(0U, render_text.runs_[0]->CountMissingGlyphs()); | 2338 ASSERT_EQ(1U, run_list->size()); |
| 2339 EXPECT_EQ(0U, run_list->runs()[0]->CountMissingGlyphs()); |
2317 } | 2340 } |
2318 #endif // defined(OS_WIN) | 2341 #endif // defined(OS_WIN) |
2319 | 2342 |
2320 // Ensure that the width reported by RenderText is sufficient for drawing. Draws | 2343 // Ensure that the width reported by RenderText is sufficient for drawing. Draws |
2321 // to a canvas and checks whether any pixel beyond the width is colored. | 2344 // to a canvas and checks whether any pixel beyond the width is colored. |
2322 TEST_F(RenderTextTest, TextDoesntClip) { | 2345 TEST_F(RenderTextTest, TextDoesntClip) { |
2323 const wchar_t* kTestStrings[] = { L"Save", L"Remove", L"TEST", L"W", L"WWW" }; | 2346 const wchar_t* kTestStrings[] = { L"Save", L"Remove", L"TEST", L"W", L"WWW" }; |
2324 const Size kCanvasSize(300, 50); | 2347 const Size kCanvasSize(300, 50); |
2325 const int kTestWidth = 10; | 2348 const int kTestWidth = 10; |
2326 | 2349 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2383 base::StringToLowerASCII(fonts[0].GetActualFontNameForTesting())); | 2406 base::StringToLowerASCII(fonts[0].GetActualFontNameForTesting())); |
2384 | 2407 |
2385 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); | 2408 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); |
2386 render_text->SetDisplayRect(Rect(0, 0, 25, 25)); | 2409 render_text->SetDisplayRect(Rect(0, 0, 25, 25)); |
2387 render_text->SetFontList(font_list); | 2410 render_text->SetFontList(font_list); |
2388 EXPECT_GT(render_text->GetBaseline(), font_list.GetBaseline()); | 2411 EXPECT_GT(render_text->GetBaseline(), font_list.GetBaseline()); |
2389 } | 2412 } |
2390 #endif | 2413 #endif |
2391 | 2414 |
2392 } // namespace gfx | 2415 } // namespace gfx |
OLD | NEW |