Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(62)

Side by Side Diff: ui/gfx/render_text_unittest.cc

Issue 2251893004: Use parameterized tests to test multiple render text implementations. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@selection_direction
Patch Set: Refer crbug. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/gfx/render_text_mac.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <limits.h> 7 #include <limits.h>
8 #include <stddef.h> 8 #include <stddef.h>
9 #include <stdint.h> 9 #include <stdint.h>
10 10
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 namespace test { 55 namespace test {
56 56
57 class RenderTextTestApi { 57 class RenderTextTestApi {
58 public: 58 public:
59 RenderTextTestApi(RenderText* render_text) : render_text_(render_text) {} 59 RenderTextTestApi(RenderText* render_text) : render_text_(render_text) {}
60 60
61 static SkPaint& GetRendererPaint(internal::SkiaTextRenderer* renderer) { 61 static SkPaint& GetRendererPaint(internal::SkiaTextRenderer* renderer) {
62 return renderer->paint_; 62 return renderer->paint_;
63 } 63 }
64 64
65 static internal::TextRunList* GetHarfbuzzRunList( 65 // Callers should ensure that the associated RenderText object is a
66 RenderTextHarfBuzz* harfbuzz) { 66 // RenderTextHarfBuzz instance.
67 internal::TextRunList* GetHarfBuzzRunList() {
68 RenderTextHarfBuzz* harfbuzz =
69 static_cast<RenderTextHarfBuzz*>(render_text_);
67 return harfbuzz->GetRunList(); 70 return harfbuzz->GetRunList();
68 } 71 }
69 72
70 void DrawVisualText(internal::SkiaTextRenderer* renderer) { 73 void DrawVisualText(internal::SkiaTextRenderer* renderer) {
71 render_text_->EnsureLayout(); 74 render_text_->EnsureLayout();
72 render_text_->DrawVisualText(renderer); 75 render_text_->DrawVisualText(renderer);
73 } 76 }
74 77
75 private: 78 private:
76 RenderText* render_text_; 79 RenderText* render_text_;
77
78 DISALLOW_COPY_AND_ASSIGN(RenderTextTestApi); 80 DISALLOW_COPY_AND_ASSIGN(RenderTextTestApi);
79 }; 81 };
80 82
81 } // namespace test 83 } // namespace test
82 84
83 namespace { 85 namespace {
84 86
87 // An enum specifying the different RenderText implementations to be tested.
88 enum RenderTextBackend {
89 RENDER_TEXT_HARFBUZZ,
90 RENDER_TEXT_MAC,
91 };
92
85 // Various weak, LTR, RTL, and Bidi string cases with three characters each. 93 // Various weak, LTR, RTL, and Bidi string cases with three characters each.
86 const wchar_t kWeak[] = L" . "; 94 const wchar_t kWeak[] = L" . ";
87 const wchar_t kLtr[] = L"abc"; 95 const wchar_t kLtr[] = L"abc";
88 const wchar_t kRtl[] = L"\x5d0\x5d1\x5d2"; 96 const wchar_t kRtl[] = L"\x5d0\x5d1\x5d2";
89 const wchar_t kLtrRtl[] = L"a" L"\x5d0\x5d1"; 97 const wchar_t kLtrRtl[] = L"a" L"\x5d0\x5d1";
90 const wchar_t kLtrRtlLtr[] = L"a" L"\x5d1" L"b"; 98 const wchar_t kLtrRtlLtr[] = L"a" L"\x5d1" L"b";
91 const wchar_t kRtlLtr[] = L"\x5d0\x5d1" L"a"; 99 const wchar_t kRtlLtr[] = L"\x5d0\x5d1" L"a";
92 const wchar_t kRtlLtrRtl[] = L"\x5d0" L"a" L"\x5d1"; 100 const wchar_t kRtlLtrRtl[] = L"\x5d0" L"a" L"\x5d1";
93 101
94 // Checks whether |range| contains |index|. This is not the same as calling 102 // Checks whether |range| contains |index|. This is not the same as calling
(...skipping 26 matching lines...) Expand all
121 SCOPED_TRACE(base::StringPrintf( 129 SCOPED_TRACE(base::StringPrintf(
122 "BreakType-%d VisualCursorDirection-%d SelectionBehavior-%d Case-%d.", 130 "BreakType-%d VisualCursorDirection-%d SelectionBehavior-%d Case-%d.",
123 break_type, direction, selection_behavior, static_cast<int>(i))); 131 break_type, direction, selection_behavior, static_cast<int>(i)));
124 132
125 render_text->MoveCursor(break_type, direction, selection_behavior); 133 render_text->MoveCursor(break_type, direction, selection_behavior);
126 EXPECT_EQ(expected->at(i), render_text->selection()); 134 EXPECT_EQ(expected->at(i), render_text->selection());
127 } 135 }
128 expected->clear(); 136 expected->clear();
129 } 137 }
130 138
131 // TODO(asvitkine): RenderTextMac cursor movements. http://crbug.com/131618
132 #if !defined(OS_MACOSX)
133 // Ensure cursor movement in the specified |direction| yields |expected| values. 139 // Ensure cursor movement in the specified |direction| yields |expected| values.
134 void RunMoveCursorLeftRightTest(RenderText* render_text, 140 void RunMoveCursorLeftRightTest(RenderText* render_text,
135 const std::vector<SelectionModel>& expected, 141 const std::vector<SelectionModel>& expected,
136 VisualCursorDirection direction) { 142 VisualCursorDirection direction) {
137 for (size_t i = 0; i < expected.size(); ++i) { 143 for (size_t i = 0; i < expected.size(); ++i) {
138 SCOPED_TRACE(base::StringPrintf("Going %s; expected value index %d.", 144 SCOPED_TRACE(base::StringPrintf("Going %s; expected value index %d.",
139 direction == CURSOR_LEFT ? "left" : "right", static_cast<int>(i))); 145 direction == CURSOR_LEFT ? "left" : "right", static_cast<int>(i)));
140 EXPECT_EQ(expected[i], render_text->selection_model()); 146 EXPECT_EQ(expected[i], render_text->selection_model());
141 render_text->MoveCursor(CHARACTER_BREAK, direction, SELECTION_NONE); 147 render_text->MoveCursor(CHARACTER_BREAK, direction, SELECTION_NONE);
142 } 148 }
143 // Check that cursoring is clamped at the line edge. 149 // Check that cursoring is clamped at the line edge.
144 EXPECT_EQ(expected.back(), render_text->selection_model()); 150 EXPECT_EQ(expected.back(), render_text->selection_model());
145 // Check that it is the line edge. 151 // Check that it is the line edge.
146 render_text->MoveCursor(LINE_BREAK, direction, SELECTION_NONE); 152 render_text->MoveCursor(LINE_BREAK, direction, SELECTION_NONE);
147 EXPECT_EQ(expected.back(), render_text->selection_model()); 153 EXPECT_EQ(expected.back(), render_text->selection_model());
148 } 154 }
149 #endif // !defined(OS_MACOSX)
150 155
151 // The class which records the drawing operations so that the test case can 156 // The class which records the drawing operations so that the test case can
152 // verify where exactly the glyphs are drawn. 157 // verify where exactly the glyphs are drawn.
153 class TestSkiaTextRenderer : public internal::SkiaTextRenderer { 158 class TestSkiaTextRenderer : public internal::SkiaTextRenderer {
154 public: 159 public:
155 struct TextLog { 160 struct TextLog {
156 TextLog() : glyph_count(0u), color(SK_ColorTRANSPARENT) {} 161 TextLog() : glyph_count(0u), color(SK_ColorTRANSPARENT) {}
157 PointF origin; 162 PointF origin;
158 size_t glyph_count; 163 size_t glyph_count;
159 SkColor color; 164 SkColor color;
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 261
257 private: 262 private:
258 const wchar_t* string_; 263 const wchar_t* string_;
259 const SkColor* buffer_; 264 const SkColor* buffer_;
260 int stride_; 265 int stride_;
261 int row_count_; 266 int row_count_;
262 267
263 DISALLOW_COPY_AND_ASSIGN(TestRectangleBuffer); 268 DISALLOW_COPY_AND_ASSIGN(TestRectangleBuffer);
264 }; 269 };
265 270
266 // Helper to run the same test expectations on all RenderText backends.
267 class RenderTextAllBackends {
268 public:
269 RenderTextAllBackends() : renderer_(&canvas_), current_(nullptr) {}
270
271 bool Advance() {
272 if (!current_) {
273 current_ = &render_text_harfbuzz_;
274 return true;
275 }
276 #if defined(OS_MACOSX)
277 if (current_ == &render_text_harfbuzz_) {
278 current_ = &render_text_mac_;
279 return true;
280 }
281 #endif
282
283 return false;
284 }
285
286 const char* GetName() const {
287 return current_ == &render_text_harfbuzz_ ? "Harfbuzz" : "Mac";
288 }
289
290 RenderText* operator->() {
291 return current_;
292 }
293
294 void DrawVisualText() {
295 test::RenderTextTestApi test_api(current_);
296 test_api.DrawVisualText(&renderer_);
297 }
298
299 void GetTextLogAndReset(std::vector<TestSkiaTextRenderer::TextLog>* log) {
300 renderer_.GetTextLogAndReset(log);
301 }
302
303 SkPaint& paint() {
304 return test::RenderTextTestApi::GetRendererPaint(&renderer_);
305 }
306
307 internal::TextRunList* GetHarfbuzzRunList() {
308 return test::RenderTextTestApi::GetHarfbuzzRunList(&render_text_harfbuzz_);
309 }
310
311 private:
312 Canvas canvas_;
313 TestSkiaTextRenderer renderer_;
314 RenderText* current_;
315
316 RenderTextHarfBuzz render_text_harfbuzz_;
317 #if defined(OS_MACOSX)
318 RenderTextMac render_text_mac_;
319 #endif
320
321 DISALLOW_COPY_AND_ASSIGN(RenderTextAllBackends);
322 };
323
324 } // namespace 271 } // namespace
325 272
326 class RenderTextTest : public testing::Test { 273 // Test fixture class used to run parameterized tests on all RenderText
274 // implementations.
275 class RenderTextTestAll
276 : public testing::Test,
277 public ::testing::WithParamInterface<RenderTextBackend> {
278 public:
279 RenderTextTestAll()
280 : render_text_(CreateRenderTextInstance()),
281 test_api_(render_text_.get()),
282 renderer_(&canvas_){};
283
284 protected:
285 std::unique_ptr<RenderText> CreateRenderTextInstance() const {
286 std::unique_ptr<RenderText> render_text;
287 switch (GetParam()) {
288 case RENDER_TEXT_HARFBUZZ:
289 render_text.reset(new RenderTextHarfBuzz());
290 break;
291
292 case RENDER_TEXT_MAC:
293 #if defined(OS_MACOSX)
294 render_text.reset(new RenderTextMac());
295 #else
296 NOTREACHED();
297 #endif
298 break;
299 }
300 return render_text;
301 }
302
303 SkPaint& GetRendererPaint() {
304 return test::RenderTextTestApi::GetRendererPaint(&renderer_);
305 }
306
307 void DrawVisualText() { test_api_.DrawVisualText(&renderer_); }
308
309 internal::TextRunList* GetHarfbuzzRunList() {
310 DCHECK_EQ(RENDER_TEXT_HARFBUZZ, GetParam());
311 return test_api_.GetHarfBuzzRunList();
312 }
313
314 std::unique_ptr<RenderText> render_text_;
315 test::RenderTextTestApi test_api_;
316 Canvas canvas_;
317 TestSkiaTextRenderer renderer_;
318
327 private: 319 private:
328 #if defined(OS_WIN) 320 #if defined(OS_WIN)
329 // Needed to bypass DCHECK in GetFallbackFont. 321 // Needed to bypass DCHECK in GetFallbackFont.
330 base::MessageLoopForUI message_loop_; 322 base::MessageLoopForUI message_loop_;
331 #endif 323 #endif
324
325 DISALLOW_COPY_AND_ASSIGN(RenderTextTestAll);
332 }; 326 };
333 327
334 TEST_F(RenderTextTest, DefaultStyles) { 328 // Test fixture class. Use for tests which are only to be run for RenderTextMac.
329 class RenderTextMacTest : public RenderTextTestAll {
330 public:
331 RenderTextMacTest() {}
332
333 // Overridden from testing::Test:
334 void SetUp() override { DCHECK_EQ(RENDER_TEXT_MAC, GetParam()); }
335
336 private:
337 DISALLOW_COPY_AND_ASSIGN(RenderTextMacTest);
338 };
339
340 // Test fixture class. Use for tests which are only to be run on
341 // RenderTextHarfBuzz.
342 class RenderTextHarfBuzzTest : public RenderTextTestAll {
343 public:
344 RenderTextHarfBuzzTest() {}
345
346 // Overridden from testing::Test:
347 void SetUp() override { DCHECK_EQ(RENDER_TEXT_HARFBUZZ, GetParam()); }
348
349 private:
350 DISALLOW_COPY_AND_ASSIGN(RenderTextHarfBuzzTest);
351 };
352
353 TEST_P(RenderTextTestAll, DefaultStyles) {
335 // Check the default styles applied to new instances and adjusted text. 354 // Check the default styles applied to new instances and adjusted text.
336 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 355 EXPECT_TRUE(render_text_->text().empty());
337 EXPECT_TRUE(render_text->text().empty());
338 const wchar_t* const cases[] = { kWeak, kLtr, L"Hello", kRtl, L"", L"" }; 356 const wchar_t* const cases[] = { kWeak, kLtr, L"Hello", kRtl, L"", L"" };
339 for (size_t i = 0; i < arraysize(cases); ++i) { 357 for (size_t i = 0; i < arraysize(cases); ++i) {
340 EXPECT_TRUE(render_text->colors().EqualsValueForTesting(SK_ColorBLACK)); 358 EXPECT_TRUE(render_text_->colors().EqualsValueForTesting(SK_ColorBLACK));
341 EXPECT_TRUE( 359 EXPECT_TRUE(
342 render_text->baselines().EqualsValueForTesting(NORMAL_BASELINE)); 360 render_text_->baselines().EqualsValueForTesting(NORMAL_BASELINE));
343 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) 361 for (size_t style = 0; style < NUM_TEXT_STYLES; ++style)
344 EXPECT_TRUE(render_text->styles()[style].EqualsValueForTesting(false)); 362 EXPECT_TRUE(render_text_->styles()[style].EqualsValueForTesting(false));
345 render_text->SetText(WideToUTF16(cases[i])); 363 render_text_->SetText(WideToUTF16(cases[i]));
346 } 364 }
347 } 365 }
348 366
349 TEST_F(RenderTextTest, SetStyles) { 367 TEST_P(RenderTextTestAll, SetStyles) {
350 // Ensure custom default styles persist across setting and clearing text. 368 // Ensure custom default styles persist across setting and clearing text.
351 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance());
352 const SkColor color = SK_ColorRED; 369 const SkColor color = SK_ColorRED;
353 render_text->SetColor(color); 370 render_text_->SetColor(color);
354 render_text->SetBaselineStyle(SUPERSCRIPT); 371 render_text_->SetBaselineStyle(SUPERSCRIPT);
355 render_text->SetWeight(Font::Weight::BOLD); 372 render_text_->SetWeight(Font::Weight::BOLD);
356 render_text->SetStyle(UNDERLINE, false); 373 render_text_->SetStyle(UNDERLINE, false);
357 const wchar_t* const cases[] = { kWeak, kLtr, L"Hello", kRtl, L"", L"" }; 374 const wchar_t* const cases[] = { kWeak, kLtr, L"Hello", kRtl, L"", L"" };
358 for (size_t i = 0; i < arraysize(cases); ++i) { 375 for (size_t i = 0; i < arraysize(cases); ++i) {
359 EXPECT_TRUE(render_text->colors().EqualsValueForTesting(color)); 376 EXPECT_TRUE(render_text_->colors().EqualsValueForTesting(color));
360 EXPECT_TRUE(render_text->baselines().EqualsValueForTesting(SUPERSCRIPT)); 377 EXPECT_TRUE(render_text_->baselines().EqualsValueForTesting(SUPERSCRIPT));
361 EXPECT_TRUE( 378 EXPECT_TRUE(
362 render_text->weights().EqualsValueForTesting(Font::Weight::BOLD)); 379 render_text_->weights().EqualsValueForTesting(Font::Weight::BOLD));
363 EXPECT_TRUE(render_text->styles()[UNDERLINE].EqualsValueForTesting(false)); 380 EXPECT_TRUE(render_text_->styles()[UNDERLINE].EqualsValueForTesting(false));
364 render_text->SetText(WideToUTF16(cases[i])); 381 render_text_->SetText(WideToUTF16(cases[i]));
365 382
366 // Ensure custom default styles can be applied after text has been set. 383 // Ensure custom default styles can be applied after text has been set.
367 if (i == 1) 384 if (i == 1)
368 render_text->SetStyle(STRIKE, true); 385 render_text_->SetStyle(STRIKE, true);
369 if (i >= 1) 386 if (i >= 1)
370 EXPECT_TRUE(render_text->styles()[STRIKE].EqualsValueForTesting(true)); 387 EXPECT_TRUE(render_text_->styles()[STRIKE].EqualsValueForTesting(true));
371 } 388 }
372 } 389 }
373 390
374 TEST_F(RenderTextTest, ApplyStyles) { 391 TEST_P(RenderTextTestAll, ApplyStyles) {
375 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 392 render_text_->SetText(ASCIIToUTF16("012345678"));
376 render_text->SetText(ASCIIToUTF16("012345678"));
377 393
378 // Apply a ranged color and style and check the resulting breaks. 394 // Apply a ranged color and style and check the resulting breaks.
379 render_text->ApplyColor(SK_ColorRED, Range(1, 4)); 395 render_text_->ApplyColor(SK_ColorRED, Range(1, 4));
380 render_text->ApplyBaselineStyle(SUPERIOR, Range(2, 4)); 396 render_text_->ApplyBaselineStyle(SUPERIOR, Range(2, 4));
381 render_text->ApplyWeight(Font::Weight::BOLD, Range(2, 5)); 397 render_text_->ApplyWeight(Font::Weight::BOLD, Range(2, 5));
382 std::vector<std::pair<size_t, SkColor> > expected_color; 398 std::vector<std::pair<size_t, SkColor> > expected_color;
383 expected_color.push_back(std::pair<size_t, SkColor>(0, SK_ColorBLACK)); 399 expected_color.push_back(std::pair<size_t, SkColor>(0, SK_ColorBLACK));
384 expected_color.push_back(std::pair<size_t, SkColor>(1, SK_ColorRED)); 400 expected_color.push_back(std::pair<size_t, SkColor>(1, SK_ColorRED));
385 expected_color.push_back(std::pair<size_t, SkColor>(4, SK_ColorBLACK)); 401 expected_color.push_back(std::pair<size_t, SkColor>(4, SK_ColorBLACK));
386 EXPECT_TRUE(render_text->colors().EqualsForTesting(expected_color)); 402 EXPECT_TRUE(render_text_->colors().EqualsForTesting(expected_color));
387 std::vector<std::pair<size_t, BaselineStyle>> expected_baseline_style; 403 std::vector<std::pair<size_t, BaselineStyle>> expected_baseline_style;
388 expected_baseline_style.push_back( 404 expected_baseline_style.push_back(
389 std::pair<size_t, BaselineStyle>(0, NORMAL_BASELINE)); 405 std::pair<size_t, BaselineStyle>(0, NORMAL_BASELINE));
390 expected_baseline_style.push_back( 406 expected_baseline_style.push_back(
391 std::pair<size_t, BaselineStyle>(2, SUPERIOR)); 407 std::pair<size_t, BaselineStyle>(2, SUPERIOR));
392 expected_baseline_style.push_back( 408 expected_baseline_style.push_back(
393 std::pair<size_t, BaselineStyle>(4, NORMAL_BASELINE)); 409 std::pair<size_t, BaselineStyle>(4, NORMAL_BASELINE));
394 EXPECT_TRUE( 410 EXPECT_TRUE(
395 render_text->baselines().EqualsForTesting(expected_baseline_style)); 411 render_text_->baselines().EqualsForTesting(expected_baseline_style));
396 std::vector<std::pair<size_t, Font::Weight>> expected_weight; 412 std::vector<std::pair<size_t, Font::Weight>> expected_weight;
397 expected_weight.push_back( 413 expected_weight.push_back(
398 std::pair<size_t, Font::Weight>(0, Font::Weight::NORMAL)); 414 std::pair<size_t, Font::Weight>(0, Font::Weight::NORMAL));
399 expected_weight.push_back( 415 expected_weight.push_back(
400 std::pair<size_t, Font::Weight>(2, Font::Weight::BOLD)); 416 std::pair<size_t, Font::Weight>(2, Font::Weight::BOLD));
401 expected_weight.push_back( 417 expected_weight.push_back(
402 std::pair<size_t, Font::Weight>(5, Font::Weight::NORMAL)); 418 std::pair<size_t, Font::Weight>(5, Font::Weight::NORMAL));
403 EXPECT_TRUE(render_text->weights().EqualsForTesting(expected_weight)); 419 EXPECT_TRUE(render_text_->weights().EqualsForTesting(expected_weight));
404 420
405 // Ensure that setting a value overrides the ranged values. 421 // Ensure that setting a value overrides the ranged values.
406 render_text->SetColor(SK_ColorBLUE); 422 render_text_->SetColor(SK_ColorBLUE);
407 EXPECT_TRUE(render_text->colors().EqualsValueForTesting(SK_ColorBLUE)); 423 EXPECT_TRUE(render_text_->colors().EqualsValueForTesting(SK_ColorBLUE));
408 render_text->SetBaselineStyle(SUBSCRIPT); 424 render_text_->SetBaselineStyle(SUBSCRIPT);
409 EXPECT_TRUE(render_text->baselines().EqualsValueForTesting(SUBSCRIPT)); 425 EXPECT_TRUE(render_text_->baselines().EqualsValueForTesting(SUBSCRIPT));
410 render_text->SetWeight(Font::Weight::NORMAL); 426 render_text_->SetWeight(Font::Weight::NORMAL);
411 EXPECT_TRUE( 427 EXPECT_TRUE(
412 render_text->weights().EqualsValueForTesting(Font::Weight::NORMAL)); 428 render_text_->weights().EqualsValueForTesting(Font::Weight::NORMAL));
413 429
414 // Apply a value over the text end and check the resulting breaks (INT_MAX 430 // Apply a value over the text end and check the resulting breaks (INT_MAX
415 // should be used instead of the text length for the range end) 431 // should be used instead of the text length for the range end)
416 const size_t text_length = render_text->text().length(); 432 const size_t text_length = render_text_->text().length();
417 render_text->ApplyColor(SK_ColorRED, Range(0, text_length)); 433 render_text_->ApplyColor(SK_ColorRED, Range(0, text_length));
418 render_text->ApplyBaselineStyle(SUPERIOR, Range(0, text_length)); 434 render_text_->ApplyBaselineStyle(SUPERIOR, Range(0, text_length));
419 render_text->ApplyWeight(Font::Weight::BOLD, Range(2, text_length)); 435 render_text_->ApplyWeight(Font::Weight::BOLD, Range(2, text_length));
420 std::vector<std::pair<size_t, SkColor> > expected_color_end; 436 std::vector<std::pair<size_t, SkColor> > expected_color_end;
421 expected_color_end.push_back(std::pair<size_t, SkColor>(0, SK_ColorRED)); 437 expected_color_end.push_back(std::pair<size_t, SkColor>(0, SK_ColorRED));
422 EXPECT_TRUE(render_text->colors().EqualsForTesting(expected_color_end)); 438 EXPECT_TRUE(render_text_->colors().EqualsForTesting(expected_color_end));
423 std::vector<std::pair<size_t, BaselineStyle>> expected_baseline_end; 439 std::vector<std::pair<size_t, BaselineStyle>> expected_baseline_end;
424 expected_baseline_end.push_back( 440 expected_baseline_end.push_back(
425 std::pair<size_t, BaselineStyle>(0, SUPERIOR)); 441 std::pair<size_t, BaselineStyle>(0, SUPERIOR));
426 EXPECT_TRUE(render_text->baselines().EqualsForTesting(expected_baseline_end)); 442 EXPECT_TRUE(
443 render_text_->baselines().EqualsForTesting(expected_baseline_end));
427 std::vector<std::pair<size_t, Font::Weight>> expected_weight_end; 444 std::vector<std::pair<size_t, Font::Weight>> expected_weight_end;
428 expected_weight_end.push_back( 445 expected_weight_end.push_back(
429 std::pair<size_t, Font::Weight>(0, Font::Weight::NORMAL)); 446 std::pair<size_t, Font::Weight>(0, Font::Weight::NORMAL));
430 expected_weight_end.push_back( 447 expected_weight_end.push_back(
431 std::pair<size_t, Font::Weight>(2, Font::Weight::BOLD)); 448 std::pair<size_t, Font::Weight>(2, Font::Weight::BOLD));
432 EXPECT_TRUE(render_text->weights().EqualsForTesting(expected_weight_end)); 449 EXPECT_TRUE(render_text_->weights().EqualsForTesting(expected_weight_end));
433 450
434 // Ensure ranged values adjust to accommodate text length changes. 451 // Ensure ranged values adjust to accommodate text length changes.
435 render_text->ApplyStyle(ITALIC, true, Range(0, 2)); 452 render_text_->ApplyStyle(ITALIC, true, Range(0, 2));
436 render_text->ApplyStyle(ITALIC, true, Range(3, 6)); 453 render_text_->ApplyStyle(ITALIC, true, Range(3, 6));
437 render_text->ApplyStyle(ITALIC, true, Range(7, text_length)); 454 render_text_->ApplyStyle(ITALIC, true, Range(7, text_length));
438 std::vector<std::pair<size_t, bool> > expected_italic; 455 std::vector<std::pair<size_t, bool> > expected_italic;
439 expected_italic.push_back(std::pair<size_t, bool>(0, true)); 456 expected_italic.push_back(std::pair<size_t, bool>(0, true));
440 expected_italic.push_back(std::pair<size_t, bool>(2, false)); 457 expected_italic.push_back(std::pair<size_t, bool>(2, false));
441 expected_italic.push_back(std::pair<size_t, bool>(3, true)); 458 expected_italic.push_back(std::pair<size_t, bool>(3, true));
442 expected_italic.push_back(std::pair<size_t, bool>(6, false)); 459 expected_italic.push_back(std::pair<size_t, bool>(6, false));
443 expected_italic.push_back(std::pair<size_t, bool>(7, true)); 460 expected_italic.push_back(std::pair<size_t, bool>(7, true));
444 EXPECT_TRUE(render_text->styles()[ITALIC].EqualsForTesting(expected_italic)); 461 EXPECT_TRUE(render_text_->styles()[ITALIC].EqualsForTesting(expected_italic));
445 462
446 // Changing the text should clear any breaks except for the first one. 463 // Changing the text should clear any breaks except for the first one.
447 render_text->SetText(ASCIIToUTF16("0123456")); 464 render_text_->SetText(ASCIIToUTF16("0123456"));
448 expected_italic.resize(1); 465 expected_italic.resize(1);
449 EXPECT_TRUE(render_text->styles()[ITALIC].EqualsForTesting(expected_italic)); 466 EXPECT_TRUE(render_text_->styles()[ITALIC].EqualsForTesting(expected_italic));
450 render_text->ApplyStyle(ITALIC, false, Range(2, 4)); 467 render_text_->ApplyStyle(ITALIC, false, Range(2, 4));
451 render_text->SetText(ASCIIToUTF16("012345678")); 468 render_text_->SetText(ASCIIToUTF16("012345678"));
452 EXPECT_TRUE(render_text->styles()[ITALIC].EqualsForTesting(expected_italic)); 469 EXPECT_TRUE(render_text_->styles()[ITALIC].EqualsForTesting(expected_italic));
453 render_text->ApplyStyle(ITALIC, false, Range(0, 1)); 470 render_text_->ApplyStyle(ITALIC, false, Range(0, 1));
454 render_text->SetText(ASCIIToUTF16("0123456")); 471 render_text_->SetText(ASCIIToUTF16("0123456"));
455 expected_italic.begin()->second = false; 472 expected_italic.begin()->second = false;
456 EXPECT_TRUE(render_text->styles()[ITALIC].EqualsForTesting(expected_italic)); 473 EXPECT_TRUE(render_text_->styles()[ITALIC].EqualsForTesting(expected_italic));
457 render_text->ApplyStyle(ITALIC, true, Range(2, 4)); 474 render_text_->ApplyStyle(ITALIC, true, Range(2, 4));
458 render_text->SetText(ASCIIToUTF16("012345678")); 475 render_text_->SetText(ASCIIToUTF16("012345678"));
459 EXPECT_TRUE(render_text->styles()[ITALIC].EqualsForTesting(expected_italic)); 476 EXPECT_TRUE(render_text_->styles()[ITALIC].EqualsForTesting(expected_italic));
460 477
461 // TODO(tmoniuszko): Enable when RenderTextMac::IsValidCursorIndex is 478 // TODO(tmoniuszko): Enable when RenderTextMac::IsValidCursorIndex is
462 // implemented. 479 // implemented.
463 #if !defined(OS_MACOSX)
464 // Styles shouldn't be changed mid-grapheme. 480 // Styles shouldn't be changed mid-grapheme.
465 render_text->SetText(WideToUTF16( 481 if (GetParam() != RENDER_TEXT_MAC) {
466 L"0" L"\x0915\x093f" L"1" L"\x0915\x093f" L"2")); 482 render_text_->SetText(
467 render_text->ApplyStyle(UNDERLINE, true, Range(2, 5)); 483 WideToUTF16(L"0"
468 std::vector<std::pair<size_t, bool> > expected_underline; 484 L"\x0915\x093f"
469 expected_underline.push_back(std::pair<size_t, bool>(0, false)); 485 L"1"
470 expected_underline.push_back(std::pair<size_t, bool>(1, true)); 486 L"\x0915\x093f"
471 expected_underline.push_back(std::pair<size_t, bool>(6, false)); 487 L"2"));
472 EXPECT_TRUE(render_text->styles()[UNDERLINE].EqualsForTesting( 488 render_text_->ApplyStyle(UNDERLINE, true, Range(2, 5));
473 expected_underline)); 489 std::vector<std::pair<size_t, bool>> expected_underline;
474 #endif // !defined(OS_MACOSX) 490 expected_underline.push_back(std::pair<size_t, bool>(0, false));
491 expected_underline.push_back(std::pair<size_t, bool>(1, true));
492 expected_underline.push_back(std::pair<size_t, bool>(6, false));
493 EXPECT_TRUE(
494 render_text_->styles()[UNDERLINE].EqualsForTesting(expected_underline));
495 }
475 } 496 }
476 497
477 TEST_F(RenderTextTest, AppendTextKeepsStyles) { 498 TEST_P(RenderTextTestAll, AppendTextKeepsStyles) {
478 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance());
479 // Setup basic functionality. 499 // Setup basic functionality.
480 render_text->SetText(ASCIIToUTF16("abc")); 500 render_text_->SetText(ASCIIToUTF16("abc"));
481 render_text->ApplyColor(SK_ColorRED, Range(0, 1)); 501 render_text_->ApplyColor(SK_ColorRED, Range(0, 1));
482 render_text->ApplyBaselineStyle(SUPERSCRIPT, Range(1, 2)); 502 render_text_->ApplyBaselineStyle(SUPERSCRIPT, Range(1, 2));
483 render_text->ApplyStyle(UNDERLINE, true, Range(2, 3)); 503 render_text_->ApplyStyle(UNDERLINE, true, Range(2, 3));
484 // Verify basic functionality. 504 // Verify basic functionality.
485 std::vector<std::pair<size_t, SkColor>> expected_color; 505 std::vector<std::pair<size_t, SkColor>> expected_color;
486 expected_color.push_back(std::pair<size_t, SkColor>(0, SK_ColorRED)); 506 expected_color.push_back(std::pair<size_t, SkColor>(0, SK_ColorRED));
487 expected_color.push_back(std::pair<size_t, SkColor>(1, SK_ColorBLACK)); 507 expected_color.push_back(std::pair<size_t, SkColor>(1, SK_ColorBLACK));
488 EXPECT_TRUE(render_text->colors().EqualsForTesting(expected_color)); 508 EXPECT_TRUE(render_text_->colors().EqualsForTesting(expected_color));
489 std::vector<std::pair<size_t, BaselineStyle>> expected_baseline; 509 std::vector<std::pair<size_t, BaselineStyle>> expected_baseline;
490 expected_baseline.push_back( 510 expected_baseline.push_back(
491 std::pair<size_t, BaselineStyle>(0, NORMAL_BASELINE)); 511 std::pair<size_t, BaselineStyle>(0, NORMAL_BASELINE));
492 expected_baseline.push_back(std::pair<size_t, BaselineStyle>(1, SUPERSCRIPT)); 512 expected_baseline.push_back(std::pair<size_t, BaselineStyle>(1, SUPERSCRIPT));
493 expected_baseline.push_back( 513 expected_baseline.push_back(
494 std::pair<size_t, BaselineStyle>(2, NORMAL_BASELINE)); 514 std::pair<size_t, BaselineStyle>(2, NORMAL_BASELINE));
495 EXPECT_TRUE(render_text->baselines().EqualsForTesting(expected_baseline)); 515 EXPECT_TRUE(render_text_->baselines().EqualsForTesting(expected_baseline));
496 std::vector<std::pair<size_t, bool>> expected_style; 516 std::vector<std::pair<size_t, bool>> expected_style;
497 expected_style.push_back(std::pair<size_t, bool>(0, false)); 517 expected_style.push_back(std::pair<size_t, bool>(0, false));
498 expected_style.push_back(std::pair<size_t, bool>(2, true)); 518 expected_style.push_back(std::pair<size_t, bool>(2, true));
499 EXPECT_TRUE( 519 EXPECT_TRUE(
500 render_text->styles()[UNDERLINE].EqualsForTesting(expected_style)); 520 render_text_->styles()[UNDERLINE].EqualsForTesting(expected_style));
501 // Ensure AppendText maintains current text styles. 521 // Ensure AppendText maintains current text styles.
502 render_text->AppendText(ASCIIToUTF16("def")); 522 render_text_->AppendText(ASCIIToUTF16("def"));
503 EXPECT_EQ(render_text->GetDisplayText(), ASCIIToUTF16("abcdef")); 523 EXPECT_EQ(render_text_->GetDisplayText(), ASCIIToUTF16("abcdef"));
504 EXPECT_TRUE(render_text->colors().EqualsForTesting(expected_color)); 524 EXPECT_TRUE(render_text_->colors().EqualsForTesting(expected_color));
505 EXPECT_TRUE(render_text->baselines().EqualsForTesting(expected_baseline)); 525 EXPECT_TRUE(render_text_->baselines().EqualsForTesting(expected_baseline));
506 EXPECT_TRUE( 526 EXPECT_TRUE(
507 render_text->styles()[UNDERLINE].EqualsForTesting(expected_style)); 527 render_text_->styles()[UNDERLINE].EqualsForTesting(expected_style));
508 } 528 }
509 529
510 void TestVisualCursorMotionInObscuredField( 530 void TestVisualCursorMotionInObscuredField(
511 RenderText* render_text, 531 RenderText* render_text,
512 const base::string16& text, 532 const base::string16& text,
513 SelectionBehavior selection_behavior) { 533 SelectionBehavior selection_behavior) {
514 const bool select = selection_behavior != SELECTION_NONE; 534 const bool select = selection_behavior != SELECTION_NONE;
515 ASSERT_TRUE(render_text->obscured()); 535 ASSERT_TRUE(render_text->obscured());
516 render_text->SetText(text); 536 render_text->SetText(text);
517 int len = text.length(); 537 int len = text.length();
(...skipping 13 matching lines...) Expand all
531 render_text->selection_model()); 551 render_text->selection_model());
532 } 552 }
533 render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, selection_behavior); 553 render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, selection_behavior);
534 EXPECT_EQ(SelectionModel(Range(select ? 0 : len, len), CURSOR_FORWARD), 554 EXPECT_EQ(SelectionModel(Range(select ? 0 : len, len), CURSOR_FORWARD),
535 render_text->selection_model()); 555 render_text->selection_model());
536 render_text->MoveCursor(WORD_BREAK, CURSOR_LEFT, selection_behavior); 556 render_text->MoveCursor(WORD_BREAK, CURSOR_LEFT, selection_behavior);
537 EXPECT_EQ(SelectionModel(0, CURSOR_BACKWARD), render_text->selection_model()); 557 EXPECT_EQ(SelectionModel(0, CURSOR_BACKWARD), render_text->selection_model());
538 } 558 }
539 559
540 // TODO(asvitkine): RenderTextMac cursor movements. http://crbug.com/131618 560 // TODO(asvitkine): RenderTextMac cursor movements. http://crbug.com/131618
541 #if !defined(OS_MACOSX) 561 TEST_P(RenderTextHarfBuzzTest, ObscuredText) {
542 TEST_F(RenderTextTest, ObscuredText) {
543 const base::string16 seuss = ASCIIToUTF16("hop on pop"); 562 const base::string16 seuss = ASCIIToUTF16("hop on pop");
544 const base::string16 no_seuss = ASCIIToUTF16("**********"); 563 const base::string16 no_seuss = ASCIIToUTF16("**********");
545 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance());
546 564
547 // GetLayoutText() returns asterisks when the obscured bit is set. 565 // GetLayoutText() returns asterisks when the obscured bit is set.
548 render_text->SetText(seuss); 566 render_text_->SetText(seuss);
549 render_text->SetObscured(true); 567 render_text_->SetObscured(true);
550 EXPECT_EQ(seuss, render_text->text()); 568 EXPECT_EQ(seuss, render_text_->text());
551 EXPECT_EQ(no_seuss, render_text->GetDisplayText()); 569 EXPECT_EQ(no_seuss, render_text_->GetDisplayText());
552 render_text->SetObscured(false); 570 render_text_->SetObscured(false);
553 EXPECT_EQ(seuss, render_text->text()); 571 EXPECT_EQ(seuss, render_text_->text());
554 EXPECT_EQ(seuss, render_text->GetDisplayText()); 572 EXPECT_EQ(seuss, render_text_->GetDisplayText());
555 573
556 render_text->SetObscured(true); 574 render_text_->SetObscured(true);
557 575
558 // Surrogate pairs are counted as one code point. 576 // Surrogate pairs are counted as one code point.
559 const base::char16 invalid_surrogates[] = {0xDC00, 0xD800, 0}; 577 const base::char16 invalid_surrogates[] = {0xDC00, 0xD800, 0};
560 render_text->SetText(invalid_surrogates); 578 render_text_->SetText(invalid_surrogates);
561 EXPECT_EQ(ASCIIToUTF16("**"), render_text->GetDisplayText()); 579 EXPECT_EQ(ASCIIToUTF16("**"), render_text_->GetDisplayText());
562 const base::char16 valid_surrogates[] = {0xD800, 0xDC00, 0}; 580 const base::char16 valid_surrogates[] = {0xD800, 0xDC00, 0};
563 render_text->SetText(valid_surrogates); 581 render_text_->SetText(valid_surrogates);
564 EXPECT_EQ(ASCIIToUTF16("*"), render_text->GetDisplayText()); 582 EXPECT_EQ(ASCIIToUTF16("*"), render_text_->GetDisplayText());
565 EXPECT_EQ(0U, render_text->cursor_position()); 583 EXPECT_EQ(0U, render_text_->cursor_position());
566 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, SELECTION_NONE); 584 render_text_->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, SELECTION_NONE);
567 EXPECT_EQ(2U, render_text->cursor_position()); 585 EXPECT_EQ(2U, render_text_->cursor_position());
568 586
569 // Test index conversion and cursor validity with a valid surrogate pair. 587 // Test index conversion and cursor validity with a valid surrogate pair.
570 EXPECT_EQ(0U, render_text->TextIndexToDisplayIndex(0U)); 588 EXPECT_EQ(0U, render_text_->TextIndexToDisplayIndex(0U));
571 EXPECT_EQ(1U, render_text->TextIndexToDisplayIndex(1U)); 589 EXPECT_EQ(1U, render_text_->TextIndexToDisplayIndex(1U));
572 EXPECT_EQ(1U, render_text->TextIndexToDisplayIndex(2U)); 590 EXPECT_EQ(1U, render_text_->TextIndexToDisplayIndex(2U));
573 EXPECT_EQ(0U, render_text->DisplayIndexToTextIndex(0U)); 591 EXPECT_EQ(0U, render_text_->DisplayIndexToTextIndex(0U));
574 EXPECT_EQ(2U, render_text->DisplayIndexToTextIndex(1U)); 592 EXPECT_EQ(2U, render_text_->DisplayIndexToTextIndex(1U));
575 EXPECT_TRUE(render_text->IsValidCursorIndex(0U)); 593 EXPECT_TRUE(render_text_->IsValidCursorIndex(0U));
576 EXPECT_FALSE(render_text->IsValidCursorIndex(1U)); 594 EXPECT_FALSE(render_text_->IsValidCursorIndex(1U));
577 EXPECT_TRUE(render_text->IsValidCursorIndex(2U)); 595 EXPECT_TRUE(render_text_->IsValidCursorIndex(2U));
578 596
579 // FindCursorPosition() should not return positions between a surrogate pair. 597 // FindCursorPosition() should not return positions between a surrogate pair.
580 render_text->SetDisplayRect(Rect(0, 0, 20, 20)); 598 render_text_->SetDisplayRect(Rect(0, 0, 20, 20));
581 EXPECT_EQ(render_text->FindCursorPosition(Point(0, 0)).caret_pos(), 0U); 599 EXPECT_EQ(render_text_->FindCursorPosition(Point(0, 0)).caret_pos(), 0U);
582 EXPECT_EQ(render_text->FindCursorPosition(Point(20, 0)).caret_pos(), 2U); 600 EXPECT_EQ(render_text_->FindCursorPosition(Point(20, 0)).caret_pos(), 2U);
583 for (int x = -1; x <= 20; ++x) { 601 for (int x = -1; x <= 20; ++x) {
584 SelectionModel selection = render_text->FindCursorPosition(Point(x, 0)); 602 SelectionModel selection = render_text_->FindCursorPosition(Point(x, 0));
585 EXPECT_TRUE(selection.caret_pos() == 0U || selection.caret_pos() == 2U); 603 EXPECT_TRUE(selection.caret_pos() == 0U || selection.caret_pos() == 2U);
586 } 604 }
587 605
588 // GetGlyphBounds() should yield the entire string bounds for text index 0. 606 // GetGlyphBounds() should yield the entire string bounds for text index 0.
589 EXPECT_EQ(render_text->GetStringSize().width(), 607 EXPECT_EQ(render_text_->GetStringSize().width(),
590 static_cast<int>(render_text->GetGlyphBounds(0U).length())); 608 static_cast<int>(render_text_->GetGlyphBounds(0U).length()));
591 609
592 // Cursoring is independent of underlying characters when text is obscured. 610 // Cursoring is independent of underlying characters when text is obscured.
593 const wchar_t* const texts[] = { 611 const wchar_t* const texts[] = {
594 kWeak, kLtr, kLtrRtl, kLtrRtlLtr, kRtl, kRtlLtr, kRtlLtrRtl, 612 kWeak, kLtr, kLtrRtl, kLtrRtlLtr, kRtl, kRtlLtr, kRtlLtrRtl,
595 L"hop on pop", // Check LTR word boundaries. 613 L"hop on pop", // Check LTR word boundaries.
596 L"\x05d0\x05d1 \x05d0\x05d2 \x05d1\x05d2", // Check RTL word boundaries. 614 L"\x05d0\x05d1 \x05d0\x05d2 \x05d1\x05d2", // Check RTL word boundaries.
597 }; 615 };
598 for (size_t i = 0; i < arraysize(texts); ++i) { 616 for (size_t i = 0; i < arraysize(texts); ++i) {
599 base::string16 text = WideToUTF16(texts[i]); 617 base::string16 text = WideToUTF16(texts[i]);
600 TestVisualCursorMotionInObscuredField(render_text.get(), text, 618 TestVisualCursorMotionInObscuredField(render_text_.get(), text,
601 SELECTION_NONE); 619 SELECTION_NONE);
602 TestVisualCursorMotionInObscuredField(render_text.get(), text, 620 TestVisualCursorMotionInObscuredField(render_text_.get(), text,
603 SELECTION_RETAIN); 621 SELECTION_RETAIN);
604 } 622 }
605 } 623 }
606 #endif // !defined(OS_MACOSX)
607 624
608 TEST_F(RenderTextTest, RevealObscuredText) { 625 TEST_P(RenderTextTestAll, RevealObscuredText) {
609 const base::string16 seuss = ASCIIToUTF16("hop on pop"); 626 const base::string16 seuss = ASCIIToUTF16("hop on pop");
610 const base::string16 no_seuss = ASCIIToUTF16("**********"); 627 const base::string16 no_seuss = ASCIIToUTF16("**********");
611 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance());
612 628
613 render_text->SetText(seuss); 629 render_text_->SetText(seuss);
614 render_text->SetObscured(true); 630 render_text_->SetObscured(true);
615 EXPECT_EQ(seuss, render_text->text()); 631 EXPECT_EQ(seuss, render_text_->text());
616 EXPECT_EQ(no_seuss, render_text->GetDisplayText()); 632 EXPECT_EQ(no_seuss, render_text_->GetDisplayText());
617 633
618 // Valid reveal index and new revealed index clears previous one. 634 // Valid reveal index and new revealed index clears previous one.
619 render_text->RenderText::SetObscuredRevealIndex(0); 635 render_text_->RenderText::SetObscuredRevealIndex(0);
620 EXPECT_EQ(ASCIIToUTF16("h*********"), render_text->GetDisplayText()); 636 EXPECT_EQ(ASCIIToUTF16("h*********"), render_text_->GetDisplayText());
621 render_text->RenderText::SetObscuredRevealIndex(1); 637 render_text_->RenderText::SetObscuredRevealIndex(1);
622 EXPECT_EQ(ASCIIToUTF16("*o********"), render_text->GetDisplayText()); 638 EXPECT_EQ(ASCIIToUTF16("*o********"), render_text_->GetDisplayText());
623 render_text->RenderText::SetObscuredRevealIndex(2); 639 render_text_->RenderText::SetObscuredRevealIndex(2);
624 EXPECT_EQ(ASCIIToUTF16("**p*******"), render_text->GetDisplayText()); 640 EXPECT_EQ(ASCIIToUTF16("**p*******"), render_text_->GetDisplayText());
625 641
626 // Invalid reveal index. 642 // Invalid reveal index.
627 render_text->RenderText::SetObscuredRevealIndex(-1); 643 render_text_->RenderText::SetObscuredRevealIndex(-1);
628 EXPECT_EQ(no_seuss, render_text->GetDisplayText()); 644 EXPECT_EQ(no_seuss, render_text_->GetDisplayText());
629 render_text->RenderText::SetObscuredRevealIndex(seuss.length() + 1); 645 render_text_->RenderText::SetObscuredRevealIndex(seuss.length() + 1);
630 EXPECT_EQ(no_seuss, render_text->GetDisplayText()); 646 EXPECT_EQ(no_seuss, render_text_->GetDisplayText());
631 647
632 // SetObscured clears the revealed index. 648 // SetObscured clears the revealed index.
633 render_text->RenderText::SetObscuredRevealIndex(0); 649 render_text_->RenderText::SetObscuredRevealIndex(0);
634 EXPECT_EQ(ASCIIToUTF16("h*********"), render_text->GetDisplayText()); 650 EXPECT_EQ(ASCIIToUTF16("h*********"), render_text_->GetDisplayText());
635 render_text->SetObscured(false); 651 render_text_->SetObscured(false);
636 EXPECT_EQ(seuss, render_text->GetDisplayText()); 652 EXPECT_EQ(seuss, render_text_->GetDisplayText());
637 render_text->SetObscured(true); 653 render_text_->SetObscured(true);
638 EXPECT_EQ(no_seuss, render_text->GetDisplayText()); 654 EXPECT_EQ(no_seuss, render_text_->GetDisplayText());
639 655
640 // SetText clears the revealed index. 656 // SetText clears the revealed index.
641 render_text->SetText(ASCIIToUTF16("new")); 657 render_text_->SetText(ASCIIToUTF16("new"));
642 EXPECT_EQ(ASCIIToUTF16("***"), render_text->GetDisplayText()); 658 EXPECT_EQ(ASCIIToUTF16("***"), render_text_->GetDisplayText());
643 render_text->RenderText::SetObscuredRevealIndex(2); 659 render_text_->RenderText::SetObscuredRevealIndex(2);
644 EXPECT_EQ(ASCIIToUTF16("**w"), render_text->GetDisplayText()); 660 EXPECT_EQ(ASCIIToUTF16("**w"), render_text_->GetDisplayText());
645 render_text->SetText(ASCIIToUTF16("new longer")); 661 render_text_->SetText(ASCIIToUTF16("new longer"));
646 EXPECT_EQ(ASCIIToUTF16("**********"), render_text->GetDisplayText()); 662 EXPECT_EQ(ASCIIToUTF16("**********"), render_text_->GetDisplayText());
647 663
648 // Text with invalid surrogates. 664 // Text with invalid surrogates.
649 const base::char16 invalid_surrogates[] = {0xDC00, 0xD800, 'h', 'o', 'p', 0}; 665 const base::char16 invalid_surrogates[] = {0xDC00, 0xD800, 'h', 'o', 'p', 0};
650 render_text->SetText(invalid_surrogates); 666 render_text_->SetText(invalid_surrogates);
651 EXPECT_EQ(ASCIIToUTF16("*****"), render_text->GetDisplayText()); 667 EXPECT_EQ(ASCIIToUTF16("*****"), render_text_->GetDisplayText());
652 render_text->RenderText::SetObscuredRevealIndex(0); 668 render_text_->RenderText::SetObscuredRevealIndex(0);
653 const base::char16 invalid_expect_0[] = {0xDC00, '*', '*', '*', '*', 0}; 669 const base::char16 invalid_expect_0[] = {0xDC00, '*', '*', '*', '*', 0};
654 EXPECT_EQ(invalid_expect_0, render_text->GetDisplayText()); 670 EXPECT_EQ(invalid_expect_0, render_text_->GetDisplayText());
655 render_text->RenderText::SetObscuredRevealIndex(1); 671 render_text_->RenderText::SetObscuredRevealIndex(1);
656 const base::char16 invalid_expect_1[] = {'*', 0xD800, '*', '*', '*', 0}; 672 const base::char16 invalid_expect_1[] = {'*', 0xD800, '*', '*', '*', 0};
657 EXPECT_EQ(invalid_expect_1, render_text->GetDisplayText()); 673 EXPECT_EQ(invalid_expect_1, render_text_->GetDisplayText());
658 render_text->RenderText::SetObscuredRevealIndex(2); 674 render_text_->RenderText::SetObscuredRevealIndex(2);
659 EXPECT_EQ(ASCIIToUTF16("**h**"), render_text->GetDisplayText()); 675 EXPECT_EQ(ASCIIToUTF16("**h**"), render_text_->GetDisplayText());
660 676
661 // Text with valid surrogates before and after the reveal index. 677 // Text with valid surrogates before and after the reveal index.
662 const base::char16 valid_surrogates[] = 678 const base::char16 valid_surrogates[] =
663 {0xD800, 0xDC00, 'h', 'o', 'p', 0xD800, 0xDC00, 0}; 679 {0xD800, 0xDC00, 'h', 'o', 'p', 0xD800, 0xDC00, 0};
664 render_text->SetText(valid_surrogates); 680 render_text_->SetText(valid_surrogates);
665 EXPECT_EQ(ASCIIToUTF16("*****"), render_text->GetDisplayText()); 681 EXPECT_EQ(ASCIIToUTF16("*****"), render_text_->GetDisplayText());
666 render_text->RenderText::SetObscuredRevealIndex(0); 682 render_text_->RenderText::SetObscuredRevealIndex(0);
667 const base::char16 valid_expect_0_and_1[] = 683 const base::char16 valid_expect_0_and_1[] =
668 {0xD800, 0xDC00, '*', '*', '*', '*', 0}; 684 {0xD800, 0xDC00, '*', '*', '*', '*', 0};
669 EXPECT_EQ(valid_expect_0_and_1, render_text->GetDisplayText()); 685 EXPECT_EQ(valid_expect_0_and_1, render_text_->GetDisplayText());
670 render_text->RenderText::SetObscuredRevealIndex(1); 686 render_text_->RenderText::SetObscuredRevealIndex(1);
671 EXPECT_EQ(valid_expect_0_and_1, render_text->GetDisplayText()); 687 EXPECT_EQ(valid_expect_0_and_1, render_text_->GetDisplayText());
672 render_text->RenderText::SetObscuredRevealIndex(2); 688 render_text_->RenderText::SetObscuredRevealIndex(2);
673 EXPECT_EQ(ASCIIToUTF16("*h***"), render_text->GetDisplayText()); 689 EXPECT_EQ(ASCIIToUTF16("*h***"), render_text_->GetDisplayText());
674 render_text->RenderText::SetObscuredRevealIndex(5); 690 render_text_->RenderText::SetObscuredRevealIndex(5);
675 const base::char16 valid_expect_5_and_6[] = 691 const base::char16 valid_expect_5_and_6[] =
676 {'*', '*', '*', '*', 0xD800, 0xDC00, 0}; 692 {'*', '*', '*', '*', 0xD800, 0xDC00, 0};
677 EXPECT_EQ(valid_expect_5_and_6, render_text->GetDisplayText()); 693 EXPECT_EQ(valid_expect_5_and_6, render_text_->GetDisplayText());
678 render_text->RenderText::SetObscuredRevealIndex(6); 694 render_text_->RenderText::SetObscuredRevealIndex(6);
679 EXPECT_EQ(valid_expect_5_and_6, render_text->GetDisplayText()); 695 EXPECT_EQ(valid_expect_5_and_6, render_text_->GetDisplayText());
680 } 696 }
681 697
682 TEST_F(RenderTextTest, ObscuredEmoji) { 698 TEST_P(RenderTextTestAll, ObscuredEmoji) {
683 // Ensures text itemization doesn't crash on obscured multi-char glyphs. 699 // Ensures text itemization doesn't crash on obscured multi-char glyphs.
684 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 700 render_text_->SetObscured(true);
685 render_text->SetObscured(true);
686 Canvas canvas;
687 // Test the "Grinning face with smiling eyes" character followed by 'y'. 701 // Test the "Grinning face with smiling eyes" character followed by 'y'.
688 render_text->SetText(UTF8ToUTF16("\xF0\x9F\x98\x81y")); 702 render_text_->SetText(UTF8ToUTF16("\xF0\x9F\x98\x81y"));
689 render_text->Draw(&canvas); 703 render_text_->Draw(&canvas_);
690 // Test two "Camera" characters in a row. 704 // Test two "Camera" characters in a row.
691 render_text->SetText(UTF8ToUTF16("\xF0\x9F\x93\xB7\xF0\x9F\x93\xB7")); 705 render_text_->SetText(UTF8ToUTF16("\xF0\x9F\x93\xB7\xF0\x9F\x93\xB7"));
692 render_text->Draw(&canvas); 706 render_text_->Draw(&canvas_);
693 } 707 }
694 708
695 // TODO(PORT): Fails for RenderTextMac. 709 // TODO(PORT): Fails for RenderTextMac.
710 // Crashes on Mac with RenderTextHarfBuzz. See http://crbug.com/640068.
696 #if !defined(OS_MACOSX) 711 #if !defined(OS_MACOSX)
697 712
698 TEST_F(RenderTextTest, ElidedText) { 713 TEST_P(RenderTextTestAll, ElidedText) {
699 // TODO(skanuj) : Add more test cases for following 714 // TODO(skanuj) : Add more test cases for following
700 // - RenderText styles. 715 // - RenderText styles.
701 // - Cross interaction of truncate, elide and obscure. 716 // - Cross interaction of truncate, elide and obscure.
702 // - ElideText tests from text_elider.cc. 717 // - ElideText tests from text_elider.cc.
703 struct { 718 struct {
704 const wchar_t* text; 719 const wchar_t* text;
705 const wchar_t* display_text; 720 const wchar_t* display_text;
706 const bool elision_expected; 721 const bool elision_expected;
707 } cases[] = { 722 } cases[] = {
708 // Strings shorter than the elision width should be laid out in full. 723 // Strings shorter than the elision width should be laid out in full.
(...skipping 28 matching lines...) Expand all
737 // U+05E9 U+05BC U+05C1 U+05B8 forms a four-character compound glyph. Again, 752 // U+05E9 U+05BC U+05C1 U+05B8 forms a four-character compound glyph. Again,
738 // it should be either fully elided, or not elided at all. If completely 753 // it should be either fully elided, or not elided at all. If completely
739 // elided, an LTR Mark (U+200E) should be added. 754 // elided, an LTR Mark (U+200E) should be added.
740 { L"0\x05e9\x05bc\x05c1\x05b8", L"0\x05e9\x05bc\x05c1\x05b8", false }, 755 { L"0\x05e9\x05bc\x05c1\x05b8", L"0\x05e9\x05bc\x05c1\x05b8", false },
741 { L"0\x05e9\x05bc\x05c1\x05b8", L"0\x2026\x200E" , true }, 756 { L"0\x05e9\x05bc\x05c1\x05b8", L"0\x2026\x200E" , true },
742 { L"01\x05e9\x05bc\x05c1\x05b8", L"01\x2026\x200E" , true }, 757 { L"01\x05e9\x05bc\x05c1\x05b8", L"01\x2026\x200E" , true },
743 { L"012\x05e9\x05bc\x05c1\x05b8", L"012\x2026\x200E" , true }, 758 { L"012\x05e9\x05bc\x05c1\x05b8", L"012\x2026\x200E" , true },
744 { L"012\xF0\x9D\x84\x9E", L"012\xF0\x2026" , true }, 759 { L"012\xF0\x9D\x84\x9E", L"012\xF0\x2026" , true },
745 }; 760 };
746 761
747 std::unique_ptr<RenderText> expected_render_text( 762 std::unique_ptr<RenderText> expected_render_text(CreateRenderTextInstance());
748 RenderText::CreateInstance());
749 expected_render_text->SetFontList(FontList("serif, Sans serif, 12px")); 763 expected_render_text->SetFontList(FontList("serif, Sans serif, 12px"));
750 expected_render_text->SetDisplayRect(Rect(0, 0, 9999, 100)); 764 expected_render_text->SetDisplayRect(Rect(0, 0, 9999, 100));
751 765
752 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 766 render_text_->SetFontList(FontList("serif, Sans serif, 12px"));
753 render_text->SetFontList(FontList("serif, Sans serif, 12px")); 767 render_text_->SetElideBehavior(ELIDE_TAIL);
754 render_text->SetElideBehavior(ELIDE_TAIL);
755 768
756 for (size_t i = 0; i < arraysize(cases); i++) { 769 for (size_t i = 0; i < arraysize(cases); i++) {
757 SCOPED_TRACE(base::StringPrintf("Testing cases[%" PRIuS "] '%ls'", i, 770 SCOPED_TRACE(base::StringPrintf("Testing cases[%" PRIuS "] '%ls'", i,
758 cases[i].text)); 771 cases[i].text));
759 772
760 // Compute expected width 773 // Compute expected width
761 expected_render_text->SetText(WideToUTF16(cases[i].display_text)); 774 expected_render_text->SetText(WideToUTF16(cases[i].display_text));
762 int expected_width = expected_render_text->GetContentWidth(); 775 int expected_width = expected_render_text->GetContentWidth();
763 776
764 base::string16 input = WideToUTF16(cases[i].text); 777 base::string16 input = WideToUTF16(cases[i].text);
765 // Extend the input text to ensure that it is wider than the display_text, 778 // Extend the input text to ensure that it is wider than the display_text,
766 // and so it will get elided. 779 // and so it will get elided.
767 if (cases[i].elision_expected) 780 if (cases[i].elision_expected)
768 input.append(WideToUTF16(L" MMMMMMMMMMM")); 781 input.append(WideToUTF16(L" MMMMMMMMMMM"));
769 render_text->SetText(input); 782 render_text_->SetText(input);
770 render_text->SetDisplayRect(Rect(0, 0, expected_width, 100)); 783 render_text_->SetDisplayRect(Rect(0, 0, expected_width, 100));
771 EXPECT_EQ(input, render_text->text()); 784 EXPECT_EQ(input, render_text_->text());
772 EXPECT_EQ(WideToUTF16(cases[i].display_text), 785 EXPECT_EQ(WideToUTF16(cases[i].display_text),
773 render_text->GetDisplayText()); 786 render_text_->GetDisplayText());
774 expected_render_text->SetText(base::string16()); 787 expected_render_text->SetText(base::string16());
775 } 788 }
776 } 789 }
777 790
778 TEST_F(RenderTextTest, ElidedObscuredText) { 791 TEST_P(RenderTextTestAll, ElidedObscuredText) {
779 std::unique_ptr<RenderText> expected_render_text( 792 std::unique_ptr<RenderText> expected_render_text(CreateRenderTextInstance());
780 RenderText::CreateInstance());
781 expected_render_text->SetFontList(FontList("serif, Sans serif, 12px")); 793 expected_render_text->SetFontList(FontList("serif, Sans serif, 12px"));
782 expected_render_text->SetDisplayRect(Rect(0, 0, 9999, 100)); 794 expected_render_text->SetDisplayRect(Rect(0, 0, 9999, 100));
783 expected_render_text->SetText(WideToUTF16(L"**\x2026")); 795 expected_render_text->SetText(WideToUTF16(L"**\x2026"));
784 796
785 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 797 render_text_->SetFontList(FontList("serif, Sans serif, 12px"));
786 render_text->SetFontList(FontList("serif, Sans serif, 12px")); 798 render_text_->SetElideBehavior(ELIDE_TAIL);
787 render_text->SetElideBehavior(ELIDE_TAIL); 799 render_text_->SetDisplayRect(
788 render_text->SetDisplayRect(
789 Rect(0, 0, expected_render_text->GetContentWidth(), 100)); 800 Rect(0, 0, expected_render_text->GetContentWidth(), 100));
790 render_text->SetObscured(true); 801 render_text_->SetObscured(true);
791 render_text->SetText(WideToUTF16(L"abcdef")); 802 render_text_->SetText(WideToUTF16(L"abcdef"));
792 EXPECT_EQ(WideToUTF16(L"abcdef"), render_text->text()); 803 EXPECT_EQ(WideToUTF16(L"abcdef"), render_text_->text());
793 EXPECT_EQ(WideToUTF16(L"**\x2026"), render_text->GetDisplayText()); 804 EXPECT_EQ(WideToUTF16(L"**\x2026"), render_text_->GetDisplayText());
794 } 805 }
806 #endif // !defined(OS_MACOSX)
795 807
796 TEST_F(RenderTextTest, MultilineElide) { 808 // TODO(PORT): Fails for RenderTextMac.
797 std::unique_ptr<RenderText> render_text(new RenderTextHarfBuzz); 809 TEST_P(RenderTextHarfBuzzTest, MultilineElide) {
798 base::string16 input_text; 810 base::string16 input_text;
799 // Aim for 3 lines of text. 811 // Aim for 3 lines of text.
800 for (int i = 0; i < 20; ++i) 812 for (int i = 0; i < 20; ++i)
801 input_text.append(ASCIIToUTF16("hello world ")); 813 input_text.append(ASCIIToUTF16("hello world "));
802 render_text->SetText(input_text); 814 render_text_->SetText(input_text);
803 // Apply a style that tweaks the layout to make sure elision is calculated 815 // Apply a style that tweaks the layout to make sure elision is calculated
804 // with these styles. This can expose a behavior in layout where text is 816 // with these styles. This can expose a behavior in layout where text is
805 // slightly different width. This must be done after |SetText()|. 817 // slightly different width. This must be done after |SetText()|.
806 render_text->ApplyWeight(Font::Weight::BOLD, Range(1, 20)); 818 render_text_->ApplyWeight(Font::Weight::BOLD, Range(1, 20));
807 render_text->ApplyStyle(ITALIC, true, Range(1, 20)); 819 render_text_->ApplyStyle(ITALIC, true, Range(1, 20));
808 render_text->ApplyStyle(DIAGONAL_STRIKE, true, Range(1, 20)); 820 render_text_->ApplyStyle(DIAGONAL_STRIKE, true, Range(1, 20));
809 render_text->SetMultiline(true); 821 render_text_->SetMultiline(true);
810 render_text->SetElideBehavior(ELIDE_TAIL); 822 render_text_->SetElideBehavior(ELIDE_TAIL);
811 render_text->SetMaxLines(3); 823 render_text_->SetMaxLines(3);
812 const Size size = render_text->GetStringSize(); 824 const Size size = render_text_->GetStringSize();
813 // Fit in 3 lines. (If we knew the width of a word, we could 825 // Fit in 3 lines. (If we knew the width of a word, we could
814 // anticipate word wrap better.) 826 // anticipate word wrap better.)
815 render_text->SetDisplayRect(Rect((size.width() + 96) / 3, 0)); 827 render_text_->SetDisplayRect(Rect((size.width() + 96) / 3, 0));
816 // Trigger rendering. 828 // Trigger rendering.
817 render_text->GetStringSize(); 829 render_text_->GetStringSize();
818 EXPECT_EQ(input_text, render_text->GetDisplayText()); 830 EXPECT_EQ(input_text, render_text_->GetDisplayText());
819 831
820 const base::char16 kEllipsisUTF16[] = {0x2026, 0}; 832 const base::char16 kEllipsisUTF16[] = {0x2026, 0};
821 base::string16 actual_text; 833 base::string16 actual_text;
822 // Try widening the space gradually, one pixel at a time, trying 834 // Try widening the space gradually, one pixel at a time, trying
823 // to trigger a failure in layout. There was an issue where, right at 835 // to trigger a failure in layout. There was an issue where, right at
824 // the edge of a word getting truncated, the estimate would be wrong 836 // the edge of a word getting truncated, the estimate would be wrong
825 // and it would wrap instead. 837 // and it would wrap instead.
826 for (int i = (size.width() - 12) / 3; i < (size.width() + 30) / 3; ++i) { 838 for (int i = (size.width() - 12) / 3; i < (size.width() + 30) / 3; ++i) {
827 render_text->SetDisplayRect(Rect(i, 0)); 839 render_text_->SetDisplayRect(Rect(i, 0));
828 // Trigger rendering. 840 // Trigger rendering.
829 render_text->GetStringSize(); 841 render_text_->GetStringSize();
830 actual_text = render_text->GetDisplayText(); 842 actual_text = render_text_->GetDisplayText();
831 EXPECT_LT(actual_text.size(), input_text.size()); 843 EXPECT_LT(actual_text.size(), input_text.size());
832 EXPECT_EQ(actual_text, input_text.substr(0, actual_text.size() - 1) + 844 EXPECT_EQ(actual_text, input_text.substr(0, actual_text.size() - 1) +
833 base::string16(kEllipsisUTF16)); 845 base::string16(kEllipsisUTF16));
834 EXPECT_EQ(3U, render_text->GetNumLines()); 846 EXPECT_EQ(3U, render_text_->GetNumLines());
835 } 847 }
836 // Now remove line restriction. 848 // Now remove line restriction.
837 render_text->SetMaxLines(0); 849 render_text_->SetMaxLines(0);
838 render_text->GetStringSize(); 850 render_text_->GetStringSize();
839 EXPECT_EQ(input_text, render_text->GetDisplayText()); 851 EXPECT_EQ(input_text, render_text_->GetDisplayText());
840 852
841 // And put it back. 853 // And put it back.
842 render_text->SetMaxLines(3); 854 render_text_->SetMaxLines(3);
843 render_text->GetStringSize(); 855 render_text_->GetStringSize();
844 EXPECT_LT(actual_text.size(), input_text.size()); 856 EXPECT_LT(actual_text.size(), input_text.size());
845 EXPECT_EQ(actual_text, input_text.substr(0, actual_text.size() - 1) + 857 EXPECT_EQ(actual_text, input_text.substr(0, actual_text.size() - 1) +
846 base::string16(kEllipsisUTF16)); 858 base::string16(kEllipsisUTF16));
847 } 859 }
848 860
849 #endif // !defined(OS_MACOSX) 861 TEST_P(RenderTextTestAll, ElidedEmail) {
850 862 render_text_->SetText(ASCIIToUTF16("test@example.com"));
851 TEST_F(RenderTextTest, ElidedEmail) { 863 const Size size = render_text_->GetStringSize();
852 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance());
853 render_text->SetText(ASCIIToUTF16("test@example.com"));
854 const Size size = render_text->GetStringSize();
855 864
856 const base::string16 long_email = 865 const base::string16 long_email =
857 ASCIIToUTF16("longemailaddresstest@example.com"); 866 ASCIIToUTF16("longemailaddresstest@example.com");
858 render_text->SetText(long_email); 867 render_text_->SetText(long_email);
859 render_text->SetElideBehavior(ELIDE_EMAIL); 868 render_text_->SetElideBehavior(ELIDE_EMAIL);
860 render_text->SetDisplayRect(Rect(size)); 869 render_text_->SetDisplayRect(Rect(size));
861 EXPECT_GE(size.width(), render_text->GetStringSize().width()); 870 EXPECT_GE(size.width(), render_text_->GetStringSize().width());
862 EXPECT_GT(long_email.size(), render_text->GetDisplayText().size()); 871 EXPECT_GT(long_email.size(), render_text_->GetDisplayText().size());
863 } 872 }
864 873
865 TEST_F(RenderTextTest, TruncatedText) { 874 TEST_P(RenderTextTestAll, TruncatedText) {
866 struct { 875 struct {
867 const wchar_t* text; 876 const wchar_t* text;
868 const wchar_t* display_text; 877 const wchar_t* display_text;
869 } cases[] = { 878 } cases[] = {
870 // Strings shorter than the truncation length should be laid out in full. 879 // Strings shorter than the truncation length should be laid out in full.
871 { L"", L"" }, 880 { L"", L"" },
872 { kWeak, kWeak }, 881 { kWeak, kWeak },
873 { kLtr, kLtr }, 882 { kLtr, kLtr },
874 { kLtrRtl, kLtrRtl }, 883 { kLtrRtl, kLtrRtl },
875 { kLtrRtlLtr, kLtrRtlLtr }, 884 { kLtrRtlLtr, kLtrRtlLtr },
(...skipping 14 matching lines...) Expand all
890 // Surrogate pairs should be truncated reasonably enough. 899 // Surrogate pairs should be truncated reasonably enough.
891 { L"0123\x0915\x093f", L"0123\x2026" }, 900 { L"0123\x0915\x093f", L"0123\x2026" },
892 { L"0\x05e9\x05bc\x05c1\x05b8", L"0\x05e9\x05bc\x05c1\x05b8" }, 901 { L"0\x05e9\x05bc\x05c1\x05b8", L"0\x05e9\x05bc\x05c1\x05b8" },
893 { L"01\x05e9\x05bc\x05c1\x05b8", L"01\x05e9\x05bc\x2026" }, 902 { L"01\x05e9\x05bc\x05c1\x05b8", L"01\x05e9\x05bc\x2026" },
894 { L"012\x05e9\x05bc\x05c1\x05b8", L"012\x05e9\x2026" }, 903 { L"012\x05e9\x05bc\x05c1\x05b8", L"012\x05e9\x2026" },
895 { L"0123\x05e9\x05bc\x05c1\x05b8", L"0123\x2026" }, 904 { L"0123\x05e9\x05bc\x05c1\x05b8", L"0123\x2026" },
896 { L"01234\x05e9\x05bc\x05c1\x05b8", L"0123\x2026" }, 905 { L"01234\x05e9\x05bc\x05c1\x05b8", L"0123\x2026" },
897 { L"012\xF0\x9D\x84\x9E", L"012\xF0\x2026" }, 906 { L"012\xF0\x9D\x84\x9E", L"012\xF0\x2026" },
898 }; 907 };
899 908
900 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 909 render_text_->set_truncate_length(5);
901 render_text->set_truncate_length(5);
902 for (size_t i = 0; i < arraysize(cases); i++) { 910 for (size_t i = 0; i < arraysize(cases); i++) {
903 render_text->SetText(WideToUTF16(cases[i].text)); 911 render_text_->SetText(WideToUTF16(cases[i].text));
904 EXPECT_EQ(WideToUTF16(cases[i].text), render_text->text()); 912 EXPECT_EQ(WideToUTF16(cases[i].text), render_text_->text());
905 EXPECT_EQ(WideToUTF16(cases[i].display_text), render_text->GetDisplayText()) 913 EXPECT_EQ(WideToUTF16(cases[i].display_text),
914 render_text_->GetDisplayText())
906 << "For case " << i << ": " << cases[i].text; 915 << "For case " << i << ": " << cases[i].text;
907 } 916 }
908 } 917 }
909 918
910 TEST_F(RenderTextTest, TruncatedObscuredText) { 919 TEST_P(RenderTextTestAll, TruncatedObscuredText) {
911 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 920 render_text_->set_truncate_length(3);
912 render_text->set_truncate_length(3); 921 render_text_->SetObscured(true);
913 render_text->SetObscured(true); 922 render_text_->SetText(WideToUTF16(L"abcdef"));
914 render_text->SetText(WideToUTF16(L"abcdef")); 923 EXPECT_EQ(WideToUTF16(L"abcdef"), render_text_->text());
915 EXPECT_EQ(WideToUTF16(L"abcdef"), render_text->text()); 924 EXPECT_EQ(WideToUTF16(L"**\x2026"), render_text_->GetDisplayText());
916 EXPECT_EQ(WideToUTF16(L"**\x2026"), render_text->GetDisplayText());
917 } 925 }
918 926
919 // TODO(asvitkine): RenderTextMac cursor movements. http://crbug.com/131618 927 // TODO(asvitkine): RenderTextMac cursor movements. http://crbug.com/131618
920 #if !defined(OS_MACOSX) 928 TEST_P(RenderTextHarfBuzzTest, TruncatedCursorMovementLTR) {
921 TEST_F(RenderTextTest, TruncatedCursorMovementLTR) { 929 render_text_->set_truncate_length(2);
922 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 930 render_text_->SetText(WideToUTF16(L"abcd"));
923 render_text->set_truncate_length(2);
924 render_text->SetText(WideToUTF16(L"abcd"));
925 931
926 EXPECT_EQ(SelectionModel(0, CURSOR_BACKWARD), render_text->selection_model()); 932 EXPECT_EQ(SelectionModel(0, CURSOR_BACKWARD),
927 render_text->MoveCursor(LINE_BREAK, CURSOR_RIGHT, SELECTION_NONE); 933 render_text_->selection_model());
928 EXPECT_EQ(SelectionModel(4, CURSOR_FORWARD), render_text->selection_model()); 934 render_text_->MoveCursor(LINE_BREAK, CURSOR_RIGHT, SELECTION_NONE);
929 render_text->MoveCursor(LINE_BREAK, CURSOR_LEFT, SELECTION_NONE); 935 EXPECT_EQ(SelectionModel(4, CURSOR_FORWARD), render_text_->selection_model());
930 EXPECT_EQ(SelectionModel(0, CURSOR_BACKWARD), render_text->selection_model()); 936 render_text_->MoveCursor(LINE_BREAK, CURSOR_LEFT, SELECTION_NONE);
937 EXPECT_EQ(SelectionModel(0, CURSOR_BACKWARD),
938 render_text_->selection_model());
931 939
932 std::vector<SelectionModel> expected; 940 std::vector<SelectionModel> expected;
933 expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 941 expected.push_back(SelectionModel(0, CURSOR_BACKWARD));
934 expected.push_back(SelectionModel(1, CURSOR_BACKWARD)); 942 expected.push_back(SelectionModel(1, CURSOR_BACKWARD));
935 // The cursor hops over the ellipsis and elided text to the line end. 943 // The cursor hops over the ellipsis and elided text to the line end.
936 expected.push_back(SelectionModel(4, CURSOR_BACKWARD)); 944 expected.push_back(SelectionModel(4, CURSOR_BACKWARD));
937 expected.push_back(SelectionModel(4, CURSOR_FORWARD)); 945 expected.push_back(SelectionModel(4, CURSOR_FORWARD));
938 RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_RIGHT); 946 RunMoveCursorLeftRightTest(render_text_.get(), expected, CURSOR_RIGHT);
939 947
940 expected.clear(); 948 expected.clear();
941 expected.push_back(SelectionModel(4, CURSOR_FORWARD)); 949 expected.push_back(SelectionModel(4, CURSOR_FORWARD));
942 // The cursor hops over the elided text to preceeding text. 950 // The cursor hops over the elided text to preceeding text.
943 expected.push_back(SelectionModel(1, CURSOR_FORWARD)); 951 expected.push_back(SelectionModel(1, CURSOR_FORWARD));
944 expected.push_back(SelectionModel(0, CURSOR_FORWARD)); 952 expected.push_back(SelectionModel(0, CURSOR_FORWARD));
945 expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 953 expected.push_back(SelectionModel(0, CURSOR_BACKWARD));
946 RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_LEFT); 954 RunMoveCursorLeftRightTest(render_text_.get(), expected, CURSOR_LEFT);
947 } 955 }
948 956
949 TEST_F(RenderTextTest, TruncatedCursorMovementRTL) { 957 // TODO(asvitkine): RenderTextMac cursor movements. http://crbug.com/131618
950 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 958 TEST_P(RenderTextHarfBuzzTest, TruncatedCursorMovementRTL) {
951 render_text->set_truncate_length(2); 959 render_text_->set_truncate_length(2);
952 render_text->SetText(WideToUTF16(L"\x5d0\x5d1\x5d2\x5d3")); 960 render_text_->SetText(WideToUTF16(L"\x5d0\x5d1\x5d2\x5d3"));
953 961
954 EXPECT_EQ(SelectionModel(0, CURSOR_BACKWARD), render_text->selection_model()); 962 EXPECT_EQ(SelectionModel(0, CURSOR_BACKWARD),
955 render_text->MoveCursor(LINE_BREAK, CURSOR_LEFT, SELECTION_NONE); 963 render_text_->selection_model());
956 EXPECT_EQ(SelectionModel(4, CURSOR_FORWARD), render_text->selection_model()); 964 render_text_->MoveCursor(LINE_BREAK, CURSOR_LEFT, SELECTION_NONE);
957 render_text->MoveCursor(LINE_BREAK, CURSOR_RIGHT, SELECTION_NONE); 965 EXPECT_EQ(SelectionModel(4, CURSOR_FORWARD), render_text_->selection_model());
958 EXPECT_EQ(SelectionModel(0, CURSOR_BACKWARD), render_text->selection_model()); 966 render_text_->MoveCursor(LINE_BREAK, CURSOR_RIGHT, SELECTION_NONE);
967 EXPECT_EQ(SelectionModel(0, CURSOR_BACKWARD),
968 render_text_->selection_model());
959 969
960 std::vector<SelectionModel> expected; 970 std::vector<SelectionModel> expected;
961 expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 971 expected.push_back(SelectionModel(0, CURSOR_BACKWARD));
962 expected.push_back(SelectionModel(1, CURSOR_BACKWARD)); 972 expected.push_back(SelectionModel(1, CURSOR_BACKWARD));
963 // The cursor hops over the ellipsis and elided text to the line end. 973 // The cursor hops over the ellipsis and elided text to the line end.
964 expected.push_back(SelectionModel(4, CURSOR_BACKWARD)); 974 expected.push_back(SelectionModel(4, CURSOR_BACKWARD));
965 expected.push_back(SelectionModel(4, CURSOR_FORWARD)); 975 expected.push_back(SelectionModel(4, CURSOR_FORWARD));
966 RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_LEFT); 976 RunMoveCursorLeftRightTest(render_text_.get(), expected, CURSOR_LEFT);
967 977
968 expected.clear(); 978 expected.clear();
969 expected.push_back(SelectionModel(4, CURSOR_FORWARD)); 979 expected.push_back(SelectionModel(4, CURSOR_FORWARD));
970 // The cursor hops over the elided text to preceeding text. 980 // The cursor hops over the elided text to preceeding text.
971 expected.push_back(SelectionModel(1, CURSOR_FORWARD)); 981 expected.push_back(SelectionModel(1, CURSOR_FORWARD));
972 expected.push_back(SelectionModel(0, CURSOR_FORWARD)); 982 expected.push_back(SelectionModel(0, CURSOR_FORWARD));
973 expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 983 expected.push_back(SelectionModel(0, CURSOR_BACKWARD));
974 RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_RIGHT); 984 RunMoveCursorLeftRightTest(render_text_.get(), expected, CURSOR_RIGHT);
975 } 985 }
976 #endif // !defined(OS_MACOSX) 986
977 987 // TODO(asvitkine): RenderTextMac cursor movements. http://crbug.com/131618
978 TEST_F(RenderTextTest, MoveCursor_Character) { 988 TEST_P(RenderTextHarfBuzzTest, MoveCursor_Character) {
979 std::unique_ptr<RenderText> render_text( 989 render_text_->SetText(WideToUTF16(L"123 456 789"));
980 RenderText::CreateInstanceForEditing());
981 render_text->SetText(WideToUTF16(L"123 456 789"));
982 std::vector<Range> expected; 990 std::vector<Range> expected;
983 991
984 // SELECTION_NONE. 992 // SELECTION_NONE.
985 render_text->SelectRange(Range(6)); 993 render_text_->SelectRange(Range(6));
986 994
987 // Move right twice. 995 // Move right twice.
988 expected.push_back(Range(7)); 996 expected.push_back(Range(7));
989 expected.push_back(Range(8)); 997 expected.push_back(Range(8));
990 RunMoveCursorTestAndClearExpectations(render_text.get(), CHARACTER_BREAK, 998 RunMoveCursorTestAndClearExpectations(render_text_.get(), CHARACTER_BREAK,
991 CURSOR_RIGHT, SELECTION_NONE, 999 CURSOR_RIGHT, SELECTION_NONE,
992 &expected); 1000 &expected);
993 1001
994 // Move left twice. 1002 // Move left twice.
995 expected.push_back(Range(7)); 1003 expected.push_back(Range(7));
996 expected.push_back(Range(6)); 1004 expected.push_back(Range(6));
997 RunMoveCursorTestAndClearExpectations(render_text.get(), CHARACTER_BREAK, 1005 RunMoveCursorTestAndClearExpectations(render_text_.get(), CHARACTER_BREAK,
998 CURSOR_LEFT, SELECTION_NONE, &expected); 1006 CURSOR_LEFT, SELECTION_NONE, &expected);
999 1007
1000 // SELECTION_CARET. 1008 // SELECTION_CARET.
1001 render_text->SelectRange(Range(6)); 1009 render_text_->SelectRange(Range(6));
1002 expected.push_back(Range(6, 7)); 1010 expected.push_back(Range(6, 7));
1003 1011
1004 // Move right. 1012 // Move right.
1005 RunMoveCursorTestAndClearExpectations(render_text.get(), CHARACTER_BREAK, 1013 RunMoveCursorTestAndClearExpectations(render_text_.get(), CHARACTER_BREAK,
1006 CURSOR_RIGHT, SELECTION_CARET, 1014 CURSOR_RIGHT, SELECTION_CARET,
1007 &expected); 1015 &expected);
1008 1016
1009 // Move left twice. 1017 // Move left twice.
1010 expected.push_back(Range(6)); 1018 expected.push_back(Range(6));
1011 expected.push_back(Range(6, 5)); 1019 expected.push_back(Range(6, 5));
1012 RunMoveCursorTestAndClearExpectations(render_text.get(), CHARACTER_BREAK, 1020 RunMoveCursorTestAndClearExpectations(render_text_.get(), CHARACTER_BREAK,
1013 CURSOR_LEFT, SELECTION_CARET, 1021 CURSOR_LEFT, SELECTION_CARET,
1014 &expected); 1022 &expected);
1015 1023
1016 // SELECTION_RETAIN. 1024 // SELECTION_RETAIN.
1017 render_text->SelectRange(Range(6)); 1025 render_text_->SelectRange(Range(6));
1018 1026
1019 // Move right. 1027 // Move right.
1020 expected.push_back(Range(6, 7)); 1028 expected.push_back(Range(6, 7));
1021 RunMoveCursorTestAndClearExpectations(render_text.get(), CHARACTER_BREAK, 1029 RunMoveCursorTestAndClearExpectations(render_text_.get(), CHARACTER_BREAK,
1022 CURSOR_RIGHT, SELECTION_RETAIN, 1030 CURSOR_RIGHT, SELECTION_RETAIN,
1023 &expected); 1031 &expected);
1024 1032
1025 // Move left twice. 1033 // Move left twice.
1026 expected.push_back(Range(6)); 1034 expected.push_back(Range(6));
1027 expected.push_back(Range(6, 5)); 1035 expected.push_back(Range(6, 5));
1028 RunMoveCursorTestAndClearExpectations(render_text.get(), CHARACTER_BREAK, 1036 RunMoveCursorTestAndClearExpectations(render_text_.get(), CHARACTER_BREAK,
1029 CURSOR_LEFT, SELECTION_RETAIN, 1037 CURSOR_LEFT, SELECTION_RETAIN,
1030 &expected); 1038 &expected);
1031 1039
1032 // SELECTION_EXTEND. 1040 // SELECTION_EXTEND.
1033 render_text->SelectRange(Range(6)); 1041 render_text_->SelectRange(Range(6));
1034 1042
1035 // Move right. 1043 // Move right.
1036 expected.push_back(Range(6, 7)); 1044 expected.push_back(Range(6, 7));
1037 RunMoveCursorTestAndClearExpectations(render_text.get(), CHARACTER_BREAK, 1045 RunMoveCursorTestAndClearExpectations(render_text_.get(), CHARACTER_BREAK,
1038 CURSOR_RIGHT, SELECTION_EXTEND, 1046 CURSOR_RIGHT, SELECTION_EXTEND,
1039 &expected); 1047 &expected);
1040 1048
1041 // Move left twice. 1049 // Move left twice.
1042 expected.push_back(Range(7, 6)); 1050 expected.push_back(Range(7, 6));
1043 expected.push_back(Range(7, 5)); 1051 expected.push_back(Range(7, 5));
1044 RunMoveCursorTestAndClearExpectations(render_text.get(), CHARACTER_BREAK, 1052 RunMoveCursorTestAndClearExpectations(render_text_.get(), CHARACTER_BREAK,
1045 CURSOR_LEFT, SELECTION_EXTEND, 1053 CURSOR_LEFT, SELECTION_EXTEND,
1046 &expected); 1054 &expected);
1047 } 1055 }
1048 1056
1049 TEST_F(RenderTextTest, MoveCursor_Word) { 1057 // TODO(asvitkine): RenderTextMac cursor movements. http://crbug.com/131618
1050 std::unique_ptr<RenderText> render_text( 1058 TEST_P(RenderTextHarfBuzzTest, MoveCursor_Word) {
1051 RenderText::CreateInstanceForEditing()); 1059 render_text_->SetText(WideToUTF16(L"123 456 789"));
1052 render_text->SetText(WideToUTF16(L"123 456 789"));
1053 std::vector<Range> expected; 1060 std::vector<Range> expected;
1054 1061
1055 // SELECTION_NONE. 1062 // SELECTION_NONE.
1056 render_text->SelectRange(Range(6)); 1063 render_text_->SelectRange(Range(6));
1057 1064
1058 // Move left twice. 1065 // Move left twice.
1059 expected.push_back(Range(4)); 1066 expected.push_back(Range(4));
1060 expected.push_back(Range(0)); 1067 expected.push_back(Range(0));
1061 RunMoveCursorTestAndClearExpectations(render_text.get(), WORD_BREAK, 1068 RunMoveCursorTestAndClearExpectations(render_text_.get(), WORD_BREAK,
1062 CURSOR_LEFT, SELECTION_NONE, &expected); 1069 CURSOR_LEFT, SELECTION_NONE, &expected);
1063 1070
1064 // Move right twice. 1071 // Move right twice.
1065 expected.push_back(Range(3)); 1072 expected.push_back(Range(3));
1066 expected.push_back(Range(7)); 1073 expected.push_back(Range(7));
1067 RunMoveCursorTestAndClearExpectations( 1074 RunMoveCursorTestAndClearExpectations(
1068 render_text.get(), WORD_BREAK, CURSOR_RIGHT, SELECTION_NONE, &expected); 1075 render_text_.get(), WORD_BREAK, CURSOR_RIGHT, SELECTION_NONE, &expected);
1069 1076
1070 // SELECTION_CARET. 1077 // SELECTION_CARET.
1071 render_text->SelectRange(Range(6)); 1078 render_text_->SelectRange(Range(6));
1072 1079
1073 // Move left. 1080 // Move left.
1074 expected.push_back(Range(6, 4)); 1081 expected.push_back(Range(6, 4));
1075 RunMoveCursorTestAndClearExpectations( 1082 RunMoveCursorTestAndClearExpectations(
1076 render_text.get(), WORD_BREAK, CURSOR_LEFT, SELECTION_CARET, &expected); 1083 render_text_.get(), WORD_BREAK, CURSOR_LEFT, SELECTION_CARET, &expected);
1077 1084
1078 // Move right twice. 1085 // Move right twice.
1079 expected.push_back(Range(6)); 1086 expected.push_back(Range(6));
1080 expected.push_back(Range(6, 7)); 1087 expected.push_back(Range(6, 7));
1081 RunMoveCursorTestAndClearExpectations( 1088 RunMoveCursorTestAndClearExpectations(
1082 render_text.get(), WORD_BREAK, CURSOR_RIGHT, SELECTION_CARET, &expected); 1089 render_text_.get(), WORD_BREAK, CURSOR_RIGHT, SELECTION_CARET, &expected);
1083 1090
1084 // Move left. 1091 // Move left.
1085 expected.push_back(Range(6)); 1092 expected.push_back(Range(6));
1086 RunMoveCursorTestAndClearExpectations( 1093 RunMoveCursorTestAndClearExpectations(
1087 render_text.get(), WORD_BREAK, CURSOR_LEFT, SELECTION_CARET, &expected); 1094 render_text_.get(), WORD_BREAK, CURSOR_LEFT, SELECTION_CARET, &expected);
1088 1095
1089 // SELECTION_RETAIN. 1096 // SELECTION_RETAIN.
1090 render_text->SelectRange(Range(6)); 1097 render_text_->SelectRange(Range(6));
1091 1098
1092 // Move left. 1099 // Move left.
1093 expected.push_back(Range(6, 4)); 1100 expected.push_back(Range(6, 4));
1094 RunMoveCursorTestAndClearExpectations( 1101 RunMoveCursorTestAndClearExpectations(
1095 render_text.get(), WORD_BREAK, CURSOR_LEFT, SELECTION_RETAIN, &expected); 1102 render_text_.get(), WORD_BREAK, CURSOR_LEFT, SELECTION_RETAIN, &expected);
1096 1103
1097 // Move right twice. 1104 // Move right twice.
1098 expected.push_back(Range(6, 7)); 1105 expected.push_back(Range(6, 7));
1099 expected.push_back(Range(6, 11)); 1106 expected.push_back(Range(6, 11));
1100 RunMoveCursorTestAndClearExpectations( 1107 RunMoveCursorTestAndClearExpectations(render_text_.get(), WORD_BREAK,
1101 render_text.get(), WORD_BREAK, CURSOR_RIGHT, SELECTION_RETAIN, &expected); 1108 CURSOR_RIGHT, SELECTION_RETAIN,
1109 &expected);
1102 1110
1103 // Move left. 1111 // Move left.
1104 expected.push_back(Range(6, 8)); 1112 expected.push_back(Range(6, 8));
1105 RunMoveCursorTestAndClearExpectations( 1113 RunMoveCursorTestAndClearExpectations(
1106 render_text.get(), WORD_BREAK, CURSOR_LEFT, SELECTION_RETAIN, &expected); 1114 render_text_.get(), WORD_BREAK, CURSOR_LEFT, SELECTION_RETAIN, &expected);
1107 1115
1108 // SELECTION_EXTEND. 1116 // SELECTION_EXTEND.
1109 render_text->SelectRange(Range(6)); 1117 render_text_->SelectRange(Range(6));
1110 1118
1111 // Move left. 1119 // Move left.
1112 expected.push_back(Range(6, 4)); 1120 expected.push_back(Range(6, 4));
1113 RunMoveCursorTestAndClearExpectations( 1121 RunMoveCursorTestAndClearExpectations(
1114 render_text.get(), WORD_BREAK, CURSOR_LEFT, SELECTION_EXTEND, &expected); 1122 render_text_.get(), WORD_BREAK, CURSOR_LEFT, SELECTION_EXTEND, &expected);
1115 1123
1116 // Move right twice. 1124 // Move right twice.
1117 expected.push_back(Range(4, 7)); 1125 expected.push_back(Range(4, 7));
1118 expected.push_back(Range(4, 11)); 1126 expected.push_back(Range(4, 11));
1119 RunMoveCursorTestAndClearExpectations( 1127 RunMoveCursorTestAndClearExpectations(render_text_.get(), WORD_BREAK,
1120 render_text.get(), WORD_BREAK, CURSOR_RIGHT, SELECTION_EXTEND, &expected); 1128 CURSOR_RIGHT, SELECTION_EXTEND,
1129 &expected);
1121 1130
1122 // Move left. 1131 // Move left.
1123 expected.push_back(Range(4, 8)); 1132 expected.push_back(Range(4, 8));
1124 RunMoveCursorTestAndClearExpectations( 1133 RunMoveCursorTestAndClearExpectations(
1125 render_text.get(), WORD_BREAK, CURSOR_LEFT, SELECTION_EXTEND, &expected); 1134 render_text_.get(), WORD_BREAK, CURSOR_LEFT, SELECTION_EXTEND, &expected);
1126 } 1135 }
1127 1136
1128 TEST_F(RenderTextTest, MoveCursor_Line) { 1137 TEST_P(RenderTextTestAll, MoveCursor_Line) {
1129 std::unique_ptr<RenderText> render_text( 1138 render_text_->SetText(WideToUTF16(L"123 456 789"));
1130 RenderText::CreateInstanceForEditing());
1131 render_text->SetText(WideToUTF16(L"123 456 789"));
1132 std::vector<Range> expected; 1139 std::vector<Range> expected;
1133 1140
1134 // SELECTION_NONE. 1141 // SELECTION_NONE.
1135 render_text->SelectRange(Range(6)); 1142 render_text_->SelectRange(Range(6));
1136 1143
1137 // Move right twice. 1144 // Move right twice.
1138 expected.push_back(Range(11)); 1145 expected.push_back(Range(11));
1139 expected.push_back(Range(11)); 1146 expected.push_back(Range(11));
1140 RunMoveCursorTestAndClearExpectations( 1147 RunMoveCursorTestAndClearExpectations(
1141 render_text.get(), LINE_BREAK, CURSOR_RIGHT, SELECTION_NONE, &expected); 1148 render_text_.get(), LINE_BREAK, CURSOR_RIGHT, SELECTION_NONE, &expected);
1142 1149
1143 // Move left twice. 1150 // Move left twice.
1144 expected.push_back(Range(0)); 1151 expected.push_back(Range(0));
1145 expected.push_back(Range(0)); 1152 expected.push_back(Range(0));
1146 RunMoveCursorTestAndClearExpectations(render_text.get(), LINE_BREAK, 1153 RunMoveCursorTestAndClearExpectations(render_text_.get(), LINE_BREAK,
1147 CURSOR_LEFT, SELECTION_NONE, &expected); 1154 CURSOR_LEFT, SELECTION_NONE, &expected);
1148 1155
1149 // SELECTION_CARET. 1156 // SELECTION_CARET.
1150 render_text->SelectRange(Range(6)); 1157 render_text_->SelectRange(Range(6));
1151 1158
1152 // Move right. 1159 // Move right.
1153 expected.push_back(Range(6, 11)); 1160 expected.push_back(Range(6, 11));
1154 RunMoveCursorTestAndClearExpectations( 1161 RunMoveCursorTestAndClearExpectations(
1155 render_text.get(), LINE_BREAK, CURSOR_RIGHT, SELECTION_CARET, &expected); 1162 render_text_.get(), LINE_BREAK, CURSOR_RIGHT, SELECTION_CARET, &expected);
1156 1163
1157 // Move left twice. 1164 // Move left twice.
1158 expected.push_back(Range(6)); 1165 expected.push_back(Range(6));
1159 expected.push_back(Range(6, 0)); 1166 expected.push_back(Range(6, 0));
1160 RunMoveCursorTestAndClearExpectations( 1167 RunMoveCursorTestAndClearExpectations(
1161 render_text.get(), LINE_BREAK, CURSOR_LEFT, SELECTION_CARET, &expected); 1168 render_text_.get(), LINE_BREAK, CURSOR_LEFT, SELECTION_CARET, &expected);
1162 1169
1163 // Move right. 1170 // Move right.
1164 expected.push_back(Range(6)); 1171 expected.push_back(Range(6));
1165 RunMoveCursorTestAndClearExpectations( 1172 RunMoveCursorTestAndClearExpectations(
1166 render_text.get(), LINE_BREAK, CURSOR_RIGHT, SELECTION_CARET, &expected); 1173 render_text_.get(), LINE_BREAK, CURSOR_RIGHT, SELECTION_CARET, &expected);
1167 1174
1168 // SELECTION_RETAIN. 1175 // SELECTION_RETAIN.
1169 render_text->SelectRange(Range(6)); 1176 render_text_->SelectRange(Range(6));
1170 1177
1171 // Move right. 1178 // Move right.
1172 expected.push_back(Range(6, 11)); 1179 expected.push_back(Range(6, 11));
1173 RunMoveCursorTestAndClearExpectations( 1180 RunMoveCursorTestAndClearExpectations(render_text_.get(), LINE_BREAK,
1174 render_text.get(), LINE_BREAK, CURSOR_RIGHT, SELECTION_RETAIN, &expected); 1181 CURSOR_RIGHT, SELECTION_RETAIN,
1182 &expected);
1175 1183
1176 // Move left twice. 1184 // Move left twice.
1177 expected.push_back(Range(6, 0)); 1185 expected.push_back(Range(6, 0));
1178 expected.push_back(Range(6, 0)); 1186 expected.push_back(Range(6, 0));
1179 RunMoveCursorTestAndClearExpectations( 1187 RunMoveCursorTestAndClearExpectations(
1180 render_text.get(), LINE_BREAK, CURSOR_LEFT, SELECTION_RETAIN, &expected); 1188 render_text_.get(), LINE_BREAK, CURSOR_LEFT, SELECTION_RETAIN, &expected);
1181 1189
1182 // Move right. 1190 // Move right.
1183 expected.push_back(Range(6, 11)); 1191 expected.push_back(Range(6, 11));
1184 RunMoveCursorTestAndClearExpectations( 1192 RunMoveCursorTestAndClearExpectations(render_text_.get(), LINE_BREAK,
1185 render_text.get(), LINE_BREAK, CURSOR_RIGHT, SELECTION_RETAIN, &expected); 1193 CURSOR_RIGHT, SELECTION_RETAIN,
1194 &expected);
1186 1195
1187 // SELECTION_EXTEND. 1196 // SELECTION_EXTEND.
1188 render_text->SelectRange(Range(6)); 1197 render_text_->SelectRange(Range(6));
1189 1198
1190 // Move right. 1199 // Move right.
1191 expected.push_back(Range(6, 11)); 1200 expected.push_back(Range(6, 11));
1192 RunMoveCursorTestAndClearExpectations( 1201 RunMoveCursorTestAndClearExpectations(render_text_.get(), LINE_BREAK,
1193 render_text.get(), LINE_BREAK, CURSOR_RIGHT, SELECTION_EXTEND, &expected); 1202 CURSOR_RIGHT, SELECTION_EXTEND,
1203 &expected);
1194 1204
1195 // Move left twice. 1205 // Move left twice.
1196 expected.push_back(Range(11, 0)); 1206 expected.push_back(Range(11, 0));
1197 expected.push_back(Range(11, 0)); 1207 expected.push_back(Range(11, 0));
1198 RunMoveCursorTestAndClearExpectations( 1208 RunMoveCursorTestAndClearExpectations(
1199 render_text.get(), LINE_BREAK, CURSOR_LEFT, SELECTION_EXTEND, &expected); 1209 render_text_.get(), LINE_BREAK, CURSOR_LEFT, SELECTION_EXTEND, &expected);
1200 1210
1201 // Move right. 1211 // Move right.
1202 expected.push_back(Range(0, 11)); 1212 expected.push_back(Range(0, 11));
1203 RunMoveCursorTestAndClearExpectations( 1213 RunMoveCursorTestAndClearExpectations(render_text_.get(), LINE_BREAK,
1204 render_text.get(), LINE_BREAK, CURSOR_RIGHT, SELECTION_EXTEND, &expected); 1214 CURSOR_RIGHT, SELECTION_EXTEND,
1205 } 1215 &expected);
1206 1216 }
1207 TEST_F(RenderTextTest, GetDisplayTextDirection) { 1217
1218 TEST_P(RenderTextTestAll, GetDisplayTextDirection) {
1208 struct { 1219 struct {
1209 const wchar_t* text; 1220 const wchar_t* text;
1210 const base::i18n::TextDirection text_direction; 1221 const base::i18n::TextDirection text_direction;
1211 } cases[] = { 1222 } cases[] = {
1212 // Blank strings and those with no/weak directionality default to LTR. 1223 // Blank strings and those with no/weak directionality default to LTR.
1213 { L"", base::i18n::LEFT_TO_RIGHT }, 1224 { L"", base::i18n::LEFT_TO_RIGHT },
1214 { kWeak, base::i18n::LEFT_TO_RIGHT }, 1225 { kWeak, base::i18n::LEFT_TO_RIGHT },
1215 // Strings that begin with strong LTR characters. 1226 // Strings that begin with strong LTR characters.
1216 { kLtr, base::i18n::LEFT_TO_RIGHT }, 1227 { kLtr, base::i18n::LEFT_TO_RIGHT },
1217 { kLtrRtl, base::i18n::LEFT_TO_RIGHT }, 1228 { kLtrRtl, base::i18n::LEFT_TO_RIGHT },
1218 { kLtrRtlLtr, base::i18n::LEFT_TO_RIGHT }, 1229 { kLtrRtlLtr, base::i18n::LEFT_TO_RIGHT },
1219 // Strings that begin with strong RTL characters. 1230 // Strings that begin with strong RTL characters.
1220 { kRtl, base::i18n::RIGHT_TO_LEFT }, 1231 { kRtl, base::i18n::RIGHT_TO_LEFT },
1221 { kRtlLtr, base::i18n::RIGHT_TO_LEFT }, 1232 { kRtlLtr, base::i18n::RIGHT_TO_LEFT },
1222 { kRtlLtrRtl, base::i18n::RIGHT_TO_LEFT }, 1233 { kRtlLtrRtl, base::i18n::RIGHT_TO_LEFT },
1223 }; 1234 };
1224 1235
1225 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance());
1226 const bool was_rtl = base::i18n::IsRTL(); 1236 const bool was_rtl = base::i18n::IsRTL();
1227 1237
1228 for (size_t i = 0; i < 2; ++i) { 1238 for (size_t i = 0; i < 2; ++i) {
1229 // Toggle the application default text direction (to try each direction). 1239 // Toggle the application default text direction (to try each direction).
1230 SetRTL(!base::i18n::IsRTL()); 1240 SetRTL(!base::i18n::IsRTL());
1231 const base::i18n::TextDirection ui_direction = base::i18n::IsRTL() ? 1241 const base::i18n::TextDirection ui_direction = base::i18n::IsRTL() ?
1232 base::i18n::RIGHT_TO_LEFT : base::i18n::LEFT_TO_RIGHT; 1242 base::i18n::RIGHT_TO_LEFT : base::i18n::LEFT_TO_RIGHT;
1233 1243
1234 // Ensure that directionality modes yield the correct text directions. 1244 // Ensure that directionality modes yield the correct text directions.
1235 for (size_t j = 0; j < arraysize(cases); j++) { 1245 for (size_t j = 0; j < arraysize(cases); j++) {
1236 render_text->SetText(WideToUTF16(cases[j].text)); 1246 render_text_->SetText(WideToUTF16(cases[j].text));
1237 render_text->SetDirectionalityMode(DIRECTIONALITY_FROM_TEXT); 1247 render_text_->SetDirectionalityMode(DIRECTIONALITY_FROM_TEXT);
1238 EXPECT_EQ(render_text->GetDisplayTextDirection(),cases[j].text_direction); 1248 EXPECT_EQ(render_text_->GetDisplayTextDirection(),
1239 render_text->SetDirectionalityMode(DIRECTIONALITY_FROM_UI); 1249 cases[j].text_direction);
1240 EXPECT_EQ(render_text->GetDisplayTextDirection(), ui_direction); 1250 render_text_->SetDirectionalityMode(DIRECTIONALITY_FROM_UI);
1241 render_text->SetDirectionalityMode(DIRECTIONALITY_FORCE_LTR); 1251 EXPECT_EQ(render_text_->GetDisplayTextDirection(), ui_direction);
1242 EXPECT_EQ(render_text->GetDisplayTextDirection(), 1252 render_text_->SetDirectionalityMode(DIRECTIONALITY_FORCE_LTR);
1253 EXPECT_EQ(render_text_->GetDisplayTextDirection(),
1243 base::i18n::LEFT_TO_RIGHT); 1254 base::i18n::LEFT_TO_RIGHT);
1244 render_text->SetDirectionalityMode(DIRECTIONALITY_FORCE_RTL); 1255 render_text_->SetDirectionalityMode(DIRECTIONALITY_FORCE_RTL);
1245 EXPECT_EQ(render_text->GetDisplayTextDirection(), 1256 EXPECT_EQ(render_text_->GetDisplayTextDirection(),
1246 base::i18n::RIGHT_TO_LEFT); 1257 base::i18n::RIGHT_TO_LEFT);
1247 } 1258 }
1248 } 1259 }
1249 1260
1250 EXPECT_EQ(was_rtl, base::i18n::IsRTL()); 1261 EXPECT_EQ(was_rtl, base::i18n::IsRTL());
1251 1262
1252 // Ensure that text changes update the direction for DIRECTIONALITY_FROM_TEXT. 1263 // Ensure that text changes update the direction for DIRECTIONALITY_FROM_TEXT.
1253 render_text->SetDirectionalityMode(DIRECTIONALITY_FROM_TEXT); 1264 render_text_->SetDirectionalityMode(DIRECTIONALITY_FROM_TEXT);
1254 render_text->SetText(WideToUTF16(kLtr)); 1265 render_text_->SetText(WideToUTF16(kLtr));
1255 EXPECT_EQ(render_text->GetDisplayTextDirection(), base::i18n::LEFT_TO_RIGHT); 1266 EXPECT_EQ(render_text_->GetDisplayTextDirection(), base::i18n::LEFT_TO_RIGHT);
1256 render_text->SetText(WideToUTF16(kRtl)); 1267 render_text_->SetText(WideToUTF16(kRtl));
1257 EXPECT_EQ(render_text->GetDisplayTextDirection(), base::i18n::RIGHT_TO_LEFT); 1268 EXPECT_EQ(render_text_->GetDisplayTextDirection(), base::i18n::RIGHT_TO_LEFT);
1258 } 1269 }
1259 1270
1260 // TODO(asvitkine): RenderTextMac cursor movements. http://crbug.com/131618 1271 // TODO(asvitkine): RenderTextMac cursor movements. http://crbug.com/131618
1261 #if !defined(OS_MACOSX) 1272 TEST_P(RenderTextHarfBuzzTest, MoveCursorLeftRightInLtr) {
1262 TEST_F(RenderTextTest, MoveCursorLeftRightInLtr) {
1263 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance());
1264
1265 // Pure LTR. 1273 // Pure LTR.
1266 render_text->SetText(ASCIIToUTF16("abc")); 1274 render_text_->SetText(ASCIIToUTF16("abc"));
1267 // |expected| saves the expected SelectionModel when moving cursor from left 1275 // |expected| saves the expected SelectionModel when moving cursor from left
1268 // to right. 1276 // to right.
1269 std::vector<SelectionModel> expected; 1277 std::vector<SelectionModel> expected;
1270 expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 1278 expected.push_back(SelectionModel(0, CURSOR_BACKWARD));
1271 expected.push_back(SelectionModel(1, CURSOR_BACKWARD)); 1279 expected.push_back(SelectionModel(1, CURSOR_BACKWARD));
1272 expected.push_back(SelectionModel(2, CURSOR_BACKWARD)); 1280 expected.push_back(SelectionModel(2, CURSOR_BACKWARD));
1273 expected.push_back(SelectionModel(3, CURSOR_BACKWARD)); 1281 expected.push_back(SelectionModel(3, CURSOR_BACKWARD));
1274 expected.push_back(SelectionModel(3, CURSOR_FORWARD)); 1282 expected.push_back(SelectionModel(3, CURSOR_FORWARD));
1275 RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_RIGHT); 1283 RunMoveCursorLeftRightTest(render_text_.get(), expected, CURSOR_RIGHT);
1276 1284
1277 expected.clear(); 1285 expected.clear();
1278 expected.push_back(SelectionModel(3, CURSOR_FORWARD)); 1286 expected.push_back(SelectionModel(3, CURSOR_FORWARD));
1279 expected.push_back(SelectionModel(2, CURSOR_FORWARD)); 1287 expected.push_back(SelectionModel(2, CURSOR_FORWARD));
1280 expected.push_back(SelectionModel(1, CURSOR_FORWARD)); 1288 expected.push_back(SelectionModel(1, CURSOR_FORWARD));
1281 expected.push_back(SelectionModel(0, CURSOR_FORWARD)); 1289 expected.push_back(SelectionModel(0, CURSOR_FORWARD));
1282 expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 1290 expected.push_back(SelectionModel(0, CURSOR_BACKWARD));
1283 RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_LEFT); 1291 RunMoveCursorLeftRightTest(render_text_.get(), expected, CURSOR_LEFT);
1284 } 1292 }
1285 1293
1286 TEST_F(RenderTextTest, MoveCursorLeftRightInLtrRtl) { 1294 // TODO(asvitkine): RenderTextMac cursor movements. http://crbug.com/131618
1287 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 1295 TEST_P(RenderTextHarfBuzzTest, MoveCursorLeftRightInLtrRtl) {
1288 // LTR-RTL 1296 // LTR-RTL
1289 render_text->SetText(WideToUTF16(L"abc\x05d0\x05d1\x05d2")); 1297 render_text_->SetText(WideToUTF16(L"abc\x05d0\x05d1\x05d2"));
1290 // The last one is the expected END position. 1298 // The last one is the expected END position.
1291 std::vector<SelectionModel> expected; 1299 std::vector<SelectionModel> expected;
1292 expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 1300 expected.push_back(SelectionModel(0, CURSOR_BACKWARD));
1293 expected.push_back(SelectionModel(1, CURSOR_BACKWARD)); 1301 expected.push_back(SelectionModel(1, CURSOR_BACKWARD));
1294 expected.push_back(SelectionModel(2, CURSOR_BACKWARD)); 1302 expected.push_back(SelectionModel(2, CURSOR_BACKWARD));
1295 expected.push_back(SelectionModel(3, CURSOR_BACKWARD)); 1303 expected.push_back(SelectionModel(3, CURSOR_BACKWARD));
1296 expected.push_back(SelectionModel(5, CURSOR_FORWARD)); 1304 expected.push_back(SelectionModel(5, CURSOR_FORWARD));
1297 expected.push_back(SelectionModel(4, CURSOR_FORWARD)); 1305 expected.push_back(SelectionModel(4, CURSOR_FORWARD));
1298 expected.push_back(SelectionModel(3, CURSOR_FORWARD)); 1306 expected.push_back(SelectionModel(3, CURSOR_FORWARD));
1299 expected.push_back(SelectionModel(6, CURSOR_FORWARD)); 1307 expected.push_back(SelectionModel(6, CURSOR_FORWARD));
1300 RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_RIGHT); 1308 RunMoveCursorLeftRightTest(render_text_.get(), expected, CURSOR_RIGHT);
1301 1309
1302 expected.clear(); 1310 expected.clear();
1303 expected.push_back(SelectionModel(6, CURSOR_FORWARD)); 1311 expected.push_back(SelectionModel(6, CURSOR_FORWARD));
1304 expected.push_back(SelectionModel(4, CURSOR_BACKWARD)); 1312 expected.push_back(SelectionModel(4, CURSOR_BACKWARD));
1305 expected.push_back(SelectionModel(5, CURSOR_BACKWARD)); 1313 expected.push_back(SelectionModel(5, CURSOR_BACKWARD));
1306 expected.push_back(SelectionModel(6, CURSOR_BACKWARD)); 1314 expected.push_back(SelectionModel(6, CURSOR_BACKWARD));
1307 expected.push_back(SelectionModel(2, CURSOR_FORWARD)); 1315 expected.push_back(SelectionModel(2, CURSOR_FORWARD));
1308 expected.push_back(SelectionModel(1, CURSOR_FORWARD)); 1316 expected.push_back(SelectionModel(1, CURSOR_FORWARD));
1309 expected.push_back(SelectionModel(0, CURSOR_FORWARD)); 1317 expected.push_back(SelectionModel(0, CURSOR_FORWARD));
1310 expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 1318 expected.push_back(SelectionModel(0, CURSOR_BACKWARD));
1311 RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_LEFT); 1319 RunMoveCursorLeftRightTest(render_text_.get(), expected, CURSOR_LEFT);
1312 } 1320 }
1313 1321
1314 TEST_F(RenderTextTest, MoveCursorLeftRightInLtrRtlLtr) { 1322 // TODO(asvitkine): RenderTextMac cursor movements. http://crbug.com/131618
1315 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 1323 TEST_P(RenderTextHarfBuzzTest, MoveCursorLeftRightInLtrRtlLtr) {
1316 // LTR-RTL-LTR. 1324 // LTR-RTL-LTR.
1317 render_text->SetText(WideToUTF16(L"a" L"\x05d1" L"b")); 1325 render_text_->SetText(
1326 WideToUTF16(L"a"
1327 L"\x05d1"
1328 L"b"));
1318 std::vector<SelectionModel> expected; 1329 std::vector<SelectionModel> expected;
1319 expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 1330 expected.push_back(SelectionModel(0, CURSOR_BACKWARD));
1320 expected.push_back(SelectionModel(1, CURSOR_BACKWARD)); 1331 expected.push_back(SelectionModel(1, CURSOR_BACKWARD));
1321 expected.push_back(SelectionModel(1, CURSOR_FORWARD)); 1332 expected.push_back(SelectionModel(1, CURSOR_FORWARD));
1322 expected.push_back(SelectionModel(3, CURSOR_BACKWARD)); 1333 expected.push_back(SelectionModel(3, CURSOR_BACKWARD));
1323 expected.push_back(SelectionModel(3, CURSOR_FORWARD)); 1334 expected.push_back(SelectionModel(3, CURSOR_FORWARD));
1324 RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_RIGHT); 1335 RunMoveCursorLeftRightTest(render_text_.get(), expected, CURSOR_RIGHT);
1325 1336
1326 expected.clear(); 1337 expected.clear();
1327 expected.push_back(SelectionModel(3, CURSOR_FORWARD)); 1338 expected.push_back(SelectionModel(3, CURSOR_FORWARD));
1328 expected.push_back(SelectionModel(2, CURSOR_FORWARD)); 1339 expected.push_back(SelectionModel(2, CURSOR_FORWARD));
1329 expected.push_back(SelectionModel(2, CURSOR_BACKWARD)); 1340 expected.push_back(SelectionModel(2, CURSOR_BACKWARD));
1330 expected.push_back(SelectionModel(0, CURSOR_FORWARD)); 1341 expected.push_back(SelectionModel(0, CURSOR_FORWARD));
1331 expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 1342 expected.push_back(SelectionModel(0, CURSOR_BACKWARD));
1332 RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_LEFT); 1343 RunMoveCursorLeftRightTest(render_text_.get(), expected, CURSOR_LEFT);
1333 } 1344 }
1334 1345
1335 TEST_F(RenderTextTest, MoveCursorLeftRightInRtl) { 1346 // TODO(asvitkine): RenderTextMac cursor movements. http://crbug.com/131618
1336 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 1347 TEST_P(RenderTextHarfBuzzTest, MoveCursorLeftRightInRtl) {
1337 // Pure RTL. 1348 // Pure RTL.
1338 render_text->SetText(WideToUTF16(L"\x05d0\x05d1\x05d2")); 1349 render_text_->SetText(WideToUTF16(L"\x05d0\x05d1\x05d2"));
1339 render_text->MoveCursor(LINE_BREAK, CURSOR_RIGHT, SELECTION_NONE); 1350 render_text_->MoveCursor(LINE_BREAK, CURSOR_RIGHT, SELECTION_NONE);
1340 std::vector<SelectionModel> expected; 1351 std::vector<SelectionModel> expected;
1341 1352
1342 expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 1353 expected.push_back(SelectionModel(0, CURSOR_BACKWARD));
1343 expected.push_back(SelectionModel(1, CURSOR_BACKWARD)); 1354 expected.push_back(SelectionModel(1, CURSOR_BACKWARD));
1344 expected.push_back(SelectionModel(2, CURSOR_BACKWARD)); 1355 expected.push_back(SelectionModel(2, CURSOR_BACKWARD));
1345 expected.push_back(SelectionModel(3, CURSOR_BACKWARD)); 1356 expected.push_back(SelectionModel(3, CURSOR_BACKWARD));
1346 expected.push_back(SelectionModel(3, CURSOR_FORWARD)); 1357 expected.push_back(SelectionModel(3, CURSOR_FORWARD));
1347 RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_LEFT); 1358 RunMoveCursorLeftRightTest(render_text_.get(), expected, CURSOR_LEFT);
1348 1359
1349 expected.clear(); 1360 expected.clear();
1350 1361
1351 expected.push_back(SelectionModel(3, CURSOR_FORWARD)); 1362 expected.push_back(SelectionModel(3, CURSOR_FORWARD));
1352 expected.push_back(SelectionModel(2, CURSOR_FORWARD)); 1363 expected.push_back(SelectionModel(2, CURSOR_FORWARD));
1353 expected.push_back(SelectionModel(1, CURSOR_FORWARD)); 1364 expected.push_back(SelectionModel(1, CURSOR_FORWARD));
1354 expected.push_back(SelectionModel(0, CURSOR_FORWARD)); 1365 expected.push_back(SelectionModel(0, CURSOR_FORWARD));
1355 expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 1366 expected.push_back(SelectionModel(0, CURSOR_BACKWARD));
1356 RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_RIGHT); 1367 RunMoveCursorLeftRightTest(render_text_.get(), expected, CURSOR_RIGHT);
1357 } 1368 }
1358 1369
1359 TEST_F(RenderTextTest, MoveCursorLeftRightInRtlLtr) { 1370 // TODO(asvitkine): RenderTextMac cursor movements. http://crbug.com/131618
1360 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 1371 TEST_P(RenderTextHarfBuzzTest, MoveCursorLeftRightInRtlLtr) {
1361 // RTL-LTR 1372 // RTL-LTR
1362 render_text->SetText(WideToUTF16(L"\x05d0\x05d1\x05d2" L"abc")); 1373 render_text_->SetText(
1363 render_text->MoveCursor(LINE_BREAK, CURSOR_RIGHT, SELECTION_NONE); 1374 WideToUTF16(L"\x05d0\x05d1\x05d2"
1375 L"abc"));
1376 render_text_->MoveCursor(LINE_BREAK, CURSOR_RIGHT, SELECTION_NONE);
1364 std::vector<SelectionModel> expected; 1377 std::vector<SelectionModel> expected;
1365 expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 1378 expected.push_back(SelectionModel(0, CURSOR_BACKWARD));
1366 expected.push_back(SelectionModel(1, CURSOR_BACKWARD)); 1379 expected.push_back(SelectionModel(1, CURSOR_BACKWARD));
1367 expected.push_back(SelectionModel(2, CURSOR_BACKWARD)); 1380 expected.push_back(SelectionModel(2, CURSOR_BACKWARD));
1368 expected.push_back(SelectionModel(3, CURSOR_BACKWARD)); 1381 expected.push_back(SelectionModel(3, CURSOR_BACKWARD));
1369 expected.push_back(SelectionModel(5, CURSOR_FORWARD)); 1382 expected.push_back(SelectionModel(5, CURSOR_FORWARD));
1370 expected.push_back(SelectionModel(4, CURSOR_FORWARD)); 1383 expected.push_back(SelectionModel(4, CURSOR_FORWARD));
1371 expected.push_back(SelectionModel(3, CURSOR_FORWARD)); 1384 expected.push_back(SelectionModel(3, CURSOR_FORWARD));
1372 expected.push_back(SelectionModel(6, CURSOR_FORWARD)); 1385 expected.push_back(SelectionModel(6, CURSOR_FORWARD));
1373 RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_LEFT); 1386 RunMoveCursorLeftRightTest(render_text_.get(), expected, CURSOR_LEFT);
1374 1387
1375 expected.clear(); 1388 expected.clear();
1376 expected.push_back(SelectionModel(6, CURSOR_FORWARD)); 1389 expected.push_back(SelectionModel(6, CURSOR_FORWARD));
1377 expected.push_back(SelectionModel(4, CURSOR_BACKWARD)); 1390 expected.push_back(SelectionModel(4, CURSOR_BACKWARD));
1378 expected.push_back(SelectionModel(5, CURSOR_BACKWARD)); 1391 expected.push_back(SelectionModel(5, CURSOR_BACKWARD));
1379 expected.push_back(SelectionModel(6, CURSOR_BACKWARD)); 1392 expected.push_back(SelectionModel(6, CURSOR_BACKWARD));
1380 expected.push_back(SelectionModel(2, CURSOR_FORWARD)); 1393 expected.push_back(SelectionModel(2, CURSOR_FORWARD));
1381 expected.push_back(SelectionModel(1, CURSOR_FORWARD)); 1394 expected.push_back(SelectionModel(1, CURSOR_FORWARD));
1382 expected.push_back(SelectionModel(0, CURSOR_FORWARD)); 1395 expected.push_back(SelectionModel(0, CURSOR_FORWARD));
1383 expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 1396 expected.push_back(SelectionModel(0, CURSOR_BACKWARD));
1384 RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_RIGHT); 1397 RunMoveCursorLeftRightTest(render_text_.get(), expected, CURSOR_RIGHT);
1385 } 1398 }
1386 1399
1387 TEST_F(RenderTextTest, MoveCursorLeftRightInRtlLtrRtl) { 1400 // TODO(asvitkine): RenderTextMac cursor movements. http://crbug.com/131618
1388 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 1401 TEST_P(RenderTextHarfBuzzTest, MoveCursorLeftRightInRtlLtrRtl) {
1389 // RTL-LTR-RTL. 1402 // RTL-LTR-RTL.
1390 render_text->SetText(WideToUTF16(L"\x05d0" L"a" L"\x05d1")); 1403 render_text_->SetText(
1391 render_text->MoveCursor(LINE_BREAK, CURSOR_RIGHT, SELECTION_NONE); 1404 WideToUTF16(L"\x05d0"
1405 L"a"
1406 L"\x05d1"));
1407 render_text_->MoveCursor(LINE_BREAK, CURSOR_RIGHT, SELECTION_NONE);
1392 std::vector<SelectionModel> expected; 1408 std::vector<SelectionModel> expected;
1393 expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 1409 expected.push_back(SelectionModel(0, CURSOR_BACKWARD));
1394 expected.push_back(SelectionModel(1, CURSOR_BACKWARD)); 1410 expected.push_back(SelectionModel(1, CURSOR_BACKWARD));
1395 expected.push_back(SelectionModel(1, CURSOR_FORWARD)); 1411 expected.push_back(SelectionModel(1, CURSOR_FORWARD));
1396 expected.push_back(SelectionModel(3, CURSOR_BACKWARD)); 1412 expected.push_back(SelectionModel(3, CURSOR_BACKWARD));
1397 expected.push_back(SelectionModel(3, CURSOR_FORWARD)); 1413 expected.push_back(SelectionModel(3, CURSOR_FORWARD));
1398 RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_LEFT); 1414 RunMoveCursorLeftRightTest(render_text_.get(), expected, CURSOR_LEFT);
1399 1415
1400 expected.clear(); 1416 expected.clear();
1401 expected.push_back(SelectionModel(3, CURSOR_FORWARD)); 1417 expected.push_back(SelectionModel(3, CURSOR_FORWARD));
1402 expected.push_back(SelectionModel(2, CURSOR_FORWARD)); 1418 expected.push_back(SelectionModel(2, CURSOR_FORWARD));
1403 expected.push_back(SelectionModel(2, CURSOR_BACKWARD)); 1419 expected.push_back(SelectionModel(2, CURSOR_BACKWARD));
1404 expected.push_back(SelectionModel(0, CURSOR_FORWARD)); 1420 expected.push_back(SelectionModel(0, CURSOR_FORWARD));
1405 expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 1421 expected.push_back(SelectionModel(0, CURSOR_BACKWARD));
1406 RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_RIGHT); 1422 RunMoveCursorLeftRightTest(render_text_.get(), expected, CURSOR_RIGHT);
1407 } 1423 }
1408 1424
1409 TEST_F(RenderTextTest, MoveCursorLeftRight_ComplexScript) { 1425 // TODO(asvitkine): RenderTextMac cursor movements. http://crbug.com/131618
1410 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 1426 TEST_P(RenderTextHarfBuzzTest, MoveCursorLeftRight_ComplexScript) {
1427 render_text_->SetText(WideToUTF16(L"\x0915\x093f\x0915\x094d\x0915"));
1428 EXPECT_EQ(0U, render_text_->cursor_position());
1429 render_text_->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, SELECTION_NONE);
1430 EXPECT_EQ(2U, render_text_->cursor_position());
1431 render_text_->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, SELECTION_NONE);
1432 EXPECT_EQ(4U, render_text_->cursor_position());
1433 render_text_->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, SELECTION_NONE);
1434 EXPECT_EQ(5U, render_text_->cursor_position());
1435 render_text_->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, SELECTION_NONE);
1436 EXPECT_EQ(5U, render_text_->cursor_position());
1411 1437
1412 render_text->SetText(WideToUTF16(L"\x0915\x093f\x0915\x094d\x0915")); 1438 render_text_->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, SELECTION_NONE);
1413 EXPECT_EQ(0U, render_text->cursor_position()); 1439 EXPECT_EQ(4U, render_text_->cursor_position());
1414 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, SELECTION_NONE); 1440 render_text_->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, SELECTION_NONE);
1415 EXPECT_EQ(2U, render_text->cursor_position()); 1441 EXPECT_EQ(2U, render_text_->cursor_position());
1416 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, SELECTION_NONE); 1442 render_text_->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, SELECTION_NONE);
1417 EXPECT_EQ(4U, render_text->cursor_position()); 1443 EXPECT_EQ(0U, render_text_->cursor_position());
1418 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, SELECTION_NONE); 1444 render_text_->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, SELECTION_NONE);
1419 EXPECT_EQ(5U, render_text->cursor_position()); 1445 EXPECT_EQ(0U, render_text_->cursor_position());
1420 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, SELECTION_NONE);
1421 EXPECT_EQ(5U, render_text->cursor_position());
1422
1423 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, SELECTION_NONE);
1424 EXPECT_EQ(4U, render_text->cursor_position());
1425 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, SELECTION_NONE);
1426 EXPECT_EQ(2U, render_text->cursor_position());
1427 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, SELECTION_NONE);
1428 EXPECT_EQ(0U, render_text->cursor_position());
1429 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, SELECTION_NONE);
1430 EXPECT_EQ(0U, render_text->cursor_position());
1431 } 1446 }
1432 1447
1433 TEST_F(RenderTextTest, MoveCursorLeftRight_MeiryoUILigatures) { 1448 // TODO(asvitkine): RenderTextMac cursor movements. http://crbug.com/131618
1434 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 1449 // Crashes on Mac with RenderTextHarfBuzz. See http://crbug.com/640068.
1450 #if !defined(OS_MACOSX)
1451 TEST_P(RenderTextHarfBuzzTest, MoveCursorLeftRight_MeiryoUILigatures) {
1435 // Meiryo UI uses single-glyph ligatures for 'ff' and 'ffi', but each letter 1452 // Meiryo UI uses single-glyph ligatures for 'ff' and 'ffi', but each letter
1436 // (code point) has unique bounds, so mid-glyph cursoring should be possible. 1453 // (code point) has unique bounds, so mid-glyph cursoring should be possible.
1437 render_text->SetFontList(FontList("Meiryo UI, 12px")); 1454 render_text_->SetFontList(FontList("Meiryo UI, 12px"));
1438 render_text->SetText(WideToUTF16(L"ff ffi")); 1455 render_text_->SetText(WideToUTF16(L"ff ffi"));
1439 EXPECT_EQ(0U, render_text->cursor_position()); 1456 EXPECT_EQ(0U, render_text_->cursor_position());
1440 for (size_t i = 0; i < render_text->text().length(); ++i) { 1457 for (size_t i = 0; i < render_text_->text().length(); ++i) {
1441 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, SELECTION_NONE); 1458 render_text_->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, SELECTION_NONE);
1442 EXPECT_EQ(i + 1, render_text->cursor_position()); 1459 EXPECT_EQ(i + 1, render_text_->cursor_position());
1443 } 1460 }
1444 EXPECT_EQ(6U, render_text->cursor_position()); 1461 EXPECT_EQ(6U, render_text_->cursor_position());
1445 } 1462 }
1463 #endif // !defined(OS_MACOSX)
1446 1464
1447 TEST_F(RenderTextTest, GraphemePositions) { 1465 // TODO(asvitkine): RenderTextMac cursor movements. http://crbug.com/131618
1466 TEST_P(RenderTextHarfBuzzTest, GraphemePositions) {
1448 // LTR 2-character grapheme, LTR abc, LTR 2-character grapheme. 1467 // LTR 2-character grapheme, LTR abc, LTR 2-character grapheme.
1449 const base::string16 kText1 = 1468 const base::string16 kText1 =
1450 WideToUTF16(L"\x0915\x093f" L"abc" L"\x0915\x093f"); 1469 WideToUTF16(L"\x0915\x093f" L"abc" L"\x0915\x093f");
1451 1470
1452 // LTR ab, LTR 2-character grapheme, LTR cd. 1471 // LTR ab, LTR 2-character grapheme, LTR cd.
1453 const base::string16 kText2 = WideToUTF16(L"ab" L"\x0915\x093f" L"cd"); 1472 const base::string16 kText2 = WideToUTF16(L"ab" L"\x0915\x093f" L"cd");
1454 1473
1455 // The below is 'MUSICAL SYMBOL G CLEF', which is represented in UTF-16 as 1474 // The below is 'MUSICAL SYMBOL G CLEF', which is represented in UTF-16 as
1456 // two characters forming the surrogate pair 0x0001D11E. 1475 // two characters forming the surrogate pair 0x0001D11E.
1457 const std::string kSurrogate = "\xF0\x9D\x84\x9E"; 1476 const std::string kSurrogate = "\xF0\x9D\x84\x9E";
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1497 { kText3, 7, 6, 6 }, 1516 { kText3, 7, 6, 6 },
1498 { kText3, 50, 6, 6 }, 1517 { kText3, 50, 6, 6 },
1499 }; 1518 };
1500 1519
1501 #if defined(OS_WIN) 1520 #if defined(OS_WIN)
1502 // TODO(msw): XP fails due to lack of font support: http://crbug.com/106450 1521 // TODO(msw): XP fails due to lack of font support: http://crbug.com/106450
1503 if (base::win::GetVersion() < base::win::VERSION_VISTA) 1522 if (base::win::GetVersion() < base::win::VERSION_VISTA)
1504 return; 1523 return;
1505 #endif 1524 #endif
1506 1525
1507 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance());
1508 for (size_t i = 0; i < arraysize(cases); i++) { 1526 for (size_t i = 0; i < arraysize(cases); i++) {
1509 SCOPED_TRACE(base::StringPrintf("Testing cases[%" PRIuS "]", i)); 1527 SCOPED_TRACE(base::StringPrintf("Testing cases[%" PRIuS "]", i));
1510 render_text->SetText(cases[i].text); 1528 render_text_->SetText(cases[i].text);
1511 1529
1512 size_t next = render_text->IndexOfAdjacentGrapheme(cases[i].index, 1530 size_t next =
1513 CURSOR_FORWARD); 1531 render_text_->IndexOfAdjacentGrapheme(cases[i].index, CURSOR_FORWARD);
1514 EXPECT_EQ(cases[i].expected_next, next); 1532 EXPECT_EQ(cases[i].expected_next, next);
1515 EXPECT_TRUE(render_text->IsValidCursorIndex(next)); 1533 EXPECT_TRUE(render_text_->IsValidCursorIndex(next));
1516 1534
1517 size_t previous = render_text->IndexOfAdjacentGrapheme(cases[i].index, 1535 size_t previous =
1518 CURSOR_BACKWARD); 1536 render_text_->IndexOfAdjacentGrapheme(cases[i].index, CURSOR_BACKWARD);
1519 EXPECT_EQ(cases[i].expected_previous, previous); 1537 EXPECT_EQ(cases[i].expected_previous, previous);
1520 EXPECT_TRUE(render_text->IsValidCursorIndex(previous)); 1538 EXPECT_TRUE(render_text_->IsValidCursorIndex(previous));
1521 } 1539 }
1522 } 1540 }
1523 1541
1524 TEST_F(RenderTextTest, MidGraphemeSelectionBounds) { 1542 // TODO(asvitkine): RenderTextMac cursor movements. http://crbug.com/131618
1543 TEST_P(RenderTextHarfBuzzTest, MidGraphemeSelectionBounds) {
1525 #if defined(OS_WIN) 1544 #if defined(OS_WIN)
1526 // TODO(msw): XP fails due to lack of font support: http://crbug.com/106450 1545 // TODO(msw): XP fails due to lack of font support: http://crbug.com/106450
1527 if (base::win::GetVersion() < base::win::VERSION_VISTA) 1546 if (base::win::GetVersion() < base::win::VERSION_VISTA)
1528 return; 1547 return;
1529 #endif 1548 #endif
1530 1549
1531 // Test that selection bounds may be set amid multi-character graphemes. 1550 // Test that selection bounds may be set amid multi-character graphemes.
1532 const base::string16 kHindi = WideToUTF16(L"\x0915\x093f"); 1551 const base::string16 kHindi = WideToUTF16(L"\x0915\x093f");
1533 const base::string16 kThai = WideToUTF16(L"\x0e08\x0e33"); 1552 const base::string16 kThai = WideToUTF16(L"\x0e08\x0e33");
1534 const base::string16 cases[] = { kHindi, kThai }; 1553 const base::string16 cases[] = { kHindi, kThai };
1535 1554
1536 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance());
1537 for (size_t i = 0; i < arraysize(cases); i++) { 1555 for (size_t i = 0; i < arraysize(cases); i++) {
1538 SCOPED_TRACE(base::StringPrintf("Testing cases[%" PRIuS "]", i)); 1556 SCOPED_TRACE(base::StringPrintf("Testing cases[%" PRIuS "]", i));
1539 render_text->SetText(cases[i]); 1557 render_text_->SetText(cases[i]);
1540 EXPECT_TRUE(render_text->IsValidLogicalIndex(1)); 1558 EXPECT_TRUE(render_text_->IsValidLogicalIndex(1));
1541 EXPECT_FALSE(render_text->IsValidCursorIndex(1)); 1559 EXPECT_FALSE(render_text_->IsValidCursorIndex(1));
1542 EXPECT_TRUE(render_text->SelectRange(Range(2, 1))); 1560 EXPECT_TRUE(render_text_->SelectRange(Range(2, 1)));
1543 EXPECT_EQ(Range(2, 1), render_text->selection()); 1561 EXPECT_EQ(Range(2, 1), render_text_->selection());
1544 EXPECT_EQ(1U, render_text->cursor_position()); 1562 EXPECT_EQ(1U, render_text_->cursor_position());
1545 // Although selection bounds may be set within a multi-character grapheme, 1563 // Although selection bounds may be set within a multi-character grapheme,
1546 // cursor movement (e.g. via arrow key) should avoid those indices. 1564 // cursor movement (e.g. via arrow key) should avoid those indices.
1547 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, SELECTION_NONE); 1565 render_text_->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, SELECTION_NONE);
1548 EXPECT_EQ(0U, render_text->cursor_position()); 1566 EXPECT_EQ(0U, render_text_->cursor_position());
1549 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, SELECTION_NONE); 1567 render_text_->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, SELECTION_NONE);
1550 EXPECT_EQ(2U, render_text->cursor_position()); 1568 EXPECT_EQ(2U, render_text_->cursor_position());
1551 } 1569 }
1552 } 1570 }
1553 1571
1554 TEST_F(RenderTextTest, FindCursorPosition) { 1572 // TODO(asvitkine): RenderTextMac cursor movements. http://crbug.com/131618
1573 TEST_P(RenderTextHarfBuzzTest, FindCursorPosition) {
1555 const wchar_t* kTestStrings[] = { kLtrRtl, kLtrRtlLtr, kRtlLtr, kRtlLtrRtl }; 1574 const wchar_t* kTestStrings[] = { kLtrRtl, kLtrRtlLtr, kRtlLtr, kRtlLtrRtl };
1556 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 1575 render_text_->SetDisplayRect(Rect(0, 0, 100, 20));
1557 render_text->SetDisplayRect(Rect(0, 0, 100, 20));
1558 for (size_t i = 0; i < arraysize(kTestStrings); ++i) { 1576 for (size_t i = 0; i < arraysize(kTestStrings); ++i) {
1559 SCOPED_TRACE(base::StringPrintf("Testing case[%" PRIuS "]", i)); 1577 SCOPED_TRACE(base::StringPrintf("Testing case[%" PRIuS "]", i));
1560 render_text->SetText(WideToUTF16(kTestStrings[i])); 1578 render_text_->SetText(WideToUTF16(kTestStrings[i]));
1561 for(size_t j = 0; j < render_text->text().length(); ++j) { 1579 for (size_t j = 0; j < render_text_->text().length(); ++j) {
1562 const Range range(render_text->GetGlyphBounds(j)); 1580 const Range range(render_text_->GetGlyphBounds(j));
1563 // Test a point just inside the leading edge of the glyph bounds. 1581 // Test a point just inside the leading edge of the glyph bounds.
1564 int x = range.is_reversed() ? range.GetMax() - 1 : range.GetMin() + 1; 1582 int x = range.is_reversed() ? range.GetMax() - 1 : range.GetMin() + 1;
1565 EXPECT_EQ(j, render_text->FindCursorPosition(Point(x, 0)).caret_pos()); 1583 EXPECT_EQ(j, render_text_->FindCursorPosition(Point(x, 0)).caret_pos());
1566 } 1584 }
1567 } 1585 }
1568 } 1586 }
1569 #endif // !defined(OS_MACOSX)
1570 1587
1571 TEST_F(RenderTextTest, EdgeSelectionModels) { 1588 TEST_P(RenderTextTestAll, EdgeSelectionModels) {
1572 // Simple Latin text. 1589 // Simple Latin text.
1573 const base::string16 kLatin = WideToUTF16(L"abc"); 1590 const base::string16 kLatin = WideToUTF16(L"abc");
1574 // LTR 2-character grapheme. 1591 // LTR 2-character grapheme.
1575 const base::string16 kLTRGrapheme = WideToUTF16(L"\x0915\x093f"); 1592 const base::string16 kLTRGrapheme = WideToUTF16(L"\x0915\x093f");
1576 // LTR 2-character grapheme, LTR a, LTR 2-character grapheme. 1593 // LTR 2-character grapheme, LTR a, LTR 2-character grapheme.
1577 const base::string16 kHindiLatin = 1594 const base::string16 kHindiLatin =
1578 WideToUTF16(L"\x0915\x093f" L"a" L"\x0915\x093f"); 1595 WideToUTF16(L"\x0915\x093f" L"a" L"\x0915\x093f");
1579 // RTL 2-character grapheme. 1596 // RTL 2-character grapheme.
1580 const base::string16 kRTLGrapheme = WideToUTF16(L"\x05e0\x05b8"); 1597 const base::string16 kRTLGrapheme = WideToUTF16(L"\x05e0\x05b8");
1581 // RTL 2-character grapheme, LTR a, RTL 2-character grapheme. 1598 // RTL 2-character grapheme, LTR a, RTL 2-character grapheme.
(...skipping 11 matching lines...) Expand all
1593 { kRTLGrapheme, base::i18n::RIGHT_TO_LEFT }, 1610 { kRTLGrapheme, base::i18n::RIGHT_TO_LEFT },
1594 { kHebrewLatin, base::i18n::RIGHT_TO_LEFT }, 1611 { kHebrewLatin, base::i18n::RIGHT_TO_LEFT },
1595 }; 1612 };
1596 1613
1597 #if defined(OS_WIN) 1614 #if defined(OS_WIN)
1598 // TODO(msw): XP fails due to lack of font support: http://crbug.com/106450 1615 // TODO(msw): XP fails due to lack of font support: http://crbug.com/106450
1599 if (base::win::GetVersion() < base::win::VERSION_VISTA) 1616 if (base::win::GetVersion() < base::win::VERSION_VISTA)
1600 return; 1617 return;
1601 #endif 1618 #endif
1602 1619
1603 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance());
1604 for (size_t i = 0; i < arraysize(cases); i++) { 1620 for (size_t i = 0; i < arraysize(cases); i++) {
1605 render_text->SetText(cases[i].text); 1621 render_text_->SetText(cases[i].text);
1606 bool ltr = (cases[i].expected_text_direction == base::i18n::LEFT_TO_RIGHT); 1622 bool ltr = (cases[i].expected_text_direction == base::i18n::LEFT_TO_RIGHT);
1607 1623
1608 SelectionModel start_edge = 1624 SelectionModel start_edge =
1609 render_text->EdgeSelectionModel(ltr ? CURSOR_LEFT : CURSOR_RIGHT); 1625 render_text_->EdgeSelectionModel(ltr ? CURSOR_LEFT : CURSOR_RIGHT);
1610 EXPECT_EQ(start_edge, SelectionModel(0, CURSOR_BACKWARD)); 1626 EXPECT_EQ(start_edge, SelectionModel(0, CURSOR_BACKWARD));
1611 1627
1612 SelectionModel end_edge = 1628 SelectionModel end_edge =
1613 render_text->EdgeSelectionModel(ltr ? CURSOR_RIGHT : CURSOR_LEFT); 1629 render_text_->EdgeSelectionModel(ltr ? CURSOR_RIGHT : CURSOR_LEFT);
1614 EXPECT_EQ(end_edge, SelectionModel(cases[i].text.length(), CURSOR_FORWARD)); 1630 EXPECT_EQ(end_edge, SelectionModel(cases[i].text.length(), CURSOR_FORWARD));
1615 } 1631 }
1616 } 1632 }
1617 1633
1618 TEST_F(RenderTextTest, SelectAll) { 1634 TEST_P(RenderTextTestAll, SelectAll) {
1619 const wchar_t* const cases[] = 1635 const wchar_t* const cases[] =
1620 { kWeak, kLtr, kLtrRtl, kLtrRtlLtr, kRtl, kRtlLtr, kRtlLtrRtl }; 1636 { kWeak, kLtr, kLtrRtl, kLtrRtlLtr, kRtl, kRtlLtr, kRtlLtrRtl };
1621 1637
1622 // Ensure that SelectAll respects the |reversed| argument regardless of 1638 // Ensure that SelectAll respects the |reversed| argument regardless of
1623 // application locale and text content directionality. 1639 // application locale and text content directionality.
1624 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance());
1625 const SelectionModel expected_reversed(Range(3, 0), CURSOR_FORWARD); 1640 const SelectionModel expected_reversed(Range(3, 0), CURSOR_FORWARD);
1626 const SelectionModel expected_forwards(Range(0, 3), CURSOR_BACKWARD); 1641 const SelectionModel expected_forwards(Range(0, 3), CURSOR_BACKWARD);
1627 const bool was_rtl = base::i18n::IsRTL(); 1642 const bool was_rtl = base::i18n::IsRTL();
1628 1643
1629 for (size_t i = 0; i < 2; ++i) { 1644 for (size_t i = 0; i < 2; ++i) {
1630 SetRTL(!base::i18n::IsRTL()); 1645 SetRTL(!base::i18n::IsRTL());
1631 // Test that an empty string produces an empty selection model. 1646 // Test that an empty string produces an empty selection model.
1632 render_text->SetText(base::string16()); 1647 render_text_->SetText(base::string16());
1633 EXPECT_EQ(render_text->selection_model(), SelectionModel()); 1648 EXPECT_EQ(render_text_->selection_model(), SelectionModel());
1634 1649
1635 // Test the weak, LTR, RTL, and Bidi string cases. 1650 // Test the weak, LTR, RTL, and Bidi string cases.
1636 for (size_t j = 0; j < arraysize(cases); j++) { 1651 for (size_t j = 0; j < arraysize(cases); j++) {
1637 render_text->SetText(WideToUTF16(cases[j])); 1652 render_text_->SetText(WideToUTF16(cases[j]));
1638 render_text->SelectAll(false); 1653 render_text_->SelectAll(false);
1639 EXPECT_EQ(render_text->selection_model(), expected_forwards); 1654 EXPECT_EQ(render_text_->selection_model(), expected_forwards);
1640 render_text->SelectAll(true); 1655 render_text_->SelectAll(true);
1641 EXPECT_EQ(render_text->selection_model(), expected_reversed); 1656 EXPECT_EQ(render_text_->selection_model(), expected_reversed);
1642 } 1657 }
1643 } 1658 }
1644 1659
1645 EXPECT_EQ(was_rtl, base::i18n::IsRTL()); 1660 EXPECT_EQ(was_rtl, base::i18n::IsRTL());
1646 } 1661 }
1647 1662
1648 // TODO(asvitkine): RenderTextMac cursor movements. http://crbug.com/131618 1663 // TODO(asvitkine): RenderTextMac cursor movements. http://crbug.com/131618
1649 #if !defined(OS_MACOSX) 1664 TEST_P(RenderTextHarfBuzzTest, MoveCursorLeftRightWithSelection) {
1650 TEST_F(RenderTextTest, MoveCursorLeftRightWithSelection) { 1665 render_text_->SetText(WideToUTF16(L"abc\x05d0\x05d1\x05d2"));
1651 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance());
1652 render_text->SetText(WideToUTF16(L"abc\x05d0\x05d1\x05d2"));
1653 // Left arrow on select ranging (6, 4). 1666 // Left arrow on select ranging (6, 4).
1654 render_text->MoveCursor(LINE_BREAK, CURSOR_RIGHT, SELECTION_NONE); 1667 render_text_->MoveCursor(LINE_BREAK, CURSOR_RIGHT, SELECTION_NONE);
1655 EXPECT_EQ(Range(6), render_text->selection()); 1668 EXPECT_EQ(Range(6), render_text_->selection());
1656 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, SELECTION_NONE); 1669 render_text_->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, SELECTION_NONE);
1657 EXPECT_EQ(Range(4), render_text->selection()); 1670 EXPECT_EQ(Range(4), render_text_->selection());
1658 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, SELECTION_NONE); 1671 render_text_->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, SELECTION_NONE);
1659 EXPECT_EQ(Range(5), render_text->selection()); 1672 EXPECT_EQ(Range(5), render_text_->selection());
1660 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, SELECTION_NONE); 1673 render_text_->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, SELECTION_NONE);
1661 EXPECT_EQ(Range(6), render_text->selection()); 1674 EXPECT_EQ(Range(6), render_text_->selection());
1662 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, SELECTION_RETAIN); 1675 render_text_->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, SELECTION_RETAIN);
1663 EXPECT_EQ(Range(6, 5), render_text->selection()); 1676 EXPECT_EQ(Range(6, 5), render_text_->selection());
1664 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, SELECTION_RETAIN); 1677 render_text_->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, SELECTION_RETAIN);
1665 EXPECT_EQ(Range(6, 4), render_text->selection()); 1678 EXPECT_EQ(Range(6, 4), render_text_->selection());
1666 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, SELECTION_NONE); 1679 render_text_->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, SELECTION_NONE);
1667 EXPECT_EQ(Range(6), render_text->selection()); 1680 EXPECT_EQ(Range(6), render_text_->selection());
1668 1681
1669 // Right arrow on select ranging (4, 6). 1682 // Right arrow on select ranging (4, 6).
1670 render_text->MoveCursor(LINE_BREAK, CURSOR_LEFT, SELECTION_NONE); 1683 render_text_->MoveCursor(LINE_BREAK, CURSOR_LEFT, SELECTION_NONE);
1671 EXPECT_EQ(Range(0), render_text->selection()); 1684 EXPECT_EQ(Range(0), render_text_->selection());
1672 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, SELECTION_NONE); 1685 render_text_->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, SELECTION_NONE);
1673 EXPECT_EQ(Range(1), render_text->selection()); 1686 EXPECT_EQ(Range(1), render_text_->selection());
1674 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, SELECTION_NONE); 1687 render_text_->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, SELECTION_NONE);
1675 EXPECT_EQ(Range(2), render_text->selection()); 1688 EXPECT_EQ(Range(2), render_text_->selection());
1676 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, SELECTION_NONE); 1689 render_text_->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, SELECTION_NONE);
1677 EXPECT_EQ(Range(3), render_text->selection()); 1690 EXPECT_EQ(Range(3), render_text_->selection());
1678 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, SELECTION_NONE); 1691 render_text_->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, SELECTION_NONE);
1679 EXPECT_EQ(Range(5), render_text->selection()); 1692 EXPECT_EQ(Range(5), render_text_->selection());
1680 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, SELECTION_NONE); 1693 render_text_->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, SELECTION_NONE);
1681 EXPECT_EQ(Range(4), render_text->selection()); 1694 EXPECT_EQ(Range(4), render_text_->selection());
1682 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, SELECTION_RETAIN); 1695 render_text_->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, SELECTION_RETAIN);
1683 EXPECT_EQ(Range(4, 5), render_text->selection()); 1696 EXPECT_EQ(Range(4, 5), render_text_->selection());
1684 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, SELECTION_RETAIN); 1697 render_text_->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, SELECTION_RETAIN);
1685 EXPECT_EQ(Range(4, 6), render_text->selection()); 1698 EXPECT_EQ(Range(4, 6), render_text_->selection());
1686 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, SELECTION_NONE); 1699 render_text_->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, SELECTION_NONE);
1687 EXPECT_EQ(Range(4), render_text->selection()); 1700 EXPECT_EQ(Range(4), render_text_->selection());
1688 } 1701 }
1689 #endif // !defined(OS_MACOSX)
1690 1702
1691 TEST_F(RenderTextTest, CenteredDisplayOffset) { 1703 TEST_P(RenderTextTestAll, CenteredDisplayOffset) {
1692 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 1704 render_text_->SetText(ASCIIToUTF16("abcdefghij"));
1693 render_text->SetText(ASCIIToUTF16("abcdefghij")); 1705 render_text_->SetHorizontalAlignment(ALIGN_CENTER);
1694 render_text->SetHorizontalAlignment(ALIGN_CENTER);
1695 1706
1696 const int kEnlargement = 10; 1707 const int kEnlargement = 10;
1697 const int content_width = render_text->GetContentWidth(); 1708 const int content_width = render_text_->GetContentWidth();
1698 Rect display_rect(0, 0, content_width / 2, 1709 Rect display_rect(0, 0, content_width / 2,
1699 render_text->font_list().GetHeight()); 1710 render_text_->font_list().GetHeight());
1700 render_text->SetDisplayRect(display_rect); 1711 render_text_->SetDisplayRect(display_rect);
1701 1712
1702 // Move the cursor to the beginning of the text and, by checking the cursor 1713 // Move the cursor to the beginning of the text and, by checking the cursor
1703 // bounds, make sure no empty space is to the left of the text. 1714 // bounds, make sure no empty space is to the left of the text.
1704 render_text->SetCursorPosition(0); 1715 render_text_->SetCursorPosition(0);
1705 EXPECT_EQ(display_rect.x(), render_text->GetUpdatedCursorBounds().x()); 1716 EXPECT_EQ(display_rect.x(), render_text_->GetUpdatedCursorBounds().x());
1706 1717
1707 // Widen the display rect and, by checking the cursor bounds, make sure no 1718 // Widen the display rect and, by checking the cursor bounds, make sure no
1708 // empty space is introduced to the left of the text. 1719 // empty space is introduced to the left of the text.
1709 display_rect.Inset(0, 0, -kEnlargement, 0); 1720 display_rect.Inset(0, 0, -kEnlargement, 0);
1710 render_text->SetDisplayRect(display_rect); 1721 render_text_->SetDisplayRect(display_rect);
1711 EXPECT_EQ(display_rect.x(), render_text->GetUpdatedCursorBounds().x()); 1722 EXPECT_EQ(display_rect.x(), render_text_->GetUpdatedCursorBounds().x());
1712 1723
1713 // TODO(asvitkine): RenderTextMac cursor movements. http://crbug.com/131618 1724 // TODO(asvitkine): RenderTextMac cursor movements. http://crbug.com/131618
1714 #if !defined(OS_MACOSX) 1725 if (GetParam() != RENDER_TEXT_MAC) {
1715 // Move the cursor to the end of the text and, by checking the cursor bounds, 1726 // Move the cursor to the end of the text and, by checking the cursor
1716 // make sure no empty space is to the right of the text. 1727 // bounds,
1717 render_text->SetCursorPosition(render_text->text().length()); 1728 // make sure no empty space is to the right of the text.
1718 EXPECT_EQ(display_rect.right(), 1729 render_text_->SetCursorPosition(render_text_->text().length());
1719 render_text->GetUpdatedCursorBounds().right()); 1730 EXPECT_EQ(display_rect.right(),
1731 render_text_->GetUpdatedCursorBounds().right());
1720 1732
1721 // Widen the display rect and, by checking the cursor bounds, make sure no 1733 // Widen the display rect and, by checking the cursor bounds, make sure no
1722 // empty space is introduced to the right of the text. 1734 // empty space is introduced to the right of the text.
1723 display_rect.Inset(0, 0, -kEnlargement, 0); 1735 display_rect.Inset(0, 0, -kEnlargement, 0);
1724 render_text->SetDisplayRect(display_rect); 1736 render_text_->SetDisplayRect(display_rect);
1725 EXPECT_EQ(display_rect.right(), 1737 EXPECT_EQ(display_rect.right(),
1726 render_text->GetUpdatedCursorBounds().right()); 1738 render_text_->GetUpdatedCursorBounds().right());
1727 #endif // !defined(OS_MACOSX) 1739 }
1728 } 1740 }
1729 1741
1730 void MoveLeftRightByWordVerifier(RenderText* render_text, 1742 void MoveLeftRightByWordVerifier(RenderText* render_text,
1731 const wchar_t* str) { 1743 const wchar_t* str) {
1732 render_text->SetText(WideToUTF16(str)); 1744 render_text->SetText(WideToUTF16(str));
1733 1745
1734 // Test moving by word from left ro right. 1746 // Test moving by word from left ro right.
1735 render_text->MoveCursor(LINE_BREAK, CURSOR_LEFT, SELECTION_NONE); 1747 render_text->MoveCursor(LINE_BREAK, CURSOR_LEFT, SELECTION_NONE);
1736 bool first_word = true; 1748 bool first_word = true;
1737 while (true) { 1749 while (true) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1783 render_text->MoveCursorTo(start); 1795 render_text->MoveCursorTo(start);
1784 for (int k = 0; k < j; ++k) 1796 for (int k = 0; k < j; ++k)
1785 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, SELECTION_NONE); 1797 render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, SELECTION_NONE);
1786 render_text->MoveCursor(WORD_BREAK, CURSOR_LEFT, SELECTION_NONE); 1798 render_text->MoveCursor(WORD_BREAK, CURSOR_LEFT, SELECTION_NONE);
1787 EXPECT_EQ(end, render_text->selection_model()); 1799 EXPECT_EQ(end, render_text->selection_model());
1788 } 1800 }
1789 } 1801 }
1790 } 1802 }
1791 1803
1792 // TODO(asvitkine): RenderTextMac cursor movements. http://crbug.com/131618 1804 // TODO(asvitkine): RenderTextMac cursor movements. http://crbug.com/131618
1793 #if !defined(OS_MACOSX)
1794 // TODO(msw): Make these work on Windows. 1805 // TODO(msw): Make these work on Windows.
1795 #if !defined(OS_WIN) 1806 #if !defined(OS_WIN)
1796 TEST_F(RenderTextTest, MoveLeftRightByWordInBidiText) { 1807 TEST_P(RenderTextHarfBuzzTest, MoveLeftRightByWordInBidiText) {
1797 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance());
1798
1799 // For testing simplicity, each word is a 3-character word. 1808 // For testing simplicity, each word is a 3-character word.
1800 std::vector<const wchar_t*> test; 1809 std::vector<const wchar_t*> test;
1801 test.push_back(L"abc"); 1810 test.push_back(L"abc");
1802 test.push_back(L"abc def"); 1811 test.push_back(L"abc def");
1803 test.push_back(L"\x05E1\x05E2\x05E3"); 1812 test.push_back(L"\x05E1\x05E2\x05E3");
1804 test.push_back(L"\x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6"); 1813 test.push_back(L"\x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6");
1805 test.push_back(L"abc \x05E1\x05E2\x05E3"); 1814 test.push_back(L"abc \x05E1\x05E2\x05E3");
1806 test.push_back(L"abc def \x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6"); 1815 test.push_back(L"abc def \x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6");
1807 test.push_back(L"abc def hij \x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6" 1816 test.push_back(L"abc def hij \x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6"
1808 L" \x05E7\x05E8\x05E9"); 1817 L" \x05E7\x05E8\x05E9");
1809 1818
1810 test.push_back(L"abc \x05E1\x05E2\x05E3 hij"); 1819 test.push_back(L"abc \x05E1\x05E2\x05E3 hij");
1811 test.push_back(L"abc def \x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6 hij opq"); 1820 test.push_back(L"abc def \x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6 hij opq");
1812 test.push_back(L"abc def hij \x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6" 1821 test.push_back(L"abc def hij \x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6"
1813 L" \x05E7\x05E8\x05E9" L" opq rst uvw"); 1822 L" \x05E7\x05E8\x05E9" L" opq rst uvw");
1814 1823
1815 test.push_back(L"\x05E1\x05E2\x05E3 abc"); 1824 test.push_back(L"\x05E1\x05E2\x05E3 abc");
1816 test.push_back(L"\x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6 abc def"); 1825 test.push_back(L"\x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6 abc def");
1817 test.push_back(L"\x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6 \x05E7\x05E8\x05E9" 1826 test.push_back(L"\x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6 \x05E7\x05E8\x05E9"
1818 L" abc def hij"); 1827 L" abc def hij");
1819 1828
1820 test.push_back(L"\x05D1\x05D2\x05D3 abc \x05E1\x05E2\x05E3"); 1829 test.push_back(L"\x05D1\x05D2\x05D3 abc \x05E1\x05E2\x05E3");
1821 test.push_back(L"\x05D1\x05D2\x05D3 \x05D4\x05D5\x05D6 abc def" 1830 test.push_back(L"\x05D1\x05D2\x05D3 \x05D4\x05D5\x05D6 abc def"
1822 L" \x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6"); 1831 L" \x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6");
1823 test.push_back(L"\x05D1\x05D2\x05D3 \x05D4\x05D5\x05D6 \x05D7\x05D8\x05D9" 1832 test.push_back(L"\x05D1\x05D2\x05D3 \x05D4\x05D5\x05D6 \x05D7\x05D8\x05D9"
1824 L" abc def hij \x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6" 1833 L" abc def hij \x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6"
1825 L" \x05E7\x05E8\x05E9"); 1834 L" \x05E7\x05E8\x05E9");
1826 1835
1827 for (size_t i = 0; i < test.size(); ++i) 1836 for (size_t i = 0; i < test.size(); ++i)
1828 MoveLeftRightByWordVerifier(render_text.get(), test[i]); 1837 MoveLeftRightByWordVerifier(render_text_.get(), test[i]);
1829 } 1838 }
1830 1839
1831 TEST_F(RenderTextTest, MoveLeftRightByWordInBidiText_TestEndOfText) { 1840 // TODO(asvitkine): RenderTextMac cursor movements. http://crbug.com/131618
1832 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 1841 TEST_P(RenderTextHarfBuzzTest, MoveLeftRightByWordInBidiText_TestEndOfText) {
1833 1842 render_text_->SetText(WideToUTF16(L"ab\x05E1"));
1834 render_text->SetText(WideToUTF16(L"ab\x05E1"));
1835 // Moving the cursor by word from "abC|" to the left should return "|abC". 1843 // Moving the cursor by word from "abC|" to the left should return "|abC".
1836 // But since end of text is always treated as a word break, it returns 1844 // But since end of text is always treated as a word break, it returns
1837 // position "ab|C". 1845 // position "ab|C".
1838 // TODO(xji): Need to make it work as expected. 1846 // TODO(xji): Need to make it work as expected.
1839 render_text->MoveCursor(LINE_BREAK, CURSOR_RIGHT, SELECTION_NONE); 1847 render_text_->MoveCursor(LINE_BREAK, CURSOR_RIGHT, SELECTION_NONE);
1840 render_text->MoveCursor(WORD_BREAK, CURSOR_LEFT, SELECTION_NONE); 1848 render_text_->MoveCursor(WORD_BREAK, CURSOR_LEFT, SELECTION_NONE);
1841 // EXPECT_EQ(SelectionModel(), render_text->selection_model()); 1849 // EXPECT_EQ(SelectionModel(), render_text_->selection_model());
1842 1850
1843 // Moving the cursor by word from "|abC" to the right returns "abC|". 1851 // Moving the cursor by word from "|abC" to the right returns "abC|".
1844 render_text->MoveCursor(LINE_BREAK, CURSOR_LEFT, SELECTION_NONE); 1852 render_text_->MoveCursor(LINE_BREAK, CURSOR_LEFT, SELECTION_NONE);
1845 render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, SELECTION_NONE); 1853 render_text_->MoveCursor(WORD_BREAK, CURSOR_RIGHT, SELECTION_NONE);
1846 EXPECT_EQ(SelectionModel(3, CURSOR_FORWARD), render_text->selection_model()); 1854 EXPECT_EQ(SelectionModel(3, CURSOR_FORWARD), render_text_->selection_model());
1847 1855
1848 render_text->SetText(WideToUTF16(L"\x05E1\x05E2" L"a")); 1856 render_text_->SetText(
1857 WideToUTF16(L"\x05E1\x05E2"
1858 L"a"));
1849 // For logical text "BCa", moving the cursor by word from "aCB|" to the left 1859 // For logical text "BCa", moving the cursor by word from "aCB|" to the left
1850 // returns "|aCB". 1860 // returns "|aCB".
1851 render_text->MoveCursor(LINE_BREAK, CURSOR_RIGHT, SELECTION_NONE); 1861 render_text_->MoveCursor(LINE_BREAK, CURSOR_RIGHT, SELECTION_NONE);
1852 render_text->MoveCursor(WORD_BREAK, CURSOR_LEFT, SELECTION_NONE); 1862 render_text_->MoveCursor(WORD_BREAK, CURSOR_LEFT, SELECTION_NONE);
1853 EXPECT_EQ(SelectionModel(3, CURSOR_FORWARD), render_text->selection_model()); 1863 EXPECT_EQ(SelectionModel(3, CURSOR_FORWARD), render_text_->selection_model());
1854 1864
1855 // Moving the cursor by word from "|aCB" to the right should return "aCB|". 1865 // Moving the cursor by word from "|aCB" to the right should return "aCB|".
1856 // But since end of text is always treated as a word break, it returns 1866 // But since end of text is always treated as a word break, it returns
1857 // position "a|CB". 1867 // position "a|CB".
1858 // TODO(xji): Need to make it work as expected. 1868 // TODO(xji): Need to make it work as expected.
1859 render_text->MoveCursor(LINE_BREAK, CURSOR_LEFT, SELECTION_NONE); 1869 render_text_->MoveCursor(LINE_BREAK, CURSOR_LEFT, SELECTION_NONE);
1860 render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, SELECTION_NONE); 1870 render_text_->MoveCursor(WORD_BREAK, CURSOR_RIGHT, SELECTION_NONE);
1861 // EXPECT_EQ(SelectionModel(), render_text->selection_model()); 1871 // EXPECT_EQ(SelectionModel(), render_text_->selection_model());
1862 } 1872 }
1863 1873
1864 TEST_F(RenderTextTest, MoveLeftRightByWordInTextWithMultiSpaces) { 1874 // TODO(asvitkine): RenderTextMac cursor movements. http://crbug.com/131618
1865 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 1875 TEST_P(RenderTextHarfBuzzTest, MoveLeftRightByWordInTextWithMultiSpaces) {
1866 render_text->SetText(WideToUTF16(L"abc def")); 1876 render_text_->SetText(WideToUTF16(L"abc def"));
1867 render_text->MoveCursorTo(SelectionModel(5, CURSOR_FORWARD)); 1877 render_text_->MoveCursorTo(SelectionModel(5, CURSOR_FORWARD));
1868 render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, SELECTION_NONE); 1878 render_text_->MoveCursor(WORD_BREAK, CURSOR_RIGHT, SELECTION_NONE);
1869 EXPECT_EQ(11U, render_text->cursor_position()); 1879 EXPECT_EQ(11U, render_text_->cursor_position());
1870 1880
1871 render_text->MoveCursorTo(SelectionModel(5, CURSOR_FORWARD)); 1881 render_text_->MoveCursorTo(SelectionModel(5, CURSOR_FORWARD));
1872 render_text->MoveCursor(WORD_BREAK, CURSOR_LEFT, SELECTION_NONE); 1882 render_text_->MoveCursor(WORD_BREAK, CURSOR_LEFT, SELECTION_NONE);
1873 EXPECT_EQ(0U, render_text->cursor_position()); 1883 EXPECT_EQ(0U, render_text_->cursor_position());
1874 } 1884 }
1875 #endif // !defined(OS_WIN) 1885 #endif // !defined(OS_WIN)
1876 1886
1877 TEST_F(RenderTextTest, MoveLeftRightByWordInChineseText) { 1887 // TODO(asvitkine): RenderTextMac cursor movements. http://crbug.com/131618
1878 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 1888 TEST_P(RenderTextHarfBuzzTest, MoveLeftRightByWordInChineseText) {
1879 render_text->SetText(WideToUTF16(L"\x6211\x4EEC\x53BB\x516C\x56ED\x73A9")); 1889 render_text_->SetText(WideToUTF16(L"\x6211\x4EEC\x53BB\x516C\x56ED\x73A9"));
1880 render_text->MoveCursor(LINE_BREAK, CURSOR_LEFT, SELECTION_NONE); 1890 render_text_->MoveCursor(LINE_BREAK, CURSOR_LEFT, SELECTION_NONE);
1881 EXPECT_EQ(0U, render_text->cursor_position()); 1891 EXPECT_EQ(0U, render_text_->cursor_position());
1882 render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, SELECTION_NONE); 1892 render_text_->MoveCursor(WORD_BREAK, CURSOR_RIGHT, SELECTION_NONE);
1883 EXPECT_EQ(2U, render_text->cursor_position()); 1893 EXPECT_EQ(2U, render_text_->cursor_position());
1884 render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, SELECTION_NONE); 1894 render_text_->MoveCursor(WORD_BREAK, CURSOR_RIGHT, SELECTION_NONE);
1885 EXPECT_EQ(3U, render_text->cursor_position()); 1895 EXPECT_EQ(3U, render_text_->cursor_position());
1886 render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, SELECTION_NONE); 1896 render_text_->MoveCursor(WORD_BREAK, CURSOR_RIGHT, SELECTION_NONE);
1887 EXPECT_EQ(5U, render_text->cursor_position()); 1897 EXPECT_EQ(5U, render_text_->cursor_position());
1888 render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, SELECTION_NONE); 1898 render_text_->MoveCursor(WORD_BREAK, CURSOR_RIGHT, SELECTION_NONE);
1889 EXPECT_EQ(6U, render_text->cursor_position()); 1899 EXPECT_EQ(6U, render_text_->cursor_position());
1890 render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, SELECTION_NONE); 1900 render_text_->MoveCursor(WORD_BREAK, CURSOR_RIGHT, SELECTION_NONE);
1891 EXPECT_EQ(6U, render_text->cursor_position()); 1901 EXPECT_EQ(6U, render_text_->cursor_position());
1892 } 1902 }
1893 #endif // !defined(OS_MACOSX)
1894 1903
1895 TEST_F(RenderTextTest, StringSizeSanity) { 1904 TEST_P(RenderTextTestAll, StringSizeSanity) {
1896 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 1905 render_text_->SetText(UTF8ToUTF16("Hello World"));
1897 render_text->SetText(UTF8ToUTF16("Hello World")); 1906 const Size string_size = render_text_->GetStringSize();
1898 const Size string_size = render_text->GetStringSize();
1899 EXPECT_GT(string_size.width(), 0); 1907 EXPECT_GT(string_size.width(), 0);
1900 EXPECT_GT(string_size.height(), 0); 1908 EXPECT_GT(string_size.height(), 0);
1901 } 1909 }
1902 1910
1903 TEST_F(RenderTextTest, StringSizeLongStrings) { 1911 TEST_P(RenderTextTestAll, StringSizeLongStrings) {
1904 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance());
1905 Size previous_string_size; 1912 Size previous_string_size;
1906 for (size_t length = 10; length < 1000000; length *= 10) { 1913 for (size_t length = 10; length < 1000000; length *= 10) {
1907 render_text->SetText(base::string16(length, 'a')); 1914 render_text_->SetText(base::string16(length, 'a'));
1908 const Size string_size = render_text->GetStringSize(); 1915 const Size string_size = render_text_->GetStringSize();
1909 EXPECT_GT(string_size.width(), previous_string_size.width()); 1916 EXPECT_GT(string_size.width(), previous_string_size.width());
1910 EXPECT_GT(string_size.height(), 0); 1917 EXPECT_GT(string_size.height(), 0);
1911 previous_string_size = string_size; 1918 previous_string_size = string_size;
1912 } 1919 }
1913 } 1920 }
1914 1921
1915 // TODO(asvitkine): This test fails because PlatformFontMac uses point font 1922 TEST_P(RenderTextTestAll, StringSizeEmptyString) {
1916 // sizes instead of pixel sizes like other implementations.
1917 #if !defined(OS_MACOSX)
1918 TEST_F(RenderTextTest, StringSizeEmptyString) {
karandeepb 2016/08/24 03:36:27 This doesn't fail with RenderTextMac now.
1919 // Ascent and descent of Arial and Symbol are different on most platforms. 1923 // Ascent and descent of Arial and Symbol are different on most platforms.
1920 const FontList font_list("Arial,Symbol, 16px"); 1924 const FontList font_list("Arial,Symbol, 16px");
1921 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 1925 render_text_->SetFontList(font_list);
1922 render_text->SetFontList(font_list); 1926 render_text_->SetDisplayRect(Rect(0, 0, 0, font_list.GetHeight()));
1923 render_text->SetDisplayRect(Rect(0, 0, 0, font_list.GetHeight()));
1924 1927
1925 // The empty string respects FontList metrics for non-zero height 1928 // The empty string respects FontList metrics for non-zero height
1926 // and baseline. 1929 // and baseline.
1927 render_text->SetText(base::string16()); 1930 render_text_->SetText(base::string16());
1928 EXPECT_EQ(font_list.GetHeight(), render_text->GetStringSize().height()); 1931 EXPECT_EQ(font_list.GetHeight(), render_text_->GetStringSize().height());
1929 EXPECT_EQ(0, render_text->GetStringSize().width()); 1932 EXPECT_EQ(0, render_text_->GetStringSize().width());
1930 EXPECT_EQ(font_list.GetBaseline(), render_text->GetBaseline()); 1933 EXPECT_EQ(font_list.GetBaseline(), render_text_->GetBaseline());
1931 1934
1932 render_text->SetText(UTF8ToUTF16(" ")); 1935 render_text_->SetText(UTF8ToUTF16(" "));
1933 EXPECT_EQ(font_list.GetHeight(), render_text->GetStringSize().height()); 1936 EXPECT_EQ(font_list.GetHeight(), render_text_->GetStringSize().height());
1934 EXPECT_EQ(font_list.GetBaseline(), render_text->GetBaseline()); 1937 EXPECT_EQ(font_list.GetBaseline(), render_text_->GetBaseline());
1935 } 1938 }
1936 #endif // !defined(OS_MACOSX)
1937 1939
1938 TEST_F(RenderTextTest, StringSizeRespectsFontListMetrics) { 1940 TEST_P(RenderTextTestAll, StringSizeRespectsFontListMetrics) {
1939 // Check that Arial and Symbol have different font metrics. 1941 // Check that Arial and Symbol have different font metrics.
1940 Font arial_font("Arial", 16); 1942 Font arial_font("Arial", 16);
1941 ASSERT_EQ("arial", 1943 ASSERT_EQ("arial",
1942 base::ToLowerASCII(arial_font.GetActualFontNameForTesting())); 1944 base::ToLowerASCII(arial_font.GetActualFontNameForTesting()));
1943 Font symbol_font("Symbol", 16); 1945 Font symbol_font("Symbol", 16);
1944 ASSERT_EQ("symbol", 1946 ASSERT_EQ("symbol",
1945 base::ToLowerASCII(symbol_font.GetActualFontNameForTesting())); 1947 base::ToLowerASCII(symbol_font.GetActualFontNameForTesting()));
1946 EXPECT_NE(arial_font.GetHeight(), symbol_font.GetHeight()); 1948 EXPECT_NE(arial_font.GetHeight(), symbol_font.GetHeight());
1947 EXPECT_NE(arial_font.GetBaseline(), symbol_font.GetBaseline()); 1949 EXPECT_NE(arial_font.GetBaseline(), symbol_font.GetBaseline());
1948 // "a" should be rendered with Arial, not with Symbol. 1950 // "a" should be rendered with Arial, not with Symbol.
1949 const char* arial_font_text = "a"; 1951 const char* arial_font_text = "a";
1950 // "®" (registered trademark symbol) should be rendered with Symbol, 1952 // "®" (registered trademark symbol) should be rendered with Symbol,
1951 // not with Arial. 1953 // not with Arial.
1952 const char* symbol_font_text = "\xC2\xAE"; 1954 const char* symbol_font_text = "\xC2\xAE";
1953 1955
1954 Font smaller_font = arial_font; 1956 Font smaller_font = arial_font;
1955 Font larger_font = symbol_font; 1957 Font larger_font = symbol_font;
1956 const char* smaller_font_text = arial_font_text; 1958 const char* smaller_font_text = arial_font_text;
1957 const char* larger_font_text = symbol_font_text; 1959 const char* larger_font_text = symbol_font_text;
1958 if (symbol_font.GetHeight() < arial_font.GetHeight() && 1960 if (symbol_font.GetHeight() < arial_font.GetHeight() &&
1959 symbol_font.GetBaseline() < arial_font.GetBaseline()) { 1961 symbol_font.GetBaseline() < arial_font.GetBaseline()) {
1960 std::swap(smaller_font, larger_font); 1962 std::swap(smaller_font, larger_font);
1961 std::swap(smaller_font_text, larger_font_text); 1963 std::swap(smaller_font_text, larger_font_text);
1962 } 1964 }
1963 ASSERT_LT(smaller_font.GetHeight(), larger_font.GetHeight()); 1965 ASSERT_LT(smaller_font.GetHeight(), larger_font.GetHeight());
1964 ASSERT_LT(smaller_font.GetBaseline(), larger_font.GetBaseline()); 1966 ASSERT_LT(smaller_font.GetBaseline(), larger_font.GetBaseline());
1965 1967
1966 // Check |smaller_font_text| is rendered with the smaller font. 1968 // Check |smaller_font_text| is rendered with the smaller font.
1967 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 1969 render_text_->SetText(UTF8ToUTF16(smaller_font_text));
1968 render_text->SetText(UTF8ToUTF16(smaller_font_text)); 1970 render_text_->SetFontList(FontList(smaller_font));
1969 render_text->SetFontList(FontList(smaller_font)); 1971 render_text_->SetDisplayRect(
1970 render_text->SetDisplayRect(Rect(0, 0, 0, 1972 Rect(0, 0, 0, render_text_->font_list().GetHeight()));
1971 render_text->font_list().GetHeight())); 1973 EXPECT_EQ(smaller_font.GetHeight(), render_text_->GetStringSize().height());
1972 EXPECT_EQ(smaller_font.GetHeight(), render_text->GetStringSize().height()); 1974 EXPECT_EQ(smaller_font.GetBaseline(), render_text_->GetBaseline());
1973 EXPECT_EQ(smaller_font.GetBaseline(), render_text->GetBaseline());
1974 1975
1975 // Layout the same text with mixed fonts. The text should be rendered with 1976 // Layout the same text with mixed fonts. The text should be rendered with
1976 // the smaller font, but the height and baseline are determined with the 1977 // the smaller font, but the height and baseline are determined with the
1977 // metrics of the font list, which is equal to the larger font. 1978 // metrics of the font list, which is equal to the larger font.
1978 std::vector<Font> fonts; 1979 std::vector<Font> fonts;
1979 fonts.push_back(smaller_font); // The primary font is the smaller font. 1980 fonts.push_back(smaller_font); // The primary font is the smaller font.
1980 fonts.push_back(larger_font); 1981 fonts.push_back(larger_font);
1981 const FontList font_list(fonts); 1982 const FontList font_list(fonts);
1982 render_text->SetFontList(font_list); 1983 render_text_->SetFontList(font_list);
1983 render_text->SetDisplayRect(Rect(0, 0, 0, 1984 render_text_->SetDisplayRect(
1984 render_text->font_list().GetHeight())); 1985 Rect(0, 0, 0, render_text_->font_list().GetHeight()));
1985 EXPECT_LT(smaller_font.GetHeight(), render_text->GetStringSize().height()); 1986 EXPECT_LT(smaller_font.GetHeight(), render_text_->GetStringSize().height());
1986 EXPECT_LT(smaller_font.GetBaseline(), render_text->GetBaseline()); 1987 EXPECT_LT(smaller_font.GetBaseline(), render_text_->GetBaseline());
1987 EXPECT_EQ(font_list.GetHeight(), render_text->GetStringSize().height()); 1988 EXPECT_EQ(font_list.GetHeight(), render_text_->GetStringSize().height());
1988 EXPECT_EQ(font_list.GetBaseline(), render_text->GetBaseline()); 1989 EXPECT_EQ(font_list.GetBaseline(), render_text_->GetBaseline());
1989 } 1990 }
1990 1991
1991 TEST_F(RenderTextTest, MinLineHeight) { 1992 TEST_P(RenderTextTestAll, MinLineHeight) {
1992 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 1993 render_text_->SetText(ASCIIToUTF16("Hello!"));
1993 1994 SizeF default_size = render_text_->GetStringSizeF();
1994 render_text->SetText(ASCIIToUTF16("Hello!"));
1995 SizeF default_size = render_text->GetStringSizeF();
1996 ASSERT_NE(0, default_size.height()); 1995 ASSERT_NE(0, default_size.height());
1997 ASSERT_NE(0, default_size.width()); 1996 ASSERT_NE(0, default_size.width());
1998 1997
1999 render_text->SetMinLineHeight(default_size.height() / 2); 1998 render_text_->SetMinLineHeight(default_size.height() / 2);
2000 EXPECT_EQ(default_size.ToString(), render_text->GetStringSizeF().ToString()); 1999 EXPECT_EQ(default_size.ToString(), render_text_->GetStringSizeF().ToString());
2001 2000
2002 render_text->SetMinLineHeight(default_size.height() * 2); 2001 render_text_->SetMinLineHeight(default_size.height() * 2);
2003 SizeF taller_size = render_text->GetStringSizeF(); 2002 SizeF taller_size = render_text_->GetStringSizeF();
2004 EXPECT_EQ(default_size.height() * 2, taller_size.height()); 2003 EXPECT_EQ(default_size.height() * 2, taller_size.height());
2005 EXPECT_EQ(default_size.width(), taller_size.width()); 2004 EXPECT_EQ(default_size.width(), taller_size.width());
2006 } 2005 }
2007 2006
2008 TEST_F(RenderTextTest, SetFontList) { 2007 TEST_P(RenderTextTestAll, SetFontList) {
2009 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 2008 render_text_->SetFontList(FontList("Arial,Symbol, 13px"));
2010 render_text->SetFontList(FontList("Arial,Symbol, 13px")); 2009 const std::vector<Font>& fonts = render_text_->font_list().GetFonts();
2011 const std::vector<Font>& fonts = render_text->font_list().GetFonts();
2012 ASSERT_EQ(2U, fonts.size()); 2010 ASSERT_EQ(2U, fonts.size());
2013 EXPECT_EQ("Arial", fonts[0].GetFontName()); 2011 EXPECT_EQ("Arial", fonts[0].GetFontName());
2014 EXPECT_EQ("Symbol", fonts[1].GetFontName()); 2012 EXPECT_EQ("Symbol", fonts[1].GetFontName());
2015 EXPECT_EQ(13, render_text->font_list().GetFontSize()); 2013 EXPECT_EQ(13, render_text_->font_list().GetFontSize());
2016 } 2014 }
2017 2015
2016 // Todo check why parameterized tests fail if they have a MAYBE_ in their name?
2018 // http://crbug/624513 2017 // http://crbug/624513
2019 #if defined(OS_WIN) 2018 #if !defined(OS_WIN)
karandeepb 2016/08/24 03:36:28 It seems that the TEST_P macro doesn't work correc
2020 #define MAYBE_StringSizeBoldWidth DISABLED_StringSizeBoldWidth 2019 TEST_P(RenderTextTestAll, StringSizeBoldWidth) {
2021 #else
2022 #define MAYBE_StringSizeBoldWidth StringSizeBoldWidth
2023 #endif
2024 TEST_F(RenderTextTest, MAYBE_StringSizeBoldWidth) {
2025 // TODO(mboc): Add some unittests for other weights (currently not 2020 // TODO(mboc): Add some unittests for other weights (currently not
2026 // implemented because of test system font configuration). 2021 // implemented because of test system font configuration).
2027 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 2022 render_text_->SetText(UTF8ToUTF16("Hello World"));
2028 render_text->SetText(UTF8ToUTF16("Hello World"));
2029 2023
2030 const int plain_width = render_text->GetStringSize().width(); 2024 const int plain_width = render_text_->GetStringSize().width();
2031 EXPECT_GT(plain_width, 0); 2025 EXPECT_GT(plain_width, 0);
2032 2026
2033 // Apply a bold style and check that the new width is greater. 2027 // Apply a bold style and check that the new width is greater.
2034 render_text->SetWeight(Font::Weight::BOLD); 2028 render_text_->SetWeight(Font::Weight::BOLD);
2035 const int bold_width = render_text->GetStringSize().width(); 2029 const int bold_width = render_text_->GetStringSize().width();
2036 EXPECT_GT(bold_width, plain_width); 2030 EXPECT_GT(bold_width, plain_width);
2037 2031
2038 #if defined(OS_WIN) 2032 #if defined(OS_WIN)
2039 render_text->SetWeight(Font::Weight::SEMIBOLD); 2033 render_text_->SetWeight(Font::Weight::SEMIBOLD);
2040 const int semibold_width = render_text->GetStringSize().width(); 2034 const int semibold_width = render_text_->GetStringSize().width();
2041 EXPECT_GT(bold_width, semibold_width); 2035 EXPECT_GT(bold_width, semibold_width);
2042 #endif 2036 #endif
2043 2037
2044 // Now, apply a plain style over the first word only. 2038 // Now, apply a plain style over the first word only.
2045 render_text->ApplyWeight(Font::Weight::NORMAL, Range(0, 5)); 2039 render_text_->ApplyWeight(Font::Weight::NORMAL, Range(0, 5));
2046 const int plain_bold_width = render_text->GetStringSize().width(); 2040 const int plain_bold_width = render_text_->GetStringSize().width();
2047 EXPECT_GT(plain_bold_width, plain_width); 2041 EXPECT_GT(plain_bold_width, plain_width);
2048 EXPECT_LT(plain_bold_width, bold_width); 2042 EXPECT_LT(plain_bold_width, bold_width);
2049 } 2043 }
2044 #endif
2050 2045
2051 TEST_F(RenderTextTest, StringSizeHeight) { 2046 TEST_P(RenderTextTestAll, StringSizeHeight) {
2052 base::string16 cases[] = { 2047 base::string16 cases[] = {
2053 WideToUTF16(L"Hello World!"), // English 2048 WideToUTF16(L"Hello World!"), // English
2054 WideToUTF16(L"\x6328\x62f6"), // Japanese 2049 WideToUTF16(L"\x6328\x62f6"), // Japanese
2055 WideToUTF16(L"\x0915\x093f"), // Hindi 2050 WideToUTF16(L"\x0915\x093f"), // Hindi
2056 WideToUTF16(L"\x05e0\x05b8"), // Hebrew 2051 WideToUTF16(L"\x05e0\x05b8"), // Hebrew
2057 }; 2052 };
2058 2053
2059 const FontList default_font_list; 2054 const FontList default_font_list;
2060 const FontList& larger_font_list = default_font_list.DeriveWithSizeDelta(24); 2055 const FontList& larger_font_list = default_font_list.DeriveWithSizeDelta(24);
2061 EXPECT_GT(larger_font_list.GetHeight(), default_font_list.GetHeight()); 2056 EXPECT_GT(larger_font_list.GetHeight(), default_font_list.GetHeight());
2062 2057
2063 for (size_t i = 0; i < arraysize(cases); i++) { 2058 for (size_t i = 0; i < arraysize(cases); i++) {
2064 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 2059 render_text_ = CreateRenderTextInstance();
2065 render_text->SetFontList(default_font_list); 2060 render_text_->SetFontList(default_font_list);
2066 render_text->SetText(cases[i]); 2061 render_text_->SetText(cases[i]);
2067 2062
2068 const int height1 = render_text->GetStringSize().height(); 2063 const int height1 = render_text_->GetStringSize().height();
2069 EXPECT_GT(height1, 0); 2064 EXPECT_GT(height1, 0);
2070 2065
2071 // Check that setting the larger font increases the height. 2066 // Check that setting the larger font increases the height.
2072 render_text->SetFontList(larger_font_list); 2067 render_text_->SetFontList(larger_font_list);
2073 const int height2 = render_text->GetStringSize().height(); 2068 const int height2 = render_text_->GetStringSize().height();
2074 EXPECT_GT(height2, height1); 2069 EXPECT_GT(height2, height1);
2075 } 2070 }
2076 } 2071 }
2077 2072
2078 TEST_F(RenderTextTest, GetBaselineSanity) { 2073 TEST_P(RenderTextTestAll, GetBaselineSanity) {
2079 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 2074 render_text_->SetText(UTF8ToUTF16("Hello World"));
2080 render_text->SetText(UTF8ToUTF16("Hello World")); 2075 const int baseline = render_text_->GetBaseline();
2081 const int baseline = render_text->GetBaseline();
2082 EXPECT_GT(baseline, 0); 2076 EXPECT_GT(baseline, 0);
2083 } 2077 }
2084 2078
2085 TEST_F(RenderTextTest, CursorBoundsInReplacementMode) { 2079 TEST_P(RenderTextTestAll, CursorBoundsInReplacementMode) {
2086 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 2080 render_text_->SetText(ASCIIToUTF16("abcdefg"));
2087 render_text->SetText(ASCIIToUTF16("abcdefg")); 2081 render_text_->SetDisplayRect(Rect(100, 17));
2088 render_text->SetDisplayRect(Rect(100, 17));
2089 SelectionModel sel_b(1, CURSOR_FORWARD); 2082 SelectionModel sel_b(1, CURSOR_FORWARD);
2090 SelectionModel sel_c(2, CURSOR_FORWARD); 2083 SelectionModel sel_c(2, CURSOR_FORWARD);
2091 Rect cursor_around_b = render_text->GetCursorBounds(sel_b, false); 2084 Rect cursor_around_b = render_text_->GetCursorBounds(sel_b, false);
2092 Rect cursor_before_b = render_text->GetCursorBounds(sel_b, true); 2085 Rect cursor_before_b = render_text_->GetCursorBounds(sel_b, true);
2093 Rect cursor_before_c = render_text->GetCursorBounds(sel_c, true); 2086 Rect cursor_before_c = render_text_->GetCursorBounds(sel_c, true);
2094 EXPECT_EQ(cursor_around_b.x(), cursor_before_b.x()); 2087 EXPECT_EQ(cursor_around_b.x(), cursor_before_b.x());
2095 EXPECT_EQ(cursor_around_b.right(), cursor_before_c.x()); 2088 EXPECT_EQ(cursor_around_b.right(), cursor_before_c.x());
2096 } 2089 }
2097 2090
2098 TEST_F(RenderTextTest, GetTextOffset) { 2091 TEST_P(RenderTextTestAll, GetTextOffset) {
2099 // The default horizontal text offset differs for LTR and RTL, and is only set 2092 // The default horizontal text offset differs for LTR and RTL, and is only set
2100 // when the RenderText object is created. This test will check the default in 2093 // when the RenderText object is created. This test will check the default in
2101 // LTR mode, and the next test will check the RTL default. 2094 // LTR mode, and the next test will check the RTL default.
2102 const bool was_rtl = base::i18n::IsRTL(); 2095 const bool was_rtl = base::i18n::IsRTL();
2103 SetRTL(false); 2096 SetRTL(false);
2104 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 2097
2105 render_text->SetText(ASCIIToUTF16("abcdefg")); 2098 // Reset the render text instance since the locale was changed.
2106 render_text->SetFontList(FontList("Arial, 13px")); 2099 render_text_ = CreateRenderTextInstance();
2100
2101 render_text_->SetText(ASCIIToUTF16("abcdefg"));
2102 render_text_->SetFontList(FontList("Arial, 13px"));
2107 2103
2108 // Set display area's size equal to the font size. 2104 // Set display area's size equal to the font size.
2109 const Size font_size(render_text->GetContentWidth(), 2105 const Size font_size(render_text_->GetContentWidth(),
2110 render_text->font_list().GetHeight()); 2106 render_text_->font_list().GetHeight());
2111 Rect display_rect(font_size); 2107 Rect display_rect(font_size);
2112 render_text->SetDisplayRect(display_rect); 2108 render_text_->SetDisplayRect(display_rect);
2113 2109
2114 Vector2d offset = render_text->GetLineOffset(0); 2110 Vector2d offset = render_text_->GetLineOffset(0);
2115 EXPECT_TRUE(offset.IsZero()); 2111 EXPECT_TRUE(offset.IsZero());
2116 2112
2117 const int kEnlargementX = 2; 2113 const int kEnlargementX = 2;
2118 display_rect.Inset(0, 0, -kEnlargementX, 0); 2114 display_rect.Inset(0, 0, -kEnlargementX, 0);
2119 render_text->SetDisplayRect(display_rect); 2115 render_text_->SetDisplayRect(display_rect);
2120 2116
2121 // Check the default horizontal alignment. 2117 // Check the default horizontal alignment.
2122 offset = render_text->GetLineOffset(0); 2118 offset = render_text_->GetLineOffset(0);
2123 EXPECT_EQ(0, offset.x()); 2119 EXPECT_EQ(0, offset.x());
2124 2120
2125 // Check explicitly setting the horizontal alignment. 2121 // Check explicitly setting the horizontal alignment.
2126 render_text->SetHorizontalAlignment(ALIGN_LEFT); 2122 render_text_->SetHorizontalAlignment(ALIGN_LEFT);
2127 offset = render_text->GetLineOffset(0); 2123 offset = render_text_->GetLineOffset(0);
2128 EXPECT_EQ(0, offset.x()); 2124 EXPECT_EQ(0, offset.x());
2129 render_text->SetHorizontalAlignment(ALIGN_CENTER); 2125 render_text_->SetHorizontalAlignment(ALIGN_CENTER);
2130 offset = render_text->GetLineOffset(0); 2126 offset = render_text_->GetLineOffset(0);
2131 EXPECT_EQ(kEnlargementX / 2, offset.x()); 2127 EXPECT_EQ(kEnlargementX / 2, offset.x());
2132 render_text->SetHorizontalAlignment(ALIGN_RIGHT); 2128 render_text_->SetHorizontalAlignment(ALIGN_RIGHT);
2133 offset = render_text->GetLineOffset(0); 2129 offset = render_text_->GetLineOffset(0);
2134 EXPECT_EQ(kEnlargementX, offset.x()); 2130 EXPECT_EQ(kEnlargementX, offset.x());
2135 2131
2136 // Check that text is vertically centered within taller display rects. 2132 // Check that text is vertically centered within taller display rects.
2137 const int kEnlargementY = display_rect.height(); 2133 const int kEnlargementY = display_rect.height();
2138 display_rect.Inset(0, 0, 0, -kEnlargementY); 2134 display_rect.Inset(0, 0, 0, -kEnlargementY);
2139 render_text->SetDisplayRect(display_rect); 2135 render_text_->SetDisplayRect(display_rect);
2140 const Vector2d prev_offset = render_text->GetLineOffset(0); 2136 const Vector2d prev_offset = render_text_->GetLineOffset(0);
2141 display_rect.Inset(0, 0, 0, -2 * kEnlargementY); 2137 display_rect.Inset(0, 0, 0, -2 * kEnlargementY);
2142 render_text->SetDisplayRect(display_rect); 2138 render_text_->SetDisplayRect(display_rect);
2143 offset = render_text->GetLineOffset(0); 2139 offset = render_text_->GetLineOffset(0);
2144 EXPECT_EQ(prev_offset.y() + kEnlargementY, offset.y()); 2140 EXPECT_EQ(prev_offset.y() + kEnlargementY, offset.y());
2145 2141
2146 SetRTL(was_rtl); 2142 SetRTL(was_rtl);
2147 } 2143 }
2148 2144
2149 TEST_F(RenderTextTest, GetTextOffsetHorizontalDefaultInRTL) { 2145 TEST_P(RenderTextTestAll, GetTextOffsetHorizontalDefaultInRTL) {
2150 // This only checks the default horizontal alignment in RTL mode; all other 2146 // This only checks the default horizontal alignment in RTL mode; all other
2151 // GetLineOffset(0) attributes are checked by the test above. 2147 // GetLineOffset(0) attributes are checked by the test above.
2152 const bool was_rtl = base::i18n::IsRTL(); 2148 const bool was_rtl = base::i18n::IsRTL();
2153 SetRTL(true); 2149 SetRTL(true);
2154 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 2150
2155 render_text->SetText(ASCIIToUTF16("abcdefg")); 2151 // Reset the render text instance since the locale was changed.
2156 render_text->SetFontList(FontList("Arial, 13px")); 2152 render_text_ = CreateRenderTextInstance();
2153
2154 render_text_->SetText(ASCIIToUTF16("abcdefg"));
2155 render_text_->SetFontList(FontList("Arial, 13px"));
2157 const int kEnlargement = 2; 2156 const int kEnlargement = 2;
2158 const Size font_size(render_text->GetContentWidth() + kEnlargement, 2157 const Size font_size(render_text_->GetContentWidth() + kEnlargement,
2159 render_text->GetStringSize().height()); 2158 render_text_->GetStringSize().height());
2160 Rect display_rect(font_size); 2159 Rect display_rect(font_size);
2161 render_text->SetDisplayRect(display_rect); 2160 render_text_->SetDisplayRect(display_rect);
2162 Vector2d offset = render_text->GetLineOffset(0); 2161 Vector2d offset = render_text_->GetLineOffset(0);
2163 EXPECT_EQ(kEnlargement, offset.x()); 2162 EXPECT_EQ(kEnlargement, offset.x());
2164 SetRTL(was_rtl); 2163 SetRTL(was_rtl);
2165 } 2164 }
2166 2165
2167 TEST_F(RenderTextTest, SetDisplayOffset) { 2166 TEST_P(RenderTextTestAll, SetDisplayOffset) {
2168 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 2167 render_text_->SetText(ASCIIToUTF16("abcdefg"));
2169 render_text->SetText(ASCIIToUTF16("abcdefg")); 2168 render_text_->SetFontList(FontList("Arial, 13px"));
2170 render_text->SetFontList(FontList("Arial, 13px"));
2171 2169
2172 const Size font_size(render_text->GetContentWidth(), 2170 const Size font_size(render_text_->GetContentWidth(),
2173 render_text->font_list().GetHeight()); 2171 render_text_->font_list().GetHeight());
2174 const int kEnlargement = 10; 2172 const int kEnlargement = 10;
2175 2173
2176 // Set display width |kEnlargement| pixels greater than content width and test 2174 // Set display width |kEnlargement| pixels greater than content width and test
2177 // different possible situations. In this case the only possible display 2175 // different possible situations. In this case the only possible display
2178 // offset is zero. 2176 // offset is zero.
2179 Rect display_rect(font_size); 2177 Rect display_rect(font_size);
2180 display_rect.Inset(0, 0, -kEnlargement, 0); 2178 display_rect.Inset(0, 0, -kEnlargement, 0);
2181 render_text->SetDisplayRect(display_rect); 2179 render_text_->SetDisplayRect(display_rect);
2182 2180
2183 struct { 2181 struct {
2184 HorizontalAlignment alignment; 2182 HorizontalAlignment alignment;
2185 int offset; 2183 int offset;
2186 } small_content_cases[] = { 2184 } small_content_cases[] = {
2187 { ALIGN_LEFT, -kEnlargement }, 2185 { ALIGN_LEFT, -kEnlargement },
2188 { ALIGN_LEFT, 0 }, 2186 { ALIGN_LEFT, 0 },
2189 { ALIGN_LEFT, kEnlargement }, 2187 { ALIGN_LEFT, kEnlargement },
2190 { ALIGN_RIGHT, -kEnlargement }, 2188 { ALIGN_RIGHT, -kEnlargement },
2191 { ALIGN_RIGHT, 0 }, 2189 { ALIGN_RIGHT, 0 },
2192 { ALIGN_RIGHT, kEnlargement }, 2190 { ALIGN_RIGHT, kEnlargement },
2193 { ALIGN_CENTER, -kEnlargement }, 2191 { ALIGN_CENTER, -kEnlargement },
2194 { ALIGN_CENTER, 0 }, 2192 { ALIGN_CENTER, 0 },
2195 { ALIGN_CENTER, kEnlargement }, 2193 { ALIGN_CENTER, kEnlargement },
2196 }; 2194 };
2197 2195
2198 for (size_t i = 0; i < arraysize(small_content_cases); i++) { 2196 for (size_t i = 0; i < arraysize(small_content_cases); i++) {
2199 render_text->SetHorizontalAlignment(small_content_cases[i].alignment); 2197 render_text_->SetHorizontalAlignment(small_content_cases[i].alignment);
2200 render_text->SetDisplayOffset(small_content_cases[i].offset); 2198 render_text_->SetDisplayOffset(small_content_cases[i].offset);
2201 EXPECT_EQ(0, render_text->GetUpdatedDisplayOffset().x()); 2199 EXPECT_EQ(0, render_text_->GetUpdatedDisplayOffset().x());
2202 } 2200 }
2203 2201
2204 // Set display width |kEnlargement| pixels less than content width and test 2202 // Set display width |kEnlargement| pixels less than content width and test
2205 // different possible situations. 2203 // different possible situations.
2206 display_rect = Rect(font_size); 2204 display_rect = Rect(font_size);
2207 display_rect.Inset(0, 0, kEnlargement, 0); 2205 display_rect.Inset(0, 0, kEnlargement, 0);
2208 render_text->SetDisplayRect(display_rect); 2206 render_text_->SetDisplayRect(display_rect);
2209 2207
2210 struct { 2208 struct {
2211 HorizontalAlignment alignment; 2209 HorizontalAlignment alignment;
2212 int offset; 2210 int offset;
2213 int expected_offset; 2211 int expected_offset;
2214 } large_content_cases[] = { 2212 } large_content_cases[] = {
2215 // When text is left-aligned, display offset can be in range 2213 // When text is left-aligned, display offset can be in range
2216 // [-kEnlargement, 0]. 2214 // [-kEnlargement, 0].
2217 { ALIGN_LEFT, -2 * kEnlargement, -kEnlargement }, 2215 { ALIGN_LEFT, -2 * kEnlargement, -kEnlargement },
2218 { ALIGN_LEFT, -kEnlargement / 2, -kEnlargement / 2 }, 2216 { ALIGN_LEFT, -kEnlargement / 2, -kEnlargement / 2 },
2219 { ALIGN_LEFT, kEnlargement, 0 }, 2217 { ALIGN_LEFT, kEnlargement, 0 },
2220 // When text is right-aligned, display offset can be in range 2218 // When text is right-aligned, display offset can be in range
2221 // [0, kEnlargement]. 2219 // [0, kEnlargement].
2222 { ALIGN_RIGHT, -kEnlargement, 0 }, 2220 { ALIGN_RIGHT, -kEnlargement, 0 },
2223 { ALIGN_RIGHT, kEnlargement / 2, kEnlargement / 2 }, 2221 { ALIGN_RIGHT, kEnlargement / 2, kEnlargement / 2 },
2224 { ALIGN_RIGHT, 2 * kEnlargement, kEnlargement }, 2222 { ALIGN_RIGHT, 2 * kEnlargement, kEnlargement },
2225 // When text is center-aligned, display offset can be in range 2223 // When text is center-aligned, display offset can be in range
2226 // [-kEnlargement / 2 - 1, (kEnlargement - 1) / 2]. 2224 // [-kEnlargement / 2 - 1, (kEnlargement - 1) / 2].
2227 { ALIGN_CENTER, -kEnlargement, -kEnlargement / 2 - 1 }, 2225 { ALIGN_CENTER, -kEnlargement, -kEnlargement / 2 - 1 },
2228 { ALIGN_CENTER, -kEnlargement / 4, -kEnlargement / 4 }, 2226 { ALIGN_CENTER, -kEnlargement / 4, -kEnlargement / 4 },
2229 { ALIGN_CENTER, kEnlargement / 4, kEnlargement / 4 }, 2227 { ALIGN_CENTER, kEnlargement / 4, kEnlargement / 4 },
2230 { ALIGN_CENTER, kEnlargement, (kEnlargement - 1) / 2 }, 2228 { ALIGN_CENTER, kEnlargement, (kEnlargement - 1) / 2 },
2231 }; 2229 };
2232 2230
2233 for (size_t i = 0; i < arraysize(large_content_cases); i++) { 2231 for (size_t i = 0; i < arraysize(large_content_cases); i++) {
2234 render_text->SetHorizontalAlignment(large_content_cases[i].alignment); 2232 render_text_->SetHorizontalAlignment(large_content_cases[i].alignment);
2235 render_text->SetDisplayOffset(large_content_cases[i].offset); 2233 render_text_->SetDisplayOffset(large_content_cases[i].offset);
2236 EXPECT_EQ(large_content_cases[i].expected_offset, 2234 EXPECT_EQ(large_content_cases[i].expected_offset,
2237 render_text->GetUpdatedDisplayOffset().x()); 2235 render_text_->GetUpdatedDisplayOffset().x());
2238 } 2236 }
2239 } 2237 }
2240 2238
2241 TEST_F(RenderTextTest, SameFontForParentheses) { 2239 TEST_P(RenderTextTestAll, SameFontForParentheses) {
2242 struct { 2240 struct {
2243 const base::char16 left_char; 2241 const base::char16 left_char;
2244 const base::char16 right_char; 2242 const base::char16 right_char;
2245 } punctuation_pairs[] = { 2243 } punctuation_pairs[] = {
2246 { '(', ')' }, 2244 { '(', ')' },
2247 { '{', '}' }, 2245 { '{', '}' },
2248 { '<', '>' }, 2246 { '<', '>' },
2249 }; 2247 };
2250 struct { 2248 struct {
2251 base::string16 text; 2249 base::string16 text;
(...skipping 18 matching lines...) Expand all
2270 { WideToUTF16(L"Hello World(\x0915\x093f)Hello World") }, 2268 { WideToUTF16(L"Hello World(\x0915\x093f)Hello World") },
2271 2269
2272 // Hebrew(English) 2270 // Hebrew(English)
2273 { WideToUTF16(L"\x05e0\x05b8(a)") }, 2271 { WideToUTF16(L"\x05e0\x05b8(a)") },
2274 // Hebrew(English)Hebrew 2272 // Hebrew(English)Hebrew
2275 { WideToUTF16(L"\x05e0\x05b8(a)\x05e0\x05b8") }, 2273 { WideToUTF16(L"\x05e0\x05b8(a)\x05e0\x05b8") },
2276 // English(Hebrew)English 2274 // English(Hebrew)English
2277 { WideToUTF16(L"Hello World(\x05e0\x05b8)Hello World") }, 2275 { WideToUTF16(L"Hello World(\x05e0\x05b8)Hello World") },
2278 }; 2276 };
2279 2277
2280 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance());
2281 for (size_t i = 0; i < arraysize(cases); ++i) { 2278 for (size_t i = 0; i < arraysize(cases); ++i) {
2282 base::string16 text = cases[i].text; 2279 base::string16 text = cases[i].text;
2283 const size_t start_paren_char_index = text.find('('); 2280 const size_t start_paren_char_index = text.find('(');
2284 ASSERT_NE(base::string16::npos, start_paren_char_index); 2281 ASSERT_NE(base::string16::npos, start_paren_char_index);
2285 const size_t end_paren_char_index = text.find(')'); 2282 const size_t end_paren_char_index = text.find(')');
2286 ASSERT_NE(base::string16::npos, end_paren_char_index); 2283 ASSERT_NE(base::string16::npos, end_paren_char_index);
2287 2284
2288 for (size_t j = 0; j < arraysize(punctuation_pairs); ++j) { 2285 for (size_t j = 0; j < arraysize(punctuation_pairs); ++j) {
2289 text[start_paren_char_index] = punctuation_pairs[j].left_char; 2286 text[start_paren_char_index] = punctuation_pairs[j].left_char;
2290 text[end_paren_char_index] = punctuation_pairs[j].right_char; 2287 text[end_paren_char_index] = punctuation_pairs[j].right_char;
2291 render_text->SetText(text); 2288 render_text_->SetText(text);
2292 2289
2293 const std::vector<RenderText::FontSpan> spans = 2290 const std::vector<RenderText::FontSpan> spans =
2294 render_text->GetFontSpansForTesting(); 2291 render_text_->GetFontSpansForTesting();
2295 2292
2296 int start_paren_span_index = -1; 2293 int start_paren_span_index = -1;
2297 int end_paren_span_index = -1; 2294 int end_paren_span_index = -1;
2298 for (size_t k = 0; k < spans.size(); ++k) { 2295 for (size_t k = 0; k < spans.size(); ++k) {
2299 if (IndexInRange(spans[k].second, start_paren_char_index)) 2296 if (IndexInRange(spans[k].second, start_paren_char_index))
2300 start_paren_span_index = k; 2297 start_paren_span_index = k;
2301 if (IndexInRange(spans[k].second, end_paren_char_index)) 2298 if (IndexInRange(spans[k].second, end_paren_char_index))
2302 end_paren_span_index = k; 2299 end_paren_span_index = k;
2303 } 2300 }
2304 ASSERT_NE(-1, start_paren_span_index); 2301 ASSERT_NE(-1, start_paren_span_index);
2305 ASSERT_NE(-1, end_paren_span_index); 2302 ASSERT_NE(-1, end_paren_span_index);
2306 2303
2307 const Font& start_font = spans[start_paren_span_index].first; 2304 const Font& start_font = spans[start_paren_span_index].first;
2308 const Font& end_font = spans[end_paren_span_index].first; 2305 const Font& end_font = spans[end_paren_span_index].first;
2309 EXPECT_EQ(start_font.GetFontName(), end_font.GetFontName()); 2306 EXPECT_EQ(start_font.GetFontName(), end_font.GetFontName());
2310 EXPECT_EQ(start_font.GetFontSize(), end_font.GetFontSize()); 2307 EXPECT_EQ(start_font.GetFontSize(), end_font.GetFontSize());
2311 EXPECT_EQ(start_font.GetStyle(), end_font.GetStyle()); 2308 EXPECT_EQ(start_font.GetStyle(), end_font.GetStyle());
2312 } 2309 }
2313 } 2310 }
2314 } 2311 }
2315 2312
2316 // Make sure the caret width is always >=1 so that the correct 2313 // Make sure the caret width is always >=1 so that the correct
2317 // caret is drawn at high DPI. crbug.com/164100. 2314 // caret is drawn at high DPI. crbug.com/164100.
2318 TEST_F(RenderTextTest, CaretWidth) { 2315 TEST_P(RenderTextTestAll, CaretWidth) {
2319 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 2316 render_text_->SetText(ASCIIToUTF16("abcdefg"));
2320 render_text->SetText(ASCIIToUTF16("abcdefg")); 2317 EXPECT_GE(render_text_->GetUpdatedCursorBounds().width(), 1);
2321 EXPECT_GE(render_text->GetUpdatedCursorBounds().width(), 1);
2322 } 2318 }
2323 2319
2324 TEST_F(RenderTextTest, SelectWord) { 2320 TEST_P(RenderTextTestAll, SelectWord) {
2325 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 2321 render_text_->SetText(ASCIIToUTF16(" foo a.bc.d bar"));
2326 render_text->SetText(ASCIIToUTF16(" foo a.bc.d bar"));
2327 2322
2328 struct { 2323 struct {
2329 size_t cursor; 2324 size_t cursor;
2330 size_t selection_start; 2325 size_t selection_start;
2331 size_t selection_end; 2326 size_t selection_end;
2332 } cases[] = { 2327 } cases[] = {
2333 { 0, 0, 1 }, 2328 { 0, 0, 1 },
2334 { 1, 1, 4 }, 2329 { 1, 1, 4 },
2335 { 2, 1, 4 }, 2330 { 2, 1, 4 },
2336 { 3, 1, 4 }, 2331 { 3, 1, 4 },
2337 { 4, 4, 6 }, 2332 { 4, 4, 6 },
2338 { 5, 4, 6 }, 2333 { 5, 4, 6 },
2339 { 6, 6, 7 }, 2334 { 6, 6, 7 },
2340 { 7, 7, 8 }, 2335 { 7, 7, 8 },
2341 { 8, 8, 10 }, 2336 { 8, 8, 10 },
2342 { 9, 8, 10 }, 2337 { 9, 8, 10 },
2343 { 10, 10, 11 }, 2338 { 10, 10, 11 },
2344 { 11, 11, 12 }, 2339 { 11, 11, 12 },
2345 { 12, 12, 13 }, 2340 { 12, 12, 13 },
2346 { 13, 13, 16 }, 2341 { 13, 13, 16 },
2347 { 14, 13, 16 }, 2342 { 14, 13, 16 },
2348 { 15, 13, 16 }, 2343 { 15, 13, 16 },
2349 { 16, 13, 16 }, 2344 { 16, 13, 16 },
2350 }; 2345 };
2351 2346
2352 for (size_t i = 0; i < arraysize(cases); ++i) { 2347 for (size_t i = 0; i < arraysize(cases); ++i) {
2353 render_text->SetCursorPosition(cases[i].cursor); 2348 render_text_->SetCursorPosition(cases[i].cursor);
2354 render_text->SelectWord(); 2349 render_text_->SelectWord();
2355 EXPECT_EQ(Range(cases[i].selection_start, cases[i].selection_end), 2350 EXPECT_EQ(Range(cases[i].selection_start, cases[i].selection_end),
2356 render_text->selection()); 2351 render_text_->selection());
2357 } 2352 }
2358 } 2353 }
2359 2354
2360 // Make sure the last word is selected when the cursor is at text.length(). 2355 // Make sure the last word is selected when the cursor is at text.length().
2361 TEST_F(RenderTextTest, LastWordSelected) { 2356 TEST_P(RenderTextTestAll, LastWordSelected) {
2362 const std::string kTestURL1 = "http://www.google.com"; 2357 const std::string kTestURL1 = "http://www.google.com";
2363 const std::string kTestURL2 = "http://www.google.com/something/"; 2358 const std::string kTestURL2 = "http://www.google.com/something/";
2364 2359
2365 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 2360 render_text_->SetText(ASCIIToUTF16(kTestURL1));
2361 render_text_->SetCursorPosition(kTestURL1.length());
2362 render_text_->SelectWord();
2363 EXPECT_EQ(ASCIIToUTF16("com"), GetSelectedText(render_text_.get()));
2364 EXPECT_FALSE(render_text_->selection().is_reversed());
2366 2365
2367 render_text->SetText(ASCIIToUTF16(kTestURL1)); 2366 render_text_->SetText(ASCIIToUTF16(kTestURL2));
2368 render_text->SetCursorPosition(kTestURL1.length()); 2367 render_text_->SetCursorPosition(kTestURL2.length());
2369 render_text->SelectWord(); 2368 render_text_->SelectWord();
2370 EXPECT_EQ(ASCIIToUTF16("com"), GetSelectedText(render_text.get())); 2369 EXPECT_EQ(ASCIIToUTF16("/"), GetSelectedText(render_text_.get()));
2371 EXPECT_FALSE(render_text->selection().is_reversed()); 2370 EXPECT_FALSE(render_text_->selection().is_reversed());
2372
2373 render_text->SetText(ASCIIToUTF16(kTestURL2));
2374 render_text->SetCursorPosition(kTestURL2.length());
2375 render_text->SelectWord();
2376 EXPECT_EQ(ASCIIToUTF16("/"), GetSelectedText(render_text.get()));
2377 EXPECT_FALSE(render_text->selection().is_reversed());
2378 } 2371 }
2379 2372
2380 // When given a non-empty selection, SelectWord should expand the selection to 2373 // When given a non-empty selection, SelectWord should expand the selection to
2381 // nearest word boundaries. 2374 // nearest word boundaries.
2382 TEST_F(RenderTextTest, SelectMultipleWords) { 2375 TEST_P(RenderTextTestAll, SelectMultipleWords) {
2383 const std::string kTestURL = "http://www.google.com"; 2376 const std::string kTestURL = "http://www.google.com";
2384 2377
2385 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 2378 render_text_->SetText(ASCIIToUTF16(kTestURL));
2386 2379 render_text_->SelectRange(Range(16, 20));
2387 render_text->SetText(ASCIIToUTF16(kTestURL)); 2380 render_text_->SelectWord();
2388 render_text->SelectRange(Range(16, 20)); 2381 EXPECT_EQ(ASCIIToUTF16("google.com"), GetSelectedText(render_text_.get()));
2389 render_text->SelectWord(); 2382 EXPECT_FALSE(render_text_->selection().is_reversed());
2390 EXPECT_EQ(ASCIIToUTF16("google.com"), GetSelectedText(render_text.get()));
2391 EXPECT_FALSE(render_text->selection().is_reversed());
2392 2383
2393 // SelectWord should preserve the selection direction. 2384 // SelectWord should preserve the selection direction.
2394 render_text->SelectRange(Range(20, 16)); 2385 render_text_->SelectRange(Range(20, 16));
2395 render_text->SelectWord(); 2386 render_text_->SelectWord();
2396 EXPECT_EQ(ASCIIToUTF16("google.com"), GetSelectedText(render_text.get())); 2387 EXPECT_EQ(ASCIIToUTF16("google.com"), GetSelectedText(render_text_.get()));
2397 EXPECT_TRUE(render_text->selection().is_reversed()); 2388 EXPECT_TRUE(render_text_->selection().is_reversed());
2398 } 2389 }
2399 2390
2400 // TODO(asvitkine): RenderTextMac cursor movements. http://crbug.com/131618 2391 // TODO(asvitkine): RenderTextMac cursor movements. http://crbug.com/131618
2401 #if !defined(OS_MACOSX) 2392 TEST_P(RenderTextHarfBuzzTest, DisplayRectShowsCursorLTR) {
2402 TEST_F(RenderTextTest, DisplayRectShowsCursorLTR) {
2403 ASSERT_FALSE(base::i18n::IsRTL()); 2393 ASSERT_FALSE(base::i18n::IsRTL());
2404 ASSERT_FALSE(base::i18n::ICUIsRTL()); 2394 ASSERT_FALSE(base::i18n::ICUIsRTL());
2405 2395
2406 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 2396 render_text_->SetText(WideToUTF16(L"abcdefghijklmnopqrstuvwxzyabcdefg"));
2407 render_text->SetText(WideToUTF16(L"abcdefghijklmnopqrstuvwxzyabcdefg")); 2397 render_text_->MoveCursorTo(
2408 render_text->MoveCursorTo(SelectionModel(render_text->text().length(), 2398 SelectionModel(render_text_->text().length(), CURSOR_FORWARD));
2409 CURSOR_FORWARD)); 2399 int width = render_text_->GetStringSize().width();
2410 int width = render_text->GetStringSize().width();
2411 ASSERT_GT(width, 10); 2400 ASSERT_GT(width, 10);
2412 2401
2413 // Ensure that the cursor is placed at the width of its preceding text. 2402 // Ensure that the cursor is placed at the width of its preceding text.
2414 render_text->SetDisplayRect(Rect(width + 10, 1)); 2403 render_text_->SetDisplayRect(Rect(width + 10, 1));
2415 EXPECT_EQ(width, render_text->GetUpdatedCursorBounds().x()); 2404 EXPECT_EQ(width, render_text_->GetUpdatedCursorBounds().x());
2416 2405
2417 // Ensure that shrinking the display rectangle keeps the cursor in view. 2406 // Ensure that shrinking the display rectangle keeps the cursor in view.
2418 render_text->SetDisplayRect(Rect(width - 10, 1)); 2407 render_text_->SetDisplayRect(Rect(width - 10, 1));
2419 EXPECT_EQ(render_text->display_rect().width(), 2408 EXPECT_EQ(render_text_->display_rect().width(),
2420 render_text->GetUpdatedCursorBounds().right()); 2409 render_text_->GetUpdatedCursorBounds().right());
2421 2410
2422 // Ensure that the text will pan to fill its expanding display rectangle. 2411 // Ensure that the text will pan to fill its expanding display rectangle.
2423 render_text->SetDisplayRect(Rect(width - 5, 1)); 2412 render_text_->SetDisplayRect(Rect(width - 5, 1));
2424 EXPECT_EQ(render_text->display_rect().width(), 2413 EXPECT_EQ(render_text_->display_rect().width(),
2425 render_text->GetUpdatedCursorBounds().right()); 2414 render_text_->GetUpdatedCursorBounds().right());
2426 2415
2427 // Ensure that a sufficiently large display rectangle shows all the text. 2416 // Ensure that a sufficiently large display rectangle shows all the text.
2428 render_text->SetDisplayRect(Rect(width + 10, 1)); 2417 render_text_->SetDisplayRect(Rect(width + 10, 1));
2429 EXPECT_EQ(width, render_text->GetUpdatedCursorBounds().x()); 2418 EXPECT_EQ(width, render_text_->GetUpdatedCursorBounds().x());
2430 2419
2431 // Repeat the test with RTL text. 2420 // Repeat the test with RTL text.
2432 render_text->SetText(WideToUTF16(L"\x5d0\x5d1\x5d2\x5d3\x5d4\x5d5\x5d6\x5d7" 2421 render_text_->SetText(
2433 L"\x5d8\x5d9\x5da\x5db\x5dc\x5dd\x5de\x5df")); 2422 WideToUTF16(L"\x5d0\x5d1\x5d2\x5d3\x5d4\x5d5\x5d6\x5d7"
2434 render_text->MoveCursorTo(SelectionModel(0, CURSOR_FORWARD)); 2423 L"\x5d8\x5d9\x5da\x5db\x5dc\x5dd\x5de\x5df"));
2435 width = render_text->GetStringSize().width(); 2424 render_text_->MoveCursorTo(SelectionModel(0, CURSOR_FORWARD));
2425 width = render_text_->GetStringSize().width();
2436 ASSERT_GT(width, 10); 2426 ASSERT_GT(width, 10);
2437 2427
2438 // Ensure that the cursor is placed at the width of its preceding text. 2428 // Ensure that the cursor is placed at the width of its preceding text.
2439 render_text->SetDisplayRect(Rect(width + 10, 1)); 2429 render_text_->SetDisplayRect(Rect(width + 10, 1));
2440 EXPECT_EQ(width, render_text->GetUpdatedCursorBounds().x()); 2430 EXPECT_EQ(width, render_text_->GetUpdatedCursorBounds().x());
2441 2431
2442 // Ensure that shrinking the display rectangle keeps the cursor in view. 2432 // Ensure that shrinking the display rectangle keeps the cursor in view.
2443 render_text->SetDisplayRect(Rect(width - 10, 1)); 2433 render_text_->SetDisplayRect(Rect(width - 10, 1));
2444 EXPECT_EQ(render_text->display_rect().width(), 2434 EXPECT_EQ(render_text_->display_rect().width(),
2445 render_text->GetUpdatedCursorBounds().right()); 2435 render_text_->GetUpdatedCursorBounds().right());
2446 2436
2447 // Ensure that the text will pan to fill its expanding display rectangle. 2437 // Ensure that the text will pan to fill its expanding display rectangle.
2448 render_text->SetDisplayRect(Rect(width - 5, 1)); 2438 render_text_->SetDisplayRect(Rect(width - 5, 1));
2449 EXPECT_EQ(render_text->display_rect().width(), 2439 EXPECT_EQ(render_text_->display_rect().width(),
2450 render_text->GetUpdatedCursorBounds().right()); 2440 render_text_->GetUpdatedCursorBounds().right());
2451 2441
2452 // Ensure that a sufficiently large display rectangle shows all the text. 2442 // Ensure that a sufficiently large display rectangle shows all the text.
2453 render_text->SetDisplayRect(Rect(width + 10, 1)); 2443 render_text_->SetDisplayRect(Rect(width + 10, 1));
2454 EXPECT_EQ(width, render_text->GetUpdatedCursorBounds().x()); 2444 EXPECT_EQ(width, render_text_->GetUpdatedCursorBounds().x());
2455 } 2445 }
2456 #endif // !defined(OS_MACOSX)
2457 2446
2458 TEST_F(RenderTextTest, DisplayRectShowsCursorRTL) { 2447 TEST_P(RenderTextTestAll, DisplayRectShowsCursorRTL) {
2459 // Set the application default text direction to RTL. 2448 // Set the application default text direction to RTL.
2460 const bool was_rtl = base::i18n::IsRTL(); 2449 const bool was_rtl = base::i18n::IsRTL();
2461 SetRTL(true); 2450 SetRTL(true);
2462 2451
2463 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 2452 // Reset the render text instance since the locale was changed.
2464 render_text->SetText(WideToUTF16(L"abcdefghijklmnopqrstuvwxzyabcdefg")); 2453 render_text_ = CreateRenderTextInstance();
2465 render_text->MoveCursorTo(SelectionModel(0, CURSOR_FORWARD)); 2454 render_text_->SetText(WideToUTF16(L"abcdefghijklmnopqrstuvwxzyabcdefg"));
2466 int width = render_text->GetStringSize().width(); 2455 render_text_->MoveCursorTo(SelectionModel(0, CURSOR_FORWARD));
2456 int width = render_text_->GetStringSize().width();
2467 ASSERT_GT(width, 10); 2457 ASSERT_GT(width, 10);
2468 2458
2469 // Ensure that the cursor is placed at the width of its preceding text. 2459 // Ensure that the cursor is placed at the width of its preceding text.
2470 render_text->SetDisplayRect(Rect(width + 10, 1)); 2460 render_text_->SetDisplayRect(Rect(width + 10, 1));
2471 EXPECT_EQ(render_text->display_rect().width() - width - 1, 2461 EXPECT_EQ(render_text_->display_rect().width() - width - 1,
2472 render_text->GetUpdatedCursorBounds().x()); 2462 render_text_->GetUpdatedCursorBounds().x());
2473 2463
2474 // Ensure that shrinking the display rectangle keeps the cursor in view. 2464 // Ensure that shrinking the display rectangle keeps the cursor in view.
2475 render_text->SetDisplayRect(Rect(width - 10, 1)); 2465 render_text_->SetDisplayRect(Rect(width - 10, 1));
2476 EXPECT_EQ(0, render_text->GetUpdatedCursorBounds().x()); 2466 EXPECT_EQ(0, render_text_->GetUpdatedCursorBounds().x());
2477 2467
2478 // Ensure that the text will pan to fill its expanding display rectangle. 2468 // Ensure that the text will pan to fill its expanding display rectangle.
2479 render_text->SetDisplayRect(Rect(width - 5, 1)); 2469 render_text_->SetDisplayRect(Rect(width - 5, 1));
2480 EXPECT_EQ(0, render_text->GetUpdatedCursorBounds().x()); 2470 EXPECT_EQ(0, render_text_->GetUpdatedCursorBounds().x());
2481 2471
2482 // Ensure that a sufficiently large display rectangle shows all the text. 2472 // Ensure that a sufficiently large display rectangle shows all the text.
2483 render_text->SetDisplayRect(Rect(width + 10, 1)); 2473 render_text_->SetDisplayRect(Rect(width + 10, 1));
2484 EXPECT_EQ(render_text->display_rect().width() - width - 1, 2474 EXPECT_EQ(render_text_->display_rect().width() - width - 1,
2485 render_text->GetUpdatedCursorBounds().x()); 2475 render_text_->GetUpdatedCursorBounds().x());
2486 2476
2487 // Repeat the test with RTL text. 2477 // Repeat the test with RTL text.
2488 render_text->SetText(WideToUTF16(L"\x5d0\x5d1\x5d2\x5d3\x5d4\x5d5\x5d6\x5d7" 2478 render_text_->SetText(
2489 L"\x5d8\x5d9\x5da\x5db\x5dc\x5dd\x5de\x5df")); 2479 WideToUTF16(L"\x5d0\x5d1\x5d2\x5d3\x5d4\x5d5\x5d6\x5d7"
2490 render_text->MoveCursorTo(SelectionModel(render_text->text().length(), 2480 L"\x5d8\x5d9\x5da\x5db\x5dc\x5dd\x5de\x5df"));
2491 CURSOR_FORWARD)); 2481 render_text_->MoveCursorTo(
2492 width = render_text->GetStringSize().width(); 2482 SelectionModel(render_text_->text().length(), CURSOR_FORWARD));
2483 width = render_text_->GetStringSize().width();
2493 ASSERT_GT(width, 10); 2484 ASSERT_GT(width, 10);
2494 2485
2495 // Ensure that the cursor is placed at the width of its preceding text. 2486 // Ensure that the cursor is placed at the width of its preceding text.
2496 render_text->SetDisplayRect(Rect(width + 10, 1)); 2487 render_text_->SetDisplayRect(Rect(width + 10, 1));
2497 EXPECT_EQ(render_text->display_rect().width() - width - 1, 2488 EXPECT_EQ(render_text_->display_rect().width() - width - 1,
2498 render_text->GetUpdatedCursorBounds().x()); 2489 render_text_->GetUpdatedCursorBounds().x());
2499 2490
2500 // Ensure that shrinking the display rectangle keeps the cursor in view. 2491 // Ensure that shrinking the display rectangle keeps the cursor in view.
2501 render_text->SetDisplayRect(Rect(width - 10, 1)); 2492 render_text_->SetDisplayRect(Rect(width - 10, 1));
2502 EXPECT_EQ(0, render_text->GetUpdatedCursorBounds().x()); 2493 EXPECT_EQ(0, render_text_->GetUpdatedCursorBounds().x());
2503 2494
2504 // Ensure that the text will pan to fill its expanding display rectangle. 2495 // Ensure that the text will pan to fill its expanding display rectangle.
2505 render_text->SetDisplayRect(Rect(width - 5, 1)); 2496 render_text_->SetDisplayRect(Rect(width - 5, 1));
2506 EXPECT_EQ(0, render_text->GetUpdatedCursorBounds().x()); 2497 EXPECT_EQ(0, render_text_->GetUpdatedCursorBounds().x());
2507 2498
2508 // Ensure that a sufficiently large display rectangle shows all the text. 2499 // Ensure that a sufficiently large display rectangle shows all the text.
2509 render_text->SetDisplayRect(Rect(width + 10, 1)); 2500 render_text_->SetDisplayRect(Rect(width + 10, 1));
2510 EXPECT_EQ(render_text->display_rect().width() - width - 1, 2501 EXPECT_EQ(render_text_->display_rect().width() - width - 1,
2511 render_text->GetUpdatedCursorBounds().x()); 2502 render_text_->GetUpdatedCursorBounds().x());
2512 2503
2513 // Reset the application default text direction to LTR. 2504 // Reset the application default text direction to LTR.
2514 SetRTL(was_rtl); 2505 SetRTL(was_rtl);
2515 EXPECT_EQ(was_rtl, base::i18n::IsRTL()); 2506 EXPECT_EQ(was_rtl, base::i18n::IsRTL());
2516 } 2507 }
2517 2508
2518 // Changing colors between or inside ligated glyphs should not break shaping. 2509 // Changing colors between or inside ligated glyphs should not break shaping.
2519 TEST_F(RenderTextTest, SelectionKeepsLigatures) { 2510 TEST_P(RenderTextTestAll, SelectionKeepsLigatures) {
2520 const wchar_t* kTestStrings[] = { L"\x644\x623", L"\x633\x627" }; 2511 const wchar_t* kTestStrings[] = { L"\x644\x623", L"\x633\x627" };
2521 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 2512 render_text_->set_selection_color(SK_ColorRED);
2522 render_text->set_selection_color(SK_ColorRED);
2523 Canvas canvas;
2524 2513
2525 for (size_t i = 0; i < arraysize(kTestStrings); ++i) { 2514 for (size_t i = 0; i < arraysize(kTestStrings); ++i) {
2526 render_text->SetText(WideToUTF16(kTestStrings[i])); 2515 render_text_->SetText(WideToUTF16(kTestStrings[i]));
2527 const int expected_width = render_text->GetStringSize().width(); 2516 const int expected_width = render_text_->GetStringSize().width();
2528 render_text->MoveCursorTo(SelectionModel(Range(0, 1), CURSOR_FORWARD)); 2517 render_text_->MoveCursorTo(SelectionModel(Range(0, 1), CURSOR_FORWARD));
2529 EXPECT_EQ(expected_width, render_text->GetStringSize().width()); 2518 EXPECT_EQ(expected_width, render_text_->GetStringSize().width());
2530 // Drawing the text should not DCHECK or crash; see http://crbug.com/262119 2519 // Drawing the text should not DCHECK or crash; see http://crbug.com/262119
2531 render_text->Draw(&canvas); 2520 render_text_->Draw(&canvas_);
2532 render_text->MoveCursorTo(SelectionModel(0, CURSOR_FORWARD)); 2521 render_text_->MoveCursorTo(SelectionModel(0, CURSOR_FORWARD));
2533 } 2522 }
2534 } 2523 }
2535 2524
2536 // Ensure strings wrap onto multiple lines for a small available width. 2525 // Ensure strings wrap onto multiple lines for a small available width.
2537 TEST_F(RenderTextTest, Multiline_MinWidth) { 2526 TEST_P(RenderTextHarfBuzzTest, Multiline_MinWidth) {
2538 const wchar_t* kTestStrings[] = { kWeak, kLtr, kLtrRtl, kLtrRtlLtr, kRtl, 2527 const wchar_t* kTestStrings[] = { kWeak, kLtr, kLtrRtl, kLtrRtlLtr, kRtl,
2539 kRtlLtr, kRtlLtrRtl }; 2528 kRtlLtr, kRtlLtrRtl };
2540 2529
2541 RenderTextHarfBuzz render_text; 2530 render_text_->SetDisplayRect(Rect(1, 1000));
2542 render_text.SetDisplayRect(Rect(1, 1000)); 2531 render_text_->SetMultiline(true);
2543 render_text.SetMultiline(true); 2532 render_text_->SetWordWrapBehavior(WRAP_LONG_WORDS);
2544 render_text.SetWordWrapBehavior(WRAP_LONG_WORDS);
2545 Canvas canvas;
2546 2533
2547 for (size_t i = 0; i < arraysize(kTestStrings); ++i) { 2534 for (size_t i = 0; i < arraysize(kTestStrings); ++i) {
2548 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i)); 2535 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i));
2549 render_text.SetText(WideToUTF16(kTestStrings[i])); 2536 render_text_->SetText(WideToUTF16(kTestStrings[i]));
2550 render_text.Draw(&canvas); 2537 render_text_->Draw(&canvas_);
2551 EXPECT_GT(render_text.lines_.size(), 1U); 2538 EXPECT_GT(render_text_->lines_.size(), 1U);
2552 } 2539 }
2553 } 2540 }
2554 2541
2555 // Ensure strings wrap onto multiple lines for a normal available width. 2542 // Ensure strings wrap onto multiple lines for a normal available width.
2556 TEST_F(RenderTextTest, Multiline_NormalWidth) { 2543 TEST_P(RenderTextHarfBuzzTest, Multiline_NormalWidth) {
2557 const struct { 2544 const struct {
2558 const wchar_t* const text; 2545 const wchar_t* const text;
2559 const Range first_line_char_range; 2546 const Range first_line_char_range;
2560 const Range second_line_char_range; 2547 const Range second_line_char_range;
2561 bool is_ltr; 2548 bool is_ltr;
2562 } kTestStrings[] = { 2549 } kTestStrings[] = {
2563 { L"abc defg hijkl", Range(0, 9), Range(9, 14), true }, 2550 { L"abc defg hijkl", Range(0, 9), Range(9, 14), true },
2564 { L"qwertyzxcvbn", Range(0, 10), Range(10, 12), true }, 2551 { L"qwertyzxcvbn", Range(0, 10), Range(10, 12), true },
2565 { L"\x0627\x0644\x0644\x063A\x0629 " 2552 { L"\x0627\x0644\x0644\x063A\x0629 "
2566 L"\x0627\x0644\x0639\x0631\x0628\x064A\x0629", 2553 L"\x0627\x0644\x0639\x0631\x0628\x064A\x0629",
2567 Range(0, 6), Range(6, 13), false }, 2554 Range(0, 6), Range(6, 13), false },
2568 { L"\x062A\x0641\x0627\x062D \x05EA\x05E4\x05D5\x05D6\x05D9" 2555 { L"\x062A\x0641\x0627\x062D \x05EA\x05E4\x05D5\x05D6\x05D9"
2569 L"\x05DA\x05DB\x05DD", Range(0, 5), Range(5, 13), false } 2556 L"\x05DA\x05DB\x05DD", Range(0, 5), Range(5, 13), false }
2570 }; 2557 };
2571 2558
2572 RenderTextHarfBuzz render_text; 2559 RenderTextHarfBuzz* render_text =
2560 static_cast<RenderTextHarfBuzz*>(render_text_.get());
2573 // Specify the fixed width for characters to suppress the possible variations 2561 // Specify the fixed width for characters to suppress the possible variations
2574 // of linebreak results. 2562 // of linebreak results.
2575 render_text.set_glyph_width_for_test(5); 2563 render_text->set_glyph_width_for_test(5);
2576 render_text.SetDisplayRect(Rect(50, 1000)); 2564 render_text->SetDisplayRect(Rect(50, 1000));
2577 render_text.SetMultiline(true); 2565 render_text->SetMultiline(true);
2578 render_text.SetWordWrapBehavior(WRAP_LONG_WORDS); 2566 render_text->SetWordWrapBehavior(WRAP_LONG_WORDS);
2579 render_text.SetHorizontalAlignment(ALIGN_TO_HEAD); 2567 render_text->SetHorizontalAlignment(ALIGN_TO_HEAD);
2580
2581 Canvas canvas;
2582 TestSkiaTextRenderer renderer(&canvas);
2583 2568
2584 for (size_t i = 0; i < arraysize(kTestStrings); ++i) { 2569 for (size_t i = 0; i < arraysize(kTestStrings); ++i) {
2585 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i)); 2570 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i));
2586 render_text.SetText(WideToUTF16(kTestStrings[i].text)); 2571 render_text->SetText(WideToUTF16(kTestStrings[i].text));
2587 render_text.EnsureLayout(); 2572 DrawVisualText();
2588 render_text.DrawVisualText(&renderer);
2589 2573
2590 ASSERT_EQ(2U, render_text.lines_.size()); 2574 ASSERT_EQ(2U, render_text->lines_.size());
2591 ASSERT_EQ(1U, render_text.lines_[0].segments.size()); 2575 ASSERT_EQ(1U, render_text->lines_[0].segments.size());
2592 EXPECT_EQ(kTestStrings[i].first_line_char_range, 2576 EXPECT_EQ(kTestStrings[i].first_line_char_range,
2593 render_text.lines_[0].segments[0].char_range); 2577 render_text->lines_[0].segments[0].char_range);
2594 ASSERT_EQ(1U, render_text.lines_[1].segments.size()); 2578 ASSERT_EQ(1U, render_text->lines_[1].segments.size());
2595 EXPECT_EQ(kTestStrings[i].second_line_char_range, 2579 EXPECT_EQ(kTestStrings[i].second_line_char_range,
2596 render_text.lines_[1].segments[0].char_range); 2580 render_text->lines_[1].segments[0].char_range);
2597 2581
2598 std::vector<TestSkiaTextRenderer::TextLog> text_log; 2582 std::vector<TestSkiaTextRenderer::TextLog> text_log;
2599 renderer.GetTextLogAndReset(&text_log); 2583 renderer_.GetTextLogAndReset(&text_log);
2600 ASSERT_EQ(2U, text_log.size()); 2584 ASSERT_EQ(2U, text_log.size());
2601 // NOTE: this expectation compares the character length and glyph counts, 2585 // NOTE: this expectation compares the character length and glyph counts,
2602 // which isn't always equal. This is okay only because all the test 2586 // which isn't always equal. This is okay only because all the test
2603 // strings are simple (like, no compound characters nor UTF16-surrogate 2587 // strings are simple (like, no compound characters nor UTF16-surrogate
2604 // pairs). Be careful in case more complicated test strings are added. 2588 // pairs). Be careful in case more complicated test strings are added.
2605 EXPECT_EQ(kTestStrings[i].first_line_char_range.length(), 2589 EXPECT_EQ(kTestStrings[i].first_line_char_range.length(),
2606 text_log[0].glyph_count); 2590 text_log[0].glyph_count);
2607 EXPECT_EQ(kTestStrings[i].second_line_char_range.length(), 2591 EXPECT_EQ(kTestStrings[i].second_line_char_range.length(),
2608 text_log[1].glyph_count); 2592 text_log[1].glyph_count);
2609 EXPECT_LT(text_log[0].origin.y(), text_log[1].origin.y()); 2593 EXPECT_LT(text_log[0].origin.y(), text_log[1].origin.y());
2610 if (kTestStrings[i].is_ltr) { 2594 if (kTestStrings[i].is_ltr) {
2611 EXPECT_EQ(0, text_log[0].origin.x()); 2595 EXPECT_EQ(0, text_log[0].origin.x());
2612 EXPECT_EQ(0, text_log[1].origin.x()); 2596 EXPECT_EQ(0, text_log[1].origin.x());
2613 } else { 2597 } else {
2614 EXPECT_LT(0, text_log[0].origin.x()); 2598 EXPECT_LT(0, text_log[0].origin.x());
2615 EXPECT_LT(0, text_log[1].origin.x()); 2599 EXPECT_LT(0, text_log[1].origin.x());
2616 } 2600 }
2617 } 2601 }
2618 } 2602 }
2619 2603
2620 // Ensure strings don't wrap onto multiple lines for a sufficient available 2604 // Ensure strings don't wrap onto multiple lines for a sufficient available
2621 // width. 2605 // width.
2622 TEST_F(RenderTextTest, Multiline_SufficientWidth) { 2606 TEST_P(RenderTextHarfBuzzTest, Multiline_SufficientWidth) {
2623 const wchar_t* kTestStrings[] = { L"", L" ", L".", L" . ", L"abc", L"a b c", 2607 const wchar_t* kTestStrings[] = { L"", L" ", L".", L" . ", L"abc", L"a b c",
2624 L"\x62E\x628\x632", L"\x62E \x628 \x632" }; 2608 L"\x62E\x628\x632", L"\x62E \x628 \x632" };
2625 2609
2626 RenderTextHarfBuzz render_text; 2610 render_text_->SetDisplayRect(Rect(1000, 1000));
2627 render_text.SetDisplayRect(Rect(1000, 1000)); 2611 render_text_->SetMultiline(true);
2628 render_text.SetMultiline(true);
2629 Canvas canvas;
2630 2612
2631 for (size_t i = 0; i < arraysize(kTestStrings); ++i) { 2613 for (size_t i = 0; i < arraysize(kTestStrings); ++i) {
2632 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i)); 2614 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i));
2633 render_text.SetText(WideToUTF16(kTestStrings[i])); 2615 render_text_->SetText(WideToUTF16(kTestStrings[i]));
2634 render_text.Draw(&canvas); 2616 render_text_->Draw(&canvas_);
2635 EXPECT_EQ(1U, render_text.lines_.size()); 2617 EXPECT_EQ(1U, render_text_->lines_.size());
2636 } 2618 }
2637 } 2619 }
2638 2620
2639 TEST_F(RenderTextTest, Multiline_Newline) { 2621 TEST_P(RenderTextHarfBuzzTest, Multiline_Newline) {
2640 const struct { 2622 const struct {
2641 const wchar_t* const text; 2623 const wchar_t* const text;
2642 const size_t lines_count; 2624 const size_t lines_count;
2643 // Ranges of the characters on each line preceding the newline. 2625 // Ranges of the characters on each line preceding the newline.
2644 const Range line_char_ranges[3]; 2626 const Range line_char_ranges[3];
2645 } kTestStrings[] = { 2627 } kTestStrings[] = {
2646 {L"abc\ndef", 2ul, { Range(0, 3), Range(4, 7), Range::InvalidRange() } }, 2628 {L"abc\ndef", 2ul, { Range(0, 3), Range(4, 7), Range::InvalidRange() } },
2647 {L"a \n b ", 2ul, { Range(0, 2), Range(3, 6), Range::InvalidRange() } }, 2629 {L"a \n b ", 2ul, { Range(0, 2), Range(3, 6), Range::InvalidRange() } },
2648 {L"ab\n", 2ul, { Range(0, 2), Range(), Range::InvalidRange() } }, 2630 {L"ab\n", 2ul, { Range(0, 2), Range(), Range::InvalidRange() } },
2649 {L"a\n\nb", 3ul, { Range(0, 1), Range(), Range(3, 4) } }, 2631 {L"a\n\nb", 3ul, { Range(0, 1), Range(), Range(3, 4) } },
2650 {L"\nab", 2ul, { Range(), Range(1, 3), Range::InvalidRange() } }, 2632 {L"\nab", 2ul, { Range(), Range(1, 3), Range::InvalidRange() } },
2651 {L"\n", 2ul, { Range(), Range(), Range::InvalidRange() } }, 2633 {L"\n", 2ul, { Range(), Range(), Range::InvalidRange() } },
2652 }; 2634 };
2653 2635
2654 RenderTextHarfBuzz render_text; 2636 render_text_->SetDisplayRect(Rect(200, 1000));
2655 render_text.SetDisplayRect(Rect(200, 1000)); 2637 render_text_->SetMultiline(true);
2656 render_text.SetMultiline(true);
2657 Canvas canvas;
2658 2638
2659 for (size_t i = 0; i < arraysize(kTestStrings); ++i) { 2639 for (size_t i = 0; i < arraysize(kTestStrings); ++i) {
2660 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i)); 2640 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i));
2661 render_text.SetText(WideToUTF16(kTestStrings[i].text)); 2641 render_text_->SetText(WideToUTF16(kTestStrings[i].text));
2662 render_text.Draw(&canvas); 2642 render_text_->Draw(&canvas_);
2663 EXPECT_EQ(kTestStrings[i].lines_count, render_text.lines_.size()); 2643 EXPECT_EQ(kTestStrings[i].lines_count, render_text_->lines_.size());
2664 if (kTestStrings[i].lines_count != render_text.lines_.size()) 2644 if (kTestStrings[i].lines_count != render_text_->lines_.size())
2665 continue; 2645 continue;
2666 2646
2667 for (size_t j = 0; j < kTestStrings[i].lines_count; ++j) { 2647 for (size_t j = 0; j < kTestStrings[i].lines_count; ++j) {
2668 SCOPED_TRACE(base::StringPrintf("Line %" PRIuS "", j)); 2648 SCOPED_TRACE(base::StringPrintf("Line %" PRIuS "", j));
2669 // There might be multiple segments in one line. Merge all the segments 2649 // There might be multiple segments in one line. Merge all the segments
2670 // ranges in the same line. 2650 // ranges in the same line.
2671 const size_t segment_size = render_text.lines()[j].segments.size(); 2651 const size_t segment_size = render_text_->lines()[j].segments.size();
2672 Range line_range; 2652 Range line_range;
2673 if (segment_size > 0) 2653 if (segment_size > 0)
2674 line_range = Range( 2654 line_range =
2675 render_text.lines()[j].segments[0].char_range.start(), 2655 Range(render_text_->lines()[j].segments[0].char_range.start(),
2676 render_text.lines()[j].segments[segment_size - 1].char_range.end()); 2656 render_text_->lines()[j]
2657 .segments[segment_size - 1]
2658 .char_range.end());
2677 EXPECT_EQ(kTestStrings[i].line_char_ranges[j], line_range); 2659 EXPECT_EQ(kTestStrings[i].line_char_ranges[j], line_range);
2678 } 2660 }
2679 } 2661 }
2680 } 2662 }
2681 2663
2682 // Make sure that multiline mode ignores elide behavior. 2664 // Make sure that multiline mode ignores elide behavior.
2683 TEST_F(RenderTextTest, Multiline_IgnoreElide) { 2665 TEST_P(RenderTextHarfBuzzTest, Multiline_IgnoreElide) {
2684 const wchar_t kTestString[] = 2666 const wchar_t kTestString[] =
2685 L"very very very long string xxxxxxxxxxxxxxxxxxxxxxxxxx"; 2667 L"very very very long string xxxxxxxxxxxxxxxxxxxxxxxxxx";
2686 const wchar_t kEllipsis[] = L"\x2026"; 2668 const wchar_t kEllipsis[] = L"\x2026";
2687 2669
2688 RenderTextHarfBuzz render_text; 2670 render_text_->SetElideBehavior(ELIDE_TAIL);
2689 render_text.SetElideBehavior(ELIDE_TAIL); 2671 render_text_->SetDisplayRect(Rect(20, 1000));
2690 render_text.SetDisplayRect(Rect(20, 1000)); 2672 render_text_->SetText(base::WideToUTF16(kTestString));
2691 render_text.SetText(base::WideToUTF16(kTestString));
2692 EXPECT_NE(base::string16::npos, 2673 EXPECT_NE(base::string16::npos,
2693 render_text.GetDisplayText().find(base::WideToUTF16(kEllipsis))); 2674 render_text_->GetDisplayText().find(base::WideToUTF16(kEllipsis)));
2694 2675
2695 render_text.SetMultiline(true); 2676 render_text_->SetMultiline(true);
2696 EXPECT_EQ(base::string16::npos, 2677 EXPECT_EQ(base::string16::npos,
2697 render_text.GetDisplayText().find(base::WideToUTF16(kEllipsis))); 2678 render_text_->GetDisplayText().find(base::WideToUTF16(kEllipsis)));
2698 } 2679 }
2699 2680
2700 TEST_F(RenderTextTest, Multiline_NewlineCharacterReplacement) { 2681 TEST_P(RenderTextHarfBuzzTest, Multiline_NewlineCharacterReplacement) {
2701 const wchar_t* kTestStrings[] = { 2682 const wchar_t* kTestStrings[] = {
2702 L"abc\ndef", L"a \n b ", L"ab\n", L"a\n\nb", L"\nab", L"\n", 2683 L"abc\ndef", L"a \n b ", L"ab\n", L"a\n\nb", L"\nab", L"\n",
2703 }; 2684 };
2704 2685
2705 for (size_t i = 0; i < arraysize(kTestStrings); ++i) { 2686 for (size_t i = 0; i < arraysize(kTestStrings); ++i) {
2706 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i)); 2687 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i));
2707 RenderTextHarfBuzz render_text; 2688 render_text_ = CreateRenderTextInstance();
2708 render_text.SetDisplayRect(Rect(200, 1000)); 2689 render_text_->SetDisplayRect(Rect(200, 1000));
2709 render_text.SetText(WideToUTF16(kTestStrings[i])); 2690 render_text_->SetText(WideToUTF16(kTestStrings[i]));
2710 2691
2711 base::string16 display_text = render_text.GetDisplayText(); 2692 base::string16 display_text = render_text_->GetDisplayText();
2712 // If RenderText is not multiline, the newline characters are replaced 2693 // If RenderText is not multiline, the newline characters are replaced
2713 // by symbols, therefore the character should be changed. 2694 // by symbols, therefore the character should be changed.
2714 EXPECT_NE(WideToUTF16(kTestStrings[i]), render_text.GetDisplayText()); 2695 EXPECT_NE(WideToUTF16(kTestStrings[i]), render_text_->GetDisplayText());
2715 2696
2716 // Setting multiline will fix this, the newline characters will be back 2697 // Setting multiline will fix this, the newline characters will be back
2717 // to the original text. 2698 // to the original text.
2718 render_text.SetMultiline(true); 2699 render_text_->SetMultiline(true);
2719 EXPECT_EQ(WideToUTF16(kTestStrings[i]), render_text.GetDisplayText()); 2700 EXPECT_EQ(WideToUTF16(kTestStrings[i]), render_text_->GetDisplayText());
2720 } 2701 }
2721 } 2702 }
2722 2703
2723 // Ensure horizontal alignment works in multiline mode. 2704 // Ensure horizontal alignment works in multiline mode.
2724 TEST_F(RenderTextTest, Multiline_HorizontalAlignment) { 2705 TEST_P(RenderTextHarfBuzzTest, Multiline_HorizontalAlignment) {
2725 const struct { 2706 const struct {
2726 const wchar_t* const text; 2707 const wchar_t* const text;
2727 const HorizontalAlignment alignment; 2708 const HorizontalAlignment alignment;
2728 } kTestStrings[] = { 2709 } kTestStrings[] = {
2729 { L"abcdefghij\nhijkl", ALIGN_LEFT }, 2710 { L"abcdefghij\nhijkl", ALIGN_LEFT },
2730 { L"nhijkl\nabcdefghij", ALIGN_LEFT }, 2711 { L"nhijkl\nabcdefghij", ALIGN_LEFT },
2731 // hebrew, 2nd line shorter 2712 // hebrew, 2nd line shorter
2732 { L"\x5d0\x5d1\x5d2\x5d3\x5d4\x5d5\x5d6\x5d7\n\x5d0\x5d1\x5d2\x5d3", 2713 { L"\x5d0\x5d1\x5d2\x5d3\x5d4\x5d5\x5d6\x5d7\n\x5d0\x5d1\x5d2\x5d3",
2733 ALIGN_RIGHT }, 2714 ALIGN_RIGHT },
2734 // hebrew, 2nd line longer 2715 // hebrew, 2nd line longer
2735 { L"\x5d0\x5d1\x5d2\x5d3\n\x5d0\x5d1\x5d2\x5d3\x5d4\x5d5\x5d6\x5d7", 2716 { L"\x5d0\x5d1\x5d2\x5d3\n\x5d0\x5d1\x5d2\x5d3\x5d4\x5d5\x5d6\x5d7",
2736 ALIGN_RIGHT }, 2717 ALIGN_RIGHT },
2737 // arabic, 2nd line shorter 2718 // arabic, 2nd line shorter
2738 { L"\x62a\x62b\x62c\x62d\x62e\x62f\x630\n\x660\x661\x662\x663\x664", 2719 { L"\x62a\x62b\x62c\x62d\x62e\x62f\x630\n\x660\x661\x662\x663\x664",
2739 ALIGN_RIGHT }, 2720 ALIGN_RIGHT },
2740 // arabic, 2nd line longer 2721 // arabic, 2nd line longer
2741 { L"\x660\x661\x662\x663\x664\n\x62a\x62b\x62c\x62d\x62e\x62f\x630", 2722 { L"\x660\x661\x662\x663\x664\n\x62a\x62b\x62c\x62d\x62e\x62f\x630",
2742 ALIGN_RIGHT }, 2723 ALIGN_RIGHT },
2743 }; 2724 };
2744 const int kGlyphSize = 5; 2725 const int kGlyphSize = 5;
2745 RenderTextHarfBuzz render_text; 2726 RenderTextHarfBuzz* render_text =
2746 render_text.SetHorizontalAlignment(ALIGN_TO_HEAD); 2727 static_cast<RenderTextHarfBuzz*>(render_text_.get());
2747 render_text.set_glyph_width_for_test(kGlyphSize); 2728 render_text->SetHorizontalAlignment(ALIGN_TO_HEAD);
2748 render_text.SetDisplayRect(Rect(100, 1000)); 2729 render_text->set_glyph_width_for_test(kGlyphSize);
2749 render_text.SetMultiline(true); 2730 render_text->SetDisplayRect(Rect(100, 1000));
2731 render_text->SetMultiline(true);
2750 2732
2751 Canvas canvas;
2752 for (size_t i = 0; i < arraysize(kTestStrings); ++i) { 2733 for (size_t i = 0; i < arraysize(kTestStrings); ++i) {
2753 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "] %ls", i, 2734 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "] %ls", i,
2754 kTestStrings[i].text)); 2735 kTestStrings[i].text));
2755 render_text.SetText(WideToUTF16(kTestStrings[i].text)); 2736 render_text->SetText(WideToUTF16(kTestStrings[i].text));
2756 render_text.Draw(&canvas); 2737 render_text->Draw(&canvas_);
2757 ASSERT_LE(2u, render_text.lines().size()); 2738 ASSERT_LE(2u, render_text->lines().size());
2758 if (kTestStrings[i].alignment == ALIGN_LEFT) { 2739 if (kTestStrings[i].alignment == ALIGN_LEFT) {
2759 EXPECT_EQ(0, render_text.GetAlignmentOffset(0).x()); 2740 EXPECT_EQ(0, render_text->GetAlignmentOffset(0).x());
2760 EXPECT_EQ(0, render_text.GetAlignmentOffset(1).x()); 2741 EXPECT_EQ(0, render_text->GetAlignmentOffset(1).x());
2761 } else { 2742 } else {
2762 std::vector<base::string16> lines = base::SplitString( 2743 std::vector<base::string16> lines = base::SplitString(
2763 base::WideToUTF16(kTestStrings[i].text), 2744 base::WideToUTF16(kTestStrings[i].text),
2764 base::string16(1, '\n'), base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); 2745 base::string16(1, '\n'), base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
2765 ASSERT_EQ(2u, lines.size()); 2746 ASSERT_EQ(2u, lines.size());
2766 int difference = (lines[0].length() - lines[1].length()) * kGlyphSize; 2747 int difference = (lines[0].length() - lines[1].length()) * kGlyphSize;
2767 EXPECT_EQ(render_text.GetAlignmentOffset(0).x() + difference, 2748 EXPECT_EQ(render_text->GetAlignmentOffset(0).x() + difference,
2768 render_text.GetAlignmentOffset(1).x()); 2749 render_text->GetAlignmentOffset(1).x());
2769 } 2750 }
2770 } 2751 }
2771 } 2752 }
2772 2753
2773 TEST_F(RenderTextTest, Multiline_WordWrapBehavior) { 2754 TEST_P(RenderTextHarfBuzzTest, Multiline_WordWrapBehavior) {
2774 const int kGlyphSize = 5; 2755 const int kGlyphSize = 5;
2775 const struct { 2756 const struct {
2776 const WordWrapBehavior behavior; 2757 const WordWrapBehavior behavior;
2777 const size_t num_lines; 2758 const size_t num_lines;
2778 const Range char_ranges[4]; 2759 const Range char_ranges[4];
2779 } kTestScenarios[] = { 2760 } kTestScenarios[] = {
2780 { IGNORE_LONG_WORDS, 3u, 2761 { IGNORE_LONG_WORDS, 3u,
2781 { Range(0, 4), Range(4, 11), Range(11, 14), Range::InvalidRange() } }, 2762 { Range(0, 4), Range(4, 11), Range(11, 14), Range::InvalidRange() } },
2782 { TRUNCATE_LONG_WORDS, 3u, 2763 { TRUNCATE_LONG_WORDS, 3u,
2783 { Range(0, 4), Range(4, 8), Range(11, 14), Range::InvalidRange() } }, 2764 { Range(0, 4), Range(4, 8), Range(11, 14), Range::InvalidRange() } },
2784 { WRAP_LONG_WORDS, 4u, 2765 { WRAP_LONG_WORDS, 4u,
2785 { Range(0, 4), Range(4, 8), Range(8, 11), Range(11, 14) } }, 2766 { Range(0, 4), Range(4, 8), Range(8, 11), Range(11, 14) } },
2786 // TODO(mukai): implement ELIDE_LONG_WORDS. It's not used right now. 2767 // TODO(mukai): implement ELIDE_LONG_WORDS. It's not used right now.
2787 }; 2768 };
2788 RenderTextHarfBuzz render_text; 2769 RenderTextHarfBuzz* render_text =
2789 render_text.SetMultiline(true); 2770 static_cast<RenderTextHarfBuzz*>(render_text_.get());
2790 render_text.SetText(ASCIIToUTF16("foo fooooo foo")); 2771 render_text->SetMultiline(true);
2791 render_text.set_glyph_width_for_test(kGlyphSize); 2772 render_text->SetText(ASCIIToUTF16("foo fooooo foo"));
2792 render_text.SetDisplayRect(Rect(0, 0, kGlyphSize * 4, 0)); 2773 render_text->set_glyph_width_for_test(kGlyphSize);
2793 2774 render_text->SetDisplayRect(Rect(0, 0, kGlyphSize * 4, 0));
2794 Canvas canvas;
2795 2775
2796 for (size_t i = 0; i < arraysize(kTestScenarios); ++i) { 2776 for (size_t i = 0; i < arraysize(kTestScenarios); ++i) {
2797 SCOPED_TRACE(base::StringPrintf( 2777 SCOPED_TRACE(base::StringPrintf(
2798 "kTestScenarios[%" PRIuS "] %d", i, kTestScenarios[i].behavior)); 2778 "kTestScenarios[%" PRIuS "] %d", i, kTestScenarios[i].behavior));
2799 render_text.SetWordWrapBehavior(kTestScenarios[i].behavior); 2779 render_text->SetWordWrapBehavior(kTestScenarios[i].behavior);
2800 render_text.Draw(&canvas); 2780 render_text->Draw(&canvas_);
2801 2781
2802 ASSERT_EQ(kTestScenarios[i].num_lines, render_text.lines().size()); 2782 ASSERT_EQ(kTestScenarios[i].num_lines, render_text->lines().size());
2803 for (size_t j = 0; j < render_text.lines().size(); ++j) { 2783 for (size_t j = 0; j < render_text->lines().size(); ++j) {
2804 SCOPED_TRACE(base::StringPrintf("%" PRIuS "-th line", j)); 2784 SCOPED_TRACE(base::StringPrintf("%" PRIuS "-th line", j));
2805 EXPECT_EQ(kTestScenarios[i].char_ranges[j], 2785 EXPECT_EQ(kTestScenarios[i].char_ranges[j],
2806 render_text.lines()[j].segments[0].char_range); 2786 render_text->lines()[j].segments[0].char_range);
2807 EXPECT_EQ(kTestScenarios[i].char_ranges[j].length() * kGlyphSize, 2787 EXPECT_EQ(kTestScenarios[i].char_ranges[j].length() * kGlyphSize,
2808 render_text.lines()[j].size.width()); 2788 render_text->lines()[j].size.width());
2809 } 2789 }
2810 } 2790 }
2811 } 2791 }
2812 2792
2813 TEST_F(RenderTextTest, Multiline_LineBreakerBehavior) { 2793 TEST_P(RenderTextHarfBuzzTest, Multiline_LineBreakerBehavior) {
2814 const int kGlyphSize = 5; 2794 const int kGlyphSize = 5;
2815 const struct { 2795 const struct {
2816 const wchar_t* const text; 2796 const wchar_t* const text;
2817 const WordWrapBehavior behavior; 2797 const WordWrapBehavior behavior;
2818 const Range char_ranges[3]; 2798 const Range char_ranges[3];
2819 } kTestScenarios[] = { 2799 } kTestScenarios[] = {
2820 { L"a single run", IGNORE_LONG_WORDS, 2800 { L"a single run", IGNORE_LONG_WORDS,
2821 {Range(0, 2), Range(2, 9), Range(9, 12) } }, 2801 {Range(0, 2), Range(2, 9), Range(9, 12) } },
2822 // 3 words: "That's ", ""good". ", "aaa" and 7 runs: "That", "'", "s ", 2802 // 3 words: "That's ", ""good". ", "aaa" and 7 runs: "That", "'", "s ",
2823 // """, "good", "". ", "aaa". They all mixed together. 2803 // """, "good", "". ", "aaa". They all mixed together.
(...skipping 14 matching lines...) Expand all
2838 { L"a \"good\" one.", TRUNCATE_LONG_WORDS, 2818 { L"a \"good\" one.", TRUNCATE_LONG_WORDS,
2839 {Range(0, 2), Range(2, 6), Range(9, 13) } }, 2819 {Range(0, 2), Range(2, 6), Range(9, 13) } },
2840 { L"asingleword", WRAP_LONG_WORDS, 2820 { L"asingleword", WRAP_LONG_WORDS,
2841 {Range(0, 4), Range(4, 8), Range(8, 11) } }, 2821 {Range(0, 4), Range(4, 8), Range(8, 11) } },
2842 { L"That's good", WRAP_LONG_WORDS, 2822 { L"That's good", WRAP_LONG_WORDS,
2843 {Range(0, 4), Range(4, 7), Range(7, 11) } }, 2823 {Range(0, 4), Range(4, 7), Range(7, 11) } },
2844 { L"That's \"g\".", WRAP_LONG_WORDS, 2824 { L"That's \"g\".", WRAP_LONG_WORDS,
2845 {Range(0, 4), Range(4, 7), Range(7, 11) } }, 2825 {Range(0, 4), Range(4, 7), Range(7, 11) } },
2846 }; 2826 };
2847 2827
2848 RenderTextHarfBuzz render_text; 2828 RenderTextHarfBuzz* render_text =
2849 render_text.SetMultiline(true); 2829 static_cast<RenderTextHarfBuzz*>(render_text_.get());
2850 render_text.set_glyph_width_for_test(kGlyphSize); 2830 render_text->SetMultiline(true);
2851 render_text.SetDisplayRect(Rect(0, 0, kGlyphSize * 4, 0)); 2831 render_text->set_glyph_width_for_test(kGlyphSize);
2852 2832 render_text->SetDisplayRect(Rect(0, 0, kGlyphSize * 4, 0));
2853 Canvas canvas;
2854 2833
2855 for (size_t i = 0; i < arraysize(kTestScenarios); ++i) { 2834 for (size_t i = 0; i < arraysize(kTestScenarios); ++i) {
2856 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i)); 2835 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i));
2857 render_text.SetText(WideToUTF16(kTestScenarios[i].text)); 2836 render_text->SetText(WideToUTF16(kTestScenarios[i].text));
2858 render_text.SetWordWrapBehavior(kTestScenarios[i].behavior); 2837 render_text->SetWordWrapBehavior(kTestScenarios[i].behavior);
2859 render_text.Draw(&canvas); 2838 render_text->Draw(&canvas_);
2860 2839
2861 ASSERT_EQ(3u, render_text.lines().size()); 2840 ASSERT_EQ(3u, render_text->lines().size());
2862 for (size_t j = 0; j < render_text.lines().size(); ++j) { 2841 for (size_t j = 0; j < render_text->lines().size(); ++j) {
2863 SCOPED_TRACE(base::StringPrintf("%" PRIuS "-th line", j)); 2842 SCOPED_TRACE(base::StringPrintf("%" PRIuS "-th line", j));
2864 // Merge all the segments ranges in the same line. 2843 // Merge all the segments ranges in the same line.
2865 size_t segment_size = render_text.lines()[j].segments.size(); 2844 size_t segment_size = render_text->lines()[j].segments.size();
2866 Range line_range; 2845 Range line_range;
2867 if (segment_size > 0) 2846 if (segment_size > 0)
2868 line_range = Range( 2847 line_range =
2869 render_text.lines()[j].segments[0].char_range.start(), 2848 Range(render_text->lines()[j].segments[0].char_range.start(),
2870 render_text.lines()[j].segments[segment_size - 1].char_range.end()); 2849 render_text->lines()[j]
2850 .segments[segment_size - 1]
2851 .char_range.end());
2871 EXPECT_EQ(kTestScenarios[i].char_ranges[j], line_range); 2852 EXPECT_EQ(kTestScenarios[i].char_ranges[j], line_range);
2872 EXPECT_EQ(kTestScenarios[i].char_ranges[j].length() * kGlyphSize, 2853 EXPECT_EQ(kTestScenarios[i].char_ranges[j].length() * kGlyphSize,
2873 render_text.lines()[j].size.width()); 2854 render_text->lines()[j].size.width());
2874 } 2855 }
2875 } 2856 }
2876 } 2857 }
2877 2858
2878 // Test that Surrogate pairs or combining character sequences do not get 2859 // Test that Surrogate pairs or combining character sequences do not get
2879 // separated by line breaking. 2860 // separated by line breaking.
2880 TEST_F(RenderTextTest, Multiline_SurrogatePairsOrCombiningChars) { 2861 TEST_P(RenderTextHarfBuzzTest, Multiline_SurrogatePairsOrCombiningChars) {
2881 RenderTextHarfBuzz render_text; 2862 RenderTextHarfBuzz* render_text =
2882 render_text.SetMultiline(true); 2863 static_cast<RenderTextHarfBuzz*>(render_text_.get());
2883 render_text.SetWordWrapBehavior(WRAP_LONG_WORDS); 2864 render_text->SetMultiline(true);
2865 render_text->SetWordWrapBehavior(WRAP_LONG_WORDS);
2884 2866
2885 // Below is 'MUSICAL SYMBOL G CLEF' (U+1D11E), which is represented in UTF-16 2867 // Below is 'MUSICAL SYMBOL G CLEF' (U+1D11E), which is represented in UTF-16
2886 // as two code units forming a surrogate pair: 0xD834 0xDD1E. 2868 // as two code units forming a surrogate pair: 0xD834 0xDD1E.
2887 const base::char16 kSurrogate[] = {0xD834, 0xDD1E, 0}; 2869 const base::char16 kSurrogate[] = {0xD834, 0xDD1E, 0};
2888 const base::string16 text_surrogate(kSurrogate); 2870 const base::string16 text_surrogate(kSurrogate);
2889 const int kSurrogateWidth = 2871 const int kSurrogateWidth =
2890 GetStringWidth(kSurrogate, render_text.font_list()); 2872 GetStringWidth(kSurrogate, render_text->font_list());
2891 2873
2892 // Below is a Devanagari two-character combining sequence U+0921 U+093F. The 2874 // Below is a Devanagari two-character combining sequence U+0921 U+093F. The
2893 // sequence forms a single display character and should not be separated. 2875 // sequence forms a single display character and should not be separated.
2894 const base::char16 kCombiningChars[] = {0x921, 0x93F, 0}; 2876 const base::char16 kCombiningChars[] = {0x921, 0x93F, 0};
2895 const base::string16 text_combining(kCombiningChars); 2877 const base::string16 text_combining(kCombiningChars);
2896 const int kCombiningCharsWidth = 2878 const int kCombiningCharsWidth =
2897 GetStringWidth(kCombiningChars, render_text.font_list()); 2879 GetStringWidth(kCombiningChars, render_text->font_list());
2898 2880
2899 const struct { 2881 const struct {
2900 const base::string16 text; 2882 const base::string16 text;
2901 const int display_width; 2883 const int display_width;
2902 const Range char_ranges[3]; 2884 const Range char_ranges[3];
2903 } kTestScenarios[] = { 2885 } kTestScenarios[] = {
2904 { text_surrogate + text_surrogate + text_surrogate, 2886 { text_surrogate + text_surrogate + text_surrogate,
2905 kSurrogateWidth / 2 * 3, 2887 kSurrogateWidth / 2 * 3,
2906 { Range(0, 2), Range(2, 4), Range(4, 6) } }, 2888 { Range(0, 2), Range(2, 4), Range(4, 6) } },
2907 { text_surrogate + UTF8ToUTF16(" ") + kCombiningChars, 2889 { text_surrogate + UTF8ToUTF16(" ") + kCombiningChars,
2908 std::min(kSurrogateWidth, kCombiningCharsWidth) / 2, 2890 std::min(kSurrogateWidth, kCombiningCharsWidth) / 2,
2909 { Range(0, 2), Range(2, 3), Range(3, 5) } }, 2891 { Range(0, 2), Range(2, 3), Range(3, 5) } },
2910 }; 2892 };
2911 2893
2912 Canvas canvas;
2913 2894
2914 for (size_t i = 0; i < arraysize(kTestScenarios); ++i) { 2895 for (size_t i = 0; i < arraysize(kTestScenarios); ++i) {
2915 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i)); 2896 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i));
2916 render_text.SetText(kTestScenarios[i].text); 2897 render_text->SetText(kTestScenarios[i].text);
2917 render_text.SetDisplayRect(Rect(0, 0, kTestScenarios[i].display_width, 0)); 2898 render_text->SetDisplayRect(Rect(0, 0, kTestScenarios[i].display_width, 0));
2918 render_text.Draw(&canvas); 2899 render_text->Draw(&canvas_);
2919 2900
2920 ASSERT_EQ(3u, render_text.lines().size()); 2901 ASSERT_EQ(3u, render_text->lines().size());
2921 for (size_t j = 0; j < render_text.lines().size(); ++j) { 2902 for (size_t j = 0; j < render_text->lines().size(); ++j) {
2922 SCOPED_TRACE(base::StringPrintf("%" PRIuS "-th line", j)); 2903 SCOPED_TRACE(base::StringPrintf("%" PRIuS "-th line", j));
2923 // There is only one segment in each line. 2904 // There is only one segment in each line.
2924 EXPECT_EQ(kTestScenarios[i].char_ranges[j], 2905 EXPECT_EQ(kTestScenarios[i].char_ranges[j],
2925 render_text.lines()[j].segments[0].char_range); 2906 render_text->lines()[j].segments[0].char_range);
2926 } 2907 }
2927 } 2908 }
2928 } 2909 }
2929 2910
2930 // Test that Zero width characters have the correct line breaking behavior. 2911 // Test that Zero width characters have the correct line breaking behavior.
2931 TEST_F(RenderTextTest, Multiline_ZeroWidthChars) { 2912 TEST_P(RenderTextHarfBuzzTest, Multiline_ZeroWidthChars) {
2932 RenderTextHarfBuzz render_text; 2913 RenderTextHarfBuzz* render_text =
2933 render_text.SetMultiline(true); 2914 static_cast<RenderTextHarfBuzz*>(render_text_.get());
2934 render_text.SetWordWrapBehavior(WRAP_LONG_WORDS); 2915 render_text->SetMultiline(true);
2916 render_text->SetWordWrapBehavior(WRAP_LONG_WORDS);
2935 2917
2936 const base::char16 kZeroWidthSpace = {0x200B}; 2918 const base::char16 kZeroWidthSpace = {0x200B};
2937 const base::string16 text(UTF8ToUTF16("test") + kZeroWidthSpace + 2919 const base::string16 text(UTF8ToUTF16("test") + kZeroWidthSpace +
2938 UTF8ToUTF16("\n") + kZeroWidthSpace + 2920 UTF8ToUTF16("\n") + kZeroWidthSpace +
2939 UTF8ToUTF16("test.")); 2921 UTF8ToUTF16("test."));
2940 const int kTestWidth = 2922 const int kTestWidth =
2941 GetStringWidth(UTF8ToUTF16("test"), render_text.font_list()); 2923 GetStringWidth(UTF8ToUTF16("test"), render_text->font_list());
2942 const Range char_ranges[3] = {Range(0, 5), Range(6, 11), Range(11, 12)}; 2924 const Range char_ranges[3] = {Range(0, 5), Range(6, 11), Range(11, 12)};
2943 2925
2944 Canvas canvas; 2926 render_text->SetText(text);
2945 render_text.SetText(text); 2927 render_text->SetDisplayRect(Rect(0, 0, kTestWidth, 0));
2946 render_text.SetDisplayRect(Rect(0, 0, kTestWidth, 0)); 2928 render_text->Draw(&canvas_);
2947 render_text.Draw(&canvas);
2948 2929
2949 ASSERT_EQ(3u, render_text.lines().size()); 2930 ASSERT_EQ(3u, render_text->lines().size());
2950 for (size_t j = 0; j < render_text.lines().size(); ++j) { 2931 for (size_t j = 0; j < render_text->lines().size(); ++j) {
2951 SCOPED_TRACE(base::StringPrintf("%" PRIuS "-th line", j)); 2932 SCOPED_TRACE(base::StringPrintf("%" PRIuS "-th line", j));
2952 int segment_size = render_text.lines()[j].segments.size(); 2933 int segment_size = render_text->lines()[j].segments.size();
2953 ASSERT_GT(segment_size, 0); 2934 ASSERT_GT(segment_size, 0);
2954 Range line_range( 2935 Range line_range(
2955 render_text.lines()[j].segments[0].char_range.start(), 2936 render_text->lines()[j].segments[0].char_range.start(),
2956 render_text.lines()[j].segments[segment_size - 1].char_range.end()); 2937 render_text->lines()[j].segments[segment_size - 1].char_range.end());
2957 EXPECT_EQ(char_ranges[j], line_range); 2938 EXPECT_EQ(char_ranges[j], line_range);
2958 } 2939 }
2959 } 2940 }
2960 2941
2961 TEST_F(RenderTextTest, NewlineWithoutMultilineFlag) { 2942 TEST_P(RenderTextHarfBuzzTest, NewlineWithoutMultilineFlag) {
2962 const wchar_t* kTestStrings[] = { 2943 const wchar_t* kTestStrings[] = {
2963 L"abc\ndef", L"a \n b ", L"ab\n", L"a\n\nb", L"\nab", L"\n", 2944 L"abc\ndef", L"a \n b ", L"ab\n", L"a\n\nb", L"\nab", L"\n",
2964 }; 2945 };
2965 2946
2966 RenderTextHarfBuzz render_text; 2947 render_text_->SetDisplayRect(Rect(200, 1000));
2967 render_text.SetDisplayRect(Rect(200, 1000));
2968 Canvas canvas;
2969 2948
2970 for (size_t i = 0; i < arraysize(kTestStrings); ++i) { 2949 for (size_t i = 0; i < arraysize(kTestStrings); ++i) {
2971 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i)); 2950 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i));
2972 render_text.SetText(WideToUTF16(kTestStrings[i])); 2951 render_text_->SetText(WideToUTF16(kTestStrings[i]));
2973 render_text.Draw(&canvas); 2952 render_text_->Draw(&canvas_);
2974 2953
2975 EXPECT_EQ(1U, render_text.lines_.size()); 2954 EXPECT_EQ(1U, render_text_->lines_.size());
2976 } 2955 }
2977 } 2956 }
2978 2957
2979 // Make sure the horizontal positions of runs in a line (left-to-right for 2958 // Make sure the horizontal positions of runs in a line (left-to-right for
2980 // LTR languages and right-to-left for RTL languages). 2959 // LTR languages and right-to-left for RTL languages).
2981 TEST_F(RenderTextTest, HarfBuzz_HorizontalPositions) { 2960 TEST_P(RenderTextHarfBuzzTest, HarfBuzz_HorizontalPositions) {
2982 const struct { 2961 const struct {
2983 const wchar_t* const text; 2962 const wchar_t* const text;
2984 const Range first_run_char_range; 2963 const Range first_run_char_range;
2985 const Range second_run_char_range; 2964 const Range second_run_char_range;
2986 bool is_rtl; 2965 bool is_rtl;
2987 } kTestStrings[] = { 2966 } kTestStrings[] = {
2988 { L"abc\x3042\x3044\x3046\x3048\x304A", Range(0, 3), Range(3, 8), false }, 2967 { L"abc\x3042\x3044\x3046\x3048\x304A", Range(0, 3), Range(3, 8), false },
2989 { L"\x062A\x0641\x0627\x062D" 2968 { L"\x062A\x0641\x0627\x062D"
2990 L"\x05EA\x05E4\x05D5\x05D6\x05D9\x05DA\x05DB\x05DD", 2969 L"\x05EA\x05E4\x05D5\x05D6\x05D9\x05DA\x05DB\x05DD",
2991 Range(0, 4), Range(4, 12), true }, 2970 Range(0, 4), Range(4, 12), true },
2992 }; 2971 };
2993 2972
2994 RenderTextHarfBuzz render_text; 2973 RenderTextHarfBuzz* render_text =
2995 Canvas canvas; 2974 static_cast<RenderTextHarfBuzz*>(render_text_.get());
2996 TestSkiaTextRenderer renderer(&canvas);
2997 2975
2998 for (size_t i = 0; i < arraysize(kTestStrings); ++i) { 2976 for (size_t i = 0; i < arraysize(kTestStrings); ++i) {
2999 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i)); 2977 SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i));
3000 render_text.SetText(WideToUTF16(kTestStrings[i].text)); 2978 render_text->SetText(WideToUTF16(kTestStrings[i].text));
3001 2979
3002 render_text.EnsureLayout(); 2980 render_text->EnsureLayout();
3003 const internal::TextRunList* run_list = render_text.GetRunList(); 2981 const internal::TextRunList* run_list = render_text->GetRunList();
3004 ASSERT_EQ(2U, run_list->runs().size()); 2982 ASSERT_EQ(2U, run_list->runs().size());
3005 EXPECT_EQ(kTestStrings[i].first_run_char_range, run_list->runs()[0]->range); 2983 EXPECT_EQ(kTestStrings[i].first_run_char_range, run_list->runs()[0]->range);
3006 EXPECT_EQ(kTestStrings[i].second_run_char_range, 2984 EXPECT_EQ(kTestStrings[i].second_run_char_range,
3007 run_list->runs()[1]->range); 2985 run_list->runs()[1]->range);
3008 // If it's RTL, the visual order is reversed. 2986 // If it's RTL, the visual order is reversed.
3009 if (kTestStrings[i].is_rtl) { 2987 if (kTestStrings[i].is_rtl) {
3010 EXPECT_EQ(1U, run_list->logical_to_visual(0)); 2988 EXPECT_EQ(1U, run_list->logical_to_visual(0));
3011 EXPECT_EQ(0U, run_list->logical_to_visual(1)); 2989 EXPECT_EQ(0U, run_list->logical_to_visual(1));
3012 } else { 2990 } else {
3013 EXPECT_EQ(0U, run_list->logical_to_visual(0)); 2991 EXPECT_EQ(0U, run_list->logical_to_visual(0));
3014 EXPECT_EQ(1U, run_list->logical_to_visual(1)); 2992 EXPECT_EQ(1U, run_list->logical_to_visual(1));
3015 } 2993 }
3016 2994
3017 render_text.DrawVisualText(&renderer); 2995 render_text->DrawVisualText(&renderer_);
3018 2996
3019 std::vector<TestSkiaTextRenderer::TextLog> text_log; 2997 std::vector<TestSkiaTextRenderer::TextLog> text_log;
3020 renderer.GetTextLogAndReset(&text_log); 2998 renderer_.GetTextLogAndReset(&text_log);
3021 2999
3022 EXPECT_EQ(2U, text_log.size()); 3000 EXPECT_EQ(2U, text_log.size());
3023 3001
3024 // Verifies the DrawText happens in the visual order and left-to-right. 3002 // Verifies the DrawText happens in the visual order and left-to-right.
3025 // If the text is RTL, the logically first run should be drawn at last. 3003 // If the text is RTL, the logically first run should be drawn at last.
3026 EXPECT_EQ(run_list->runs()[run_list->logical_to_visual(0)]->glyph_count, 3004 EXPECT_EQ(run_list->runs()[run_list->logical_to_visual(0)]->glyph_count,
3027 text_log[0].glyph_count); 3005 text_log[0].glyph_count);
3028 EXPECT_EQ(run_list->runs()[run_list->logical_to_visual(1)]->glyph_count, 3006 EXPECT_EQ(run_list->runs()[run_list->logical_to_visual(1)]->glyph_count,
3029 text_log[1].glyph_count); 3007 text_log[1].glyph_count);
3030 EXPECT_LT(text_log[0].origin.x(), text_log[1].origin.x()); 3008 EXPECT_LT(text_log[0].origin.x(), text_log[1].origin.x());
3031 } 3009 }
3032 } 3010 }
3033 3011
3034 // Test TextRunHarfBuzz's cluster finding logic. 3012 // Test TextRunHarfBuzz's cluster finding logic.
3035 TEST_F(RenderTextTest, HarfBuzz_Clusters) { 3013 TEST_P(RenderTextHarfBuzzTest, HarfBuzz_Clusters) {
3036 struct { 3014 struct {
3037 uint32_t glyph_to_char[4]; 3015 uint32_t glyph_to_char[4];
3038 Range chars[4]; 3016 Range chars[4];
3039 Range glyphs[4]; 3017 Range glyphs[4];
3040 bool is_rtl; 3018 bool is_rtl;
3041 } cases[] = { 3019 } cases[] = {
3042 { // From string "A B C D" to glyphs "a b c d". 3020 { // From string "A B C D" to glyphs "a b c d".
3043 { 0, 1, 2, 3 }, 3021 { 0, 1, 2, 3 },
3044 { Range(0, 1), Range(1, 2), Range(2, 3), Range(3, 4) }, 3022 { Range(0, 1), Range(1, 2), Range(2, 3), Range(3, 4) },
3045 { Range(0, 1), Range(1, 2), Range(2, 3), Range(3, 4) }, 3023 { Range(0, 1), Range(1, 2), Range(2, 3), Range(3, 4) },
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
3081 Range glyphs; 3059 Range glyphs;
3082 run.GetClusterAt(j, &chars, &glyphs); 3060 run.GetClusterAt(j, &chars, &glyphs);
3083 EXPECT_EQ(cases[i].chars[j], chars); 3061 EXPECT_EQ(cases[i].chars[j], chars);
3084 EXPECT_EQ(cases[i].glyphs[j], glyphs); 3062 EXPECT_EQ(cases[i].glyphs[j], glyphs);
3085 EXPECT_EQ(cases[i].glyphs[j], run.CharRangeToGlyphRange(chars)); 3063 EXPECT_EQ(cases[i].glyphs[j], run.CharRangeToGlyphRange(chars));
3086 } 3064 }
3087 } 3065 }
3088 } 3066 }
3089 3067
3090 // Ensure that graphemes with multiple code points do not get split. 3068 // Ensure that graphemes with multiple code points do not get split.
3091 TEST_F(RenderTextTest, HarfBuzz_SubglyphGraphemeCases) { 3069 TEST_P(RenderTextHarfBuzzTest, HarfBuzz_SubglyphGraphemeCases) {
3092 const wchar_t* cases[] = { 3070 const wchar_t* cases[] = {
3093 // "A" with a combining umlaut, followed by a "B". 3071 // "A" with a combining umlaut, followed by a "B".
3094 L"A\x0308" L"B", 3072 L"A\x0308" L"B",
3095 // Devanagari biconsonantal conjunct "ki", followed by an "a". 3073 // Devanagari biconsonantal conjunct "ki", followed by an "a".
3096 L"\x0915\x093f\x0905", 3074 L"\x0915\x093f\x0905",
3097 // Thai consonant and vowel pair "cho chan" + "sara am", followed by Thai 3075 // Thai consonant and vowel pair "cho chan" + "sara am", followed by Thai
3098 // digit 0. 3076 // digit 0.
3099 L"\x0e08\x0e33\x0E50", 3077 L"\x0e08\x0e33\x0E50",
3100 }; 3078 };
3101 3079
3102 RenderTextHarfBuzz render_text; 3080 RenderTextHarfBuzz* render_text =
3081 static_cast<RenderTextHarfBuzz*>(render_text_.get());
3103 3082
3104 for (size_t i = 0; i < arraysize(cases); ++i) { 3083 for (size_t i = 0; i < arraysize(cases); ++i) {
3105 SCOPED_TRACE(base::StringPrintf("Case %" PRIuS, i)); 3084 SCOPED_TRACE(base::StringPrintf("Case %" PRIuS, i));
3106 3085
3107 base::string16 text = WideToUTF16(cases[i]); 3086 base::string16 text = WideToUTF16(cases[i]);
3108 render_text.SetText(text); 3087 render_text->SetText(text);
3109 render_text.EnsureLayout(); 3088 render_text->EnsureLayout();
3110 internal::TextRunList* run_list = render_text.GetRunList(); 3089 internal::TextRunList* run_list = render_text->GetRunList();
3111 ASSERT_EQ(1U, run_list->size()); 3090 ASSERT_EQ(1U, run_list->size());
3112 internal::TextRunHarfBuzz* run = run_list->runs()[0]; 3091 internal::TextRunHarfBuzz* run = run_list->runs()[0];
3113 3092
3114 base::i18n::BreakIterator* iter = render_text.grapheme_iterator_.get(); 3093 base::i18n::BreakIterator* iter = render_text->grapheme_iterator_.get();
3115 auto first_grapheme_bounds = run->GetGraphemeBounds(iter, 0); 3094 auto first_grapheme_bounds = run->GetGraphemeBounds(iter, 0);
3116 EXPECT_EQ(first_grapheme_bounds, run->GetGraphemeBounds(iter, 1)); 3095 EXPECT_EQ(first_grapheme_bounds, run->GetGraphemeBounds(iter, 1));
3117 auto second_grapheme_bounds = run->GetGraphemeBounds(iter, 2); 3096 auto second_grapheme_bounds = run->GetGraphemeBounds(iter, 2);
3118 EXPECT_EQ(first_grapheme_bounds.end(), second_grapheme_bounds.start()); 3097 EXPECT_EQ(first_grapheme_bounds.end(), second_grapheme_bounds.start());
3119 } 3098 }
3120 } 3099 }
3121 3100
3122 // Test the partition of a multi-grapheme cluster into grapheme ranges. 3101 // Test the partition of a multi-grapheme cluster into grapheme ranges.
3123 TEST_F(RenderTextTest, HarfBuzz_SubglyphGraphemePartition) { 3102 TEST_P(RenderTextHarfBuzzTest, HarfBuzz_SubglyphGraphemePartition) {
3124 struct { 3103 struct {
3125 uint32_t glyph_to_char[2]; 3104 uint32_t glyph_to_char[2];
3126 Range bounds[4]; 3105 Range bounds[4];
3127 bool is_rtl; 3106 bool is_rtl;
3128 } cases[] = { 3107 } cases[] = {
3129 { // From string "A B C D" to glyphs "a bcd". 3108 { // From string "A B C D" to glyphs "a bcd".
3130 { 0, 1 }, 3109 { 0, 1 },
3131 { Range(0, 10), Range(10, 13), Range(13, 17), Range(17, 20) }, 3110 { Range(0, 10), Range(10, 13), Range(13, 17), Range(17, 20) },
3132 false 3111 false
3133 }, 3112 },
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
3168 run.positions[j].set(j * 10, 0); 3147 run.positions[j].set(j * 10, 0);
3169 3148
3170 for (size_t j = 0; j < 4; ++j) { 3149 for (size_t j = 0; j < 4; ++j) {
3171 SCOPED_TRACE(base::StringPrintf("Case %" PRIuS ", char %" PRIuS, i, j)); 3150 SCOPED_TRACE(base::StringPrintf("Case %" PRIuS ", char %" PRIuS, i, j));
3172 EXPECT_EQ(cases[i].bounds[j], 3151 EXPECT_EQ(cases[i].bounds[j],
3173 run.GetGraphemeBounds(iter.get(), j).Round()); 3152 run.GetGraphemeBounds(iter.get(), j).Round());
3174 } 3153 }
3175 } 3154 }
3176 } 3155 }
3177 3156
3178 TEST_F(RenderTextTest, HarfBuzz_RunDirection) { 3157 TEST_P(RenderTextHarfBuzzTest, HarfBuzz_RunDirection) {
3179 RenderTextHarfBuzz render_text; 3158 RenderTextHarfBuzz* render_text =
3159 static_cast<RenderTextHarfBuzz*>(render_text_.get());
3180 const base::string16 mixed = WideToUTF16( 3160 const base::string16 mixed = WideToUTF16(
3181 L"\x05D0\x05D1" 3161 L"\x05D0\x05D1"
3182 L"1234" 3162 L"1234"
3183 L"\x05D2\x05D3" 3163 L"\x05D2\x05D3"
3184 L"abc"); 3164 L"abc");
3185 render_text.SetText(mixed); 3165 render_text->SetText(mixed);
3186 3166
3187 // Get the run list for both display directions. 3167 // Get the run list for both display directions.
3188 render_text.SetDirectionalityMode(DIRECTIONALITY_FORCE_LTR); 3168 render_text->SetDirectionalityMode(DIRECTIONALITY_FORCE_LTR);
3189 render_text.EnsureLayout(); 3169 render_text->EnsureLayout();
3190 internal::TextRunList* run_list = render_text.GetRunList(); 3170 internal::TextRunList* run_list = render_text->GetRunList();
3191 ASSERT_EQ(4U, run_list->size()); 3171 ASSERT_EQ(4U, run_list->size());
3192 EXPECT_TRUE(run_list->runs()[0]->is_rtl); 3172 EXPECT_TRUE(run_list->runs()[0]->is_rtl);
3193 EXPECT_FALSE(run_list->runs()[1]->is_rtl); 3173 EXPECT_FALSE(run_list->runs()[1]->is_rtl);
3194 EXPECT_TRUE(run_list->runs()[2]->is_rtl); 3174 EXPECT_TRUE(run_list->runs()[2]->is_rtl);
3195 EXPECT_FALSE(run_list->runs()[3]->is_rtl); 3175 EXPECT_FALSE(run_list->runs()[3]->is_rtl);
3196 3176
3197 // The Latin letters should appear to the right of the other runs. 3177 // The Latin letters should appear to the right of the other runs.
3198 EXPECT_EQ(2U, run_list->logical_to_visual(0)); 3178 EXPECT_EQ(2U, run_list->logical_to_visual(0));
3199 EXPECT_EQ(1U, run_list->logical_to_visual(1)); 3179 EXPECT_EQ(1U, run_list->logical_to_visual(1));
3200 EXPECT_EQ(0U, run_list->logical_to_visual(2)); 3180 EXPECT_EQ(0U, run_list->logical_to_visual(2));
3201 EXPECT_EQ(3U, run_list->logical_to_visual(3)); 3181 EXPECT_EQ(3U, run_list->logical_to_visual(3));
3202 3182
3203 render_text.SetDirectionalityMode(DIRECTIONALITY_FORCE_RTL); 3183 render_text->SetDirectionalityMode(DIRECTIONALITY_FORCE_RTL);
3204 render_text.EnsureLayout(); 3184 render_text->EnsureLayout();
3205 run_list = render_text.GetRunList(); 3185 run_list = render_text->GetRunList();
3206 ASSERT_EQ(4U, run_list->size()); 3186 ASSERT_EQ(4U, run_list->size());
3207 EXPECT_TRUE(run_list->runs()[0]->is_rtl); 3187 EXPECT_TRUE(run_list->runs()[0]->is_rtl);
3208 EXPECT_FALSE(run_list->runs()[1]->is_rtl); 3188 EXPECT_FALSE(run_list->runs()[1]->is_rtl);
3209 EXPECT_TRUE(run_list->runs()[2]->is_rtl); 3189 EXPECT_TRUE(run_list->runs()[2]->is_rtl);
3210 EXPECT_FALSE(run_list->runs()[3]->is_rtl); 3190 EXPECT_FALSE(run_list->runs()[3]->is_rtl);
3211 3191
3212 // The Latin letters should appear to the left of the other runs. 3192 // The Latin letters should appear to the left of the other runs.
3213 EXPECT_EQ(3U, run_list->logical_to_visual(0)); 3193 EXPECT_EQ(3U, run_list->logical_to_visual(0));
3214 EXPECT_EQ(2U, run_list->logical_to_visual(1)); 3194 EXPECT_EQ(2U, run_list->logical_to_visual(1));
3215 EXPECT_EQ(1U, run_list->logical_to_visual(2)); 3195 EXPECT_EQ(1U, run_list->logical_to_visual(2));
3216 EXPECT_EQ(0U, run_list->logical_to_visual(3)); 3196 EXPECT_EQ(0U, run_list->logical_to_visual(3));
3217 } 3197 }
3218 3198
3219 TEST_F(RenderTextTest, HarfBuzz_BreakRunsByUnicodeBlocks) { 3199 TEST_P(RenderTextHarfBuzzTest, HarfBuzz_BreakRunsByUnicodeBlocks) {
3220 RenderTextHarfBuzz render_text; 3200 RenderTextHarfBuzz* render_text =
3201 static_cast<RenderTextHarfBuzz*>(render_text_.get());
3221 3202
3222 // The '\x25B6' "play character" should break runs. http://crbug.com/278913 3203 // The '\x25B6' "play character" should break runs. http://crbug.com/278913
3223 render_text.SetText(WideToUTF16(L"x\x25B6y")); 3204 render_text->SetText(WideToUTF16(L"x\x25B6y"));
3224 render_text.EnsureLayout(); 3205 render_text->EnsureLayout();
3225 internal::TextRunList* run_list = render_text.GetRunList(); 3206 internal::TextRunList* run_list = render_text->GetRunList();
3226 ASSERT_EQ(3U, run_list->size()); 3207 ASSERT_EQ(3U, run_list->size());
3227 EXPECT_EQ(Range(0, 1), run_list->runs()[0]->range); 3208 EXPECT_EQ(Range(0, 1), run_list->runs()[0]->range);
3228 EXPECT_EQ(Range(1, 2), run_list->runs()[1]->range); 3209 EXPECT_EQ(Range(1, 2), run_list->runs()[1]->range);
3229 EXPECT_EQ(Range(2, 3), run_list->runs()[2]->range); 3210 EXPECT_EQ(Range(2, 3), run_list->runs()[2]->range);
3230 3211
3231 render_text.SetText(WideToUTF16(L"x \x25B6 y")); 3212 render_text->SetText(WideToUTF16(L"x \x25B6 y"));
3232 render_text.EnsureLayout(); 3213 render_text->EnsureLayout();
3233 run_list = render_text.GetRunList(); 3214 run_list = render_text->GetRunList();
3234 ASSERT_EQ(4U, run_list->size()); 3215 ASSERT_EQ(4U, run_list->size());
3235 EXPECT_EQ(Range(0, 2), run_list->runs()[0]->range); 3216 EXPECT_EQ(Range(0, 2), run_list->runs()[0]->range);
3236 EXPECT_EQ(Range(2, 3), run_list->runs()[1]->range); 3217 EXPECT_EQ(Range(2, 3), run_list->runs()[1]->range);
3237 EXPECT_EQ(Range(3, 4), run_list->runs()[2]->range); 3218 EXPECT_EQ(Range(3, 4), run_list->runs()[2]->range);
3238 EXPECT_EQ(Range(4, 5), run_list->runs()[3]->range); 3219 EXPECT_EQ(Range(4, 5), run_list->runs()[3]->range);
3239 } 3220 }
3240 3221
3241 TEST_F(RenderTextTest, HarfBuzz_BreakRunsByEmoji) { 3222 TEST_P(RenderTextHarfBuzzTest, HarfBuzz_BreakRunsByEmoji) {
3242 RenderTextHarfBuzz render_text; 3223 RenderTextHarfBuzz* render_text =
3224 static_cast<RenderTextHarfBuzz*>(render_text_.get());
3243 3225
3244 // \xF0\x9F\x98\x81 (U+1F601) is smile icon emoji. \xE2\x9C\xA8 (U+2728) is 3226 // \xF0\x9F\x98\x81 (U+1F601) is smile icon emoji. \xE2\x9C\xA8 (U+2728) is
3245 // a sparkle icon. Both can be drawn with color emoji fonts, so runs should be 3227 // a sparkle icon. Both can be drawn with color emoji fonts, so runs should be
3246 // separated. See crbug.com/448909 3228 // separated. See crbug.com/448909
3247 render_text.SetText(UTF8ToUTF16("x\xF0\x9F\x98\x81y\xE2\x9C\xA8")); 3229 render_text->SetText(UTF8ToUTF16("x\xF0\x9F\x98\x81y\xE2\x9C\xA8"));
3248 render_text.EnsureLayout(); 3230 render_text->EnsureLayout();
3249 internal::TextRunList* run_list = render_text.GetRunList(); 3231 internal::TextRunList* run_list = render_text->GetRunList();
3250 ASSERT_EQ(4U, run_list->size()); 3232 ASSERT_EQ(4U, run_list->size());
3251 EXPECT_EQ(Range(0, 1), run_list->runs()[0]->range); 3233 EXPECT_EQ(Range(0, 1), run_list->runs()[0]->range);
3252 // The length is 2 since U+1F601 is represented as a surrogate pair in UTF16. 3234 // The length is 2 since U+1F601 is represented as a surrogate pair in UTF16.
3253 EXPECT_EQ(Range(1, 3), run_list->runs()[1]->range); 3235 EXPECT_EQ(Range(1, 3), run_list->runs()[1]->range);
3254 EXPECT_EQ(Range(3, 4), run_list->runs()[2]->range); 3236 EXPECT_EQ(Range(3, 4), run_list->runs()[2]->range);
3255 EXPECT_EQ(Range(4, 5), run_list->runs()[3]->range); 3237 EXPECT_EQ(Range(4, 5), run_list->runs()[3]->range);
3256 } 3238 }
3257 3239
3258 TEST_F(RenderTextTest, HarfBuzz_BreakRunsByAscii) { 3240 TEST_P(RenderTextHarfBuzzTest, HarfBuzz_BreakRunsByAscii) {
3259 RenderTextHarfBuzz render_text; 3241 RenderTextHarfBuzz* render_text =
3242 static_cast<RenderTextHarfBuzz*>(render_text_.get());
3260 3243
3261 // \xF0\x9F\x90\xB1 (U+1F431) is a cat face. It should be put into a separate 3244 // \xF0\x9F\x90\xB1 (U+1F431) is a cat face. It should be put into a separate
3262 // run from the ASCII period character. 3245 // run from the ASCII period character.
3263 render_text.SetText(UTF8ToUTF16("\xF0\x9F\x90\xB1.")); 3246 render_text->SetText(UTF8ToUTF16("\xF0\x9F\x90\xB1."));
3264 render_text.EnsureLayout(); 3247 render_text->EnsureLayout();
3265 internal::TextRunList* run_list = render_text.GetRunList(); 3248 internal::TextRunList* run_list = render_text->GetRunList();
3266 ASSERT_EQ(2U, run_list->size()); 3249 ASSERT_EQ(2U, run_list->size());
3267 // U+1F431 is represented as a surrogate pair in UTF16. 3250 // U+1F431 is represented as a surrogate pair in UTF16.
3268 EXPECT_EQ(Range(0, 2), run_list->runs()[0]->range); 3251 EXPECT_EQ(Range(0, 2), run_list->runs()[0]->range);
3269 EXPECT_EQ(Range(2, 3), run_list->runs()[1]->range); 3252 EXPECT_EQ(Range(2, 3), run_list->runs()[1]->range);
3270 } 3253 }
3271 3254
3272 TEST_F(RenderTextTest, GlyphBounds) { 3255 TEST_P(RenderTextHarfBuzzTest, GlyphBounds) {
3273 const wchar_t* kTestStrings[] = { 3256 const wchar_t* kTestStrings[] = {
3274 L"asdf 1234 qwer", L"\x0647\x0654", L"\x0645\x0631\x062D\x0628\x0627" 3257 L"asdf 1234 qwer", L"\x0647\x0654", L"\x0645\x0631\x062D\x0628\x0627"
3275 }; 3258 };
3276 std::unique_ptr<RenderText> render_text(new RenderTextHarfBuzz);
3277 3259
3278 for (size_t i = 0; i < arraysize(kTestStrings); ++i) { 3260 for (size_t i = 0; i < arraysize(kTestStrings); ++i) {
3279 render_text->SetText(WideToUTF16(kTestStrings[i])); 3261 render_text_->SetText(WideToUTF16(kTestStrings[i]));
3280 render_text->EnsureLayout(); 3262 render_text_->EnsureLayout();
3281 3263
3282 for (size_t j = 0; j < render_text->text().length(); ++j) 3264 for (size_t j = 0; j < render_text_->text().length(); ++j)
3283 EXPECT_FALSE(render_text->GetGlyphBounds(j).is_empty()); 3265 EXPECT_FALSE(render_text_->GetGlyphBounds(j).is_empty());
3284 } 3266 }
3285 } 3267 }
3286 3268
3287 // Ensure that shaping with a non-existent font does not cause a crash. 3269 // Ensure that shaping with a non-existent font does not cause a crash.
3288 TEST_F(RenderTextTest, HarfBuzz_NonExistentFont) { 3270 TEST_P(RenderTextHarfBuzzTest, HarfBuzz_NonExistentFont) {
3289 RenderTextHarfBuzz render_text; 3271 RenderTextHarfBuzz* render_text =
3290 render_text.SetText(ASCIIToUTF16("test")); 3272 static_cast<RenderTextHarfBuzz*>(render_text_.get());
3291 render_text.EnsureLayout(); 3273 render_text->SetText(ASCIIToUTF16("test"));
3292 internal::TextRunList* run_list = render_text.GetRunList(); 3274 render_text->EnsureLayout();
3275 internal::TextRunList* run_list = render_text->GetRunList();
3293 ASSERT_EQ(1U, run_list->size()); 3276 ASSERT_EQ(1U, run_list->size());
3294 internal::TextRunHarfBuzz* run = run_list->runs()[0]; 3277 internal::TextRunHarfBuzz* run = run_list->runs()[0];
3295 render_text.ShapeRunWithFont(render_text.text(), 3278 render_text->ShapeRunWithFont(render_text->text(),
3296 Font("TheFontThatDoesntExist", 13), 3279 Font("TheFontThatDoesntExist", 13),
3297 FontRenderParams(), run); 3280 FontRenderParams(), run);
3298 } 3281 }
3299 3282
3300 // Ensure an empty run returns sane values to queries. 3283 // Ensure an empty run returns sane values to queries.
3301 TEST_F(RenderTextTest, HarfBuzz_EmptyRun) { 3284 TEST_P(RenderTextHarfBuzzTest, HarfBuzz_EmptyRun) {
3302 internal::TextRunHarfBuzz run((Font())); 3285 internal::TextRunHarfBuzz run((Font()));
3303 const base::string16 kString = ASCIIToUTF16("abcdefgh"); 3286 const base::string16 kString = ASCIIToUTF16("abcdefgh");
3304 std::unique_ptr<base::i18n::BreakIterator> iter(new base::i18n::BreakIterator( 3287 std::unique_ptr<base::i18n::BreakIterator> iter(new base::i18n::BreakIterator(
3305 kString, base::i18n::BreakIterator::BREAK_CHARACTER)); 3288 kString, base::i18n::BreakIterator::BREAK_CHARACTER));
3306 ASSERT_TRUE(iter->Init()); 3289 ASSERT_TRUE(iter->Init());
3307 3290
3308 run.range = Range(3, 8); 3291 run.range = Range(3, 8);
3309 run.glyph_count = 0; 3292 run.glyph_count = 0;
3310 EXPECT_EQ(Range(0, 0), run.CharRangeToGlyphRange(Range(4, 5))); 3293 EXPECT_EQ(Range(0, 0), run.CharRangeToGlyphRange(Range(4, 5)));
3311 EXPECT_EQ(Range(0, 0), run.GetGraphemeBounds(iter.get(), 4).Round()); 3294 EXPECT_EQ(Range(0, 0), run.GetGraphemeBounds(iter.get(), 4).Round());
3312 Range chars; 3295 Range chars;
3313 Range glyphs; 3296 Range glyphs;
3314 run.GetClusterAt(4, &chars, &glyphs); 3297 run.GetClusterAt(4, &chars, &glyphs);
3315 EXPECT_EQ(Range(3, 8), chars); 3298 EXPECT_EQ(Range(3, 8), chars);
3316 EXPECT_EQ(Range(0, 0), glyphs); 3299 EXPECT_EQ(Range(0, 0), glyphs);
3317 } 3300 }
3318 3301
3319 // Ensure the line breaker doesn't compute the word's width bigger than the 3302 // Ensure the line breaker doesn't compute the word's width bigger than the
3320 // actual size. See http://crbug.com/470073 3303 // actual size. See http://crbug.com/470073
3321 TEST_F(RenderTextTest, HarfBuzz_WordWidthWithDiacritics) { 3304 TEST_P(RenderTextHarfBuzzTest, HarfBuzz_WordWidthWithDiacritics) {
3322 RenderTextHarfBuzz render_text; 3305 RenderTextHarfBuzz* render_text =
3306 static_cast<RenderTextHarfBuzz*>(render_text_.get());
3323 const base::string16 kWord = WideToUTF16(L"\u0906\u092A\u0915\u0947 "); 3307 const base::string16 kWord = WideToUTF16(L"\u0906\u092A\u0915\u0947 ");
3324 render_text.SetText(kWord); 3308 render_text->SetText(kWord);
3325 const SizeF text_size = render_text.GetStringSizeF(); 3309 const SizeF text_size = render_text->GetStringSizeF();
3326 3310
3327 render_text.SetText(kWord + kWord); 3311 render_text->SetText(kWord + kWord);
3328 render_text.SetMultiline(true); 3312 render_text->SetMultiline(true);
3329 EXPECT_EQ(text_size.width() * 2, render_text.GetStringSizeF().width()); 3313 EXPECT_EQ(text_size.width() * 2, render_text->GetStringSizeF().width());
3330 EXPECT_EQ(text_size.height(), render_text.GetStringSizeF().height()); 3314 EXPECT_EQ(text_size.height(), render_text->GetStringSizeF().height());
3331 render_text.SetDisplayRect(Rect(0, 0, std::ceil(text_size.width()), 0)); 3315 render_text->SetDisplayRect(Rect(0, 0, std::ceil(text_size.width()), 0));
3332 EXPECT_NEAR(text_size.width(), render_text.GetStringSizeF().width(), 1.0f); 3316 EXPECT_NEAR(text_size.width(), render_text->GetStringSizeF().width(), 1.0f);
3333 EXPECT_EQ(text_size.height() * 2, render_text.GetStringSizeF().height()); 3317 EXPECT_EQ(text_size.height() * 2, render_text->GetStringSizeF().height());
3334 } 3318 }
3335 3319
3336 // Ensure a string fits in a display rect with a width equal to the string's. 3320 // Ensure a string fits in a display rect with a width equal to the string's.
3337 TEST_F(RenderTextTest, StringFitsOwnWidth) { 3321 TEST_P(RenderTextTestAll, StringFitsOwnWidth) {
3338 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance());
3339 const base::string16 kString = ASCIIToUTF16("www.example.com"); 3322 const base::string16 kString = ASCIIToUTF16("www.example.com");
3340 3323
3341 render_text->SetText(kString); 3324 render_text_->SetText(kString);
3342 render_text->ApplyWeight(Font::Weight::BOLD, Range(0, 3)); 3325 render_text_->ApplyWeight(Font::Weight::BOLD, Range(0, 3));
3343 render_text->SetElideBehavior(ELIDE_TAIL); 3326 render_text_->SetElideBehavior(ELIDE_TAIL);
3344 3327
3345 render_text->SetDisplayRect(Rect(0, 0, 500, 100)); 3328 render_text_->SetDisplayRect(Rect(0, 0, 500, 100));
3346 EXPECT_EQ(kString, render_text->GetDisplayText()); 3329 EXPECT_EQ(kString, render_text_->GetDisplayText());
3347 render_text->SetDisplayRect(Rect(0, 0, render_text->GetContentWidth(), 100)); 3330 render_text_->SetDisplayRect(
3348 EXPECT_EQ(kString, render_text->GetDisplayText()); 3331 Rect(0, 0, render_text_->GetContentWidth(), 100));
3332 EXPECT_EQ(kString, render_text_->GetDisplayText());
3349 } 3333 }
3350 3334
3351 // TODO(derat): Figure out why this fails on Windows: http://crbug.com/427184 3335 // TODO(derat): Figure out why this fails on Windows: http://crbug.com/427184
3352 #if !defined(OS_WIN) 3336 #if !defined(OS_WIN)
3353 // Ensure that RenderText examines all of the fonts in its FontList before 3337 // Ensure that RenderText examines all of the fonts in its FontList before
3354 // falling back to other fonts. 3338 // falling back to other fonts.
3355 TEST_F(RenderTextTest, HarfBuzz_FontListFallback) { 3339 TEST_P(RenderTextHarfBuzzTest, HarfBuzz_FontListFallback) {
3356 // Double-check that the requested fonts are present. 3340 // Double-check that the requested fonts are present.
3357 FontList font_list("Arial, Symbol, 12px"); 3341 FontList font_list("Arial, Symbol, 12px");
3358 const std::vector<Font>& fonts = font_list.GetFonts(); 3342 const std::vector<Font>& fonts = font_list.GetFonts();
3359 ASSERT_EQ(2u, fonts.size()); 3343 ASSERT_EQ(2u, fonts.size());
3360 ASSERT_EQ("arial", 3344 ASSERT_EQ("arial",
3361 base::ToLowerASCII(fonts[0].GetActualFontNameForTesting())); 3345 base::ToLowerASCII(fonts[0].GetActualFontNameForTesting()));
3362 ASSERT_EQ("symbol", 3346 ASSERT_EQ("symbol",
3363 base::ToLowerASCII(fonts[1].GetActualFontNameForTesting())); 3347 base::ToLowerASCII(fonts[1].GetActualFontNameForTesting()));
3364 3348
3365 // "⊕" (CIRCLED PLUS) should be rendered with Symbol rather than falling back 3349 // "⊕" (CIRCLED PLUS) should be rendered with Symbol rather than falling back
3366 // to some other font that's present on the system. 3350 // to some other font that's present on the system.
3367 RenderTextHarfBuzz render_text; 3351 RenderTextHarfBuzz* render_text =
3368 render_text.SetFontList(font_list); 3352 static_cast<RenderTextHarfBuzz*>(render_text_.get());
3369 render_text.SetText(UTF8ToUTF16("\xE2\x8A\x95")); 3353 render_text->SetFontList(font_list);
3354 render_text->SetText(UTF8ToUTF16("\xE2\x8A\x95"));
3370 const std::vector<RenderText::FontSpan> spans = 3355 const std::vector<RenderText::FontSpan> spans =
3371 render_text.GetFontSpansForTesting(); 3356 render_text->GetFontSpansForTesting();
3372 ASSERT_EQ(static_cast<size_t>(1), spans.size()); 3357 ASSERT_EQ(static_cast<size_t>(1), spans.size());
3373 EXPECT_EQ("Symbol", spans[0].first.GetFontName()); 3358 EXPECT_EQ("Symbol", spans[0].first.GetFontName());
3374 } 3359 }
3375 #endif // !defined(OS_WIN) 3360 #endif // !defined(OS_WIN)
3376 3361
3377 // Ensure that the fallback fonts of the Uniscribe font are tried for shaping. 3362 // Ensure that the fallback fonts of the Uniscribe font are tried for shaping.
3378 #if defined(OS_WIN) 3363 #if defined(OS_WIN)
3379 TEST_F(RenderTextTest, HarfBuzz_UniscribeFallback) { 3364 TEST_P(RenderTextHarfBuzzTest, HarfBuzz_UniscribeFallback) {
3380 RenderTextHarfBuzz render_text; 3365 RenderTextHarfBuzz* render_text =
3366 static_cast<RenderTextHarfBuzz*>(render_text_.get());
3381 PlatformFontWin* font_win = new PlatformFontWin("Meiryo", 12); 3367 PlatformFontWin* font_win = new PlatformFontWin("Meiryo", 12);
3382 // Japanese name for Meiryo. This name won't be found in the system's linked 3368 // Japanese name for Meiryo. This name won't be found in the system's linked
3383 // fonts, forcing RTHB to try the Uniscribe font and its fallbacks. 3369 // fonts, forcing RTHB to try the Uniscribe font and its fallbacks.
3384 font_win->font_ref_->font_name_ = WideToUTF8(L"\x30e1\x30a4\x30ea\x30aa"); 3370 font_win->font_ref_->font_name_ = WideToUTF8(L"\x30e1\x30a4\x30ea\x30aa");
3385 FontList font_list((Font(font_win))); 3371 FontList font_list((Font(font_win)));
3386 3372
3387 render_text.SetFontList(font_list); 3373 render_text->SetFontList(font_list);
3388 // Korean character "han". 3374 // Korean character "han".
3389 render_text.SetText(WideToUTF16(L"\xd55c")); 3375 render_text->SetText(WideToUTF16(L"\xd55c"));
3390 render_text.EnsureLayout(); 3376 render_text->EnsureLayout();
3391 internal::TextRunList* run_list = render_text.GetRunList(); 3377 internal::TextRunList* run_list = render_text->GetRunList();
3392 ASSERT_EQ(1U, run_list->size()); 3378 ASSERT_EQ(1U, run_list->size());
3393 EXPECT_EQ(0U, run_list->runs()[0]->CountMissingGlyphs()); 3379 EXPECT_EQ(0U, run_list->runs()[0]->CountMissingGlyphs());
3394 } 3380 }
3395 #endif // defined(OS_WIN) 3381 #endif // defined(OS_WIN)
3396 3382
3397 // Ensure that the fallback fonts offered by GetFallbackFonts() are 3383 // Ensure that the fallback fonts offered by GetFallbackFonts() are
3398 // tried. Note this test assumes the font "Arial" doesn't provide a unicode 3384 // tried. Note this test assumes the font "Arial" doesn't provide a unicode
3399 // glyph for a particular character, and that there exists a system fallback 3385 // glyph for a particular character, and that there exists a system fallback
3400 // font which does. 3386 // font which does.
3401 // TODO(msw): Fallback doesn't find a glyph on Linux. 3387 // TODO(msw): Fallback doesn't find a glyph on Linux.
3402 #if !defined(OS_LINUX) 3388 #if !defined(OS_LINUX)
3403 TEST_F(RenderTextTest, HarfBuzz_UnicodeFallback) { 3389 TEST_P(RenderTextHarfBuzzTest, HarfBuzz_UnicodeFallback) {
3404 RenderTextHarfBuzz render_text; 3390 RenderTextHarfBuzz* render_text =
3405 render_text.SetFontList(FontList("Arial, 12px")); 3391 static_cast<RenderTextHarfBuzz*>(render_text_.get());
3392 render_text->SetFontList(FontList("Arial, 12px"));
3406 3393
3407 // Korean character "han". 3394 // Korean character "han".
3408 render_text.SetText(WideToUTF16(L"\xd55c")); 3395 render_text->SetText(WideToUTF16(L"\xd55c"));
3409 render_text.EnsureLayout(); 3396 render_text->EnsureLayout();
3410 internal::TextRunList* run_list = render_text.GetRunList(); 3397 internal::TextRunList* run_list = render_text->GetRunList();
3411 ASSERT_EQ(1U, run_list->size()); 3398 ASSERT_EQ(1U, run_list->size());
3412 EXPECT_EQ(0U, run_list->runs()[0]->CountMissingGlyphs()); 3399 EXPECT_EQ(0U, run_list->runs()[0]->CountMissingGlyphs());
3413 } 3400 }
3414 #endif // !defined(OS_LINUX) 3401 #endif // !defined(OS_LINUX)
3415 3402
3416 // http://crbug/624513 3403 // http://crbug/624513
3417 #if defined(OS_WIN) 3404 #if !defined(OS_WIN)
3418 #define MAYBE_TextDoesntClip DISABLED_TextDoesntClip
3419 #else
3420 #define MAYBE_TextDoesntClip TextDoesntClip
3421 #endif
3422 // Ensure that the width reported by RenderText is sufficient for drawing. Draws 3405 // Ensure that the width reported by RenderText is sufficient for drawing. Draws
3423 // to a canvas and checks if any pixel beyond the bounding rectangle is colored. 3406 // to a canvas and checks if any pixel beyond the bounding rectangle is colored.
3424 TEST_F(RenderTextTest, MAYBE_TextDoesntClip) { 3407 TEST_P(RenderTextTestAll, TextDoesntClip) {
3408 // Fails on Mac with RenderTextHarfBuzz. See http://crbug.com/640068.
3409 #if defined(OS_MACOSX)
3410 if (GetParam() == RENDER_TEXT_HARFBUZZ)
3411 return;
3412 #endif
3413
3425 const wchar_t* kTestStrings[] = { 3414 const wchar_t* kTestStrings[] = {
3426 L" ", 3415 L" ",
3427 // TODO(dschuyler): Underscores draw outside GetStringSize; 3416 // TODO(dschuyler): Underscores draw outside GetStringSize;
3428 // crbug.com/459812. This appears to be a preexisting issue that wasn't 3417 // crbug.com/459812. This appears to be a preexisting issue that wasn't
3429 // revealed by the prior unit tests. 3418 // revealed by the prior unit tests.
3430 // L"TEST_______", 3419 // L"TEST_______",
3431 L"TEST some stuff", 3420 L"TEST some stuff",
3432 L"WWWWWWWWWW", 3421 L"WWWWWWWWWW",
3433 L"gAXAXAXAXAXAXA", 3422 L"gAXAXAXAXAXAXA",
3434 // TODO(dschuyler): A-Ring draws outside GetStringSize; crbug.com/459812. 3423 // TODO(dschuyler): A-Ring draws outside GetStringSize; crbug.com/459812.
3435 // L"g\x00C5X\x00C5X\x00C5X\x00C5X\x00C5X\x00C5X\x00C5", 3424 // L"g\x00C5X\x00C5X\x00C5X\x00C5X\x00C5X\x00C5X\x00C5",
3436 L"\x0647\x0654\x0647\x0654\x0647\x0654\x0647\x0654\x0645\x0631\x062D" 3425 L"\x0647\x0654\x0647\x0654\x0647\x0654\x0647\x0654\x0645\x0631\x062D"
3437 L"\x0628\x0627"}; 3426 L"\x0628\x0627"};
3438 const Size kCanvasSize(300, 50); 3427 const Size kCanvasSize(300, 50);
3439 const int kTestSize = 10; 3428 const int kTestSize = 10;
3440 3429
3441 sk_sp<SkSurface> surface = 3430 sk_sp<SkSurface> surface =
3442 SkSurface::MakeRasterN32Premul(kCanvasSize.width(), kCanvasSize.height()); 3431 SkSurface::MakeRasterN32Premul(kCanvasSize.width(), kCanvasSize.height());
3443 Canvas canvas(sk_ref_sp(surface->getCanvas()), 1.0f); 3432 Canvas canvas(sk_ref_sp(surface->getCanvas()), 1.0f);
3444 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 3433 render_text_->SetHorizontalAlignment(ALIGN_LEFT);
3445 render_text->SetHorizontalAlignment(ALIGN_LEFT); 3434 render_text_->SetColor(SK_ColorBLACK);
3446 render_text->SetColor(SK_ColorBLACK);
3447 3435
3448 for (auto* string : kTestStrings) { 3436 for (auto* string : kTestStrings) {
3449 surface->getCanvas()->clear(SK_ColorWHITE); 3437 surface->getCanvas()->clear(SK_ColorWHITE);
3450 render_text->SetText(WideToUTF16(string)); 3438 render_text_->SetText(WideToUTF16(string));
3451 const Size string_size = render_text->GetStringSize(); 3439 const Size string_size = render_text_->GetStringSize();
3452 render_text->ApplyBaselineStyle(SUPERSCRIPT, Range(1, 2)); 3440 render_text_->ApplyBaselineStyle(SUPERSCRIPT, Range(1, 2));
3453 render_text->ApplyBaselineStyle(SUPERIOR, Range(3, 4)); 3441 render_text_->ApplyBaselineStyle(SUPERIOR, Range(3, 4));
3454 render_text->ApplyBaselineStyle(INFERIOR, Range(5, 6)); 3442 render_text_->ApplyBaselineStyle(INFERIOR, Range(5, 6));
3455 render_text->ApplyBaselineStyle(SUBSCRIPT, Range(7, 8)); 3443 render_text_->ApplyBaselineStyle(SUBSCRIPT, Range(7, 8));
3456 render_text->SetWeight(Font::Weight::BOLD); 3444 render_text_->SetWeight(Font::Weight::BOLD);
3457 render_text->SetDisplayRect( 3445 render_text_->SetDisplayRect(
3458 Rect(kTestSize, kTestSize, string_size.width(), string_size.height())); 3446 Rect(kTestSize, kTestSize, string_size.width(), string_size.height()));
3459 // Allow the RenderText to paint outside of its display rect. 3447 // Allow the RenderText to paint outside of its display rect.
3460 render_text->set_clip_to_display_rect(false); 3448 render_text_->set_clip_to_display_rect(false);
3461 ASSERT_LE(string_size.width() + kTestSize * 2, kCanvasSize.width()); 3449 ASSERT_LE(string_size.width() + kTestSize * 2, kCanvasSize.width());
3462 3450
3463 render_text->Draw(&canvas); 3451 render_text_->Draw(&canvas);
3464 ASSERT_LT(string_size.width() + kTestSize, kCanvasSize.width()); 3452 ASSERT_LT(string_size.width() + kTestSize, kCanvasSize.width());
3465 SkPixmap pixmap; 3453 SkPixmap pixmap;
3466 surface->peekPixels(&pixmap); 3454 surface->peekPixels(&pixmap);
3467 const uint32_t* buffer = static_cast<const uint32_t*>(pixmap.addr()); 3455 const uint32_t* buffer = static_cast<const uint32_t*>(pixmap.addr());
3468 ASSERT_NE(nullptr, buffer); 3456 ASSERT_NE(nullptr, buffer);
3469 TestRectangleBuffer rect_buffer(string, buffer, kCanvasSize.width(), 3457 TestRectangleBuffer rect_buffer(string, buffer, kCanvasSize.width(),
3470 kCanvasSize.height()); 3458 kCanvasSize.height());
3471 { 3459 {
3472 #if !defined(OS_CHROMEOS) 3460 #if !defined(OS_CHROMEOS)
3473 int top_test_height = kTestSize; 3461 int top_test_height = kTestSize;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
3515 // TODO(dschuyler): On Mac text draws to right of GetStringSize. This 3503 // TODO(dschuyler): On Mac text draws to right of GetStringSize. This
3516 // appears to be a preexisting issue that wasn't revealed by the prior 3504 // appears to be a preexisting issue that wasn't revealed by the prior
3517 // unit tests. 3505 // unit tests.
3518 rect_buffer.EnsureSolidRect(SK_ColorWHITE, 3506 rect_buffer.EnsureSolidRect(SK_ColorWHITE,
3519 kTestSize + string_size.width(), kTestSize, 3507 kTestSize + string_size.width(), kTestSize,
3520 kTestSize, string_size.height()); 3508 kTestSize, string_size.height());
3521 #endif 3509 #endif
3522 } 3510 }
3523 } 3511 }
3524 } 3512 }
3513 #endif // OS_WINDOWS
3525 3514
3526 // Ensure that the text will clip to the display rect. Draws to a canvas and 3515 // Ensure that the text will clip to the display rect. Draws to a canvas and
3527 // checks whether any pixel beyond the bounding rectangle is colored. 3516 // checks whether any pixel beyond the bounding rectangle is colored.
3528 TEST_F(RenderTextTest, TextDoesClip) { 3517 TEST_P(RenderTextTestAll, TextDoesClip) {
3529 const wchar_t* kTestStrings[] = {L"TEST", L"W", L"WWWW", L"gAXAXWWWW"}; 3518 const wchar_t* kTestStrings[] = {L"TEST", L"W", L"WWWW", L"gAXAXWWWW"};
3530 const Size kCanvasSize(300, 50); 3519 const Size kCanvasSize(300, 50);
3531 const int kTestSize = 10; 3520 const int kTestSize = 10;
3532 3521
3533 sk_sp<SkSurface> surface = 3522 sk_sp<SkSurface> surface =
3534 SkSurface::MakeRasterN32Premul(kCanvasSize.width(), kCanvasSize.height()); 3523 SkSurface::MakeRasterN32Premul(kCanvasSize.width(), kCanvasSize.height());
3535 Canvas canvas(sk_ref_sp(surface->getCanvas()), 1.0f); 3524 Canvas canvas(sk_ref_sp(surface->getCanvas()), 1.0f);
3536 std::unique_ptr<RenderText> render_text(RenderText::CreateInstance()); 3525 render_text_->SetHorizontalAlignment(ALIGN_LEFT);
3537 render_text->SetHorizontalAlignment(ALIGN_LEFT); 3526 render_text_->SetColor(SK_ColorBLACK);
3538 render_text->SetColor(SK_ColorBLACK);
3539 3527
3540 for (auto* string : kTestStrings) { 3528 for (auto* string : kTestStrings) {
3541 surface->getCanvas()->clear(SK_ColorWHITE); 3529 surface->getCanvas()->clear(SK_ColorWHITE);
3542 render_text->SetText(WideToUTF16(string)); 3530 render_text_->SetText(WideToUTF16(string));
3543 const Size string_size = render_text->GetStringSize(); 3531 const Size string_size = render_text_->GetStringSize();
3544 int fake_width = string_size.width() / 2; 3532 int fake_width = string_size.width() / 2;
3545 int fake_height = string_size.height() / 2; 3533 int fake_height = string_size.height() / 2;
3546 render_text->SetDisplayRect( 3534 render_text_->SetDisplayRect(
3547 Rect(kTestSize, kTestSize, fake_width, fake_height)); 3535 Rect(kTestSize, kTestSize, fake_width, fake_height));
3548 render_text->set_clip_to_display_rect(true); 3536 render_text_->set_clip_to_display_rect(true);
3549 render_text->Draw(&canvas); 3537 render_text_->Draw(&canvas);
3550 ASSERT_LT(string_size.width() + kTestSize, kCanvasSize.width()); 3538 ASSERT_LT(string_size.width() + kTestSize, kCanvasSize.width());
3551 SkPixmap pixmap; 3539 SkPixmap pixmap;
3552 surface->peekPixels(&pixmap); 3540 surface->peekPixels(&pixmap);
3553 const uint32_t* buffer = static_cast<const uint32_t*>(pixmap.addr()); 3541 const uint32_t* buffer = static_cast<const uint32_t*>(pixmap.addr());
3554 ASSERT_NE(nullptr, buffer); 3542 ASSERT_NE(nullptr, buffer);
3555 TestRectangleBuffer rect_buffer(string, buffer, kCanvasSize.width(), 3543 TestRectangleBuffer rect_buffer(string, buffer, kCanvasSize.width(),
3556 kCanvasSize.height()); 3544 kCanvasSize.height());
3557 { 3545 {
3558 SCOPED_TRACE("TextDoesClip Top Side"); 3546 SCOPED_TRACE("TextDoesClip Top Side");
3559 rect_buffer.EnsureSolidRect(SK_ColorWHITE, 0, 0, kCanvasSize.width(), 3547 rect_buffer.EnsureSolidRect(SK_ColorWHITE, 0, 0, kCanvasSize.width(),
(...skipping 12 matching lines...) Expand all
3572 } 3560 }
3573 { 3561 {
3574 SCOPED_TRACE("TextDoesClip Right Side"); 3562 SCOPED_TRACE("TextDoesClip Right Side");
3575 rect_buffer.EnsureSolidRect(SK_ColorWHITE, kTestSize + fake_width, 3563 rect_buffer.EnsureSolidRect(SK_ColorWHITE, kTestSize + fake_width,
3576 kTestSize, kTestSize, fake_height); 3564 kTestSize, kTestSize, fake_height);
3577 } 3565 }
3578 } 3566 }
3579 } 3567 }
3580 3568
3581 #if defined(OS_MACOSX) 3569 #if defined(OS_MACOSX)
3582 TEST_F(RenderTextTest, Mac_ElidedText) { 3570 TEST_P(RenderTextMacTest, Mac_ElidedText) {
3583 RenderTextMac render_text; 3571 RenderTextMac* render_text = static_cast<RenderTextMac*>(render_text_.get());
3584 base::string16 text(ASCIIToUTF16("This is an example.")); 3572 base::string16 text(ASCIIToUTF16("This is an example."));
3585 render_text.SetText(text); 3573 render_text->SetText(text);
3586 Size string_size = render_text.GetStringSize(); 3574 Size string_size = render_text->GetStringSize();
3587 render_text.SetDisplayRect(Rect(string_size)); 3575 render_text->SetDisplayRect(Rect(string_size));
3588 render_text.EnsureLayout(); 3576 render_text->EnsureLayout();
3589 // NOTE: Character and glyph counts are only comparable for simple text. 3577 // NOTE: Character and glyph counts are only comparable for simple text.
3590 EXPECT_EQ(text.size(), 3578 EXPECT_EQ(text.size(),
3591 static_cast<size_t>(CTLineGetGlyphCount(render_text.line_))); 3579 static_cast<size_t>(CTLineGetGlyphCount(render_text->line_)));
3592 3580
3593 render_text.SetElideBehavior(ELIDE_TAIL); 3581 render_text->SetElideBehavior(ELIDE_TAIL);
3594 string_size.set_width(string_size.width() / 2); 3582 string_size.set_width(string_size.width() / 2);
3595 render_text.SetDisplayRect(Rect(string_size)); 3583 render_text->SetDisplayRect(Rect(string_size));
3596 render_text.EnsureLayout(); 3584 render_text->EnsureLayout();
3597 CFIndex glyph_count = CTLineGetGlyphCount(render_text.line_); 3585 CFIndex glyph_count = CTLineGetGlyphCount(render_text->line_);
3598 EXPECT_GT(text.size(), static_cast<size_t>(glyph_count)); 3586 EXPECT_GT(text.size(), static_cast<size_t>(glyph_count));
3599 EXPECT_NE(0, glyph_count); 3587 EXPECT_NE(0, glyph_count);
3600 } 3588 }
3601 #endif 3589 #endif
3602 3590
3603 // Ensure color changes are picked up by the RenderText implementation. 3591 // Ensure color changes are picked up by the RenderText implementation.
3604 TEST_F(RenderTextTest, ColorChange) { 3592 TEST_P(RenderTextTestAll, ColorChange) {
3605 RenderTextAllBackends backend; 3593 render_text_->SetText(ASCIIToUTF16("x"));
3594 DrawVisualText();
3606 3595
3607 while (backend.Advance()) { 3596 std::vector<TestSkiaTextRenderer::TextLog> text_log;
3608 SCOPED_TRACE(testing::Message() << "backend: " << backend.GetName()); 3597 renderer_.GetTextLogAndReset(&text_log);
3609 backend->SetText(ASCIIToUTF16("x")); 3598 EXPECT_EQ(1u, text_log.size());
3610 backend.DrawVisualText(); 3599 EXPECT_EQ(SK_ColorBLACK, text_log[0].color);
3611 3600
3612 std::vector<TestSkiaTextRenderer::TextLog> text_log; 3601 render_text_->SetColor(SK_ColorRED);
3613 backend.GetTextLogAndReset(&text_log); 3602 DrawVisualText();
3614 EXPECT_EQ(1u, text_log.size()); 3603 renderer_.GetTextLogAndReset(&text_log);
3615 EXPECT_EQ(SK_ColorBLACK, text_log[0].color);
3616 3604
3617 backend->SetColor(SK_ColorRED); 3605 EXPECT_EQ(1u, text_log.size());
3618 backend.DrawVisualText(); 3606 EXPECT_EQ(SK_ColorRED, text_log[0].color);
3619 backend.GetTextLogAndReset(&text_log);
3620
3621 EXPECT_EQ(1u, text_log.size());
3622 EXPECT_EQ(SK_ColorRED, text_log[0].color);
3623 }
3624 } 3607 }
3625 3608
3626 // Ensure style information propagates to the typeface on the text renderer. 3609 // Ensure style information propagates to the typeface on the text renderer.
3627 TEST_F(RenderTextTest, StylePropagated) { 3610 TEST_P(RenderTextTestAll, StylePropagated) {
3628 RenderTextAllBackends backend;
3629
3630 // Default-constructed fonts on Mac are system fonts. These can have all kinds 3611 // Default-constructed fonts on Mac are system fonts. These can have all kinds
3631 // of weird weights and style, which are preserved by PlatformFontMac, but do 3612 // of weird weights and style, which are preserved by PlatformFontMac, but do
3632 // not map simply to a SkTypeface::Style (the full details in SkFontStyle is 3613 // not map simply to a SkTypeface::Style (the full details in SkFontStyle is
3633 // needed). They also vary depending on the OS version, so set a known font. 3614 // needed). They also vary depending on the OS version, so set a known font.
3634 FontList font_list(Font("Arial", 10)); 3615 FontList font_list(Font("Arial", 10));
3635 3616
3636 while (backend.Advance()) { 3617 render_text_->SetText(ASCIIToUTF16("x"));
3637 SCOPED_TRACE(testing::Message() << "backend: " << backend.GetName()); 3618 render_text_->SetFontList(font_list);
3638 backend->SetText(ASCIIToUTF16("x"));
3639 backend->SetFontList(font_list);
3640 3619
3641 backend.DrawVisualText(); 3620 DrawVisualText();
3642 EXPECT_EQ(SkTypeface::kNormal, backend.paint().getTypeface()->style()); 3621 EXPECT_EQ(SkTypeface::kNormal, GetRendererPaint().getTypeface()->style());
3643 3622
3644 backend->SetWeight(Font::Weight::BOLD); 3623 render_text_->SetWeight(Font::Weight::BOLD);
3645 backend.DrawVisualText(); 3624 DrawVisualText();
3646 EXPECT_EQ(SkTypeface::kBold, backend.paint().getTypeface()->style()); 3625 EXPECT_EQ(SkTypeface::kBold, GetRendererPaint().getTypeface()->style());
3647 3626
3648 backend->SetStyle(TextStyle::ITALIC, true); 3627 render_text_->SetStyle(TextStyle::ITALIC, true);
3649 backend.DrawVisualText(); 3628 DrawVisualText();
3650 EXPECT_EQ(SkTypeface::kBoldItalic, backend.paint().getTypeface()->style()); 3629 EXPECT_EQ(SkTypeface::kBoldItalic, GetRendererPaint().getTypeface()->style());
3651 3630
3652 backend->SetWeight(Font::Weight::NORMAL); 3631 render_text_->SetWeight(Font::Weight::NORMAL);
3653 backend.DrawVisualText(); 3632 DrawVisualText();
3654 EXPECT_EQ(SkTypeface::kItalic, backend.paint().getTypeface()->style()); 3633 EXPECT_EQ(SkTypeface::kItalic, GetRendererPaint().getTypeface()->style());
3655 }
3656 } 3634 }
3657 3635
3658 // Ensure the painter adheres to RenderText::subpixel_rendering_suppressed(). 3636 // Ensure the painter adheres to RenderText::subpixel_rendering_suppressed().
3659 TEST_F(RenderTextTest, SubpixelRenderingSuppressed) { 3637 TEST_P(RenderTextTestAll, SubpixelRenderingSuppressed) {
3660 RenderTextAllBackends backend; 3638 render_text_->SetText(ASCIIToUTF16("x"));
3661 3639
3662 while (backend.Advance()) { 3640 DrawVisualText();
3663 SCOPED_TRACE(testing::Message() << "backend: " << backend.GetName()); 3641 #if defined(OS_LINUX)
3664 backend->SetText(ASCIIToUTF16("x")); 3642 // On Linux, whether subpixel AA is supported is determined by the platform
3643 // FontConfig. Force it into a particular style after computing runs. Other
3644 // platforms use a known default FontRenderParams from a static local.
3645 GetHarfbuzzRunList()->runs()[0]->render_params.subpixel_rendering =
3646 FontRenderParams::SUBPIXEL_RENDERING_RGB;
3647 DrawVisualText();
3648 #endif
3649 EXPECT_TRUE(GetRendererPaint().isLCDRenderText());
3665 3650
3666 backend.DrawVisualText(); 3651 render_text_->set_subpixel_rendering_suppressed(true);
3667 #if defined(OS_LINUX) 3652 DrawVisualText();
3668 // On Linux, whether subpixel AA is supported is determined by the platform
3669 // FontConfig. Force it into a particular style after computing runs. Other
3670 // platforms use a known default FontRenderParams from a static local.
3671 backend.GetHarfbuzzRunList()->runs()[0]->render_params.subpixel_rendering =
3672 FontRenderParams::SUBPIXEL_RENDERING_RGB;
3673 backend.DrawVisualText();
3674 #endif
3675 EXPECT_TRUE(backend.paint().isLCDRenderText());
3676
3677 backend->set_subpixel_rendering_suppressed(true);
3678 backend.DrawVisualText();
3679 #if defined(OS_LINUX) 3653 #if defined(OS_LINUX)
3680 // For Linux, runs shouldn't be re-calculated, and the suppression of the 3654 // For Linux, runs shouldn't be re-calculated, and the suppression of the
3681 // SUBPIXEL_RENDERING_RGB set above should now take effect. But, after 3655 // SUBPIXEL_RENDERING_RGB set above should now take effect. But, after
3682 // checking, apply the override anyway to be explicit that it is suppressed. 3656 // checking, apply the override anyway to be explicit that it is suppressed.
3683 EXPECT_FALSE(backend.paint().isLCDRenderText()); 3657 EXPECT_FALSE(GetRendererPaint().isLCDRenderText());
3684 backend.GetHarfbuzzRunList()->runs()[0]->render_params.subpixel_rendering = 3658 GetHarfbuzzRunList()->runs()[0]->render_params.subpixel_rendering =
3685 FontRenderParams::SUBPIXEL_RENDERING_RGB; 3659 FontRenderParams::SUBPIXEL_RENDERING_RGB;
3686 backend.DrawVisualText(); 3660 DrawVisualText();
3687 #endif 3661 #endif
3688 EXPECT_FALSE(backend.paint().isLCDRenderText()); 3662 EXPECT_FALSE(GetRendererPaint().isLCDRenderText());
3689 }
3690 } 3663 }
3691 3664
3665 #if defined(OS_MACOSX)
3666 INSTANTIATE_TEST_CASE_P(,
3667 RenderTextTestAll,
3668 ::testing::Values(RENDER_TEXT_HARFBUZZ,
3669 RENDER_TEXT_MAC));
3670 INSTANTIATE_TEST_CASE_P(,
3671 RenderTextMacTest,
3672 ::testing::Values(RENDER_TEXT_MAC));
3673 #else
3674 INSTANTIATE_TEST_CASE_P(,
3675 RenderTextTestAll,
3676 ::testing::Values(RENDER_TEXT_HARFBUZZ));
3677 #endif
3678
3679 INSTANTIATE_TEST_CASE_P(,
3680 RenderTextHarfBuzzTest,
3681 ::testing::Values(RENDER_TEXT_HARFBUZZ));
3692 } // namespace gfx 3682 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gfx/render_text_mac.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698