OLD | NEW |
1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2014 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 "platform/fonts/shaping/CachingWordShaper.h" | 5 #include "platform/fonts/shaping/CachingWordShaper.h" |
6 | 6 |
7 #include "platform/fonts/CharacterRange.h" | 7 #include "platform/fonts/CharacterRange.h" |
8 #include "platform/fonts/FontCache.h" | 8 #include "platform/fonts/FontCache.h" |
9 #include "platform/fonts/GlyphBuffer.h" | |
10 #include "platform/fonts/shaping/CachingWordShapeIterator.h" | 9 #include "platform/fonts/shaping/CachingWordShapeIterator.h" |
11 #include "platform/fonts/shaping/ShapeResultTestInfo.h" | 10 #include "platform/fonts/shaping/ShapeResultTestInfo.h" |
12 #include "testing/gtest/include/gtest/gtest.h" | 11 #include "testing/gtest/include/gtest/gtest.h" |
13 #include "wtf/PtrUtil.h" | 12 #include "wtf/PtrUtil.h" |
14 #include <memory> | 13 #include <memory> |
15 | 14 |
16 namespace blink { | 15 namespace blink { |
17 | 16 |
18 class CachingWordShaperTest : public ::testing::Test { | 17 class CachingWordShaperTest : public ::testing::Test { |
19 protected: | 18 protected: |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 ASSERT_EQ(5u, offset); | 107 ASSERT_EQ(5u, offset); |
109 ASSERT_FALSE(iterator.next(&result)); | 108 ASSERT_FALSE(iterator.next(&result)); |
110 } | 109 } |
111 | 110 |
112 // Tests that filling a glyph buffer for a specific range returns the same | 111 // Tests that filling a glyph buffer for a specific range returns the same |
113 // results when shaping word by word as when shaping the full run in one go. | 112 // results when shaping word by word as when shaping the full run in one go. |
114 TEST_F(CachingWordShaperTest, CommonAccentLeftToRightFillGlyphBuffer) { | 113 TEST_F(CachingWordShaperTest, CommonAccentLeftToRightFillGlyphBuffer) { |
115 // "/. ." with an accent mark over the first dot. | 114 // "/. ." with an accent mark over the first dot. |
116 const UChar str[] = {0x2F, 0x301, 0x2E, 0x20, 0x2E, 0x0}; | 115 const UChar str[] = {0x2F, 0x301, 0x2E, 0x20, 0x2E, 0x0}; |
117 TextRun textRun(str, 5); | 116 TextRun textRun(str, 5); |
| 117 TextRunPaintInfo runInfo(textRun); |
| 118 runInfo.to = 3; |
118 | 119 |
119 CachingWordShaper shaper(font); | 120 ShapeResultBloberizer bloberizer(font, 1); |
120 GlyphBuffer glyphBuffer; | 121 CachingWordShaper(font).fillGlyphs(runInfo, bloberizer); |
121 shaper.fillGlyphBuffer(textRun, &glyphBuffer, 0, 3); | |
122 | 122 |
123 Font referenceFont(fontDescription); | 123 Font referenceFont(fontDescription); |
124 referenceFont.update(nullptr); | 124 referenceFont.update(nullptr); |
125 CachingWordShaper referenceShaper(referenceFont); | |
126 GlyphBuffer referenceGlyphBuffer; | |
127 referenceFont.setCanShapeWordByWordForTesting(false); | 125 referenceFont.setCanShapeWordByWordForTesting(false); |
128 referenceShaper.fillGlyphBuffer(textRun, &referenceGlyphBuffer, 0, 3); | 126 ShapeResultBloberizer referenceBloberizer(referenceFont, 1); |
| 127 CachingWordShaper(referenceFont).fillGlyphs(runInfo, referenceBloberizer); |
129 | 128 |
130 ASSERT_EQ(referenceGlyphBuffer.glyphAt(0), glyphBuffer.glyphAt(0)); | 129 const auto& glyphs = |
131 ASSERT_EQ(referenceGlyphBuffer.glyphAt(1), glyphBuffer.glyphAt(1)); | 130 ShapeResultBloberizerTestInfo::pendingRunGlyphs(bloberizer); |
132 ASSERT_EQ(referenceGlyphBuffer.glyphAt(2), glyphBuffer.glyphAt(2)); | 131 ASSERT_EQ(glyphs.size(), 3ul); |
| 132 const auto referenceGlyphs = |
| 133 ShapeResultBloberizerTestInfo::pendingRunGlyphs(referenceBloberizer); |
| 134 ASSERT_EQ(referenceGlyphs.size(), 3ul); |
| 135 |
| 136 EXPECT_EQ(referenceGlyphs[0], glyphs[0]); |
| 137 EXPECT_EQ(referenceGlyphs[1], glyphs[1]); |
| 138 EXPECT_EQ(referenceGlyphs[2], glyphs[2]); |
133 } | 139 } |
134 | 140 |
135 // Tests that filling a glyph buffer for a specific range returns the same | 141 // Tests that filling a glyph buffer for a specific range returns the same |
136 // results when shaping word by word as when shaping the full run in one go. | 142 // results when shaping word by word as when shaping the full run in one go. |
137 TEST_F(CachingWordShaperTest, CommonAccentRightToLeftFillGlyphBuffer) { | 143 TEST_F(CachingWordShaperTest, CommonAccentRightToLeftFillGlyphBuffer) { |
138 // "[] []" with an accent mark over the last square bracket. | 144 // "[] []" with an accent mark over the last square bracket. |
139 const UChar str[] = {0x5B, 0x5D, 0x20, 0x5B, 0x301, 0x5D, 0x0}; | 145 const UChar str[] = {0x5B, 0x5D, 0x20, 0x5B, 0x301, 0x5D, 0x0}; |
140 TextRun textRun(str, 6); | 146 TextRun textRun(str, 6); |
141 textRun.setDirection(TextDirection::kRtl); | 147 textRun.setDirection(TextDirection::kRtl); |
| 148 TextRunPaintInfo runInfo(textRun); |
| 149 runInfo.from = 1; |
142 | 150 |
143 CachingWordShaper shaper(font); | 151 ShapeResultBloberizer bloberizer(font, 1); |
144 GlyphBuffer glyphBuffer; | 152 CachingWordShaper(font).fillGlyphs(runInfo, bloberizer); |
145 shaper.fillGlyphBuffer(textRun, &glyphBuffer, 1, 6); | |
146 | 153 |
147 Font referenceFont(fontDescription); | 154 Font referenceFont(fontDescription); |
148 referenceFont.update(nullptr); | 155 referenceFont.update(nullptr); |
149 CachingWordShaper referenceShaper(referenceFont); | |
150 GlyphBuffer referenceGlyphBuffer; | |
151 referenceFont.setCanShapeWordByWordForTesting(false); | 156 referenceFont.setCanShapeWordByWordForTesting(false); |
152 referenceShaper.fillGlyphBuffer(textRun, &referenceGlyphBuffer, 1, 6); | 157 ShapeResultBloberizer referenceBloberizer(referenceFont, 1); |
| 158 CachingWordShaper(referenceFont).fillGlyphs(runInfo, referenceBloberizer); |
153 | 159 |
154 ASSERT_EQ(5u, referenceGlyphBuffer.size()); | 160 const auto& glyphs = |
155 ASSERT_EQ(referenceGlyphBuffer.size(), glyphBuffer.size()); | 161 ShapeResultBloberizerTestInfo::pendingRunGlyphs(bloberizer); |
| 162 ASSERT_EQ(5u, glyphs.size()); |
| 163 const auto referenceGlyphs = |
| 164 ShapeResultBloberizerTestInfo::pendingRunGlyphs(referenceBloberizer); |
| 165 ASSERT_EQ(5u, referenceGlyphs.size()); |
156 | 166 |
157 ASSERT_EQ(referenceGlyphBuffer.glyphAt(0), glyphBuffer.glyphAt(0)); | 167 EXPECT_EQ(referenceGlyphs[0], glyphs[0]); |
158 ASSERT_EQ(referenceGlyphBuffer.glyphAt(1), glyphBuffer.glyphAt(1)); | 168 EXPECT_EQ(referenceGlyphs[1], glyphs[1]); |
159 ASSERT_EQ(referenceGlyphBuffer.glyphAt(2), glyphBuffer.glyphAt(2)); | 169 EXPECT_EQ(referenceGlyphs[2], glyphs[2]); |
160 ASSERT_EQ(referenceGlyphBuffer.glyphAt(3), glyphBuffer.glyphAt(3)); | 170 EXPECT_EQ(referenceGlyphs[3], glyphs[3]); |
161 ASSERT_EQ(referenceGlyphBuffer.glyphAt(4), glyphBuffer.glyphAt(4)); | 171 EXPECT_EQ(referenceGlyphs[4], glyphs[4]); |
162 } | 172 } |
163 | 173 |
164 // Tests that runs with zero glyphs (the ZWJ non-printable character in this | 174 // Tests that runs with zero glyphs (the ZWJ non-printable character in this |
165 // case) are handled correctly. This test passes if it does not cause a crash. | 175 // case) are handled correctly. This test passes if it does not cause a crash. |
166 TEST_F(CachingWordShaperTest, SubRunWithZeroGlyphs) { | 176 TEST_F(CachingWordShaperTest, SubRunWithZeroGlyphs) { |
167 // "Foo ‌ bar" | 177 // "Foo ‌ bar" |
168 const UChar str[] = {0x46, 0x6F, 0x6F, 0x20, 0x200C, | 178 const UChar str[] = {0x46, 0x6F, 0x6F, 0x20, 0x200C, |
169 0x20, 0x62, 0x61, 0x71, 0x0}; | 179 0x20, 0x62, 0x61, 0x71, 0x0}; |
170 TextRun textRun(str, 9); | 180 TextRun textRun(str, 9); |
171 | 181 |
172 CachingWordShaper shaper(font); | 182 CachingWordShaper shaper(font); |
173 FloatRect glyphBounds; | 183 FloatRect glyphBounds; |
174 ASSERT_GT(shaper.width(textRun, nullptr, &glyphBounds), 0); | 184 ASSERT_GT(shaper.width(textRun, nullptr, &glyphBounds), 0); |
175 | 185 |
176 GlyphBuffer glyphBuffer; | 186 ShapeResultBloberizer bloberizer(font, 1); |
177 shaper.fillGlyphBuffer(textRun, &glyphBuffer, 0, 8); | 187 TextRunPaintInfo runInfo(textRun); |
| 188 runInfo.to = 8; |
| 189 shaper.fillGlyphs(runInfo, bloberizer); |
178 | 190 |
179 shaper.getCharacterRange(textRun, 0, 8); | 191 shaper.getCharacterRange(textRun, 0, 8); |
180 } | 192 } |
181 | 193 |
182 TEST_F(CachingWordShaperTest, SegmentCJKByCharacter) { | 194 TEST_F(CachingWordShaperTest, SegmentCJKByCharacter) { |
183 const UChar str[] = {0x56FD, 0x56FD, // CJK Unified Ideograph | 195 const UChar str[] = {0x56FD, 0x56FD, // CJK Unified Ideograph |
184 'a', 'b', | 196 'a', 'b', |
185 0x56FD, // CJK Unified Ideograph | 197 0x56FD, // CJK Unified Ideograph |
186 'x', 'y', 'z', | 198 'x', 'y', 'z', |
187 0x3042, // HIRAGANA LETTER A | 199 0x3042, // HIRAGANA LETTER A |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
467 // The total width of periods and spaces should be longer than the width of | 479 // The total width of periods and spaces should be longer than the width of |
468 // periods alone. | 480 // periods alone. |
469 ASSERT_GT(periodsAndSpacesWidth, periodsWidth); | 481 ASSERT_GT(periodsAndSpacesWidth, periodsWidth); |
470 | 482 |
471 // The glyph bounds of periods and spaces should be longer than the glyph | 483 // The glyph bounds of periods and spaces should be longer than the glyph |
472 // bounds of periods alone. | 484 // bounds of periods alone. |
473 ASSERT_GT(periodsAndSpacesGlyphBounds.width(), periodsGlyphBounds.width()); | 485 ASSERT_GT(periodsAndSpacesGlyphBounds.width(), periodsGlyphBounds.width()); |
474 } | 486 } |
475 | 487 |
476 } // namespace blink | 488 } // namespace blink |
OLD | NEW |