|
1 /* |
|
2 * Copyright (C) 2010 Google Inc. All rights reserved. |
|
3 * |
|
4 * Redistribution and use in source and binary forms, with or without |
|
5 * modification, are permitted provided that the following conditions are |
|
6 * met: |
|
7 * |
|
8 * * Redistributions of source code must retain the above copyright |
|
9 * notice, this list of conditions and the following disclaimer. |
|
10 * * Redistributions in binary form must reproduce the above |
|
11 * copyright notice, this list of conditions and the following disclaimer |
|
12 * in the documentation and/or other materials provided with the |
|
13 * distribution. |
|
14 * * Neither the name of Google Inc. nor the names of its |
|
15 * contributors may be used to endorse or promote products derived from |
|
16 * this software without specific prior written permission. |
|
17 * |
|
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
|
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
|
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
29 */ |
|
30 |
|
31 #include "config.h" |
|
32 |
|
33 #include <gtest/gtest.h> |
|
34 |
|
35 #include "PlatformString.h" |
|
36 #include "UniscribeHelper.h" |
|
37 |
|
38 using namespace WebCore; |
|
39 |
|
40 namespace { |
|
41 |
|
42 class UniscribeTest : public testing::Test { |
|
43 public: |
|
44 UniscribeTest() |
|
45 { |
|
46 } |
|
47 |
|
48 // Returns an HFONT with the given name. The caller does not have to free |
|
49 // this, it will be automatically freed at the end of the test. Returns 0 |
|
50 // on failure. On success, the |
|
51 HFONT MakeFont(const wchar_t* fontName, SCRIPT_CACHE** cache) |
|
52 { |
|
53 LOGFONT lf; |
|
54 memset(&lf, 0, sizeof(LOGFONT)); |
|
55 lf.lfHeight = 20; |
|
56 wcscpy_s(lf.lfFaceName, fontName); |
|
57 |
|
58 HFONT hfont = CreateFontIndirect(&lf); |
|
59 if (!hfont) |
|
60 return 0; |
|
61 |
|
62 *cache = new SCRIPT_CACHE; |
|
63 **cache = 0; |
|
64 createdFonts.append(std::make_pair(hfont, *cache)); |
|
65 return hfont; |
|
66 } |
|
67 |
|
68 protected: |
|
69 // Default font properties structure for tests to use. |
|
70 SCRIPT_FONTPROPERTIES properties; |
|
71 |
|
72 private: |
|
73 virtual void SetUp() |
|
74 { |
|
75 memset(&properties, 0, sizeof(SCRIPT_FONTPROPERTIES)); |
|
76 properties.cBytes = sizeof(SCRIPT_FONTPROPERTIES); |
|
77 properties.wgBlank = ' '; |
|
78 properties.wgDefault = '?'; // Used when the char is not in the font. |
|
79 properties.wgInvalid = '#'; // Used for invalid characters. |
|
80 } |
|
81 |
|
82 virtual void TearDown() |
|
83 { |
|
84 // Free any allocated fonts. |
|
85 for (size_t i = 0; i < createdFonts.size(); i++) { |
|
86 DeleteObject(createdFonts[i].first); |
|
87 ScriptFreeCache(createdFonts[i].second); |
|
88 delete createdFonts[i].second; |
|
89 } |
|
90 createdFonts.clear(); |
|
91 } |
|
92 |
|
93 // Tracks allocated fonts so we can delete them at the end of the test. |
|
94 // The script cache pointer is heap allocated and must be freed. |
|
95 Vector< std::pair<HFONT, SCRIPT_CACHE*> > createdFonts; |
|
96 }; |
|
97 |
|
98 } // namespace |
|
99 |
|
100 // This test tests giving Uniscribe a very large buffer, which will cause a |
|
101 // failure. |
|
102 TEST_F(UniscribeTest, TooBig) |
|
103 { |
|
104 // Make a large string with an e with a zillion combining accents. |
|
105 String input(L"e"); |
|
106 for (int i = 0; i < 100000; i++) |
|
107 input.append(static_cast<UChar>(0x301)); // Combining acute accent. |
|
108 |
|
109 SCRIPT_CACHE* scriptCache; |
|
110 HFONT hfont = MakeFont(L"Times New Roman", &scriptCache); |
|
111 ASSERT_TRUE(hfont); |
|
112 |
|
113 // Test a long string without the normal length protection we have. This |
|
114 // will cause shaping to fail. |
|
115 { |
|
116 UniscribeHelper uniscribe( |
|
117 input.characters(), static_cast<int>(input.length()), |
|
118 false, hfont, scriptCache, &properties); |
|
119 uniscribe.initWithOptionalLengthProtection(false); |
|
120 |
|
121 // There should be one shaping entry, with nothing in it. |
|
122 ASSERT_EQ(1, uniscribe.m_shapes.size()); |
|
123 EXPECT_EQ(0, uniscribe.m_shapes[0].m_glyphs.size()); |
|
124 EXPECT_EQ(0, uniscribe.m_shapes[0].m_logs.size()); |
|
125 EXPECT_EQ(0, uniscribe.m_shapes[0].m_visualAttributes.size()); |
|
126 EXPECT_EQ(0, uniscribe.m_shapes[0].m_advance.size()); |
|
127 EXPECT_EQ(0, uniscribe.m_shapes[0].m_offsets.size()); |
|
128 EXPECT_EQ(0, uniscribe.m_shapes[0].m_justify.size()); |
|
129 EXPECT_EQ(0, uniscribe.m_shapes[0].m_abc.abcA); |
|
130 EXPECT_EQ(0, uniscribe.m_shapes[0].m_abc.abcB); |
|
131 EXPECT_EQ(0, uniscribe.m_shapes[0].m_abc.abcC); |
|
132 |
|
133 // The sizes of the other stuff should match the shaping entry. |
|
134 EXPECT_EQ(1, uniscribe.m_runs.size()); |
|
135 EXPECT_EQ(1, uniscribe.m_screenOrder.size()); |
|
136 |
|
137 // Check that the various querying functions handle the empty case |
|
138 // properly. |
|
139 EXPECT_EQ(0, uniscribe.width()); |
|
140 EXPECT_EQ(0, uniscribe.firstGlyphForCharacter(0)); |
|
141 EXPECT_EQ(0, uniscribe.firstGlyphForCharacter(1000)); |
|
142 EXPECT_EQ(0, uniscribe.xToCharacter(0)); |
|
143 EXPECT_EQ(0, uniscribe.xToCharacter(1000)); |
|
144 } |
|
145 |
|
146 // Now test the very large string and make sure it is handled properly by |
|
147 // the length protection. |
|
148 { |
|
149 UniscribeHelper uniscribe( |
|
150 input.characters(), static_cast<int>(input.length()), |
|
151 false, hfont, scriptCache, &properties); |
|
152 uniscribe.initWithOptionalLengthProtection(true); |
|
153 |
|
154 // There should be 0 runs and shapes. |
|
155 EXPECT_EQ(0, uniscribe.m_runs.size()); |
|
156 EXPECT_EQ(0, uniscribe.m_shapes.size()); |
|
157 EXPECT_EQ(0, uniscribe.m_screenOrder.size()); |
|
158 |
|
159 EXPECT_EQ(0, uniscribe.width()); |
|
160 EXPECT_EQ(0, uniscribe.firstGlyphForCharacter(0)); |
|
161 EXPECT_EQ(0, uniscribe.firstGlyphForCharacter(1000)); |
|
162 EXPECT_EQ(0, uniscribe.xToCharacter(0)); |
|
163 EXPECT_EQ(0, uniscribe.xToCharacter(1000)); |
|
164 } |
|
165 } |