| 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" | 9 #include "platform/fonts/GlyphBuffer.h" |
| 10 #include "platform/fonts/shaping/CachingWordShapeIterator.h" | 10 #include "platform/fonts/shaping/CachingWordShapeIterator.h" |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 ASSERT_FALSE(iterator.next(&result)); | 109 ASSERT_FALSE(iterator.next(&result)); |
| 110 } | 110 } |
| 111 | 111 |
| 112 // Tests that filling a glyph buffer for a specific range returns the same | 112 // 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. | 113 // results when shaping word by word as when shaping the full run in one go. |
| 114 TEST_F(CachingWordShaperTest, CommonAccentLeftToRightFillGlyphBuffer) { | 114 TEST_F(CachingWordShaperTest, CommonAccentLeftToRightFillGlyphBuffer) { |
| 115 // "/. ." with an accent mark over the first dot. | 115 // "/. ." with an accent mark over the first dot. |
| 116 const UChar str[] = {0x2F, 0x301, 0x2E, 0x20, 0x2E, 0x0}; | 116 const UChar str[] = {0x2F, 0x301, 0x2E, 0x20, 0x2E, 0x0}; |
| 117 TextRun textRun(str, 5); | 117 TextRun textRun(str, 5); |
| 118 | 118 |
| 119 CachingWordShaper shaper(cache.get()); | 119 CachingWordShaper shaper(font); |
| 120 GlyphBuffer glyphBuffer; | 120 GlyphBuffer glyphBuffer; |
| 121 shaper.fillGlyphBuffer(&font, textRun, fallbackFonts, &glyphBuffer, 0, 3); | 121 shaper.fillGlyphBuffer(textRun, &glyphBuffer, 0, 3); |
| 122 | 122 |
| 123 std::unique_ptr<ShapeCache> referenceCache = WTF::makeUnique<ShapeCache>(); | 123 Font referenceFont(fontDescription); |
| 124 CachingWordShaper referenceShaper(referenceCache.get()); | 124 referenceFont.update(nullptr); |
| 125 CachingWordShaper referenceShaper(referenceFont); |
| 125 GlyphBuffer referenceGlyphBuffer; | 126 GlyphBuffer referenceGlyphBuffer; |
| 126 font.setCanShapeWordByWordForTesting(false); | 127 referenceFont.setCanShapeWordByWordForTesting(false); |
| 127 referenceShaper.fillGlyphBuffer(&font, textRun, fallbackFonts, | 128 referenceShaper.fillGlyphBuffer(textRun, &referenceGlyphBuffer, 0, 3); |
| 128 &referenceGlyphBuffer, 0, 3); | |
| 129 | 129 |
| 130 ASSERT_EQ(referenceGlyphBuffer.glyphAt(0), glyphBuffer.glyphAt(0)); | 130 ASSERT_EQ(referenceGlyphBuffer.glyphAt(0), glyphBuffer.glyphAt(0)); |
| 131 ASSERT_EQ(referenceGlyphBuffer.glyphAt(1), glyphBuffer.glyphAt(1)); | 131 ASSERT_EQ(referenceGlyphBuffer.glyphAt(1), glyphBuffer.glyphAt(1)); |
| 132 ASSERT_EQ(referenceGlyphBuffer.glyphAt(2), glyphBuffer.glyphAt(2)); | 132 ASSERT_EQ(referenceGlyphBuffer.glyphAt(2), glyphBuffer.glyphAt(2)); |
| 133 } | 133 } |
| 134 | 134 |
| 135 // Tests that filling a glyph buffer for a specific range returns the same | 135 // 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. | 136 // results when shaping word by word as when shaping the full run in one go. |
| 137 TEST_F(CachingWordShaperTest, CommonAccentRightToLeftFillGlyphBuffer) { | 137 TEST_F(CachingWordShaperTest, CommonAccentRightToLeftFillGlyphBuffer) { |
| 138 // "[] []" with an accent mark over the last square bracket. | 138 // "[] []" with an accent mark over the last square bracket. |
| 139 const UChar str[] = {0x5B, 0x5D, 0x20, 0x5B, 0x301, 0x5D, 0x0}; | 139 const UChar str[] = {0x5B, 0x5D, 0x20, 0x5B, 0x301, 0x5D, 0x0}; |
| 140 TextRun textRun(str, 6); | 140 TextRun textRun(str, 6); |
| 141 textRun.setDirection(TextDirection::kRtl); | 141 textRun.setDirection(TextDirection::kRtl); |
| 142 | 142 |
| 143 CachingWordShaper shaper(cache.get()); | 143 CachingWordShaper shaper(font); |
| 144 GlyphBuffer glyphBuffer; | 144 GlyphBuffer glyphBuffer; |
| 145 shaper.fillGlyphBuffer(&font, textRun, fallbackFonts, &glyphBuffer, 1, 6); | 145 shaper.fillGlyphBuffer(textRun, &glyphBuffer, 1, 6); |
| 146 | 146 |
| 147 std::unique_ptr<ShapeCache> referenceCache = WTF::makeUnique<ShapeCache>(); | 147 Font referenceFont(fontDescription); |
| 148 CachingWordShaper referenceShaper(referenceCache.get()); | 148 referenceFont.update(nullptr); |
| 149 CachingWordShaper referenceShaper(referenceFont); |
| 149 GlyphBuffer referenceGlyphBuffer; | 150 GlyphBuffer referenceGlyphBuffer; |
| 150 font.setCanShapeWordByWordForTesting(false); | 151 referenceFont.setCanShapeWordByWordForTesting(false); |
| 151 referenceShaper.fillGlyphBuffer(&font, textRun, fallbackFonts, | 152 referenceShaper.fillGlyphBuffer(textRun, &referenceGlyphBuffer, 1, 6); |
| 152 &referenceGlyphBuffer, 1, 6); | |
| 153 | 153 |
| 154 ASSERT_EQ(5u, referenceGlyphBuffer.size()); | 154 ASSERT_EQ(5u, referenceGlyphBuffer.size()); |
| 155 ASSERT_EQ(referenceGlyphBuffer.size(), glyphBuffer.size()); | 155 ASSERT_EQ(referenceGlyphBuffer.size(), glyphBuffer.size()); |
| 156 | 156 |
| 157 ASSERT_EQ(referenceGlyphBuffer.glyphAt(0), glyphBuffer.glyphAt(0)); | 157 ASSERT_EQ(referenceGlyphBuffer.glyphAt(0), glyphBuffer.glyphAt(0)); |
| 158 ASSERT_EQ(referenceGlyphBuffer.glyphAt(1), glyphBuffer.glyphAt(1)); | 158 ASSERT_EQ(referenceGlyphBuffer.glyphAt(1), glyphBuffer.glyphAt(1)); |
| 159 ASSERT_EQ(referenceGlyphBuffer.glyphAt(2), glyphBuffer.glyphAt(2)); | 159 ASSERT_EQ(referenceGlyphBuffer.glyphAt(2), glyphBuffer.glyphAt(2)); |
| 160 ASSERT_EQ(referenceGlyphBuffer.glyphAt(3), glyphBuffer.glyphAt(3)); | 160 ASSERT_EQ(referenceGlyphBuffer.glyphAt(3), glyphBuffer.glyphAt(3)); |
| 161 ASSERT_EQ(referenceGlyphBuffer.glyphAt(4), glyphBuffer.glyphAt(4)); | 161 ASSERT_EQ(referenceGlyphBuffer.glyphAt(4), glyphBuffer.glyphAt(4)); |
| 162 } | 162 } |
| 163 | 163 |
| 164 // Tests that runs with zero glyphs (the ZWJ non-printable character in this | 164 // 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. | 165 // case) are handled correctly. This test passes if it does not cause a crash. |
| 166 TEST_F(CachingWordShaperTest, SubRunWithZeroGlyphs) { | 166 TEST_F(CachingWordShaperTest, SubRunWithZeroGlyphs) { |
| 167 // "Foo ‌ bar" | 167 // "Foo ‌ bar" |
| 168 const UChar str[] = {0x46, 0x6F, 0x6F, 0x20, 0x200C, | 168 const UChar str[] = {0x46, 0x6F, 0x6F, 0x20, 0x200C, |
| 169 0x20, 0x62, 0x61, 0x71, 0x0}; | 169 0x20, 0x62, 0x61, 0x71, 0x0}; |
| 170 TextRun textRun(str, 9); | 170 TextRun textRun(str, 9); |
| 171 | 171 |
| 172 CachingWordShaper shaper(cache.get()); | 172 CachingWordShaper shaper(font); |
| 173 FloatRect glyphBounds; | 173 FloatRect glyphBounds; |
| 174 ASSERT_GT(shaper.width(&font, textRun, nullptr, &glyphBounds), 0); | 174 ASSERT_GT(shaper.width(textRun, nullptr, &glyphBounds), 0); |
| 175 | 175 |
| 176 GlyphBuffer glyphBuffer; | 176 GlyphBuffer glyphBuffer; |
| 177 shaper.fillGlyphBuffer(&font, textRun, fallbackFonts, &glyphBuffer, 0, 8); | 177 shaper.fillGlyphBuffer(textRun, &glyphBuffer, 0, 8); |
| 178 | 178 |
| 179 shaper.getCharacterRange(&font, textRun, 0, 8); | 179 shaper.getCharacterRange(textRun, 0, 8); |
| 180 } | 180 } |
| 181 | 181 |
| 182 TEST_F(CachingWordShaperTest, SegmentCJKByCharacter) { | 182 TEST_F(CachingWordShaperTest, SegmentCJKByCharacter) { |
| 183 const UChar str[] = {0x56FD, 0x56FD, // CJK Unified Ideograph | 183 const UChar str[] = {0x56FD, 0x56FD, // CJK Unified Ideograph |
| 184 'a', 'b', | 184 'a', 'b', |
| 185 0x56FD, // CJK Unified Ideograph | 185 0x56FD, // CJK Unified Ideograph |
| 186 'x', 'y', 'z', | 186 'x', 'y', 'z', |
| 187 0x3042, // HIRAGANA LETTER A | 187 0x3042, // HIRAGANA LETTER A |
| 188 0x56FD, // CJK Unified Ideograph | 188 0x56FD, // CJK Unified Ideograph |
| 189 0x0}; | 189 0x0}; |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 435 // using code point such as U+3042, but it'd fallback to system | 435 // using code point such as U+3042, but it'd fallback to system |
| 436 // fonts as the glyph is missing. | 436 // fonts as the glyph is missing. |
| 437 0x0}; | 437 0x0}; |
| 438 TextRun textRun(str, 1); | 438 TextRun textRun(str, 1); |
| 439 | 439 |
| 440 fontDescription.setOrientation(FontOrientation::VerticalMixed); | 440 fontDescription.setOrientation(FontOrientation::VerticalMixed); |
| 441 Font verticalMixedFont = Font(fontDescription); | 441 Font verticalMixedFont = Font(fontDescription); |
| 442 verticalMixedFont.update(nullptr); | 442 verticalMixedFont.update(nullptr); |
| 443 ASSERT_TRUE(verticalMixedFont.canShapeWordByWord()); | 443 ASSERT_TRUE(verticalMixedFont.canShapeWordByWord()); |
| 444 | 444 |
| 445 CachingWordShaper shaper(cache.get()); | 445 CachingWordShaper shaper(verticalMixedFont); |
| 446 FloatRect glyphBounds; | 446 FloatRect glyphBounds; |
| 447 HashSet<const SimpleFontData*> fallbackFonts; | 447 HashSet<const SimpleFontData*> fallbackFonts; |
| 448 ASSERT_GT( | 448 ASSERT_GT( |
| 449 shaper.width(&verticalMixedFont, textRun, &fallbackFonts, &glyphBounds), | 449 shaper.width(textRun, &fallbackFonts, &glyphBounds), |
| 450 0); | 450 0); |
| 451 EXPECT_EQ(0u, fallbackFonts.size()); | 451 EXPECT_EQ(0u, fallbackFonts.size()); |
| 452 } | 452 } |
| 453 | 453 |
| 454 TEST_F(CachingWordShaperTest, GlyphBoundsWithSpaces) { | 454 TEST_F(CachingWordShaperTest, GlyphBoundsWithSpaces) { |
| 455 CachingWordShaper shaper(cache.get()); | 455 CachingWordShaper shaper(font); |
| 456 | 456 |
| 457 TextRun periods(reinterpret_cast<const LChar*>(".........."), 10); | 457 TextRun periods(reinterpret_cast<const LChar*>(".........."), 10); |
| 458 FloatRect periodsGlyphBounds; | 458 FloatRect periodsGlyphBounds; |
| 459 float periodsWidth = | 459 float periodsWidth = shaper.width(periods, nullptr, &periodsGlyphBounds); |
| 460 shaper.width(&font, periods, nullptr, &periodsGlyphBounds); | |
| 461 | 460 |
| 462 TextRun periodsAndSpaces( | 461 TextRun periodsAndSpaces( |
| 463 reinterpret_cast<const LChar*>(". . . . . . . . . ."), 19); | 462 reinterpret_cast<const LChar*>(". . . . . . . . . ."), 19); |
| 464 FloatRect periodsAndSpacesGlyphBounds; | 463 FloatRect periodsAndSpacesGlyphBounds; |
| 465 float periodsAndSpacesWidth = shaper.width(&font, periodsAndSpaces, nullptr, | 464 float periodsAndSpacesWidth = shaper.width(periodsAndSpaces, nullptr, |
| 466 &periodsAndSpacesGlyphBounds); | 465 &periodsAndSpacesGlyphBounds); |
| 467 | 466 |
| 468 // The total width of periods and spaces should be longer than the width of | 467 // The total width of periods and spaces should be longer than the width of |
| 469 // periods alone. | 468 // periods alone. |
| 470 ASSERT_GT(periodsAndSpacesWidth, periodsWidth); | 469 ASSERT_GT(periodsAndSpacesWidth, periodsWidth); |
| 471 | 470 |
| 472 // The glyph bounds of periods and spaces should be longer than the glyph | 471 // The glyph bounds of periods and spaces should be longer than the glyph |
| 473 // bounds of periods alone. | 472 // bounds of periods alone. |
| 474 ASSERT_GT(periodsAndSpacesGlyphBounds.width(), periodsGlyphBounds.width()); | 473 ASSERT_GT(periodsAndSpacesGlyphBounds.width(), periodsGlyphBounds.width()); |
| 475 } | 474 } |
| 476 | 475 |
| 477 } // namespace blink | 476 } // namespace blink |
| OLD | NEW |