render_text_unittest.cc revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
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) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/utf_string_conversions.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/break_list.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/windows_version.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_LINUX) 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/render_text_linux.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(TOOLKIT_GTK) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <gtk/gtk.h> 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gfx { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Various weak, LTR, RTL, and Bidi string cases with three characters each. 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kWeak[] = L" . "; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kLtr[] = L"abc"; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kLtrRtl[] = L"a"L"\x5d0\x5d1"; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kLtrRtlLtr[] = L"a"L"\x5d1"L"b"; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kRtl[] = L"\x5d0\x5d1\x5d2"; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kRtlLtr[] = L"\x5d0\x5d1"L"a"; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kRtlLtrRtl[] = L"\x5d0"L"a"L"\x5d1"; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks whether |range| contains |index|. This is not the same as calling 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |range.Contains(ui::Range(index))| - as that would return true when 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |index| == |range.end()|. 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IndexInRange(const ui::Range& range, size_t index) { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return index >= range.start() && index < range.end(); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)base::string16 GetSelectedText(RenderText* render_text) { 45a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return render_text->text().substr(render_text->selection().GetMin(), 46a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) render_text->selection().length()); 47a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 48a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A test utility function to set the application default text direction. 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SetRTL(bool rtl) { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Override the current locale/direction. 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::i18n::SetICUDefaultLocale(rtl ? "he" : "en"); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(TOOLKIT_GTK) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Do the same for GTK, which does not rely on the ICU default locale. 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gtk_widget_set_default_direction(rtl ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(rtl, base::i18n::IsRTL()); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RenderTextTest : public testing::Test { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, DefaultStyle) { 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Check the default styles applied to new instances and adjusted text. 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(render_text->text().empty()); 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const wchar_t* const cases[] = { kWeak, kLtr, L"Hello", kRtl, L"", L"" }; 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < arraysize(cases); ++i) { 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(render_text->colors().EqualsValueForTesting(SK_ColorBLACK)); 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t style = 0; style < NUM_TEXT_STYLES; ++style) 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(render_text->styles()[style].EqualsValueForTesting(false)); 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->SetText(WideToUTF16(cases[i])); 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(RenderTextTest, SetColorAndStyle) { 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Ensure custom default styles persist across setting and clearing text. 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const SkColor color = SK_ColorRED; 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->SetColor(color); 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->SetStyle(BOLD, true); 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->SetStyle(UNDERLINE, false); 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const wchar_t* const cases[] = { kWeak, kLtr, L"Hello", kRtl, L"", L"" }; 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < arraysize(cases); ++i) { 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(render_text->colors().EqualsValueForTesting(color)); 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(render_text->styles()[BOLD].EqualsValueForTesting(true)); 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(render_text->styles()[UNDERLINE].EqualsValueForTesting(false)); 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->SetText(WideToUTF16(cases[i])); 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Ensure custom default styles can be applied after text has been set. 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (i == 1) 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->SetStyle(STRIKE, true); 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (i >= 1) 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(render_text->styles()[STRIKE].EqualsValueForTesting(true)); 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(RenderTextTest, ApplyColorAndStyle) { 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->SetText(ASCIIToUTF16("012345678")); 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Apply a ranged color and style and check the resulting breaks. 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->ApplyColor(SK_ColorRED, ui::Range(1, 4)); 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->ApplyStyle(BOLD, true, ui::Range(2, 5)); 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::pair<size_t, SkColor> > expected_color; 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_color.push_back(std::pair<size_t, SkColor>(0, SK_ColorBLACK)); 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_color.push_back(std::pair<size_t, SkColor>(1, SK_ColorRED)); 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_color.push_back(std::pair<size_t, SkColor>(4, SK_ColorBLACK)); 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(render_text->colors().EqualsForTesting(expected_color)); 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::pair<size_t, bool> > expected_style; 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_style.push_back(std::pair<size_t, bool>(0, false)); 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_style.push_back(std::pair<size_t, bool>(2, true)); 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_style.push_back(std::pair<size_t, bool>(5, false)); 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(render_text->styles()[BOLD].EqualsForTesting(expected_style)); 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Ensure setting a color and style overrides the ranged colors and styles. 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->SetColor(SK_ColorBLUE); 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(render_text->colors().EqualsValueForTesting(SK_ColorBLUE)); 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->SetStyle(BOLD, false); 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(render_text->styles()[BOLD].EqualsValueForTesting(false)); 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Apply a color and style over the text end and check the resulting breaks. 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // (INT_MAX should be used instead of the text length for the range end) 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const size_t text_length = render_text->text().length(); 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->ApplyColor(SK_ColorRED, ui::Range(0, text_length)); 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->ApplyStyle(BOLD, true, ui::Range(2, text_length)); 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::pair<size_t, SkColor> > expected_color_end; 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_color_end.push_back(std::pair<size_t, SkColor>(0, SK_ColorRED)); 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(render_text->colors().EqualsForTesting(expected_color_end)); 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::pair<size_t, bool> > expected_style_end; 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_style_end.push_back(std::pair<size_t, bool>(0, false)); 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_style_end.push_back(std::pair<size_t, bool>(2, true)); 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(render_text->styles()[BOLD].EqualsForTesting(expected_style_end)); 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Ensure ranged values adjust to accommodate text length changes. 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->ApplyStyle(ITALIC, true, ui::Range(0, 2)); 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->ApplyStyle(ITALIC, true, ui::Range(3, 6)); 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->ApplyStyle(ITALIC, true, ui::Range(7, text_length)); 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::pair<size_t, bool> > expected_italic; 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_italic.push_back(std::pair<size_t, bool>(0, true)); 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_italic.push_back(std::pair<size_t, bool>(2, false)); 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_italic.push_back(std::pair<size_t, bool>(3, true)); 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_italic.push_back(std::pair<size_t, bool>(6, false)); 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_italic.push_back(std::pair<size_t, bool>(7, true)); 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(render_text->styles()[ITALIC].EqualsForTesting(expected_italic)); 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Truncating the text should trim any corresponding breaks. 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->SetText(ASCIIToUTF16("0123456")); 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_italic.resize(4); 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(render_text->styles()[ITALIC].EqualsForTesting(expected_italic)); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(ASCIIToUTF16("01234")); 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_italic.resize(3); 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(render_text->styles()[ITALIC].EqualsForTesting(expected_italic)); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Appending text should extend the terminal styles without changing breaks. 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->SetText(ASCIIToUTF16("012345678")); 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(render_text->styles()[ITALIC].EqualsForTesting(expected_italic)); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_LINUX) 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(RenderTextTest, PangoAttributes) { 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->SetText(ASCIIToUTF16("012345678")); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Apply ranged BOLD/ITALIC styles and check the resulting Pango attributes. 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->ApplyStyle(BOLD, true, ui::Range(2, 4)); 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->ApplyStyle(ITALIC, true, ui::Range(1, 3)); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct { 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int start; 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int end; 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool bold; 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool italic; 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } cases[] = { 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 0, 1, false, false }, 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 1, 2, false, true }, 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 2, 3, true, true }, 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 3, 4, true, false }, 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 4, INT_MAX, false, false }, 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int start = 0, end = 0; 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RenderTextLinux* rt_linux = static_cast<RenderTextLinux*>(render_text.get()); 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rt_linux->EnsureLayout(); 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PangoAttrList* attributes = pango_layout_get_attributes(rt_linux->layout_); 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PangoAttrIterator* iter = pango_attr_list_get_iterator(attributes); 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pango_attr_iterator_range(iter, &start, &end); 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(cases[i].start, start); 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(cases[i].end, end); 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PangoFontDescription* font = pango_font_description_new(); 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pango_attr_iterator_get_font(iter, font, NULL, NULL); 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) char* description_string = pango_font_description_to_string(font); 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const string16 desc = ASCIIToUTF16(description_string); 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const bool bold = desc.find(ASCIIToUTF16("Bold")) != std::string::npos; 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(cases[i].bold, bold); 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const bool italic = desc.find(ASCIIToUTF16("Italic")) != std::string::npos; 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(cases[i].italic, italic); 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pango_attr_iterator_next(iter); 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pango_font_description_free(font); 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) g_free(description_string); 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(pango_attr_iterator_next(iter)); 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pango_attr_iterator_destroy(iter); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(asvitkine): Cursor movements tests disabled on Mac because RenderTextMac 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// does not implement this yet. http://crbug.com/131618 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_MACOSX) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestVisualCursorMotionInObscuredField(RenderText* render_text, 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16& text, 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool select) { 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(render_text->obscured()); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(text); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int len = text.length(); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(LINE_BREAK, CURSOR_RIGHT, select); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(SelectionModel(ui::Range(select ? 0 : len, len), CURSOR_FORWARD), 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->selection_model()); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(LINE_BREAK, CURSOR_LEFT, select); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(SelectionModel(0, CURSOR_BACKWARD), render_text->selection_model()); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = 1; j <= len; ++j) { 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, select); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(SelectionModel(ui::Range(select ? 0 : j, j), CURSOR_BACKWARD), 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->selection_model()); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = len - 1; j >= 0; --j) { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, select); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(SelectionModel(ui::Range(select ? 0 : j, j), CURSOR_FORWARD), 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->selection_model()); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, select); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(SelectionModel(ui::Range(select ? 0 : len, len), CURSOR_FORWARD), 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->selection_model()); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(WORD_BREAK, CURSOR_LEFT, select); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(SelectionModel(0, CURSOR_BACKWARD), render_text->selection_model()); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, ObscuredText) { 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16 seuss = ASCIIToUTF16("hop on pop"); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16 no_seuss = ASCIIToUTF16("**********"); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // GetLayoutText() returns asterisks when the obscured bit is set. 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(seuss); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetObscured(true); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(seuss, render_text->text()); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(no_seuss, render_text->GetLayoutText()); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetObscured(false); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(seuss, render_text->text()); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(seuss, render_text->GetLayoutText()); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetObscured(true); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Surrogate pairs are counted as one code point. 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char16 invalid_surrogates[] = {0xDC00, 0xD800, 0}; 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(invalid_surrogates); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ASCIIToUTF16("**"), render_text->GetLayoutText()); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char16 valid_surrogates[] = {0xD800, 0xDC00, 0}; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(valid_surrogates); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ASCIIToUTF16("*"), render_text->GetLayoutText()); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0U, render_text->cursor_position()); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, false); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(2U, render_text->cursor_position()); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test index conversion and cursor validity with a valid surrogate pair. 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0U, render_text->TextIndexToLayoutIndex(0U)); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1U, render_text->TextIndexToLayoutIndex(1U)); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1U, render_text->TextIndexToLayoutIndex(2U)); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0U, render_text->LayoutIndexToTextIndex(0U)); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(2U, render_text->LayoutIndexToTextIndex(1U)); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(render_text->IsCursorablePosition(0U)); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(render_text->IsCursorablePosition(1U)); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(render_text->IsCursorablePosition(2U)); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FindCursorPosition() should not return positions between a surrogate pair. 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(Rect(0, 0, 20, 20)); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(render_text->FindCursorPosition(Point(0, 0)).caret_pos(), 0U); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(render_text->FindCursorPosition(Point(20, 0)).caret_pos(), 2U); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int x = -1; x <= 20; ++x) { 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SelectionModel selection = render_text->FindCursorPosition(Point(x, 0)); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(selection.caret_pos() == 0U || selection.caret_pos() == 2U); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // GetGlyphBounds() should yield the entire string bounds for text index 0. 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(render_text->GetStringSize().width(), 28990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) static_cast<int>(render_text->GetGlyphBounds(0U).length())); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cursoring is independent of underlying characters when text is obscured. 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t* const texts[] = { 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kWeak, kLtr, kLtrRtl, kLtrRtlLtr, kRtl, kRtlLtr, kRtlLtrRtl, 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) L"hop on pop", // Check LTR word boundaries. 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) L"\x05d0\x05d1 \x05d0\x05d2 \x05d1\x05d2", // Check RTL word boundaries. 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < arraysize(texts); ++i) { 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16 text = WideToUTF16(texts[i]); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestVisualCursorMotionInObscuredField(render_text.get(), text, false); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestVisualCursorMotionInObscuredField(render_text.get(), text, true); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, GetTextDirection) { 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct { 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t* text; 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::i18n::TextDirection text_direction; 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } cases[] = { 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Blank strings and those with no/weak directionality default to LTR. 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { L"", base::i18n::LEFT_TO_RIGHT }, 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kWeak, base::i18n::LEFT_TO_RIGHT }, 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Strings that begin with strong LTR characters. 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kLtr, base::i18n::LEFT_TO_RIGHT }, 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kLtrRtl, base::i18n::LEFT_TO_RIGHT }, 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kLtrRtlLtr, base::i18n::LEFT_TO_RIGHT }, 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Strings that begin with strong RTL characters. 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kRtl, base::i18n::RIGHT_TO_LEFT }, 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kRtlLtr, base::i18n::RIGHT_TO_LEFT }, 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kRtlLtrRtl, base::i18n::RIGHT_TO_LEFT }, 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool was_rtl = base::i18n::IsRTL(); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < 2; ++i) { 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Toggle the application default text direction (to try each direction). 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetRTL(!base::i18n::IsRTL()); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::i18n::TextDirection ui_direction = base::i18n::IsRTL() ? 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::i18n::RIGHT_TO_LEFT : base::i18n::LEFT_TO_RIGHT; 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that directionality modes yield the correct text directions. 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t j = 0; j < ARRAYSIZE_UNSAFE(cases); j++) { 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(WideToUTF16(cases[j].text)); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDirectionalityMode(DIRECTIONALITY_FROM_TEXT); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(render_text->GetTextDirection(), cases[j].text_direction); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDirectionalityMode(DIRECTIONALITY_FROM_UI); 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(render_text->GetTextDirection(), ui_direction); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDirectionalityMode(DIRECTIONALITY_FORCE_LTR); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(render_text->GetTextDirection(), base::i18n::LEFT_TO_RIGHT); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDirectionalityMode(DIRECTIONALITY_FORCE_RTL); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(render_text->GetTextDirection(), base::i18n::RIGHT_TO_LEFT); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(was_rtl, base::i18n::IsRTL()); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that text changes update the direction for DIRECTIONALITY_FROM_TEXT. 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDirectionalityMode(DIRECTIONALITY_FROM_TEXT); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(WideToUTF16(kLtr)); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(render_text->GetTextDirection(), base::i18n::LEFT_TO_RIGHT); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(WideToUTF16(kRtl)); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(render_text->GetTextDirection(), base::i18n::RIGHT_TO_LEFT); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RunMoveCursorLeftRightTest(RenderText* render_text, 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<SelectionModel>& expected, 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VisualCursorDirection direction) { 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < expected.size(); ++i) { 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(expected[i], render_text->selection_model()); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, direction, false); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check that cursoring is clamped at the line edge. 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(expected.back(), render_text->selection_model()); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check that it is the line edge. 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(LINE_BREAK, direction, false); 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(expected.back(), render_text->selection_model()); 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, MoveCursorLeftRightInLtr) { 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Pure LTR. 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(ASCIIToUTF16("abc")); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |expected| saves the expected SelectionModel when moving cursor from left 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to right. 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<SelectionModel> expected; 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(1, CURSOR_BACKWARD)); 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(2, CURSOR_BACKWARD)); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(3, CURSOR_BACKWARD)); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(3, CURSOR_FORWARD)); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_RIGHT); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.clear(); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(3, CURSOR_FORWARD)); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(2, CURSOR_FORWARD)); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(1, CURSOR_FORWARD)); 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(0, CURSOR_FORWARD)); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_LEFT); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, MoveCursorLeftRightInLtrRtl) { 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // LTR-RTL 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(WideToUTF16(L"abc\x05d0\x05d1\x05d2")); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The last one is the expected END position. 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<SelectionModel> expected; 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(1, CURSOR_BACKWARD)); 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(2, CURSOR_BACKWARD)); 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(3, CURSOR_BACKWARD)); 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(5, CURSOR_FORWARD)); 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(4, CURSOR_FORWARD)); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(3, CURSOR_FORWARD)); 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(6, CURSOR_FORWARD)); 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_RIGHT); 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.clear(); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(6, CURSOR_FORWARD)); 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(4, CURSOR_BACKWARD)); 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(5, CURSOR_BACKWARD)); 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(6, CURSOR_BACKWARD)); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(2, CURSOR_FORWARD)); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(1, CURSOR_FORWARD)); 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(0, CURSOR_FORWARD)); 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_LEFT); 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, MoveCursorLeftRightInLtrRtlLtr) { 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // LTR-RTL-LTR. 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(WideToUTF16(L"a"L"\x05d1"L"b")); 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<SelectionModel> expected; 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(1, CURSOR_BACKWARD)); 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(1, CURSOR_FORWARD)); 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(3, CURSOR_BACKWARD)); 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(3, CURSOR_FORWARD)); 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_RIGHT); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.clear(); 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(3, CURSOR_FORWARD)); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(2, CURSOR_FORWARD)); 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(2, CURSOR_BACKWARD)); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(0, CURSOR_FORWARD)); 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_LEFT); 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, MoveCursorLeftRightInRtl) { 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Pure RTL. 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(WideToUTF16(L"\x05d0\x05d1\x05d2")); 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(LINE_BREAK, CURSOR_RIGHT, false); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<SelectionModel> expected; 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(1, CURSOR_BACKWARD)); 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(2, CURSOR_BACKWARD)); 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(3, CURSOR_BACKWARD)); 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(3, CURSOR_FORWARD)); 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_LEFT); 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.clear(); 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(3, CURSOR_FORWARD)); 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(2, CURSOR_FORWARD)); 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(1, CURSOR_FORWARD)); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(0, CURSOR_FORWARD)); 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_RIGHT); 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, MoveCursorLeftRightInRtlLtr) { 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // RTL-LTR 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(WideToUTF16(L"\x05d0\x05d1\x05d2"L"abc")); 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(LINE_BREAK, CURSOR_RIGHT, false); 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<SelectionModel> expected; 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(1, CURSOR_BACKWARD)); 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(2, CURSOR_BACKWARD)); 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(3, CURSOR_BACKWARD)); 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(5, CURSOR_FORWARD)); 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(4, CURSOR_FORWARD)); 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(3, CURSOR_FORWARD)); 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(6, CURSOR_FORWARD)); 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_LEFT); 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.clear(); 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(6, CURSOR_FORWARD)); 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(4, CURSOR_BACKWARD)); 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(5, CURSOR_BACKWARD)); 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(6, CURSOR_BACKWARD)); 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(2, CURSOR_FORWARD)); 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(1, CURSOR_FORWARD)); 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(0, CURSOR_FORWARD)); 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_RIGHT); 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, MoveCursorLeftRightInRtlLtrRtl) { 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // RTL-LTR-RTL. 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(WideToUTF16(L"\x05d0"L"a"L"\x05d1")); 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(LINE_BREAK, CURSOR_RIGHT, false); 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<SelectionModel> expected; 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(1, CURSOR_BACKWARD)); 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(1, CURSOR_FORWARD)); 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(3, CURSOR_BACKWARD)); 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(3, CURSOR_FORWARD)); 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_LEFT); 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.clear(); 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(3, CURSOR_FORWARD)); 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(2, CURSOR_FORWARD)); 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(2, CURSOR_BACKWARD)); 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(0, CURSOR_FORWARD)); 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected.push_back(SelectionModel(0, CURSOR_BACKWARD)); 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunMoveCursorLeftRightTest(render_text.get(), expected, CURSOR_RIGHT); 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(xji): temporarily disable in platform Win since the complex script 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// characters turned into empty square due to font regression. So, not able 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to test 2 characters belong to the same grapheme. 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_LINUX) 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, MoveCursorLeftRight_ComplexScript) { 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(WideToUTF16(L"\x0915\x093f\x0915\x094d\x0915")); 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0U, render_text->cursor_position()); 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, false); 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(2U, render_text->cursor_position()); 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, false); 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(4U, render_text->cursor_position()); 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, false); 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(5U, render_text->cursor_position()); 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, false); 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(5U, render_text->cursor_position()); 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, false); 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(4U, render_text->cursor_position()); 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, false); 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(2U, render_text->cursor_position()); 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, false); 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0U, render_text->cursor_position()); 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, false); 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0U, render_text->cursor_position()); 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, GraphemePositions) { 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // LTR 2-character grapheme, LTR abc, LTR 2-character grapheme. 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16 kText1 = WideToUTF16(L"\x0915\x093f"L"abc"L"\x0915\x093f"); 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // LTR ab, LTR 2-character grapheme, LTR cd. 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16 kText2 = WideToUTF16(L"ab"L"\x0915\x093f"L"cd"); 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The below is 'MUSICAL SYMBOL G CLEF', which is represented in UTF-16 as 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // two characters forming the surrogate pair 0x0001D11E. 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string kSurrogate = "\xF0\x9D\x84\x9E"; 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // LTR ab, UTF16 surrogate pair, LTR cd. 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16 kText3 = UTF8ToUTF16("ab" + kSurrogate + "cd"); 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct { 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16 text; 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t index; 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t expected_previous; 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t expected_next; 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } cases[] = { 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { string16(), 0, 0, 0 }, 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { string16(), 1, 0, 0 }, 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { string16(), 50, 0, 0 }, 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText1, 0, 0, 2 }, 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText1, 1, 0, 2 }, 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText1, 2, 0, 3 }, 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText1, 3, 2, 4 }, 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText1, 4, 3, 5 }, 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText1, 5, 4, 7 }, 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText1, 6, 5, 7 }, 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText1, 7, 5, 7 }, 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText1, 8, 7, 7 }, 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText1, 50, 7, 7 }, 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText2, 0, 0, 1 }, 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText2, 1, 0, 2 }, 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText2, 2, 1, 4 }, 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText2, 3, 2, 4 }, 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText2, 4, 2, 5 }, 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText2, 5, 4, 6 }, 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText2, 6, 5, 6 }, 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText2, 7, 6, 6 }, 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText2, 50, 6, 6 }, 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText3, 0, 0, 1 }, 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText3, 1, 0, 2 }, 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText3, 2, 1, 4 }, 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText3, 3, 2, 4 }, 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText3, 4, 2, 5 }, 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText3, 5, 4, 6 }, 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText3, 6, 5, 6 }, 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText3, 7, 6, 6 }, 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kText3, 50, 6, 6 }, 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(asvitkine): Disable tests that fail on XP bots due to lack of complete 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // font support for some scripts - http://crbug.com/106450 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base::win::GetVersion() < base::win::VERSION_VISTA) 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); i++) { 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(cases[i].text); 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t next = render_text->IndexOfAdjacentGrapheme(cases[i].index, 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CURSOR_FORWARD); 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(cases[i].expected_next, next); 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(render_text->IsCursorablePosition(next)); 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t previous = render_text->IndexOfAdjacentGrapheme(cases[i].index, 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CURSOR_BACKWARD); 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(cases[i].expected_previous, previous); 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(render_text->IsCursorablePosition(previous)); 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, EdgeSelectionModels) { 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Simple Latin text. 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16 kLatin = WideToUTF16(L"abc"); 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // LTR 2-character grapheme. 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16 kLTRGrapheme = WideToUTF16(L"\x0915\x093f"); 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // LTR 2-character grapheme, LTR a, LTR 2-character grapheme. 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16 kHindiLatin = WideToUTF16(L"\x0915\x093f"L"a"L"\x0915\x093f"); 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // RTL 2-character grapheme. 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16 kRTLGrapheme = WideToUTF16(L"\x05e0\x05b8"); 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // RTL 2-character grapheme, LTR a, RTL 2-character grapheme. 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16 kHebrewLatin = WideToUTF16(L"\x05e0\x05b8"L"a"L"\x05e0\x05b8"); 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct { 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16 text; 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::i18n::TextDirection expected_text_direction; 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } cases[] = { 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { string16(), base::i18n::LEFT_TO_RIGHT }, 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kLatin, base::i18n::LEFT_TO_RIGHT }, 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kLTRGrapheme, base::i18n::LEFT_TO_RIGHT }, 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kHindiLatin, base::i18n::LEFT_TO_RIGHT }, 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kRTLGrapheme, base::i18n::RIGHT_TO_LEFT }, 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kHebrewLatin, base::i18n::RIGHT_TO_LEFT }, 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(asvitkine): Disable tests that fail on XP bots due to lack of complete 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // font support for some scripts - http://crbug.com/106450 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base::win::GetVersion() < base::win::VERSION_VISTA) 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); i++) { 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(cases[i].text); 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ltr = (cases[i].expected_text_direction == base::i18n::LEFT_TO_RIGHT); 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SelectionModel start_edge = 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->EdgeSelectionModel(ltr ? CURSOR_LEFT : CURSOR_RIGHT); 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(start_edge, SelectionModel(0, CURSOR_BACKWARD)); 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SelectionModel end_edge = 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->EdgeSelectionModel(ltr ? CURSOR_RIGHT : CURSOR_LEFT); 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(end_edge, SelectionModel(cases[i].text.length(), CURSOR_FORWARD)); 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, SelectAll) { 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t* const cases[] = 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { kWeak, kLtr, kLtrRtl, kLtrRtlLtr, kRtl, kRtlLtr, kRtlLtrRtl }; 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that SelectAll respects the |reversed| argument regardless of 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // application locale and text content directionality. 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SelectionModel expected_reversed(ui::Range(3, 0), CURSOR_FORWARD); 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SelectionModel expected_forwards(ui::Range(0, 3), CURSOR_BACKWARD); 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool was_rtl = base::i18n::IsRTL(); 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < 2; ++i) { 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetRTL(!base::i18n::IsRTL()); 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test that an empty string produces an empty selection model. 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(string16()); 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(render_text->selection_model(), SelectionModel()); 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test the weak, LTR, RTL, and Bidi string cases. 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t j = 0; j < ARRAYSIZE_UNSAFE(cases); j++) { 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(WideToUTF16(cases[j])); 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SelectAll(false); 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(render_text->selection_model(), expected_forwards); 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SelectAll(true); 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(render_text->selection_model(), expected_reversed); 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(was_rtl, base::i18n::IsRTL()); 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TEST_F(RenderTextTest, MoveCursorLeftRightWithSelection) { 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(WideToUTF16(L"abc\x05d0\x05d1\x05d2")); 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Left arrow on select ranging (6, 4). 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(LINE_BREAK, CURSOR_RIGHT, false); 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ui::Range(6), render_text->selection()); 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, false); 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ui::Range(4), render_text->selection()); 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, false); 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ui::Range(5), render_text->selection()); 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, false); 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ui::Range(6), render_text->selection()); 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, true); 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ui::Range(6, 5), render_text->selection()); 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, true); 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ui::Range(6, 4), render_text->selection()); 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, false); 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ui::Range(6), render_text->selection()); 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Right arrow on select ranging (4, 6). 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(LINE_BREAK, CURSOR_LEFT, false); 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ui::Range(0), render_text->selection()); 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, false); 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ui::Range(1), render_text->selection()); 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, false); 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ui::Range(2), render_text->selection()); 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, false); 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ui::Range(3), render_text->selection()); 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, false); 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ui::Range(5), render_text->selection()); 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, false); 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ui::Range(4), render_text->selection()); 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, true); 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ui::Range(4, 5), render_text->selection()); 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, true); 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ui::Range(4, 6), render_text->selection()); 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, false); 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ui::Range(4), render_text->selection()); 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // !defined(OS_MACOSX) 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(xji): Make these work on Windows. 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_LINUX) 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MoveLeftRightByWordVerifier(RenderText* render_text, 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t* str) { 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(WideToUTF16(str)); 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test moving by word from left ro right. 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(LINE_BREAK, CURSOR_LEFT, false); 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool first_word = true; 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (true) { 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First, test moving by word from a word break position, such as from 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // "|abc def" to "abc| def". 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SelectionModel start = render_text->selection_model(); 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, false); 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SelectionModel end = render_text->selection_model(); 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (end == start) // reach the end. 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For testing simplicity, each word is a 3-character word. 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_of_character_moves = first_word ? 3 : 4; 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first_word = false; 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursorTo(start); 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = 0; j < num_of_character_moves; ++j) 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, false); 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(end, render_text->selection_model()); 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Then, test moving by word from positions inside the word, such as from 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // "a|bc def" to "abc| def", and from "ab|c def" to "abc| def". 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = 1; j < num_of_character_moves; ++j) { 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursorTo(start); 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int k = 0; k < j; ++k) 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_RIGHT, false); 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, false); 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(end, render_text->selection_model()); 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test moving by word from right to left. 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(LINE_BREAK, CURSOR_RIGHT, false); 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first_word = true; 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (true) { 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SelectionModel start = render_text->selection_model(); 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(WORD_BREAK, CURSOR_LEFT, false); 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SelectionModel end = render_text->selection_model(); 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (end == start) // reach the end. 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_of_character_moves = first_word ? 3 : 4; 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first_word = false; 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursorTo(start); 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = 0; j < num_of_character_moves; ++j) 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, false); 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(end, render_text->selection_model()); 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = 1; j < num_of_character_moves; ++j) { 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursorTo(start); 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int k = 0; k < j; ++k) 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(CHARACTER_BREAK, CURSOR_LEFT, false); 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(WORD_BREAK, CURSOR_LEFT, false); 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(end, render_text->selection_model()); 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, MoveLeftRightByWordInBidiText) { 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For testing simplicity, each word is a 3-character word. 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<const wchar_t*> test; 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test.push_back(L"abc"); 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test.push_back(L"abc def"); 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test.push_back(L"\x05E1\x05E2\x05E3"); 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test.push_back(L"\x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6"); 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test.push_back(L"abc \x05E1\x05E2\x05E3"); 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test.push_back(L"abc def \x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6"); 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test.push_back(L"abc def hij \x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6" 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) L" \x05E7\x05E8\x05E9"); 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test.push_back(L"abc \x05E1\x05E2\x05E3 hij"); 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test.push_back(L"abc def \x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6 hij opq"); 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test.push_back(L"abc def hij \x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6" 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) L" \x05E7\x05E8\x05E9"L" opq rst uvw"); 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test.push_back(L"\x05E1\x05E2\x05E3 abc"); 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test.push_back(L"\x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6 abc def"); 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test.push_back(L"\x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6 \x05E7\x05E8\x05E9" 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) L" abc def hij"); 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test.push_back(L"\x05D1\x05D2\x05D3 abc \x05E1\x05E2\x05E3"); 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test.push_back(L"\x05D1\x05D2\x05D3 \x05D4\x05D5\x05D6 abc def" 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) L" \x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6"); 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test.push_back(L"\x05D1\x05D2\x05D3 \x05D4\x05D5\x05D6 \x05D7\x05D8\x05D9" 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) L" abc def hij \x05E1\x05E2\x05E3 \x05E4\x05E5\x05E6" 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) L" \x05E7\x05E8\x05E9"); 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < test.size(); ++i) 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MoveLeftRightByWordVerifier(render_text.get(), test[i]); 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, MoveLeftRightByWordInBidiText_TestEndOfText) { 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(WideToUTF16(L"ab\x05E1")); 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Moving the cursor by word from "abC|" to the left should return "|abC". 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // But since end of text is always treated as a word break, it returns 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // position "ab|C". 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(xji): Need to make it work as expected. 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(LINE_BREAK, CURSOR_RIGHT, false); 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(WORD_BREAK, CURSOR_LEFT, false); 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // EXPECT_EQ(SelectionModel(), render_text->selection_model()); 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Moving the cursor by word from "|abC" to the right returns "abC|". 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(LINE_BREAK, CURSOR_LEFT, false); 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, false); 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(SelectionModel(3, CURSOR_FORWARD), render_text->selection_model()); 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(WideToUTF16(L"\x05E1\x05E2"L"a")); 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For logical text "BCa", moving the cursor by word from "aCB|" to the left 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // returns "|aCB". 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(LINE_BREAK, CURSOR_RIGHT, false); 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(WORD_BREAK, CURSOR_LEFT, false); 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(SelectionModel(3, CURSOR_FORWARD), render_text->selection_model()); 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Moving the cursor by word from "|aCB" to the right should return "aCB|". 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // But since end of text is always treated as a word break, it returns 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // position "a|CB". 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(xji): Need to make it work as expected. 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(LINE_BREAK, CURSOR_LEFT, false); 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, false); 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // EXPECT_EQ(SelectionModel(), render_text->selection_model()); 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, MoveLeftRightByWordInTextWithMultiSpaces) { 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(WideToUTF16(L"abc def")); 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursorTo(SelectionModel(5, CURSOR_FORWARD)); 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, false); 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(11U, render_text->cursor_position()); 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursorTo(SelectionModel(5, CURSOR_FORWARD)); 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(WORD_BREAK, CURSOR_LEFT, false); 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0U, render_text->cursor_position()); 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, MoveLeftRightByWordInChineseText) { 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(WideToUTF16(L"\x6211\x4EEC\x53BB\x516C\x56ED\x73A9")); 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(LINE_BREAK, CURSOR_LEFT, false); 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0U, render_text->cursor_position()); 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, false); 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(2U, render_text->cursor_position()); 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, false); 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(3U, render_text->cursor_position()); 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, false); 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(5U, render_text->cursor_position()); 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, false); 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(6U, render_text->cursor_position()); 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursor(WORD_BREAK, CURSOR_RIGHT, false); 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(6U, render_text->cursor_position()); 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, StringSizeSanity) { 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(UTF8ToUTF16("Hello World")); 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Size string_size = render_text->GetStringSize(); 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GT(string_size.width(), 0); 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GT(string_size.height(), 0); 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(asvitkine): This test fails because PlatformFontMac uses point font 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// sizes instead of pixel sizes like other implementations. 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_MACOSX) 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, StringSizeEmptyString) { 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Font font; 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetFont(font); 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(string16()); 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(font.GetHeight(), render_text->GetStringSize().height()); 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, render_text->GetStringSize().width()); 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(UTF8ToUTF16(" ")); 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(font.GetHeight(), render_text->GetStringSize().height()); 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // !defined(OS_MACOSX) 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, SetFont) { 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetFont(Font("Arial", 12)); 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("Arial", render_text->GetFont().GetFontName()); 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(12, render_text->GetFont().GetFontSize()); 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, StringSizeBoldWidth) { 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(UTF8ToUTF16("Hello World")); 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int plain_width = render_text->GetStringSize().width(); 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GT(plain_width, 0); 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Apply a bold style and check that the new width is greater. 9402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->SetStyle(gfx::BOLD, true); 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int bold_width = render_text->GetStringSize().width(); 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GT(bold_width, plain_width); 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now, apply a plain style over the first word only. 9452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->ApplyStyle(gfx::BOLD, false, ui::Range(0, 5)); 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int plain_bold_width = render_text->GetStringSize().width(); 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GT(plain_bold_width, plain_width); 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_LT(plain_bold_width, bold_width); 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, StringSizeHeight) { 9522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) string16 cases[] = { 9532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WideToUTF16(L"Hello World!"), // English 9542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WideToUTF16(L"\x6328\x62f6"), // Japanese 9552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WideToUTF16(L"\x0915\x093f"), // Hindi 9562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WideToUTF16(L"\x05e0\x05b8"), // Hebrew 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Font default_font; 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Font larger_font = default_font.DeriveFont(24, default_font.GetStyle()); 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GT(larger_font.GetHeight(), default_font.GetHeight()); 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); i++) { 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetFont(default_font); 9662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->SetText(cases[i]); 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int height1 = render_text->GetStringSize().height(); 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GT(height1, 0); 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check that setting the larger font increases the height. 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetFont(larger_font); 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int height2 = render_text->GetStringSize().height(); 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GT(height2, height1); 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, GetBaselineSanity) { 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(UTF8ToUTF16("Hello World")); 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int baseline = render_text->GetBaseline(); 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GT(baseline, 0); 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, CursorBoundsInReplacementMode) { 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(ASCIIToUTF16("abcdefg")); 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(Rect(100, 17)); 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SelectionModel sel_b(1, CURSOR_FORWARD); 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SelectionModel sel_c(2, CURSOR_FORWARD); 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Rect cursor_around_b = render_text->GetCursorBounds(sel_b, false); 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Rect cursor_before_b = render_text->GetCursorBounds(sel_b, true); 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Rect cursor_before_c = render_text->GetCursorBounds(sel_c, true); 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(cursor_around_b.x(), cursor_before_b.x()); 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(cursor_around_b.right(), cursor_before_c.x()); 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 99890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TEST_F(RenderTextTest, GetTextOffset) { 99990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // The default horizontal text offset differs for LTR and RTL, and is only set 100090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // when the RenderText object is created. This test will check the default in 100190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // LTR mode, and the next test will check the RTL default. 100290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const bool was_rtl = base::i18n::IsRTL(); 100390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetRTL(false); 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(ASCIIToUTF16("abcdefg")); 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetFontList(FontList("Arial, 13px")); 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 100890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Set display area's size equal to the font size. 100990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const gfx::Size font_size(render_text->GetContentWidth(), 101090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) render_text->GetStringSize().height()); 101190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Rect display_rect(font_size); 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(display_rect); 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 101490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Vector2d offset = render_text->GetTextOffset(); 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(offset.IsZero()); 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 101790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Set display area's size greater than font size. 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kEnlargement = 2; 101990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) display_rect.Inset(0, 0, -kEnlargement, -kEnlargement); 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(display_rect); 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 102290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Check the default horizontal and vertical alignment. 102390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) offset = render_text->GetTextOffset(); 102490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(kEnlargement / 2, offset.y()); 102590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(0, offset.x()); 102690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 102790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Check explicitly setting the horizontal alignment. 102890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) render_text->SetHorizontalAlignment(ALIGN_LEFT); 102990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) offset = render_text->GetTextOffset(); 103090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(0, offset.x()); 103190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) render_text->SetHorizontalAlignment(ALIGN_CENTER); 103290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) offset = render_text->GetTextOffset(); 103390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(kEnlargement / 2, offset.x()); 103490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) render_text->SetHorizontalAlignment(ALIGN_RIGHT); 103590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) offset = render_text->GetTextOffset(); 103690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(kEnlargement, offset.x()); 103790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 103890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Check explicitly setting the vertical alignment. 103990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) render_text->SetVerticalAlignment(ALIGN_TOP); 104090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) offset = render_text->GetTextOffset(); 104190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(0, offset.y()); 104290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) render_text->SetVerticalAlignment(ALIGN_VCENTER); 104390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) offset = render_text->GetTextOffset(); 104490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(kEnlargement / 2, offset.y()); 104590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) render_text->SetVerticalAlignment(ALIGN_BOTTOM); 104690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) offset = render_text->GetTextOffset(); 104790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(kEnlargement, offset.y()); 104890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 104990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetRTL(was_rtl); 105090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 105190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 105290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TEST_F(RenderTextTest, GetTextOffsetHorizontalDefaultInRTL) { 105390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // This only checks the default horizontal alignment in RTL mode; all other 105490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // GetTextOffset() attributes are checked by the test above. 105590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const bool was_rtl = base::i18n::IsRTL(); 105690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetRTL(true); 105790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 105890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) render_text->SetText(ASCIIToUTF16("abcdefg")); 105990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) render_text->SetFontList(FontList("Arial, 13px")); 106090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const int kEnlargement = 2; 106190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const gfx::Size font_size(render_text->GetContentWidth() + kEnlargement, 106290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) render_text->GetStringSize().height()); 106390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Rect display_rect(font_size); 106490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) render_text->SetDisplayRect(display_rect); 106590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Vector2d offset = render_text->GetTextOffset(); 106690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(kEnlargement, offset.x()); 106790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetRTL(was_rtl); 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, SameFontForParentheses) { 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct { 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char16 left_char; 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char16 right_char; 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } punctuation_pairs[] = { 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { '(', ')' }, 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { '{', '}' }, 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { '<', '>' }, 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct { 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16 text; 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } cases[] = { 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // English(English) 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { WideToUTF16(L"Hello World(a)") }, 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // English(English)English 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { WideToUTF16(L"Hello World(a)Hello World") }, 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Japanese(English) 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { WideToUTF16(L"\x6328\x62f6(a)") }, 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Japanese(English)Japanese 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { WideToUTF16(L"\x6328\x62f6(a)\x6328\x62f6") }, 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // English(Japanese)English 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { WideToUTF16(L"Hello World(\x6328\x62f6)Hello World") }, 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Hindi(English) 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { WideToUTF16(L"\x0915\x093f(a)") }, 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Hindi(English)Hindi 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { WideToUTF16(L"\x0915\x093f(a)\x0915\x093f") }, 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // English(Hindi)English 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { WideToUTF16(L"Hello World(\x0915\x093f)Hello World") }, 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Hebrew(English) 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { WideToUTF16(L"\x05e0\x05b8(a)") }, 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Hebrew(English)Hebrew 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { WideToUTF16(L"\x05e0\x05b8(a)\x05e0\x05b8") }, 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // English(Hebrew)English 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { WideToUTF16(L"Hello World(\x05e0\x05b8)Hello World") }, 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16 text = cases[i].text; 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t start_paren_char_index = text.find('('); 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NE(string16::npos, start_paren_char_index); 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t end_paren_char_index = text.find(')'); 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NE(string16::npos, end_paren_char_index); 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t j = 0; j < ARRAYSIZE_UNSAFE(punctuation_pairs); ++j) { 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) text[start_paren_char_index] = punctuation_pairs[j].left_char; 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) text[end_paren_char_index] = punctuation_pairs[j].right_char; 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(text); 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<RenderText::FontSpan> spans = 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->GetFontSpansForTesting(); 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int start_paren_span_index = -1; 11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int end_paren_span_index = -1; 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t k = 0; k < spans.size(); ++k) { 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IndexInRange(spans[k].second, start_paren_char_index)) 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_paren_span_index = k; 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IndexInRange(spans[k].second, end_paren_char_index)) 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end_paren_span_index = k; 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NE(-1, start_paren_span_index); 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NE(-1, end_paren_span_index); 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Font& start_font = spans[start_paren_span_index].first; 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Font& end_font = spans[end_paren_span_index].first; 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(start_font.GetFontName(), end_font.GetFontName()); 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(start_font.GetFontSize(), end_font.GetFontSize()); 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(start_font.GetStyle(), end_font.GetStyle()); 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Make sure the caret width is always >=1 so that the correct 11462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// caret is drawn at high DPI. crbug.com/164100. 11472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(RenderTextTest, CaretWidth) { 11482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 11492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->SetText(ASCIIToUTF16("abcdefg")); 11502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_GE(render_text->GetUpdatedCursorBounds().width(), 1); 11512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 11522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Make sure the last word is selected when the cursor is at text.length(). 1154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(RenderTextTest, LastWordSelected) { 1155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string kTestURL1 = "http://www.google.com"; 1156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string kTestURL2 = "http://www.google.com/something/"; 1157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 1159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) render_text->SetText(ASCIIToUTF16(kTestURL1)); 1161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) render_text->SetCursorPosition(kTestURL1.length()); 1162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) render_text->SelectWord(); 1163a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(ASCIIToUTF16("com"), GetSelectedText(render_text.get())); 1164a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_FALSE(render_text->selection().is_reversed()); 1165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) render_text->SetText(ASCIIToUTF16(kTestURL2)); 1167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) render_text->SetCursorPosition(kTestURL2.length()); 1168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) render_text->SelectWord(); 1169a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(ASCIIToUTF16("/"), GetSelectedText(render_text.get())); 1170a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_FALSE(render_text->selection().is_reversed()); 1171a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 1172a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 1173a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// When given a non-empty selection, SelectWord should expand the selection to 1174a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// nearest word boundaries. 1175a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)TEST_F(RenderTextTest, SelectMultipleWords) { 1176a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const std::string kTestURL = "http://www.google.com"; 1177a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 1178a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 1179a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 1180a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) render_text->SetText(ASCIIToUTF16(kTestURL)); 1181a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) render_text->SelectRange(ui::Range(16, 20)); 1182a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) render_text->SelectWord(); 1183a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(ASCIIToUTF16("google.com"), GetSelectedText(render_text.get())); 1184a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_FALSE(render_text->selection().is_reversed()); 1185a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 1186a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // SelectWord should preserve the selection direction. 1187a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) render_text->SelectRange(ui::Range(20, 16)); 1188a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) render_text->SelectWord(); 1189a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_EQ(ASCIIToUTF16("google.com"), GetSelectedText(render_text.get())); 1190a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) EXPECT_TRUE(render_text->selection().is_reversed()); 1191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(asvitkine): Cursor movements tests disabled on Mac because RenderTextMac 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// does not implement this yet. http://crbug.com/131618 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_MACOSX) 11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, DisplayRectShowsCursorLTR) { 11972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_FALSE(base::i18n::IsRTL()); 11982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_FALSE(base::i18n::ICUIsRTL()); 11992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(WideToUTF16(L"abcdefghijklmnopqrstuvwxzyabcdefg")); 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursorTo(SelectionModel(render_text->text().length(), 12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CURSOR_FORWARD)); 12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int width = render_text->GetStringSize().width(); 12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_GT(width, 10); 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that the cursor is placed at the width of its preceding text. 12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(Rect(width + 10, 1)); 12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(width, render_text->GetUpdatedCursorBounds().x()); 12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that shrinking the display rectangle keeps the cursor in view. 12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(Rect(width - 10, 1)); 12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(render_text->display_rect().width() - 1, 12142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->GetUpdatedCursorBounds().right()); 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(msw): Investigate why this test passes with 12172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |GetUpdateCursorBounds().x()|, while the above have to use 12182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |.right()|. 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that the text will pan to fill its expanding display rectangle. 12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(Rect(width - 5, 1)); 12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(render_text->display_rect().width() - 1, 12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->GetUpdatedCursorBounds().x()); 12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that a sufficiently large display rectangle shows all the text. 12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(Rect(width + 10, 1)); 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(width, render_text->GetUpdatedCursorBounds().x()); 12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Repeat the test with RTL text. 12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(WideToUTF16(L"\x5d0\x5d1\x5d2\x5d3\x5d4\x5d5\x5d6\x5d7" 12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) L"\x5d8\x5d9\x5da\x5db\x5dc\x5dd\x5de\x5df")); 12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursorTo(SelectionModel(0, CURSOR_FORWARD)); 12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) width = render_text->GetStringSize().width(); 12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_GT(width, 10); 12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that the cursor is placed at the width of its preceding text. 12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(Rect(width + 10, 1)); 12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(width, render_text->GetUpdatedCursorBounds().x()); 12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that shrinking the display rectangle keeps the cursor in view. 12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(Rect(width - 10, 1)); 12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(render_text->display_rect().width() - 1, 12422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) render_text->GetUpdatedCursorBounds().right()); 12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that the text will pan to fill its expanding display rectangle. 12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(Rect(width - 5, 1)); 12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(render_text->display_rect().width() - 1, 12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->GetUpdatedCursorBounds().x()); 12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that a sufficiently large display rectangle shows all the text. 12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(Rect(width + 10, 1)); 12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(width, render_text->GetUpdatedCursorBounds().x()); 12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(RenderTextTest, DisplayRectShowsCursorRTL) { 12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set the application default text direction to RTL. 12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool was_rtl = base::i18n::IsRTL(); 12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetRTL(true); 12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); 12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(WideToUTF16(L"abcdefghijklmnopqrstuvwxzyabcdefg")); 12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursorTo(SelectionModel(0, CURSOR_FORWARD)); 12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int width = render_text->GetStringSize().width(); 12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_GT(width, 10); 12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that the cursor is placed at the width of its preceding text. 12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(Rect(width + 10, 1)); 12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(render_text->display_rect().width() - width - 1, 12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->GetUpdatedCursorBounds().x()); 12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that shrinking the display rectangle keeps the cursor in view. 12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(Rect(width - 10, 1)); 12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, render_text->GetUpdatedCursorBounds().x()); 12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that the text will pan to fill its expanding display rectangle. 12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(Rect(width - 5, 1)); 12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, render_text->GetUpdatedCursorBounds().x()); 12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that a sufficiently large display rectangle shows all the text. 12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(Rect(width + 10, 1)); 12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(render_text->display_rect().width() - width - 1, 12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->GetUpdatedCursorBounds().x()); 12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Repeat the test with RTL text. 12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetText(WideToUTF16(L"\x5d0\x5d1\x5d2\x5d3\x5d4\x5d5\x5d6\x5d7" 12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) L"\x5d8\x5d9\x5da\x5db\x5dc\x5dd\x5de\x5df")); 12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->MoveCursorTo(SelectionModel(render_text->text().length(), 12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CURSOR_FORWARD)); 12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) width = render_text->GetStringSize().width(); 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_GT(width, 10); 12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that the cursor is placed at the width of its preceding text. 12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(Rect(width + 10, 1)); 12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(render_text->display_rect().width() - width - 1, 12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->GetUpdatedCursorBounds().x()); 12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that shrinking the display rectangle keeps the cursor in view. 12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(Rect(width - 10, 1)); 12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, render_text->GetUpdatedCursorBounds().x()); 12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that the text will pan to fill its expanding display rectangle. 13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(Rect(width - 5, 1)); 13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, render_text->GetUpdatedCursorBounds().x()); 13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that a sufficiently large display rectangle shows all the text. 13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->SetDisplayRect(Rect(width + 10, 1)); 13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(render_text->display_rect().width() - width - 1, 13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) render_text->GetUpdatedCursorBounds().x()); 13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reset the application default text direction to LTR. 13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetRTL(was_rtl); 13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(was_rtl, base::i18n::IsRTL()); 13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // !defined(OS_MACOSX) 13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace gfx 1316