render_text_unittest.cc revision d0247b1b59f9c528cb6df88b4f2b9afaf80d181e
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/render_text.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include <algorithm> 8a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 9d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/format_macros.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/strings/stringprintf.h" 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/break_list.h" 15a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "ui/gfx/canvas.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/windows_version.h" 19558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "ui/gfx/render_text_win.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_LINUX) 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/render_text_linux.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(TOOLKIT_GTK) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <gtk/gtk.h> 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gfx { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Various weak, LTR, RTL, and Bidi string cases with three characters each. 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kWeak[] = L" . "; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kLtr[] = L"abc"; 37bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochconst wchar_t kLtrRtl[] = L"a" L"\x5d0\x5d1"; 38bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochconst wchar_t kLtrRtlLtr[] = L"a" L"\x5d1" L"b"; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kRtl[] = L"\x5d0\x5d1\x5d2"; 40bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochconst wchar_t kRtlLtr[] = L"\x5d0\x5d1" L"a"; 41bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochconst wchar_t kRtlLtrRtl[] = L"\x5d0" L"a" L"\x5d1"; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks whether |range| contains |index|. This is not the same as calling 4458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// |range.Contains(gfx::Range(index))| - as that would return true when 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |index| == |range.end()|. 46d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)bool IndexInRange(const Range& range, size_t index) { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return index >= range.start() && index < range.end(); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 50a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)base::string16 GetSelectedText(RenderText* render_text) { 51a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return render_text->text().substr(render_text->selection().GetMin(), 52a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) render_text->selection().length()); 53a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 54a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A test utility function to set the application default text direction. 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SetRTL(bool rtl) { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Override the current locale/direction. 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::i18n::SetICUDefaultLocale(rtl ? "he" : "en"); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(TOOLKIT_GTK) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Do the same for GTK, which does not rely on the ICU default locale. 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_set_default_direction(rtl ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(rtl, base::i18n::IsRTL()); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Ensure cursor movement in the specified |direction| yields |expected| values. 67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid RunMoveCursorLeftRightTest(RenderText* render_text, 68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const std::vector<SelectionModel>& expected, 69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch VisualCursorDirection direction) { 70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (size_t i = 0; i < expected.size(); ++i) { 71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SCOPED_TRACE(base::StringPrintf("Going %s; expected value index %d.", 72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch direction == CURSOR_LEFT ? "left" : "right", static_cast<int>(i))); 73eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(expected[i], render_text->selection_model()); 74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch render_text->MoveCursor(CHARACTER_BREAK, direction, false); 75eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Check that cursoring is clamped at the line edge. 77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(expected.back(), render_text->selection_model()); 78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Check that it is the line edge. 79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch render_text->MoveCursor(LINE_BREAK, direction, false); 80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(expected.back(), render_text->selection_model()); 81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RenderTextTest : public testing::Test { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, DefaultStyle) { 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Check the default styles applied to new instances and adjusted text. 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(render_text->text().empty()); 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const wchar_t* const cases[] = { kWeak, kLtr, L"Hello", kRtl, L"", L"" }; 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < arraysize(cases); ++i) { 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(render_text->colors().EqualsValueForTesting(SK_ColorBLACK)); 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(render_text->styles()[style].EqualsValueForTesting(false)); 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->SetText(WideToUTF16(cases[i])); 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(RenderTextTest, SetColorAndStyle) { 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Ensure custom default styles persist across setting and clearing text. 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const SkColor color = SK_ColorRED; 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->SetColor(color); 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->SetStyle(BOLD, true); 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->SetStyle(UNDERLINE, false); 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const wchar_t* const cases[] = { kWeak, kLtr, L"Hello", kRtl, L"", L"" }; 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < arraysize(cases); ++i) { 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(render_text->colors().EqualsValueForTesting(color)); 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(render_text->styles()[BOLD].EqualsValueForTesting(true)); 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(render_text->styles()[UNDERLINE].EqualsValueForTesting(false)); 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->SetText(WideToUTF16(cases[i])); 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Ensure custom default styles can be applied after text has been set. 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (i == 1) 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->SetStyle(STRIKE, true); 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (i >= 1) 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(render_text->styles()[STRIKE].EqualsValueForTesting(true)); 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(RenderTextTest, ApplyColorAndStyle) { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->SetText(ASCIIToUTF16("012345678")); 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Apply a ranged color and style and check the resulting breaks. 128d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) render_text->ApplyColor(SK_ColorRED, Range(1, 4)); 129d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) render_text->ApplyStyle(BOLD, true, Range(2, 5)); 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::pair<size_t, SkColor> > expected_color; 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_color.push_back(std::pair<size_t, SkColor>(0, SK_ColorBLACK)); 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_color.push_back(std::pair<size_t, SkColor>(1, SK_ColorRED)); 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_color.push_back(std::pair<size_t, SkColor>(4, SK_ColorBLACK)); 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(render_text->colors().EqualsForTesting(expected_color)); 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::pair<size_t, bool> > expected_style; 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_style.push_back(std::pair<size_t, bool>(0, false)); 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_style.push_back(std::pair<size_t, bool>(2, true)); 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_style.push_back(std::pair<size_t, bool>(5, false)); 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(render_text->styles()[BOLD].EqualsForTesting(expected_style)); 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Ensure setting a color and style overrides the ranged colors and styles. 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->SetColor(SK_ColorBLUE); 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(render_text->colors().EqualsValueForTesting(SK_ColorBLUE)); 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->SetStyle(BOLD, false); 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(render_text->styles()[BOLD].EqualsValueForTesting(false)); 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Apply a color and style over the text end and check the resulting breaks. 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // (INT_MAX should be used instead of the text length for the range end) 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const size_t text_length = render_text->text().length(); 150d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) render_text->ApplyColor(SK_ColorRED, Range(0, text_length)); 151d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) render_text->ApplyStyle(BOLD, true, Range(2, text_length)); 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::pair<size_t, SkColor> > expected_color_end; 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_color_end.push_back(std::pair<size_t, SkColor>(0, SK_ColorRED)); 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(render_text->colors().EqualsForTesting(expected_color_end)); 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::pair<size_t, bool> > expected_style_end; 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_style_end.push_back(std::pair<size_t, bool>(0, false)); 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_style_end.push_back(std::pair<size_t, bool>(2, true)); 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(render_text->styles()[BOLD].EqualsForTesting(expected_style_end)); 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Ensure ranged values adjust to accommodate text length changes. 161d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) render_text->ApplyStyle(ITALIC, true, Range(0, 2)); 162d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) render_text->ApplyStyle(ITALIC, true, Range(3, 6)); 163d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) render_text->ApplyStyle(ITALIC, true, Range(7, text_length)); 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::pair<size_t, bool> > expected_italic; 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_italic.push_back(std::pair<size_t, bool>(0, true)); 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_italic.push_back(std::pair<size_t, bool>(2, false)); 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_italic.push_back(std::pair<size_t, bool>(3, true)); 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_italic.push_back(std::pair<size_t, bool>(6, false)); 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_italic.push_back(std::pair<size_t, bool>(7, true)); 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(render_text->styles()[ITALIC].EqualsForTesting(expected_italic)); 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Truncating the text should trim any corresponding breaks. 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->SetText(ASCIIToUTF16("0123456")); 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_italic.resize(4); 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(render_text->styles()[ITALIC].EqualsForTesting(expected_italic)); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(ASCIIToUTF16("01234")); 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_italic.resize(3); 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(render_text->styles()[ITALIC].EqualsForTesting(expected_italic)); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Appending text should extend the terminal styles without changing breaks. 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->SetText(ASCIIToUTF16("012345678")); 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(render_text->styles()[ITALIC].EqualsForTesting(expected_italic)); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_LINUX) 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(RenderTextTest, PangoAttributes) { 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->SetText(ASCIIToUTF16("012345678")); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Apply ranged BOLD/ITALIC styles and check the resulting Pango attributes. 191d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) render_text->ApplyStyle(BOLD, true, Range(2, 4)); 192d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) render_text->ApplyStyle(ITALIC, true, Range(1, 3)); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct { 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int start; 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int end; 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool bold; 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool italic; 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } cases[] = { 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 0, 1, false, false }, 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 1, 2, false, true }, 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 2, 3, true, true }, 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 3, 4, true, false }, 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 4, INT_MAX, false, false }, 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int start = 0, end = 0; 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RenderTextLinux* rt_linux = static_cast<RenderTextLinux*>(render_text.get()); 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rt_linux->EnsureLayout(); 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PangoAttrList* attributes = pango_layout_get_attributes(rt_linux->layout_); 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PangoAttrIterator* iter = pango_attr_list_get_iterator(attributes); 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pango_attr_iterator_range(iter, &start, &end); 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(cases[i].start, start); 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(cases[i].end, end); 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PangoFontDescription* font = pango_font_description_new(); 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pango_attr_iterator_get_font(iter, font, NULL, NULL); 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) char* description_string = pango_font_description_to_string(font); 219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const base::string16 desc = ASCIIToUTF16(description_string); 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const bool bold = desc.find(ASCIIToUTF16("Bold")) != std::string::npos; 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(cases[i].bold, bold); 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const bool italic = desc.find(ASCIIToUTF16("Italic")) != std::string::npos; 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(cases[i].italic, italic); 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pango_attr_iterator_next(iter); 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pango_font_description_free(font); 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) g_free(description_string); 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(pango_attr_iterator_next(iter)); 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pango_attr_iterator_destroy(iter); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(asvitkine): Cursor movements tests disabled on Mac because RenderTextMac 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// does not implement this yet. http://crbug.com/131618 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_MACOSX) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestVisualCursorMotionInObscuredField(RenderText* render_text, 237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const base::string16& text, 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool select) { 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(render_text->obscured()); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(text); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int len = text.length(); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(LINE_BREAK, CURSOR_RIGHT, select); 243d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(SelectionModel(Range(select ? 0 : len, len), CURSOR_FORWARD), 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->selection_model()); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(LINE_BREAK, CURSOR_LEFT, select); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(SelectionModel(0, CURSOR_BACKWARD), render_text->selection_model()); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = 1; j <= len; ++j) { 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, select); 249d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(SelectionModel(Range(select ? 0 : j, j), CURSOR_BACKWARD), 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->selection_model()); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = len - 1; j >= 0; --j) { 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, select); 254d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(SelectionModel(Range(select ? 0 : j, j), CURSOR_FORWARD), 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->selection_model()); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, select); 258d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(SelectionModel(Range(select ? 0 : len, len), CURSOR_FORWARD), 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->selection_model()); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(WORD_BREAK, CURSOR_LEFT, select); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(SelectionModel(0, CURSOR_BACKWARD), render_text->selection_model()); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, ObscuredText) { 265868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const base::string16 seuss = ASCIIToUTF16("hop on pop"); 266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const base::string16 no_seuss = ASCIIToUTF16("**********"); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // GetLayoutText() returns asterisks when the obscured bit is set. 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(seuss); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetObscured(true); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(seuss, render_text->text()); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(no_seuss, render_text->GetLayoutText()); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetObscured(false); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(seuss, render_text->text()); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(seuss, render_text->GetLayoutText()); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetObscured(true); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Surrogate pairs are counted as one code point. 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char16 invalid_surrogates[] = {0xDC00, 0xD800, 0}; 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(invalid_surrogates); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ASCIIToUTF16("**"), render_text->GetLayoutText()); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char16 valid_surrogates[] = {0xD800, 0xDC00, 0}; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(valid_surrogates); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ASCIIToUTF16("*"), render_text->GetLayoutText()); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0U, render_text->cursor_position()); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, false); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(2U, render_text->cursor_position()); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test index conversion and cursor validity with a valid surrogate pair. 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0U, render_text->TextIndexToLayoutIndex(0U)); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1U, render_text->TextIndexToLayoutIndex(1U)); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1U, render_text->TextIndexToLayoutIndex(2U)); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0U, render_text->LayoutIndexToTextIndex(0U)); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(2U, render_text->LayoutIndexToTextIndex(1U)); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(render_text->IsCursorablePosition(0U)); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(render_text->IsCursorablePosition(1U)); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(render_text->IsCursorablePosition(2U)); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FindCursorPosition() should not return positions between a surrogate pair. 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(Rect(0, 0, 20, 20)); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(render_text->FindCursorPosition(Point(0, 0)).caret_pos(), 0U); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(render_text->FindCursorPosition(Point(20, 0)).caret_pos(), 2U); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int x = -1; x <= 20; ++x) { 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SelectionModel selection = render_text->FindCursorPosition(Point(x, 0)); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(selection.caret_pos() == 0U || selection.caret_pos() == 2U); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // GetGlyphBounds() should yield the entire string bounds for text index 0. 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(render_text->GetStringSize().width(), 31290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) static_cast<int>(render_text->GetGlyphBounds(0U).length())); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cursoring is independent of underlying characters when text is obscured. 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t* const texts[] = { 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kWeak, kLtr, kLtrRtl, kLtrRtlLtr, kRtl, kRtlLtr, kRtlLtrRtl, 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) L"hop on pop", // Check LTR word boundaries. 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) L"\x05d0\x05d1 \x05d0\x05d2 \x05d1\x05d2", // Check RTL word boundaries. 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < arraysize(texts); ++i) { 321868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::string16 text = WideToUTF16(texts[i]); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestVisualCursorMotionInObscuredField(render_text.get(), text, false); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestVisualCursorMotionInObscuredField(render_text.get(), text, true); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 327868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_F(RenderTextTest, RevealObscuredText) { 328868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const base::string16 seuss = ASCIIToUTF16("hop on pop"); 329868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const base::string16 no_seuss = ASCIIToUTF16("**********"); 330868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 331868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 332868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) render_text->SetText(seuss); 333868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) render_text->SetObscured(true); 334868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ(seuss, render_text->text()); 335868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ(no_seuss, render_text->GetLayoutText()); 336868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 337868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Valid reveal index and new revealed index clears previous one. 338868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) render_text->RenderText::SetObscuredRevealIndex(0); 339868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ(ASCIIToUTF16("h*********"), render_text->GetLayoutText()); 340868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) render_text->RenderText::SetObscuredRevealIndex(1); 341868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ(ASCIIToUTF16("*o********"), render_text->GetLayoutText()); 342868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) render_text->RenderText::SetObscuredRevealIndex(2); 343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ(ASCIIToUTF16("**p*******"), render_text->GetLayoutText()); 344868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 345868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Invalid reveal index. 346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) render_text->RenderText::SetObscuredRevealIndex(-1); 347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ(no_seuss, render_text->GetLayoutText()); 348868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) render_text->RenderText::SetObscuredRevealIndex(seuss.length() + 1); 349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ(no_seuss, render_text->GetLayoutText()); 350868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 351868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // SetObscured clears the revealed index. 352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) render_text->RenderText::SetObscuredRevealIndex(0); 353868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ(ASCIIToUTF16("h*********"), render_text->GetLayoutText()); 354868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) render_text->SetObscured(false); 355868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ(seuss, render_text->GetLayoutText()); 356868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) render_text->SetObscured(true); 357868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ(no_seuss, render_text->GetLayoutText()); 358868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 359868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // SetText clears the revealed index. 360868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) render_text->SetText(ASCIIToUTF16("new")); 361868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ(ASCIIToUTF16("***"), render_text->GetLayoutText()); 362868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) render_text->RenderText::SetObscuredRevealIndex(2); 363868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ(ASCIIToUTF16("**w"), render_text->GetLayoutText()); 364868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) render_text->SetText(ASCIIToUTF16("new longer")); 365868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ(ASCIIToUTF16("**********"), render_text->GetLayoutText()); 366868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 367868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Text with invalid surrogates. 368868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const char16 invalid_surrogates[] = {0xDC00, 0xD800, 'h', 'o', 'p', 0}; 369868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) render_text->SetText(invalid_surrogates); 370868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ(ASCIIToUTF16("*****"), render_text->GetLayoutText()); 371868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) render_text->RenderText::SetObscuredRevealIndex(0); 372868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const char16 invalid_expect_0[] = {0xDC00, '*', '*', '*', '*', 0}; 373868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ(invalid_expect_0, render_text->GetLayoutText()); 374868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) render_text->RenderText::SetObscuredRevealIndex(1); 375868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const char16 invalid_expect_1[] = {'*', 0xD800, '*', '*', '*', 0}; 376868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ(invalid_expect_1, render_text->GetLayoutText()); 377868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) render_text->RenderText::SetObscuredRevealIndex(2); 378868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ(ASCIIToUTF16("**h**"), render_text->GetLayoutText()); 379868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 380868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Text with valid surrogates before and after the reveal index. 381868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const char16 valid_surrogates[] = 382868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) {0xD800, 0xDC00, 'h', 'o', 'p', 0xD800, 0xDC00, 0}; 383868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) render_text->SetText(valid_surrogates); 384868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ(ASCIIToUTF16("*****"), render_text->GetLayoutText()); 385868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) render_text->RenderText::SetObscuredRevealIndex(0); 386868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const char16 valid_expect_0_and_1[] = {0xD800, 0xDC00, '*', '*', '*', '*', 0}; 387868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ(valid_expect_0_and_1, render_text->GetLayoutText()); 388868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) render_text->RenderText::SetObscuredRevealIndex(1); 389868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ(valid_expect_0_and_1, render_text->GetLayoutText()); 390868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) render_text->RenderText::SetObscuredRevealIndex(2); 391868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ(ASCIIToUTF16("*h***"), render_text->GetLayoutText()); 392868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) render_text->RenderText::SetObscuredRevealIndex(5); 393868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const char16 valid_expect_5_and_6[] = {'*', '*', '*', '*', 0xD800, 0xDC00, 0}; 394868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ(valid_expect_5_and_6, render_text->GetLayoutText()); 395868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) render_text->RenderText::SetObscuredRevealIndex(6); 396868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ(valid_expect_5_and_6, render_text->GetLayoutText()); 397868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 398868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 399eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_F(RenderTextTest, TruncatedText) { 400eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch struct { 401eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const wchar_t* text; 402eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const wchar_t* layout_text; 403eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } cases[] = { 404eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Strings shorter than the truncation length should be laid out in full. 405eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { L"", L"" }, 406eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { kWeak, kWeak }, 407eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { kLtr, kLtr }, 408eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { kLtrRtl, kLtrRtl }, 409eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { kLtrRtlLtr, kLtrRtlLtr }, 410eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { kRtl, kRtl }, 411eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { kRtlLtr, kRtlLtr }, 412eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { kRtlLtrRtl, kRtlLtrRtl }, 413eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Strings as long as the truncation length should be laid out in full. 414eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { L"01234", L"01234" }, 415eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Long strings should be truncated with an ellipsis appended at the end. 416eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { L"012345", L"0123\x2026" }, 417558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch { L"012" L" . ", L"012 \x2026" }, 418558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch { L"012" L"abc", L"012a\x2026" }, 419558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch { L"012" L"a" L"\x5d0\x5d1", L"012a\x2026" }, 420558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch { L"012" L"a" L"\x5d1" L"b", L"012a\x2026" }, 421558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch { L"012" L"\x5d0\x5d1\x5d2", L"012\x5d0\x2026" }, 422558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch { L"012" L"\x5d0\x5d1" L"a", L"012\x5d0\x2026" }, 423558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch { L"012" L"\x5d0" L"a" L"\x5d1", L"012\x5d0\x2026" }, 424eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Surrogate pairs should be truncated reasonably enough. 425eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { L"0123\x0915\x093f", L"0123\x2026" }, 426eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { L"0\x05e9\x05bc\x05c1\x05b8", L"0\x05e9\x05bc\x05c1\x05b8" }, 427eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { L"01\x05e9\x05bc\x05c1\x05b8", L"01\x05e9\x05bc\x2026" }, 428eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { L"012\x05e9\x05bc\x05c1\x05b8", L"012\x05e9\x2026" }, 429eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { L"0123\x05e9\x05bc\x05c1\x05b8", L"0123\x2026" }, 430eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { L"01234\x05e9\x05bc\x05c1\x05b8", L"0123\x2026" }, 431eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch { L"012\xF0\x9D\x84\x9E", L"012\xF0\x2026" }, 432eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch }; 433eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 434eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 435eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch render_text->set_truncate_length(5); 436eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); i++) { 437eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch render_text->SetText(WideToUTF16(cases[i].text)); 438eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(WideToUTF16(cases[i].text), render_text->text()); 439eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(WideToUTF16(cases[i].layout_text), render_text->GetLayoutText()) 440eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch << "For case " << i << ": " << cases[i].text; 441eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 442eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 443eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 444eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_F(RenderTextTest, TruncatedObscuredText) { 445eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 446eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch render_text->set_truncate_length(3); 447eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch render_text->SetObscured(true); 448eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch render_text->SetText(WideToUTF16(L"abcdef")); 449eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(WideToUTF16(L"abcdef"), render_text->text()); 450eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(WideToUTF16(L"**\x2026"), render_text->GetLayoutText()); 451eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 452eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 453eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_F(RenderTextTest, TruncatedCursorMovementLTR) { 454eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 455eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch render_text->set_truncate_length(2); 456eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch render_text->SetText(WideToUTF16(L"abcd")); 457eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 458eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(SelectionModel(0, CURSOR_BACKWARD), render_text->selection_model()); 459eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch render_text->MoveCursor(LINE_BREAK, CURSOR_RIGHT, false); 460eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(SelectionModel(4, CURSOR_FORWARD), render_text->selection_model()); 461eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch render_text->MoveCursor(LINE_BREAK, CURSOR_LEFT, false); 462eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(SelectionModel(0, CURSOR_BACKWARD), render_text->selection_model()); 463eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 464eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::vector<SelectionModel> expected; 465eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 466eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch expected.push_back(SelectionModel(1, CURSOR_BACKWARD)); 467558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // The cursor hops over the ellipsis and elided text to the line end. 468558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch expected.push_back(SelectionModel(4, CURSOR_BACKWARD)); 469eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch expected.push_back(SelectionModel(4, CURSOR_FORWARD)); 470eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_RIGHT); 471eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 472eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch expected.clear(); 473eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch expected.push_back(SelectionModel(4, CURSOR_FORWARD)); 474eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // The cursor hops over the elided text to preceeding text. 475eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch expected.push_back(SelectionModel(1, CURSOR_FORWARD)); 476eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch expected.push_back(SelectionModel(0, CURSOR_FORWARD)); 477eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 478eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_LEFT); 479eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 480eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 481eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_F(RenderTextTest, TruncatedCursorMovementRTL) { 482eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 483eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch render_text->set_truncate_length(2); 484eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch render_text->SetText(WideToUTF16(L"\x5d0\x5d1\x5d2\x5d3")); 485eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 486eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(SelectionModel(0, CURSOR_BACKWARD), render_text->selection_model()); 487eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch render_text->MoveCursor(LINE_BREAK, CURSOR_LEFT, false); 488eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(SelectionModel(4, CURSOR_FORWARD), render_text->selection_model()); 489eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch render_text->MoveCursor(LINE_BREAK, CURSOR_RIGHT, false); 490eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch EXPECT_EQ(SelectionModel(0, CURSOR_BACKWARD), render_text->selection_model()); 491eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 492eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::vector<SelectionModel> expected; 493eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 494eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch expected.push_back(SelectionModel(1, CURSOR_BACKWARD)); 495558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // The cursor hops over the ellipsis and elided text to the line end. 496558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch expected.push_back(SelectionModel(4, CURSOR_BACKWARD)); 497eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch expected.push_back(SelectionModel(4, CURSOR_FORWARD)); 498eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_LEFT); 499eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 500eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch expected.clear(); 501eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch expected.push_back(SelectionModel(4, CURSOR_FORWARD)); 502eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // The cursor hops over the elided text to preceeding text. 503eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch expected.push_back(SelectionModel(1, CURSOR_FORWARD)); 504eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch expected.push_back(SelectionModel(0, CURSOR_FORWARD)); 505eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 506eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_RIGHT); 507eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 508eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, GetTextDirection) { 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct { 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t* text; 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::i18n::TextDirection text_direction; 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } cases[] = { 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Blank strings and those with no/weak directionality default to LTR. 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { L"", base::i18n::LEFT_TO_RIGHT }, 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kWeak, base::i18n::LEFT_TO_RIGHT }, 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Strings that begin with strong LTR characters. 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kLtr, base::i18n::LEFT_TO_RIGHT }, 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kLtrRtl, base::i18n::LEFT_TO_RIGHT }, 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kLtrRtlLtr, base::i18n::LEFT_TO_RIGHT }, 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Strings that begin with strong RTL characters. 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kRtl, base::i18n::RIGHT_TO_LEFT }, 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kRtlLtr, base::i18n::RIGHT_TO_LEFT }, 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kRtlLtrRtl, base::i18n::RIGHT_TO_LEFT }, 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool was_rtl = base::i18n::IsRTL(); 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < 2; ++i) { 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Toggle the application default text direction (to try each direction). 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetRTL(!base::i18n::IsRTL()); 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::i18n::TextDirection ui_direction = base::i18n::IsRTL() ? 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::i18n::RIGHT_TO_LEFT : base::i18n::LEFT_TO_RIGHT; 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that directionality modes yield the correct text directions. 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t j = 0; j < ARRAYSIZE_UNSAFE(cases); j++) { 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(WideToUTF16(cases[j].text)); 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDirectionalityMode(DIRECTIONALITY_FROM_TEXT); 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(render_text->GetTextDirection(), cases[j].text_direction); 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDirectionalityMode(DIRECTIONALITY_FROM_UI); 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(render_text->GetTextDirection(), ui_direction); 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDirectionalityMode(DIRECTIONALITY_FORCE_LTR); 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(render_text->GetTextDirection(), base::i18n::LEFT_TO_RIGHT); 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDirectionalityMode(DIRECTIONALITY_FORCE_RTL); 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(render_text->GetTextDirection(), base::i18n::RIGHT_TO_LEFT); 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(was_rtl, base::i18n::IsRTL()); 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that text changes update the direction for DIRECTIONALITY_FROM_TEXT. 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDirectionalityMode(DIRECTIONALITY_FROM_TEXT); 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(WideToUTF16(kLtr)); 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(render_text->GetTextDirection(), base::i18n::LEFT_TO_RIGHT); 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(WideToUTF16(kRtl)); 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(render_text->GetTextDirection(), base::i18n::RIGHT_TO_LEFT); 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, MoveCursorLeftRightInLtr) { 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Pure LTR. 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(ASCIIToUTF16("abc")); 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |expected| saves the expected SelectionModel when moving cursor from left 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to right. 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<SelectionModel> expected; 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(1, CURSOR_BACKWARD)); 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(2, CURSOR_BACKWARD)); 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(3, CURSOR_BACKWARD)); 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(3, CURSOR_FORWARD)); 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_RIGHT); 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.clear(); 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(3, CURSOR_FORWARD)); 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(2, CURSOR_FORWARD)); 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(1, CURSOR_FORWARD)); 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(0, CURSOR_FORWARD)); 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_LEFT); 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, MoveCursorLeftRightInLtrRtl) { 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // LTR-RTL 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(WideToUTF16(L"abc\x05d0\x05d1\x05d2")); 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The last one is the expected END position. 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<SelectionModel> expected; 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(1, CURSOR_BACKWARD)); 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(2, CURSOR_BACKWARD)); 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(3, CURSOR_BACKWARD)); 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(5, CURSOR_FORWARD)); 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(4, CURSOR_FORWARD)); 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(3, CURSOR_FORWARD)); 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(6, CURSOR_FORWARD)); 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_RIGHT); 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.clear(); 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(6, CURSOR_FORWARD)); 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(4, CURSOR_BACKWARD)); 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(5, CURSOR_BACKWARD)); 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(6, CURSOR_BACKWARD)); 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(2, CURSOR_FORWARD)); 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(1, CURSOR_FORWARD)); 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(0, CURSOR_FORWARD)); 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_LEFT); 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, MoveCursorLeftRightInLtrRtlLtr) { 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // LTR-RTL-LTR. 615558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch render_text->SetText(WideToUTF16(L"a" L"\x05d1" L"b")); 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<SelectionModel> expected; 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(1, CURSOR_BACKWARD)); 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(1, CURSOR_FORWARD)); 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(3, CURSOR_BACKWARD)); 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(3, CURSOR_FORWARD)); 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_RIGHT); 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.clear(); 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(3, CURSOR_FORWARD)); 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(2, CURSOR_FORWARD)); 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(2, CURSOR_BACKWARD)); 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(0, CURSOR_FORWARD)); 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_LEFT); 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, MoveCursorLeftRightInRtl) { 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Pure RTL. 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(WideToUTF16(L"\x05d0\x05d1\x05d2")); 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(LINE_BREAK, CURSOR_RIGHT, false); 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<SelectionModel> expected; 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(1, CURSOR_BACKWARD)); 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(2, CURSOR_BACKWARD)); 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(3, CURSOR_BACKWARD)); 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(3, CURSOR_FORWARD)); 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_LEFT); 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.clear(); 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(3, CURSOR_FORWARD)); 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(2, CURSOR_FORWARD)); 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(1, CURSOR_FORWARD)); 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(0, CURSOR_FORWARD)); 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_RIGHT); 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, MoveCursorLeftRightInRtlLtr) { 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // RTL-LTR 660558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch render_text->SetText(WideToUTF16(L"\x05d0\x05d1\x05d2" L"abc")); 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(LINE_BREAK, CURSOR_RIGHT, false); 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<SelectionModel> expected; 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(1, CURSOR_BACKWARD)); 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(2, CURSOR_BACKWARD)); 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(3, CURSOR_BACKWARD)); 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(5, CURSOR_FORWARD)); 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(4, CURSOR_FORWARD)); 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(3, CURSOR_FORWARD)); 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(6, CURSOR_FORWARD)); 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_LEFT); 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.clear(); 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(6, CURSOR_FORWARD)); 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(4, CURSOR_BACKWARD)); 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(5, CURSOR_BACKWARD)); 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(6, CURSOR_BACKWARD)); 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(2, CURSOR_FORWARD)); 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(1, CURSOR_FORWARD)); 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(0, CURSOR_FORWARD)); 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_RIGHT); 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, MoveCursorLeftRightInRtlLtrRtl) { 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // RTL-LTR-RTL. 688558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch render_text->SetText(WideToUTF16(L"\x05d0" L"a" L"\x05d1")); 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(LINE_BREAK, CURSOR_RIGHT, false); 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<SelectionModel> expected; 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(1, CURSOR_BACKWARD)); 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(1, CURSOR_FORWARD)); 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(3, CURSOR_BACKWARD)); 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(3, CURSOR_FORWARD)); 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_LEFT); 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.clear(); 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(3, CURSOR_FORWARD)); 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(2, CURSOR_FORWARD)); 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(2, CURSOR_BACKWARD)); 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(0, CURSOR_FORWARD)); 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_RIGHT); 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(xji): temporarily disable in platform Win since the complex script 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// characters turned into empty square due to font regression. So, not able 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to test 2 characters belong to the same grapheme. 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_LINUX) 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, MoveCursorLeftRight_ComplexScript) { 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(WideToUTF16(L"\x0915\x093f\x0915\x094d\x0915")); 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0U, render_text->cursor_position()); 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, false); 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(2U, render_text->cursor_position()); 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, false); 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(4U, render_text->cursor_position()); 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, false); 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(5U, render_text->cursor_position()); 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, false); 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(5U, render_text->cursor_position()); 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, false); 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(4U, render_text->cursor_position()); 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, false); 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(2U, render_text->cursor_position()); 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, false); 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0U, render_text->cursor_position()); 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, false); 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0U, render_text->cursor_position()); 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(RenderTextTest, MoveCursorLeftRight_MeiryoUILigatures) { 7377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 7387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Meiryo UI uses single-glyph ligatures for 'ff' and 'ffi', but each letter 7397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // (code point) has unique bounds, so mid-glyph cursoring should be possible. 7407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) render_text->SetFont(Font("Meiryo UI", 12)); 7417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) render_text->SetText(WideToUTF16(L"ff ffi")); 7427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_EQ(0U, render_text->cursor_position()); 7437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) for (size_t i = 0; i < render_text->text().length(); ++i) { 7447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, false); 7457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_EQ(i + 1, render_text->cursor_position()); 7467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 7477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_EQ(6U, render_text->cursor_position()); 7487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 7497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, GraphemePositions) { 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // LTR 2-character grapheme, LTR abc, LTR 2-character grapheme. 752868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const base::string16 kText1 = 753558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch WideToUTF16(L"\x0915\x093f" L"abc" L"\x0915\x093f"); 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // LTR ab, LTR 2-character grapheme, LTR cd. 756558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch const base::string16 kText2 = WideToUTF16(L"ab" L"\x0915\x093f" L"cd"); 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The below is 'MUSICAL SYMBOL G CLEF', which is represented in UTF-16 as 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // two characters forming the surrogate pair 0x0001D11E. 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string kSurrogate = "\xF0\x9D\x84\x9E"; 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // LTR ab, UTF16 surrogate pair, LTR cd. 763868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const base::string16 kText3 = UTF8ToUTF16("ab" + kSurrogate + "cd"); 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct { 766868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::string16 text; 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t index; 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t expected_previous; 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t expected_next; 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } cases[] = { 771868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) { base::string16(), 0, 0, 0 }, 772868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) { base::string16(), 1, 0, 0 }, 773868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) { base::string16(), 50, 0, 0 }, 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText1, 0, 0, 2 }, 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText1, 1, 0, 2 }, 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText1, 2, 0, 3 }, 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText1, 3, 2, 4 }, 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText1, 4, 3, 5 }, 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText1, 5, 4, 7 }, 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText1, 6, 5, 7 }, 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText1, 7, 5, 7 }, 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText1, 8, 7, 7 }, 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText1, 50, 7, 7 }, 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText2, 0, 0, 1 }, 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText2, 1, 0, 2 }, 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText2, 2, 1, 4 }, 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText2, 3, 2, 4 }, 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText2, 4, 2, 5 }, 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText2, 5, 4, 6 }, 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText2, 6, 5, 6 }, 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText2, 7, 6, 6 }, 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText2, 50, 6, 6 }, 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText3, 0, 0, 1 }, 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText3, 1, 0, 2 }, 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText3, 2, 1, 4 }, 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText3, 3, 2, 4 }, 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText3, 4, 2, 5 }, 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText3, 5, 4, 6 }, 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText3, 6, 5, 6 }, 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText3, 7, 6, 6 }, 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText3, 50, 6, 6 }, 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(asvitkine): Disable tests that fail on XP bots due to lack of complete 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // font support for some scripts - http://crbug.com/106450 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base::win::GetVersion() < base::win::VERSION_VISTA) 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); i++) { 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(cases[i].text); 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t next = render_text->IndexOfAdjacentGrapheme(cases[i].index, 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CURSOR_FORWARD); 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(cases[i].expected_next, next); 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(render_text->IsCursorablePosition(next)); 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t previous = render_text->IndexOfAdjacentGrapheme(cases[i].index, 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CURSOR_BACKWARD); 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(cases[i].expected_previous, previous); 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(render_text->IsCursorablePosition(previous)); 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, EdgeSelectionModels) { 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Simple Latin text. 829868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const base::string16 kLatin = WideToUTF16(L"abc"); 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // LTR 2-character grapheme. 831868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const base::string16 kLTRGrapheme = WideToUTF16(L"\x0915\x093f"); 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // LTR 2-character grapheme, LTR a, LTR 2-character grapheme. 833868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const base::string16 kHindiLatin = 834558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch WideToUTF16(L"\x0915\x093f" L"a" L"\x0915\x093f"); 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // RTL 2-character grapheme. 836868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const base::string16 kRTLGrapheme = WideToUTF16(L"\x05e0\x05b8"); 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // RTL 2-character grapheme, LTR a, RTL 2-character grapheme. 838868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const base::string16 kHebrewLatin = 839558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch WideToUTF16(L"\x05e0\x05b8" L"a" L"\x05e0\x05b8"); 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct { 842868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::string16 text; 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::i18n::TextDirection expected_text_direction; 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } cases[] = { 845868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) { base::string16(), base::i18n::LEFT_TO_RIGHT }, 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kLatin, base::i18n::LEFT_TO_RIGHT }, 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kLTRGrapheme, base::i18n::LEFT_TO_RIGHT }, 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kHindiLatin, base::i18n::LEFT_TO_RIGHT }, 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kRTLGrapheme, base::i18n::RIGHT_TO_LEFT }, 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kHebrewLatin, base::i18n::RIGHT_TO_LEFT }, 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(asvitkine): Disable tests that fail on XP bots due to lack of complete 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // font support for some scripts - http://crbug.com/106450 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base::win::GetVersion() < base::win::VERSION_VISTA) 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); i++) { 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(cases[i].text); 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ltr = (cases[i].expected_text_direction == base::i18n::LEFT_TO_RIGHT); 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SelectionModel start_edge = 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->EdgeSelectionModel(ltr ? CURSOR_LEFT : CURSOR_RIGHT); 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(start_edge, SelectionModel(0, CURSOR_BACKWARD)); 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SelectionModel end_edge = 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->EdgeSelectionModel(ltr ? CURSOR_RIGHT : CURSOR_LEFT); 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(end_edge, SelectionModel(cases[i].text.length(), CURSOR_FORWARD)); 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, SelectAll) { 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t* const cases[] = 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kWeak, kLtr, kLtrRtl, kLtrRtlLtr, kRtl, kRtlLtr, kRtlLtrRtl }; 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that SelectAll respects the |reversed| argument regardless of 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // application locale and text content directionality. 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 882d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const SelectionModel expected_reversed(Range(3, 0), CURSOR_FORWARD); 883d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const SelectionModel expected_forwards(Range(0, 3), CURSOR_BACKWARD); 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool was_rtl = base::i18n::IsRTL(); 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < 2; ++i) { 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetRTL(!base::i18n::IsRTL()); 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test that an empty string produces an empty selection model. 889868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) render_text->SetText(base::string16()); 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(render_text->selection_model(), SelectionModel()); 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test the weak, LTR, RTL, and Bidi string cases. 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t j = 0; j < ARRAYSIZE_UNSAFE(cases); j++) { 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(WideToUTF16(cases[j])); 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SelectAll(false); 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(render_text->selection_model(), expected_forwards); 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SelectAll(true); 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(render_text->selection_model(), expected_reversed); 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(was_rtl, base::i18n::IsRTL()); 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TEST_F(RenderTextTest, MoveCursorLeftRightWithSelection) { 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(WideToUTF16(L"abc\x05d0\x05d1\x05d2")); 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Left arrow on select ranging (6, 4). 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(LINE_BREAK, CURSOR_RIGHT, false); 910d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(Range(6), render_text->selection()); 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, false); 912d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(Range(4), render_text->selection()); 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, false); 914d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(Range(5), render_text->selection()); 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, false); 916d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(Range(6), render_text->selection()); 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, true); 918d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(Range(6, 5), render_text->selection()); 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, true); 920d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(Range(6, 4), render_text->selection()); 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, false); 922d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(Range(6), render_text->selection()); 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Right arrow on select ranging (4, 6). 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(LINE_BREAK, CURSOR_LEFT, false); 926d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(Range(0), render_text->selection()); 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, false); 928d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(Range(1), render_text->selection()); 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, false); 930d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(Range(2), render_text->selection()); 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, false); 932d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(Range(3), render_text->selection()); 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, false); 934d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(Range(5), render_text->selection()); 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, false); 936d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(Range(4), render_text->selection()); 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, true); 938d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(Range(4, 5), render_text->selection()); 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, true); 940d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(Range(4, 6), render_text->selection()); 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, false); 942d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(Range(4), render_text->selection()); 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // !defined(OS_MACOSX) 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(xji): Make these work on Windows. 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_LINUX) 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MoveLeftRightByWordVerifier(RenderText* render_text, 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t* str) { 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(WideToUTF16(str)); 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test moving by word from left ro right. 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(LINE_BREAK, CURSOR_LEFT, false); 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool first_word = true; 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (true) { 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First, test moving by word from a word break position, such as from 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // "|abc def" to "abc| def". 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SelectionModel start = render_text->selection_model(); 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, false); 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SelectionModel end = render_text->selection_model(); 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (end == start) // reach the end. 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For testing simplicity, each word is a 3-character word. 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_of_character_moves = first_word ? 3 : 4; 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first_word = false; 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursorTo(start); 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = 0; j < num_of_character_moves; ++j) 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, false); 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(end, render_text->selection_model()); 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Then, test moving by word from positions inside the word, such as from 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // "a|bc def" to "abc| def", and from "ab|c def" to "abc| def". 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = 1; j < num_of_character_moves; ++j) { 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursorTo(start); 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int k = 0; k < j; ++k) 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, false); 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, false); 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(end, render_text->selection_model()); 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test moving by word from right to left. 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(LINE_BREAK, CURSOR_RIGHT, false); 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first_word = true; 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (true) { 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SelectionModel start = render_text->selection_model(); 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(WORD_BREAK, CURSOR_LEFT, false); 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SelectionModel end = render_text->selection_model(); 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (end == start) // reach the end. 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_of_character_moves = first_word ? 3 : 4; 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first_word = false; 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursorTo(start); 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = 0; j < num_of_character_moves; ++j) 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, false); 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(end, render_text->selection_model()); 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = 1; j < num_of_character_moves; ++j) { 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursorTo(start); 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int k = 0; k < j; ++k) 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, false); 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(WORD_BREAK, CURSOR_LEFT, false); 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(end, render_text->selection_model()); 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, MoveLeftRightByWordInBidiText) { 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For testing simplicity, each word is a 3-character word. 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<const wchar_t*> test; 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test.push_back(L"abc"); 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test.push_back(L"abc def"); 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test.push_back(L"\x05E1\x05E2\x05E3"); 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test.push_back(L"\x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6"); 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test.push_back(L"abc \x05E1\x05E2\x05E3"); 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test.push_back(L"abc def \x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6"); 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test.push_back(L"abc def hij \x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6" 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) L" \x05E7\x05E8\x05E9"); 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test.push_back(L"abc \x05E1\x05E2\x05E3 hij"); 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test.push_back(L"abc def \x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6 hij opq"); 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test.push_back(L"abc def hij \x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6" 1027558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch L" \x05E7\x05E8\x05E9" L" opq rst uvw"); 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test.push_back(L"\x05E1\x05E2\x05E3 abc"); 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test.push_back(L"\x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6 abc def"); 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test.push_back(L"\x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6 \x05E7\x05E8\x05E9" 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) L" abc def hij"); 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test.push_back(L"\x05D1\x05D2\x05D3 abc \x05E1\x05E2\x05E3"); 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test.push_back(L"\x05D1\x05D2\x05D3 \x05D4\x05D5\x05D6 abc def" 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) L" \x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6"); 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test.push_back(L"\x05D1\x05D2\x05D3 \x05D4\x05D5\x05D6 \x05D7\x05D8\x05D9" 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) L" abc def hij \x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6" 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) L" \x05E7\x05E8\x05E9"); 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < test.size(); ++i) 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MoveLeftRightByWordVerifier(render_text.get(), test[i]); 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, MoveLeftRightByWordInBidiText_TestEndOfText) { 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(WideToUTF16(L"ab\x05E1")); 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Moving the cursor by word from "abC|" to the left should return "|abC". 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // But since end of text is always treated as a word break, it returns 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // position "ab|C". 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(xji): Need to make it work as expected. 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(LINE_BREAK, CURSOR_RIGHT, false); 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(WORD_BREAK, CURSOR_LEFT, false); 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // EXPECT_EQ(SelectionModel(), render_text->selection_model()); 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Moving the cursor by word from "|abC" to the right returns "abC|". 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(LINE_BREAK, CURSOR_LEFT, false); 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, false); 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(SelectionModel(3, CURSOR_FORWARD), render_text->selection_model()); 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1062558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch render_text->SetText(WideToUTF16(L"\x05E1\x05E2" L"a")); 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For logical text "BCa", moving the cursor by word from "aCB|" to the left 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // returns "|aCB". 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(LINE_BREAK, CURSOR_RIGHT, false); 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(WORD_BREAK, CURSOR_LEFT, false); 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(SelectionModel(3, CURSOR_FORWARD), render_text->selection_model()); 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Moving the cursor by word from "|aCB" to the right should return "aCB|". 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // But since end of text is always treated as a word break, it returns 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // position "a|CB". 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(xji): Need to make it work as expected. 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(LINE_BREAK, CURSOR_LEFT, false); 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, false); 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // EXPECT_EQ(SelectionModel(), render_text->selection_model()); 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, MoveLeftRightByWordInTextWithMultiSpaces) { 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(WideToUTF16(L"abc def")); 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursorTo(SelectionModel(5, CURSOR_FORWARD)); 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, false); 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(11U, render_text->cursor_position()); 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursorTo(SelectionModel(5, CURSOR_FORWARD)); 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(WORD_BREAK, CURSOR_LEFT, false); 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0U, render_text->cursor_position()); 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, MoveLeftRightByWordInChineseText) { 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(WideToUTF16(L"\x6211\x4EEC\x53BB\x516C\x56ED\x73A9")); 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(LINE_BREAK, CURSOR_LEFT, false); 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0U, render_text->cursor_position()); 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, false); 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(2U, render_text->cursor_position()); 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, false); 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(3U, render_text->cursor_position()); 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, false); 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(5U, render_text->cursor_position()); 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, false); 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(6U, render_text->cursor_position()); 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, false); 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(6U, render_text->cursor_position()); 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1108558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#if defined(OS_WIN) 1109558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_F(RenderTextTest, Win_LogicalClusters) { 1110558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch scoped_ptr<RenderTextWin> render_text( 1111558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch static_cast<RenderTextWin*>(RenderText::CreateInstance())); 1112558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 1113558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch const base::string16 test_string = 1114558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch WideToUTF16(L"\x0930\x0930\x0930\x0930\x0930"); 1115558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch render_text->SetText(test_string); 1116558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch render_text->EnsureLayout(); 1117558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch ASSERT_EQ(1U, render_text->runs_.size()); 1118558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch WORD* logical_clusters = render_text->runs_[0]->logical_clusters.get(); 1119558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch for (size_t i = 0; i < test_string.length(); ++i) 1120558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch EXPECT_EQ(i, logical_clusters[i]); 1121558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 1122558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#endif // defined(OS_WIN) 1123558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, StringSizeSanity) { 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(UTF8ToUTF16("Hello World")); 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Size string_size = render_text->GetStringSize(); 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GT(string_size.width(), 0); 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GT(string_size.height(), 0); 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(asvitkine): This test fails because PlatformFontMac uses point font 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// sizes instead of pixel sizes like other implementations. 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_MACOSX) 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, StringSizeEmptyString) { 1136a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Ascent and descent of Arial and Symbol are different on most platforms. 1137a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const FontList font_list("Arial,Symbol, 16px"); 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 1139a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) render_text->SetFontList(font_list); 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1141a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // The empty string respects FontList metrics for non-zero height 1142a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // and baseline. 1143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) render_text->SetText(base::string16()); 1144a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(font_list.GetHeight(), render_text->GetStringSize().height()); 11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, render_text->GetStringSize().width()); 1146a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(font_list.GetBaseline(), render_text->GetBaseline()); 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(UTF8ToUTF16(" ")); 1149a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(font_list.GetHeight(), render_text->GetStringSize().height()); 1150a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(font_list.GetBaseline(), render_text->GetBaseline()); 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // !defined(OS_MACOSX) 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1154a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(RenderTextTest, StringSizeRespectsFontListMetrics) { 1155a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Check that Arial and Symbol have different font metrics. 1156a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Font arial_font("Arial", 16); 1157a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Font symbol_font("Symbol", 16); 1158a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_NE(arial_font.GetHeight(), symbol_font.GetHeight()); 1159a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_NE(arial_font.GetBaseline(), symbol_font.GetBaseline()); 1160a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // "a" should be rendered with Arial, not with Symbol. 1161a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const char* arial_font_text = "a"; 1162a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // "®" (registered trademark symbol) should be rendered with Symbol, 1163a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // not with Arial. 1164a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const char* symbol_font_text = "\xC2\xAE"; 1165a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1166a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Font smaller_font = arial_font; 1167a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Font larger_font = symbol_font; 1168a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const char* smaller_font_text = arial_font_text; 1169a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const char* larger_font_text = symbol_font_text; 1170a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (symbol_font.GetHeight() < arial_font.GetHeight() && 1171a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) symbol_font.GetBaseline() < arial_font.GetBaseline()) { 1172a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::swap(smaller_font, larger_font); 1173a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::swap(smaller_font_text, larger_font_text); 1174a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1175a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_LT(smaller_font.GetHeight(), larger_font.GetHeight()); 1176a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_LT(smaller_font.GetBaseline(), larger_font.GetBaseline()); 1177a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1178a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Check |smaller_font_text| is rendered with the smaller font. 1179a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 1180a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) render_text->SetText(UTF8ToUTF16(smaller_font_text)); 1181a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) render_text->SetFont(smaller_font); 1182a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(smaller_font.GetHeight(), render_text->GetStringSize().height()); 1183a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(smaller_font.GetBaseline(), render_text->GetBaseline()); 1184a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1185a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Layout the same text with mixed fonts. The text should be rendered with 1186a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // the smaller font, but the height and baseline are determined with the 1187a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // metrics of the font list, which is equal to the larger font. 1188a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::vector<Font> fonts; 1189a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) fonts.push_back(smaller_font); // The primary font is the smaller font. 1190a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) fonts.push_back(larger_font); 1191a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const FontList font_list(fonts); 1192a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) render_text->SetFontList(font_list); 1193a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_LT(smaller_font.GetHeight(), render_text->GetStringSize().height()); 1194a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_LT(smaller_font.GetBaseline(), render_text->GetBaseline()); 1195a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(font_list.GetHeight(), render_text->GetStringSize().height()); 1196a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(font_list.GetBaseline(), render_text->GetBaseline()); 1197a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1198a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, SetFont) { 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetFont(Font("Arial", 12)); 1202a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ("Arial", render_text->GetPrimaryFont().GetFontName()); 1203a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(12, render_text->GetPrimaryFont().GetFontSize()); 1204a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1205a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1206a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(RenderTextTest, SetFontList) { 1207a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 1208a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) render_text->SetFontList(FontList("Arial,Symbol, 13px")); 1209a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::vector<Font>& fonts = render_text->font_list().GetFonts(); 1210a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ASSERT_EQ(2U, fonts.size()); 1211a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ("Arial", fonts[0].GetFontName()); 1212a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ("Symbol", fonts[1].GetFontName()); 1213a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(13, render_text->GetPrimaryFont().GetFontSize()); 12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, StringSizeBoldWidth) { 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(UTF8ToUTF16("Hello World")); 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int plain_width = render_text->GetStringSize().width(); 12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GT(plain_width, 0); 12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Apply a bold style and check that the new width is greater. 12247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) render_text->SetStyle(BOLD, true); 12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int bold_width = render_text->GetStringSize().width(); 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GT(bold_width, plain_width); 12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now, apply a plain style over the first word only. 1229d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) render_text->ApplyStyle(BOLD, false, Range(0, 5)); 12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int plain_bold_width = render_text->GetStringSize().width(); 12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GT(plain_bold_width, plain_width); 12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_LT(plain_bold_width, bold_width); 12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, StringSizeHeight) { 1236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::string16 cases[] = { 12372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WideToUTF16(L"Hello World!"), // English 12382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WideToUTF16(L"\x6328\x62f6"), // Japanese 12392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WideToUTF16(L"\x0915\x093f"), // Hindi 12402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WideToUTF16(L"\x05e0\x05b8"), // Hebrew 12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Font default_font; 12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Font larger_font = default_font.DeriveFont(24, default_font.GetStyle()); 12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GT(larger_font.GetHeight(), default_font.GetHeight()); 12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); i++) { 12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetFont(default_font); 12502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->SetText(cases[i]); 12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int height1 = render_text->GetStringSize().height(); 12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GT(height1, 0); 12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check that setting the larger font increases the height. 12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetFont(larger_font); 12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int height2 = render_text->GetStringSize().height(); 12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GT(height2, height1); 12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, GetBaselineSanity) { 12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(UTF8ToUTF16("Hello World")); 12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int baseline = render_text->GetBaseline(); 12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GT(baseline, 0); 12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, CursorBoundsInReplacementMode) { 12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(ASCIIToUTF16("abcdefg")); 12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(Rect(100, 17)); 12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SelectionModel sel_b(1, CURSOR_FORWARD); 12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SelectionModel sel_c(2, CURSOR_FORWARD); 12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Rect cursor_around_b = render_text->GetCursorBounds(sel_b, false); 12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Rect cursor_before_b = render_text->GetCursorBounds(sel_b, true); 12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Rect cursor_before_c = render_text->GetCursorBounds(sel_c, true); 12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(cursor_around_b.x(), cursor_before_b.x()); 12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(cursor_around_b.right(), cursor_before_c.x()); 12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 128290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TEST_F(RenderTextTest, GetTextOffset) { 128390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // The default horizontal text offset differs for LTR and RTL, and is only set 128490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // when the RenderText object is created. This test will check the default in 128590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // LTR mode, and the next test will check the RTL default. 128690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const bool was_rtl = base::i18n::IsRTL(); 128790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetRTL(false); 12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(ASCIIToUTF16("abcdefg")); 12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetFontList(FontList("Arial, 13px")); 12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 129290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Set display area's size equal to the font size. 12937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const Size font_size(render_text->GetContentWidth(), 12947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) render_text->GetStringSize().height()); 129590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Rect display_rect(font_size); 12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(display_rect); 12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1298d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Vector2d offset = render_text->GetLineOffset(0); 12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(offset.IsZero()); 13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 130190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Set display area's size greater than font size. 13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kEnlargement = 2; 130390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) display_rect.Inset(0, 0, -kEnlargement, -kEnlargement); 13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(display_rect); 13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 130690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Check the default horizontal and vertical alignment. 1307d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) offset = render_text->GetLineOffset(0); 130890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(kEnlargement / 2, offset.y()); 130990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(0, offset.x()); 131090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 131190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Check explicitly setting the horizontal alignment. 131290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) render_text->SetHorizontalAlignment(ALIGN_LEFT); 1313d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) offset = render_text->GetLineOffset(0); 131490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(0, offset.x()); 131590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) render_text->SetHorizontalAlignment(ALIGN_CENTER); 1316d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) offset = render_text->GetLineOffset(0); 131790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(kEnlargement / 2, offset.x()); 131890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) render_text->SetHorizontalAlignment(ALIGN_RIGHT); 1319d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) offset = render_text->GetLineOffset(0); 132090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(kEnlargement, offset.x()); 132190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 132290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Check explicitly setting the vertical alignment. 132390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) render_text->SetVerticalAlignment(ALIGN_TOP); 1324d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) offset = render_text->GetLineOffset(0); 132590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(0, offset.y()); 132690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) render_text->SetVerticalAlignment(ALIGN_VCENTER); 1327d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) offset = render_text->GetLineOffset(0); 132890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(kEnlargement / 2, offset.y()); 132990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) render_text->SetVerticalAlignment(ALIGN_BOTTOM); 1330d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) offset = render_text->GetLineOffset(0); 133190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(kEnlargement, offset.y()); 133290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 133390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetRTL(was_rtl); 133490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 133590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 133690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TEST_F(RenderTextTest, GetTextOffsetHorizontalDefaultInRTL) { 133790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // This only checks the default horizontal alignment in RTL mode; all other 1338d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // GetLineOffset(0) attributes are checked by the test above. 133990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const bool was_rtl = base::i18n::IsRTL(); 134090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetRTL(true); 134190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 134290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) render_text->SetText(ASCIIToUTF16("abcdefg")); 134390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) render_text->SetFontList(FontList("Arial, 13px")); 134490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const int kEnlargement = 2; 13457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const Size font_size(render_text->GetContentWidth() + kEnlargement, 13467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) render_text->GetStringSize().height()); 134790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Rect display_rect(font_size); 134890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) render_text->SetDisplayRect(display_rect); 1349d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Vector2d offset = render_text->GetLineOffset(0); 135090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(kEnlargement, offset.x()); 135190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetRTL(was_rtl); 13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, SameFontForParentheses) { 13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct { 13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char16 left_char; 13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char16 right_char; 13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } punctuation_pairs[] = { 13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { '(', ')' }, 13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { '{', '}' }, 13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { '<', '>' }, 13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct { 1364868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::string16 text; 13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } cases[] = { 13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // English(English) 13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { WideToUTF16(L"Hello World(a)") }, 13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // English(English)English 13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { WideToUTF16(L"Hello World(a)Hello World") }, 13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Japanese(English) 13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { WideToUTF16(L"\x6328\x62f6(a)") }, 13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Japanese(English)Japanese 13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { WideToUTF16(L"\x6328\x62f6(a)\x6328\x62f6") }, 13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // English(Japanese)English 13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { WideToUTF16(L"Hello World(\x6328\x62f6)Hello World") }, 13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Hindi(English) 13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { WideToUTF16(L"\x0915\x093f(a)") }, 13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Hindi(English)Hindi 13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { WideToUTF16(L"\x0915\x093f(a)\x0915\x093f") }, 13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // English(Hindi)English 13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { WideToUTF16(L"Hello World(\x0915\x093f)Hello World") }, 13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Hebrew(English) 13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { WideToUTF16(L"\x05e0\x05b8(a)") }, 13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Hebrew(English)Hebrew 13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { WideToUTF16(L"\x05e0\x05b8(a)\x05e0\x05b8") }, 13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // English(Hebrew)English 13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { WideToUTF16(L"Hello World(\x05e0\x05b8)Hello World") }, 13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { 1395868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::string16 text = cases[i].text; 13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t start_paren_char_index = text.find('('); 1397868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASSERT_NE(base::string16::npos, start_paren_char_index); 13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t end_paren_char_index = text.find(')'); 1399868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASSERT_NE(base::string16::npos, end_paren_char_index); 14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t j = 0; j < ARRAYSIZE_UNSAFE(punctuation_pairs); ++j) { 14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) text[start_paren_char_index] = punctuation_pairs[j].left_char; 14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) text[end_paren_char_index] = punctuation_pairs[j].right_char; 14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(text); 14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<RenderText::FontSpan> spans = 14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->GetFontSpansForTesting(); 14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int start_paren_span_index = -1; 14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int end_paren_span_index = -1; 14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t k = 0; k < spans.size(); ++k) { 14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IndexInRange(spans[k].second, start_paren_char_index)) 14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_paren_span_index = k; 14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IndexInRange(spans[k].second, end_paren_char_index)) 14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end_paren_span_index = k; 14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NE(-1, start_paren_span_index); 14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NE(-1, end_paren_span_index); 14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Font& start_font = spans[start_paren_span_index].first; 14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Font& end_font = spans[end_paren_span_index].first; 14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(start_font.GetFontName(), end_font.GetFontName()); 14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(start_font.GetFontSize(), end_font.GetFontSize()); 14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(start_font.GetStyle(), end_font.GetStyle()); 14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Make sure the caret width is always >=1 so that the correct 14302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// caret is drawn at high DPI. crbug.com/164100. 14312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(RenderTextTest, CaretWidth) { 14322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 14332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->SetText(ASCIIToUTF16("abcdefg")); 14342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_GE(render_text->GetUpdatedCursorBounds().width(), 1); 14352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 14362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1437a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TEST_F(RenderTextTest, SelectWord) { 1438a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 1439a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) render_text->SetText(ASCIIToUTF16(" foo a.bc.d bar")); 1440a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1441a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) struct { 1442a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) size_t cursor; 1443a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) size_t selection_start; 1444a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) size_t selection_end; 1445a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } cases[] = { 1446a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) { 0, 0, 1 }, 1447a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) { 1, 1, 4 }, 1448a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) { 2, 1, 4 }, 1449a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) { 3, 1, 4 }, 1450a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) { 4, 4, 6 }, 1451a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) { 5, 4, 6 }, 1452a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) { 6, 6, 7 }, 1453a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) { 7, 7, 8 }, 1454a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) { 8, 8, 10 }, 1455a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) { 9, 8, 10 }, 1456a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) { 10, 10, 11 }, 1457a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) { 11, 11, 12 }, 1458a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) { 12, 12, 13 }, 1459a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) { 13, 13, 16 }, 1460a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) { 14, 13, 16 }, 1461a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) { 15, 13, 16 }, 1462a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) { 16, 13, 16 }, 1463a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) }; 1464a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1465a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { 1466a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) render_text->SetCursorPosition(cases[i].cursor); 1467a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) render_text->SelectWord(); 1468d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(Range(cases[i].selection_start, cases[i].selection_end), 1469a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) render_text->selection()); 1470a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1471a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 1472a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Make sure the last word is selected when the cursor is at text.length(). 1474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(RenderTextTest, LastWordSelected) { 1475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string kTestURL1 = "http://www.google.com"; 1476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string kTestURL2 = "http://www.google.com/something/"; 1477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 1479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) render_text->SetText(ASCIIToUTF16(kTestURL1)); 1481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) render_text->SetCursorPosition(kTestURL1.length()); 1482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) render_text->SelectWord(); 1483a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(ASCIIToUTF16("com"), GetSelectedText(render_text.get())); 1484a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_FALSE(render_text->selection().is_reversed()); 1485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) render_text->SetText(ASCIIToUTF16(kTestURL2)); 1487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) render_text->SetCursorPosition(kTestURL2.length()); 1488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) render_text->SelectWord(); 1489a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(ASCIIToUTF16("/"), GetSelectedText(render_text.get())); 1490a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_FALSE(render_text->selection().is_reversed()); 1491a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 1492a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 1493a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// When given a non-empty selection, SelectWord should expand the selection to 1494a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// nearest word boundaries. 1495a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)TEST_F(RenderTextTest, SelectMultipleWords) { 1496a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const std::string kTestURL = "http://www.google.com"; 1497a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 1498a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 1499a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 1500a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) render_text->SetText(ASCIIToUTF16(kTestURL)); 1501d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) render_text->SelectRange(Range(16, 20)); 1502a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) render_text->SelectWord(); 1503a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(ASCIIToUTF16("google.com"), GetSelectedText(render_text.get())); 1504a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_FALSE(render_text->selection().is_reversed()); 1505a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 1506a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // SelectWord should preserve the selection direction. 1507d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) render_text->SelectRange(Range(20, 16)); 1508a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) render_text->SelectWord(); 1509a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(ASCIIToUTF16("google.com"), GetSelectedText(render_text.get())); 1510a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_TRUE(render_text->selection().is_reversed()); 1511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(asvitkine): Cursor movements tests disabled on Mac because RenderTextMac 15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// does not implement this yet. http://crbug.com/131618 15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_MACOSX) 15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, DisplayRectShowsCursorLTR) { 15172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_FALSE(base::i18n::IsRTL()); 15182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_FALSE(base::i18n::ICUIsRTL()); 15192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(WideToUTF16(L"abcdefghijklmnopqrstuvwxzyabcdefg")); 15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursorTo(SelectionModel(render_text->text().length(), 15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CURSOR_FORWARD)); 15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int width = render_text->GetStringSize().width(); 15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_GT(width, 10); 15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that the cursor is placed at the width of its preceding text. 15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(Rect(width + 10, 1)); 15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(width, render_text->GetUpdatedCursorBounds().x()); 15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that shrinking the display rectangle keeps the cursor in view. 15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(Rect(width - 10, 1)); 1533a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(render_text->display_rect().width(), 15342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->GetUpdatedCursorBounds().right()); 15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that the text will pan to fill its expanding display rectangle. 15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(Rect(width - 5, 1)); 1538a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(render_text->display_rect().width(), 1539a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) render_text->GetUpdatedCursorBounds().right()); 15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that a sufficiently large display rectangle shows all the text. 15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(Rect(width + 10, 1)); 15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(width, render_text->GetUpdatedCursorBounds().x()); 15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Repeat the test with RTL text. 15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(WideToUTF16(L"\x5d0\x5d1\x5d2\x5d3\x5d4\x5d5\x5d6\x5d7" 15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) L"\x5d8\x5d9\x5da\x5db\x5dc\x5dd\x5de\x5df")); 15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursorTo(SelectionModel(0, CURSOR_FORWARD)); 15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) width = render_text->GetStringSize().width(); 15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_GT(width, 10); 15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that the cursor is placed at the width of its preceding text. 15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(Rect(width + 10, 1)); 15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(width, render_text->GetUpdatedCursorBounds().x()); 15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that shrinking the display rectangle keeps the cursor in view. 15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(Rect(width - 10, 1)); 1558a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(render_text->display_rect().width(), 15592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->GetUpdatedCursorBounds().right()); 15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that the text will pan to fill its expanding display rectangle. 15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(Rect(width - 5, 1)); 1563a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(render_text->display_rect().width(), 1564a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) render_text->GetUpdatedCursorBounds().right()); 15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that a sufficiently large display rectangle shows all the text. 15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(Rect(width + 10, 1)); 15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(width, render_text->GetUpdatedCursorBounds().x()); 15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, DisplayRectShowsCursorRTL) { 15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set the application default text direction to RTL. 15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool was_rtl = base::i18n::IsRTL(); 15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetRTL(true); 15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(WideToUTF16(L"abcdefghijklmnopqrstuvwxzyabcdefg")); 15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursorTo(SelectionModel(0, CURSOR_FORWARD)); 15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int width = render_text->GetStringSize().width(); 15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_GT(width, 10); 15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that the cursor is placed at the width of its preceding text. 15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(Rect(width + 10, 1)); 15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(render_text->display_rect().width() - width - 1, 15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->GetUpdatedCursorBounds().x()); 15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that shrinking the display rectangle keeps the cursor in view. 15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(Rect(width - 10, 1)); 15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, render_text->GetUpdatedCursorBounds().x()); 15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that the text will pan to fill its expanding display rectangle. 15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(Rect(width - 5, 1)); 15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, render_text->GetUpdatedCursorBounds().x()); 15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that a sufficiently large display rectangle shows all the text. 15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(Rect(width + 10, 1)); 15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(render_text->display_rect().width() - width - 1, 15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->GetUpdatedCursorBounds().x()); 15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Repeat the test with RTL text. 16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(WideToUTF16(L"\x5d0\x5d1\x5d2\x5d3\x5d4\x5d5\x5d6\x5d7" 16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) L"\x5d8\x5d9\x5da\x5db\x5dc\x5dd\x5de\x5df")); 16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursorTo(SelectionModel(render_text->text().length(), 16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CURSOR_FORWARD)); 16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) width = render_text->GetStringSize().width(); 16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_GT(width, 10); 16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that the cursor is placed at the width of its preceding text. 16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(Rect(width + 10, 1)); 16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(render_text->display_rect().width() - width - 1, 16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->GetUpdatedCursorBounds().x()); 16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that shrinking the display rectangle keeps the cursor in view. 16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(Rect(width - 10, 1)); 16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, render_text->GetUpdatedCursorBounds().x()); 16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that the text will pan to fill its expanding display rectangle. 16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(Rect(width - 5, 1)); 16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, render_text->GetUpdatedCursorBounds().x()); 16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that a sufficiently large display rectangle shows all the text. 16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(Rect(width + 10, 1)); 16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(render_text->display_rect().width() - width - 1, 16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->GetUpdatedCursorBounds().x()); 16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reset the application default text direction to LTR. 16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetRTL(was_rtl); 16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(was_rtl, base::i18n::IsRTL()); 16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // !defined(OS_MACOSX) 16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1632a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Changing colors between or inside ligated glyphs should not break shaping. 1633558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_F(RenderTextTest, SelectionKeepsLigatures) { 1634a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const wchar_t* kTestStrings[] = { 1635a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) L"\x644\x623", 1636a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) L"\x633\x627" 1637a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) }; 1638558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 1639558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 1640558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch render_text->set_selection_color(SK_ColorRED); 1641a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Canvas canvas; 1642a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1643a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) for (size_t i = 0; i < arraysize(kTestStrings); ++i) { 1644a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) render_text->SetText(WideToUTF16(kTestStrings[i])); 1645a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const int expected_width = render_text->GetStringSize().width(); 1646d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) render_text->MoveCursorTo(SelectionModel(Range(0, 1), CURSOR_FORWARD)); 1647a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) EXPECT_EQ(expected_width, render_text->GetStringSize().width()); 1648a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Draw the text. It shouldn't hit any DCHECKs or crash. 1649a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // See http://crbug.com/214150 1650a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) render_text->Draw(&canvas); 1651a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) render_text->MoveCursorTo(SelectionModel(0, CURSOR_FORWARD)); 1652a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1653558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 1654558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 165558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#if defined(OS_WIN) 1656d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Ensure strings wrap onto multiple lines for a small available width. 1657d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)TEST_F(RenderTextTest, Multiline_MinWidth) { 1658d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const wchar_t* kTestStrings[] = { kWeak, kLtr, kLtrRtl, kLtrRtlLtr, kRtl, 1659d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) kRtlLtr, kRtlLtrRtl }; 1660d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1661d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) scoped_ptr<RenderTextWin> render_text( 1662d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) static_cast<RenderTextWin*>(RenderText::CreateInstance())); 1663d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) render_text->SetDisplayRect(Rect(1, 1000)); 1664d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) render_text->SetMultiline(true); 1665d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Canvas canvas; 1666d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1667d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) for (size_t i = 0; i < arraysize(kTestStrings); ++i) { 1668d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i)); 1669d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) render_text->SetText(WideToUTF16(kTestStrings[i])); 1670d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) render_text->Draw(&canvas); 1671d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_GT(render_text->lines_.size(), 1U); 1672d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 1673d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 1674d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1675d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Ensure strings wrap onto multiple lines for a normal available width. 1676d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)TEST_F(RenderTextTest, Multiline_NormalWidth) { 1677d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // TODO(ckocagil): Enable this test on XP. 1678d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#if defined(OS_WIN) 1679d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (base::win::GetVersion() < base::win::VERSION_VISTA) 1680d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return; 1681d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#endif 1682d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1683d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const struct { 1684d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const wchar_t* const text; 1685d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const Range first_line_char_range; 1686d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const Range second_line_char_range; 1687d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } kTestStrings[] = { 1688d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) { L"abc defg hijkl", Range(0, 9), Range(9, 14) }, 1689d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) { L"qwertyuiop", Range(0, 8), Range(8, 10) }, 1690d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) { L"\x062A\x0641\x0627\x062D\x05EA\x05E4\x05D5\x05D6\x05D9\x05DD", 1691d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Range(4, 10), Range(0, 4) } 1692d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) }; 1693d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1694d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) scoped_ptr<RenderTextWin> render_text( 1695d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) static_cast<RenderTextWin*>(RenderText::CreateInstance())); 1696d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) render_text->SetDisplayRect(Rect(50, 1000)); 1697d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) render_text->SetMultiline(true); 1698d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Canvas canvas; 1699d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1700d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestStrings); ++i) { 1701d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i)); 1702d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) render_text->SetText(WideToUTF16(kTestStrings[i].text)); 1703d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) render_text->Draw(&canvas); 1704d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ASSERT_EQ(2U, render_text->lines_.size()); 1705d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ASSERT_EQ(1U, render_text->lines_[0].segments.size()); 1706d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(kTestStrings[i].first_line_char_range, 1707d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) render_text->lines_[0].segments[0].char_range); 1708d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ASSERT_EQ(1U, render_text->lines_[1].segments.size()); 1709d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(kTestStrings[i].second_line_char_range, 1710d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) render_text->lines_[1].segments[0].char_range); 1711d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 1712d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 1713d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1714d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Ensure strings don't wrap onto multiple lines for a sufficient available 1715d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// width. 1716d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)TEST_F(RenderTextTest, Multiline_SufficientWidth) { 1717d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const wchar_t* kTestStrings[] = { L"", L" ", L".", L" . ", L"abc", L"a b c", 1718d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) L"\x62E\x628\x632", L"\x62E \x628 \x632" }; 1719d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1720d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) scoped_ptr<RenderTextWin> render_text( 1721d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) static_cast<RenderTextWin*>(RenderText::CreateInstance())); 1722d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) render_text->SetDisplayRect(Rect(30, 1000)); 1723d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) render_text->SetMultiline(true); 1724d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) Canvas canvas; 1725d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1726d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) for (size_t i = 0; i < arraysize(kTestStrings); ++i) { 1727d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) SCOPED_TRACE(base::StringPrintf("kTestStrings[%" PRIuS "]", i)); 1728d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) render_text->SetText(WideToUTF16(kTestStrings[i])); 1729d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) render_text->Draw(&canvas); 1730d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_EQ(1U, render_text->lines_.size()); 1731d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 1732d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 1733d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#endif // defined(OS_WIN) 1734d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1735d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#if defined(OS_WIN) 173658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TEST_F(RenderTextTest, Win_BreakRunsByUnicodeBlocks) { 173758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_ptr<RenderTextWin> render_text( 173858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) static_cast<RenderTextWin*>(RenderText::CreateInstance())); 173958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 174058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) render_text->SetText(WideToUTF16(L"x\x25B6y")); 174158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) render_text->EnsureLayout(); 174258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ASSERT_EQ(3U, render_text->runs_.size()); 174358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) EXPECT_EQ(Range(0, 1), render_text->runs_[0]->range); 174458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) EXPECT_EQ(Range(1, 2), render_text->runs_[1]->range); 174558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) EXPECT_EQ(Range(2, 3), render_text->runs_[2]->range); 174658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 174758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) render_text->SetText(WideToUTF16(L"x \x25B6 y")); 174858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) render_text->EnsureLayout(); 174958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ASSERT_EQ(3U, render_text->runs_.size()); 175058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) EXPECT_EQ(Range(0, 2), render_text->runs_[0]->range); 175158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) EXPECT_EQ(Range(2, 3), render_text->runs_[1]->range); 175258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) EXPECT_EQ(Range(3, 5), render_text->runs_[2]->range); 175358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 175458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 175558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#endif // !defined(OS_WIN) 175658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace gfx 1758