|
OLD | NEW |
---|---|
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/gfx/uniscribe.h" | 5 #include "config.h" |
6 #include "base/win_util.h" | 6 #include "UniscribeHelper.h" |
7 | |
8 #include "PlatformString.h" | |
7 #include "testing/gtest/include/gtest/gtest.h" | 9 #include "testing/gtest/include/gtest/gtest.h" |
Erik does not do reviews
2008/11/17 17:01:34
Do you think it will be an issue to land gtest dep
brettw
2008/11/17 17:26:49
I don't know about gtest. Eric Seidel has tried to
| |
8 | 10 |
9 // This must be in the gfx namespace for the friend statements in uniscribe.h | 11 // This must be in the gfx namespace for the friend statements in uniscribe.h |
10 // to work. | 12 // to work. |
11 namespace gfx { | 13 namespace WebCore { |
12 | 14 |
13 namespace { | 15 namespace { |
14 | 16 |
15 class UniscribeTest : public testing::Test { | 17 class UniscribeTest : public testing::Test { |
16 public: | 18 public: |
17 UniscribeTest() { | 19 UniscribeTest() |
18 } | 20 { |
21 } | |
19 | 22 |
20 // Returns an HFONT with the given name. The caller does not have to free | 23 // Returns an HFONT with the given name. The caller does not have to free |
21 // this, it will be automatically freed at the end of the test. Returns NULL | 24 // this, it will be automatically freed at the end of the test. Returns NULL |
22 // on failure. On success, the | 25 // on failure. On success, the |
23 HFONT MakeFont(const wchar_t* font_name, SCRIPT_CACHE** cache) { | 26 HFONT MakeFont(const wchar_t* fontName, SCRIPT_CACHE** cache) |
24 LOGFONT lf; | 27 { |
25 memset(&lf, 0, sizeof(LOGFONT)); | 28 LOGFONT lf; |
26 lf.lfHeight = 20; | 29 memset(&lf, 0, sizeof(LOGFONT)); |
27 wcscpy_s(lf.lfFaceName, font_name); | 30 lf.lfHeight = 20; |
31 wcscpy_s(lf.lfFaceName, fontName); | |
28 | 32 |
29 HFONT hfont = CreateFontIndirect(&lf); | 33 HFONT hfont = CreateFontIndirect(&lf); |
30 if (!hfont) | 34 if (!hfont) |
31 return NULL; | 35 return NULL; |
32 | 36 |
33 *cache = new SCRIPT_CACHE; | 37 *cache = new SCRIPT_CACHE; |
34 **cache = NULL; | 38 **cache = NULL; |
35 created_fonts_.push_back(std::make_pair(hfont, *cache)); | 39 m_createdFonts.append(std::make_pair(hfont, *cache)); |
36 return hfont; | 40 return hfont; |
37 } | 41 } |
38 | 42 |
39 protected: | 43 protected: |
40 // Default font properties structure for tests to use. | 44 // Default font properties structure for tests to use. |
41 SCRIPT_FONTPROPERTIES properties_; | 45 SCRIPT_FONTPROPERTIES m_properties; |
42 | 46 |
43 private: | 47 private: |
44 virtual void SetUp() { | 48 virtual void SetUp() |
45 memset(&properties_, 0, sizeof(SCRIPT_FONTPROPERTIES)); | 49 { |
46 properties_.cBytes = sizeof(SCRIPT_FONTPROPERTIES); | 50 memset(&m_properties, 0, sizeof(SCRIPT_FONTPROPERTIES)); |
47 properties_.wgBlank = ' '; | 51 m_properties.cBytes = sizeof(SCRIPT_FONTPROPERTIES); |
48 properties_.wgDefault = '?'; // Used when the character is not in the font. | 52 m_properties.wgBlank = ' '; |
49 properties_.wgInvalid = '#'; // Used for invalid characters. | 53 m_properties.wgDefault = '?'; // Used when the char is not in the font. |
50 } | 54 m_properties.wgInvalid = '#'; // Used for invalid characters. |
55 } | |
51 | 56 |
52 virtual void TearDown() { | 57 virtual void TearDown() |
53 // Free any allocated fonts. | 58 { |
54 for (size_t i = 0; i < created_fonts_.size(); i++) { | 59 // Free any allocated fonts. |
55 DeleteObject(created_fonts_[i].first); | 60 for (size_t i = 0; i < m_createdFonts.size(); i++) { |
56 ScriptFreeCache(created_fonts_[i].second); | 61 DeleteObject(m_createdFonts[i].first); |
57 delete created_fonts_[i].second; | 62 ScriptFreeCache(m_createdFonts[i].second); |
63 delete m_createdFonts[i].second; | |
64 } | |
65 m_createdFonts.clear(); | |
58 } | 66 } |
59 created_fonts_.clear(); | |
60 } | |
61 | 67 |
62 // Tracks allocated fonts so we can delete them at the end of the test. | 68 // Tracks allocated fonts so we can delete them at the end of the test. |
63 // The script cache pointer is heap allocated and must be freed. | 69 // The script cache pointer is heap allocated and must be freed. |
64 std::vector< std::pair<HFONT, SCRIPT_CACHE*> > created_fonts_; | 70 Vector< std::pair<HFONT, SCRIPT_CACHE*> > m_createdFonts; |
65 | |
66 DISALLOW_EVIL_CONSTRUCTORS(UniscribeTest); | |
67 }; | 71 }; |
68 | 72 |
69 } // namespace | 73 } // namespace |
70 | 74 |
71 // This test tests giving Uniscribe a very large buffer, which will cause a | 75 // This test tests giving Uniscribe a very large buffer, which will cause a |
72 // failure. | 76 // failure. |
73 TEST_F(UniscribeTest, TooBig) { | 77 TEST_F(UniscribeTest, TooBig) |
74 // This test will only run on Windows XP. It seems Uniscribe does not have the | 78 { |
75 // internal limit on Windows 2000 that we rely on to cause this failure. | 79 // Make a large string with an e with a zillion combining accents. |
76 if (win_util::GetWinVersion() <= win_util::WINVERSION_2000) | 80 String input(L"e"); |
77 return; | 81 for (int i = 0; i < 100000; i++) |
82 input.append(static_cast<UChar>(0x301)); // Combining acute accent. | |
78 | 83 |
79 // Make a large string with an e with a zillion combining accents. | 84 SCRIPT_CACHE* scriptCache; |
80 std::wstring input(L"e"); | 85 HFONT hfont = MakeFont(L"Times New Roman", &scriptCache); |
81 for (int i = 0; i < 100000; i++) | 86 ASSERT_TRUE(hfont); |
82 input.push_back(0x301); // Combining acute accent. | |
83 | 87 |
84 SCRIPT_CACHE* script_cache; | 88 // Test a long string without the normal length protection we have. This |
85 HFONT hfont = MakeFont(L"Times New Roman", &script_cache); | 89 // will cause shaping to fail. |
86 ASSERT_TRUE(hfont); | 90 { |
91 UniscribeHelper uniscribe( | |
92 input.characters(), static_cast<int>(input.length()), | |
93 false, hfont, scriptCache, &m_properties); | |
94 uniscribe.InitWithOptionalLengthProtection(false); | |
87 | 95 |
88 // Test a long string without the normal length protection we have. This will | 96 // There should be one shaping entry, with nothing in it. |
89 // cause shaping to fail. | 97 ASSERT_EQ(1, uniscribe.m_shapes.size()); |
90 { | 98 EXPECT_EQ(0, uniscribe.m_shapes[0].m_glyphs.size()); |
91 gfx::UniscribeState uniscribe(input.data(), static_cast<int>(input.size()), | 99 EXPECT_EQ(0, uniscribe.m_shapes[0].m_logs.size()); |
92 false, hfont, script_cache, &properties_); | 100 EXPECT_EQ(0, uniscribe.m_shapes[0].m_visattr.size()); |
93 uniscribe.InitWithOptionalLengthProtection(false); | 101 EXPECT_EQ(0, uniscribe.m_shapes[0].m_advance.size()); |
102 EXPECT_EQ(0, uniscribe.m_shapes[0].m_offsets.size()); | |
103 EXPECT_EQ(0, uniscribe.m_shapes[0].m_justify.size()); | |
104 EXPECT_EQ(0, uniscribe.m_shapes[0].m_abc.abcA); | |
105 EXPECT_EQ(0, uniscribe.m_shapes[0].m_abc.abcB); | |
106 EXPECT_EQ(0, uniscribe.m_shapes[0].m_abc.abcC); | |
94 | 107 |
95 // There should be one shaping entry, with nothing in it. | 108 // The sizes of the other stuff should match the shaping entry. |
96 ASSERT_EQ(1, uniscribe.shapes_->size()); | 109 EXPECT_EQ(1, uniscribe.m_runs.size()); |
97 EXPECT_EQ(0, uniscribe.shapes_[0].glyphs->size()); | 110 EXPECT_EQ(1, uniscribe.m_screenOrder.size()); |
98 EXPECT_EQ(0, uniscribe.shapes_[0].logs->size()); | |
99 EXPECT_EQ(0, uniscribe.shapes_[0].visattr->size()); | |
100 EXPECT_EQ(0, uniscribe.shapes_[0].advance->size()); | |
101 EXPECT_EQ(0, uniscribe.shapes_[0].offsets->size()); | |
102 EXPECT_EQ(0, uniscribe.shapes_[0].justify->size()); | |
103 EXPECT_EQ(0, uniscribe.shapes_[0].abc.abcA); | |
104 EXPECT_EQ(0, uniscribe.shapes_[0].abc.abcB); | |
105 EXPECT_EQ(0, uniscribe.shapes_[0].abc.abcC); | |
106 | 111 |
107 // The sizes of the other stuff should match the shaping entry. | 112 // Check that the various querying functions handle the empty case |
108 EXPECT_EQ(1, uniscribe.runs_->size()); | 113 // properly. |
109 EXPECT_EQ(1, uniscribe.screen_order_->size()); | 114 EXPECT_EQ(0, uniscribe.Width()); |
115 EXPECT_EQ(0, uniscribe.FirstGlyphForCharacter(0)); | |
116 EXPECT_EQ(0, uniscribe.FirstGlyphForCharacter(1000)); | |
117 EXPECT_EQ(0, uniscribe.XToCharacter(0)); | |
118 EXPECT_EQ(0, uniscribe.XToCharacter(1000)); | |
119 } | |
110 | 120 |
111 // Check that the various querying functions handle the empty case properly. | 121 // Now test the very large string and make sure it is handled properly by |
112 EXPECT_EQ(0, uniscribe.Width()); | 122 // the length protection. |
113 EXPECT_EQ(0, uniscribe.FirstGlyphForCharacter(0)); | 123 { |
114 EXPECT_EQ(0, uniscribe.FirstGlyphForCharacter(1000)); | 124 UniscribeHelper uniscribe( |
115 EXPECT_EQ(0, uniscribe.XToCharacter(0)); | 125 input.characters(), static_cast<int>(input.length()), |
116 EXPECT_EQ(0, uniscribe.XToCharacter(1000)); | 126 false, hfont, scriptCache, &m_properties); |
117 } | 127 uniscribe.InitWithOptionalLengthProtection(true); |
118 | 128 |
119 // Now test the very large string and make sure it is handled properly by the | 129 // There should be 0 runs and shapes. |
120 // length protection. | 130 EXPECT_EQ(0, uniscribe.m_runs.size()); |
121 { | 131 EXPECT_EQ(0, uniscribe.m_shapes.size()); |
122 gfx::UniscribeState uniscribe(input.data(), static_cast<int>(input.size()), | 132 EXPECT_EQ(0, uniscribe.m_screenOrder.size()); |
123 false, hfont, script_cache, &properties_); | |
124 uniscribe.InitWithOptionalLengthProtection(true); | |
125 | 133 |
126 // There should be 0 runs and shapes. | 134 EXPECT_EQ(0, uniscribe.Width()); |
127 EXPECT_EQ(0, uniscribe.runs_->size()); | 135 EXPECT_EQ(0, uniscribe.FirstGlyphForCharacter(0)); |
128 EXPECT_EQ(0, uniscribe.shapes_->size()); | 136 EXPECT_EQ(0, uniscribe.FirstGlyphForCharacter(1000)); |
129 EXPECT_EQ(0, uniscribe.screen_order_->size()); | 137 EXPECT_EQ(0, uniscribe.XToCharacter(0)); |
130 | 138 EXPECT_EQ(0, uniscribe.XToCharacter(1000)); |
131 EXPECT_EQ(0, uniscribe.Width()); | 139 } |
132 EXPECT_EQ(0, uniscribe.FirstGlyphForCharacter(0)); | |
133 EXPECT_EQ(0, uniscribe.FirstGlyphForCharacter(1000)); | |
134 EXPECT_EQ(0, uniscribe.XToCharacter(0)); | |
135 EXPECT_EQ(0, uniscribe.XToCharacter(1000)); | |
136 } | |
137 } | 140 } |
138 | 141 |
139 } // namespace gfx | 142 } // namespace gfx |
Erik does not do reviews
2008/11/17 17:01:34
update comment
| |
140 | |
OLD | NEW |