Changeset 254534 in webkit
- Timestamp:
- Jan 14, 2020 2:13:54 PM (4 years ago)
- Location:
- trunk
- Files:
-
- 4 added
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r254531 r254534 1 2020-01-14 Myles C. Maxfield <mmaxfield@apple.com> 2 3 [Cocoa] Glyph lookup should be language-sensitive (specifically between Yiddish and Hebrew) 4 https://bugs.webkit.org/show_bug.cgi?id=77568 5 <rdar://problem/14649193> 6 7 Reviewed by Simon Fraser. 8 9 * fast/text/locale-shaping-complex-expected-mismatch.html: Added. 10 * fast/text/locale-shaping-complex.html: Added. 11 * fast/text/locale-shaping-expected-mismatch.html: Added. 12 * fast/text/locale-shaping.html: Added. 13 * platform/gtk/TestExpectations: 14 * platform/mac/TestExpectations: 15 * platform/win/TestExpectations: 16 1 17 2020-01-14 Lauro Moura <lmoura@igalia.com> 2 18 -
trunk/LayoutTests/platform/gtk/TestExpectations
r254525 r254534 1207 1207 webkit.org/b/206223 imported/mozilla/svg/svg-integration/clipPath-html-02.xhtml 1208 1208 1209 # locale-specific shaping isn't implemented on any non-Cocoa port yet. 1210 webkit.org/b/77568 fast/text/locale-shaping.html [ ImageOnlyFailure ] 1211 webkit.org/b/77568 fast/text/locale-shaping-complex.html [ ImageOnlyFailure ] 1212 1209 1213 #//////////////////////////////////////////////////////////////////////////////////////// 1210 1214 # End of Expected failures. -
trunk/LayoutTests/platform/mac/TestExpectations
r254449 r254534 1930 1930 1931 1931 webkit.org/b/204312 imported/w3c/web-platform-tests/svg/import/struct-dom-06-b-manual.svg [ Failure Pass ] 1932 1933 # Locale-specific shaping is only enabled on certain OSes. 1934 webkit.org/b/77568 [ Sierra HighSierra Mojave ] fast/text/locale-shaping.html [ ImageOnlyFailure ] 1935 webkit.org/b/77568 [ Sierra HighSierra Mojave ] fast/text/locale-shaping-complex.html [ ImageOnlyFailure ] -
trunk/LayoutTests/platform/win/TestExpectations
r254428 r254534 689 689 fast/visual-viewport/client-coordinates-relative-to-layout-viewport.html [ Failure ] 690 690 fast/visual-viewport/zoomed-fixed-scroll-down-then-up.html [ Failure ] 691 692 # locale-specific shaping isn't implemented on any non-Cocoa port yet. 693 webkit.org/b/77568 fast/text/locale-shaping.html [ ImageOnlyFailure ] 694 webkit.org/b/77568 fast/text/locale-shaping-complex.html [ ImageOnlyFailure ] 691 695 692 696 ################################################################################ -
trunk/Source/WTF/ChangeLog
r254514 r254534 1 2020-01-14 Myles C. Maxfield <mmaxfield@apple.com> 2 3 [Cocoa] Glyph lookup should be language-sensitive (specifically between Yiddish and Hebrew) 4 https://bugs.webkit.org/show_bug.cgi?id=77568 5 <rdar://problem/14649193> 6 7 Reviewed by Simon Fraser. 8 9 * wtf/Platform.h: 10 1 11 2020-01-13 Darin Adler <darin@apple.com> 2 12 -
trunk/Source/WTF/wtf/Platform.h
r254452 r254534 918 918 #endif 919 919 920 #if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500) || (PLATFORM(IOS_FAMILY) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 130000) 921 #define HAVE_CTFONTTRANSFORMGLYPHSWITHLANGUAGE 1 922 #endif 923 920 924 #if PLATFORM(IOS_FAMILY) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 130000 921 925 #define HAVE_ARKIT_QUICK_LOOK_PREVIEW_ITEM 1 -
trunk/Source/WebCore/ChangeLog
r254526 r254534 1 2020-01-14 Myles C. Maxfield <mmaxfield@apple.com> 2 3 [Cocoa] Glyph lookup should be language-sensitive (specifically between Yiddish and Hebrew) 4 https://bugs.webkit.org/show_bug.cgi?id=77568 5 <rdar://problem/14649193> 6 7 Reviewed by Simon Fraser. 8 9 Switch from CTFontTransformGlyphs() to CTFontTransformGlyphsWithLanguage(). 10 11 CTFontTransformGlyphsWithLanguage() accepts a callback when it needs to insert 12 glyphs and the glyph buffer isn't big enough. This patch hooks up this callback to 13 a "makeHole()" function which reallocs the glyph buffer so the hole can be filled in 14 by shaping. 15 16 We cache the CFDictionaries of the CFAttributedString we pass into CoreText using a 17 HashMap stored in Font. 18 19 Tests: fast/text/locale-shaping-complex.html 20 fast/text/locale-shaping.html 21 22 * platform/graphics/Font.cpp: 23 (WebCore::Font::applyTransforms const): 24 * platform/graphics/Font.h: 25 (WebCore::Font::CFStringAttributesKey::CFStringAttributesKey): 26 (WebCore::Font::CFStringAttributesKey::operator== const): 27 (WebCore::Font::CFStringAttributesKey::operator!= const): 28 (WebCore::Font::CFStringAttributesKey::isHashTableDeletedValue const): 29 (WebCore::Font::CFStringAttributesKey::computeHash const): 30 (WebCore::Font::CFStringAttributesKeyHash::hash): 31 (WebCore::Font::CFStringAttributesKeyHash::equal): 32 * platform/graphics/FontCascade.cpp: 33 (WebCore::FontCascade::widthForSimpleText const): 34 * platform/graphics/GlyphBuffer.h: 35 (WebCore::GlyphBuffer::isEmpty const): 36 (WebCore::GlyphBuffer::size const): 37 (WebCore::GlyphBuffer::clear): 38 (WebCore::GlyphBuffer::advances const): 39 (WebCore::GlyphBuffer::fontAt const): 40 (WebCore::GlyphBuffer::add): 41 (WebCore::GlyphBuffer::remove): 42 (WebCore::GlyphBuffer::makeHole): 43 (WebCore::GlyphBuffer::shrink): 44 (WebCore::GlyphBuffer::swap): 45 (WebCore::GlyphBuffer::advancesCount const): Deleted. 46 * platform/graphics/WidthIterator.cpp: 47 (WebCore::WidthIterator::applyFontTransforms): 48 * platform/graphics/WidthIterator.h: 49 * platform/graphics/cocoa/FontCocoa.mm: 50 (WebCore::Font::applyTransforms const): 51 * platform/graphics/mac/ComplexTextControllerCoreText.mm: 52 (WebCore::ComplexTextController::collectComplexTextRunsForCharacters): 53 * platform/graphics/mac/SimpleFontDataCoreText.cpp: 54 (WebCore::Font::getCFStringAttributes const): 55 1 56 2020-01-14 Ross Kirsling <ross.kirsling@sony.com> 2 57 -
trunk/Source/WebCore/PAL/ChangeLog
r254257 r254534 1 2020-01-14 Myles C. Maxfield <mmaxfield@apple.com> 2 3 [Cocoa] Glyph lookup should be language-sensitive (specifically between Yiddish and Hebrew) 4 https://bugs.webkit.org/show_bug.cgi?id=77568 5 <rdar://problem/14649193> 6 7 Reviewed by Simon Fraser. 8 9 * pal/spi/cocoa/CoreTextSPI.h: 10 1 11 2020-01-09 Eric Carlson <eric.carlson@apple.com> 2 12 -
trunk/Source/WebCore/PAL/pal/spi/cocoa/CoreTextSPI.h
r250310 r254534 93 93 94 94 bool CTFontTransformGlyphs(CTFontRef, CGGlyph glyphs[], CGSize advances[], CFIndex count, CTFontTransformOptions); 95 CGSize CTFontTransformGlyphsWithLanguage(CTFontRef, CGGlyph[], CGSize[], CFIndex count, CTFontTransformOptions, CFStringRef language, void (^handler)(CFRange, CGGlyph**, CGSize**)); 95 96 96 97 CGSize CTRunGetInitialAdvance(CTRunRef); -
trunk/Source/WebCore/platform/graphics/Font.cpp
r254202 r254534 500 500 } 501 501 502 bool Font::applyTransforms(GlyphBufferGlyph* glyphs, GlyphBufferAdvance* advances, size_t glyphCount, bool enableKerning, bool requiresShaping) const 503 { 504 #if PLATFORM(COCOA) 505 CTFontTransformOptions options = (enableKerning ? kCTFontTransformApplyPositioning : 0) | (requiresShaping ? kCTFontTransformApplyShaping : 0); 506 return CTFontTransformGlyphs(m_platformData.ctFont(), glyphs, reinterpret_cast<CGSize*>(advances), glyphCount, options); 507 #else 508 UNUSED_PARAM(glyphs); 509 UNUSED_PARAM(advances); 510 UNUSED_PARAM(glyphCount); 511 UNUSED_PARAM(enableKerning); 512 UNUSED_PARAM(requiresShaping); 513 return false; 514 #endif 515 } 502 #if !PLATFORM(COCOA) 503 void Font::applyTransforms(GlyphBuffer&, unsigned, bool, bool, const AtomString&) const 504 { 505 } 506 #endif 516 507 517 508 class CharacterFallbackMapKey { -
trunk/Source/WebCore/platform/graphics/Font.h
r254202 r254534 36 36 #endif 37 37 #include <wtf/BitVector.h> 38 #include <wtf/Hasher.h> 38 39 #include <wtf/Optional.h> 39 40 #include <wtf/text/StringHash.h> 40 41 41 42 #if PLATFORM(COCOA) 43 #include <CoreFoundation/CoreFoundation.h> 42 44 #include <wtf/RetainPtr.h> 43 45 #endif … … 197 199 #if PLATFORM(COCOA) 198 200 CTFontRef getCTFont() const { return m_platformData.font(); } 199 CFDictionaryRef getCFStringAttributes(bool enableKerning, FontOrientation) const;201 RetainPtr<CFDictionaryRef> getCFStringAttributes(bool enableKerning, FontOrientation, const AtomString& locale) const; 200 202 const BitVector& glyphsSupportedBySmallCaps() const; 201 203 const BitVector& glyphsSupportedByAllSmallCaps() const; … … 209 211 210 212 bool canRenderCombiningCharacterSequence(const UChar*, size_t) const; 211 bool applyTransforms(GlyphBufferGlyph*, GlyphBufferAdvance*, size_t glyphCount, bool enableKerning, bool requiresShaping) const;213 void applyTransforms(GlyphBuffer&, unsigned beginningIndex, bool enableKerning, bool requiresShaping, const AtomString& locale) const; 212 214 213 215 #if PLATFORM(WIN) … … 282 284 283 285 #if PLATFORM(COCOA) 284 mutable RetainPtr<CFMutableDictionaryRef> m_nonKernedCFStringAttributes;285 mutable RetainPtr<CFMutableDictionaryRef> m_kernedCFStringAttributes;286 286 mutable Optional<BitVector> m_glyphsSupportedBySmallCaps; 287 287 mutable Optional<BitVector> m_glyphsSupportedByAllSmallCaps; -
trunk/Source/WebCore/platform/graphics/FontCascade.cpp
r254323 r254534 417 417 return *cacheEntry; 418 418 419 GlyphBuffer glyphBuffer; 419 420 Vector<GlyphBufferGlyph, 16> glyphs; 420 421 Vector<GlyphBufferAdvance, 16> advances; … … 428 429 if (!hasKerningOrLigatures) 429 430 continue; 430 glyphs.append(glyph); 431 advances.append(FloatSize(glyphWidth, 0)); 431 glyphBuffer.add(glyph, &font, glyphWidth); 432 432 } 433 433 if (hasKerningOrLigatures) { 434 font.applyTransforms( &glyphs[0], &advances[0], glyphs.size(), enableKerning(), requiresShaping());434 font.applyTransforms(glyphBuffer, 0, enableKerning(), requiresShaping(), fontDescription().locale()); 435 435 // This is needed only to match the result of the slow path. Same glyph widths but different floating point arithmentics can 436 436 // produce different run width. 437 437 float runWidthDifferenceWithTransformApplied = -runWidth; 438 for ( auto& advance : advances)439 runWidthDifferenceWithTransformApplied += advance.width();438 for (size_t i = 0; i < glyphBuffer.size(); ++i) 439 runWidthDifferenceWithTransformApplied += glyphBuffer.advanceAt(i).width(); 440 440 runWidth += runWidthDifferenceWithTransformApplied; 441 441 } -
trunk/Source/WebCore/platform/graphics/GlyphBuffer.h
r254047 r254534 101 101 class GlyphBuffer { 102 102 public: 103 bool isEmpty() const { return m_font .isEmpty(); }104 unsigned size() const { return m_font .size(); }103 bool isEmpty() const { return m_fonts.isEmpty(); } 104 unsigned size() const { return m_fonts.size(); } 105 105 106 106 void clear() 107 107 { 108 m_font .clear();108 m_fonts.clear(); 109 109 m_glyphs.clear(); 110 110 m_advances.clear(); … … 117 117 const GlyphBufferGlyph* glyphs(unsigned from) const { return m_glyphs.data() + from; } 118 118 const GlyphBufferAdvance* advances(unsigned from) const { return m_advances.data() + from; } 119 size_t advancesCount() const { return m_advances.size(); } 120 121 const Font* fontAt(unsigned index) const { return m_font[index]; } 119 120 const Font* fontAt(unsigned index) const { return m_fonts[index]; } 122 121 123 122 void setInitialAdvance(GlyphBufferAdvance initialAdvance) { m_initialAdvance = initialAdvance; } … … 146 145 void add(Glyph glyph, const Font* font, GlyphBufferAdvance advance, unsigned offsetInString) 147 146 { 148 m_font .append(font);147 m_fonts.append(font); 149 148 m_glyphs.append(glyph); 150 149 … … 155 154 } 156 155 156 void remove(unsigned location, unsigned length) 157 { 158 m_fonts.remove(location, length); 159 m_glyphs.remove(location, length); 160 m_advances.remove(location, length); 161 if (m_offsetsInString) 162 m_offsetsInString->remove(location, length); 163 } 164 165 void makeHole(unsigned location, unsigned length, const Font* font) 166 { 167 ASSERT(location <= size()); 168 169 m_fonts.insertVector(location, Vector<const Font*>(length, font)); 170 m_glyphs.insertVector(location, Vector<GlyphBufferGlyph>(length, 0xFFFF)); 171 m_advances.insertVector(location, Vector<GlyphBufferAdvance>(length, GlyphBufferAdvance(0, 0))); 172 if (m_offsetsInString) 173 m_offsetsInString->insertVector(location, Vector<unsigned>(length, 0)); 174 } 175 157 176 void reverse(unsigned from, unsigned length) 158 177 { … … 189 208 void shrink(unsigned truncationPoint) 190 209 { 191 m_font .shrink(truncationPoint);210 m_fonts.shrink(truncationPoint); 192 211 m_glyphs.shrink(truncationPoint); 193 212 m_advances.shrink(truncationPoint); … … 199 218 void swap(unsigned index1, unsigned index2) 200 219 { 201 const Font* f = m_font [index1];202 m_font [index1] = m_font[index2];203 m_font [index2] = f;220 const Font* f = m_fonts[index1]; 221 m_fonts[index1] = m_fonts[index2]; 222 m_fonts[index2] = f; 204 223 205 224 GlyphBufferGlyph g = m_glyphs[index1]; … … 212 231 } 213 232 214 Vector<const Font*, 2048> m_font ;233 Vector<const Font*, 2048> m_fonts; 215 234 Vector<GlyphBufferGlyph, 2048> m_glyphs; 216 235 Vector<GlyphBufferAdvance, 2048> m_advances; -
trunk/Source/WebCore/platform/graphics/WidthIterator.cpp
r247688 r254534 99 99 return 0; 100 100 101 unsignedglyphBufferSize = glyphBuffer->size();101 auto glyphBufferSize = glyphBuffer->size(); 102 102 if (!force && glyphBufferSize <= lastGlyphCount + 1) { 103 103 lastGlyphCount = glyphBufferSize; … … 114 114 glyphBuffer->reverse(lastGlyphCount, glyphBufferSize - lastGlyphCount); 115 115 116 font->applyTransforms(glyphBuffer->glyphs(lastGlyphCount), advances + lastGlyphCount, glyphBufferSize - lastGlyphCount, m_enableKerning, m_requiresShaping); 116 font->applyTransforms(*glyphBuffer, lastGlyphCount, m_enableKerning, m_requiresShaping, m_font->fontDescription().locale()); 117 glyphBufferSize = glyphBuffer->size(); 117 118 118 119 for (unsigned i = lastGlyphCount; i < glyphBufferSize; ++i) … … 122 123 glyphBuffer->reverse(lastGlyphCount, glyphBufferSize - lastGlyphCount); 123 124 125 // https://bugs.webkit.org/show_bug.cgi?id=206208: This is totally, 100%, furiously, utterly, frustratingly bogus. 126 // There is absolutely no guarantee that glyph indices before shaping have any relation at all with glyph indices after shaping. 127 // One of the fundamental things that shaping does is insert glyph all over the place. 124 128 for (size_t i = 0; i < charactersTreatedAsSpace.size(); ++i) { 125 int spaceOffset = charactersTreatedAsSpace[i].first; 129 auto spaceOffset = charactersTreatedAsSpace[i].first; 130 // Shaping may have deleted the glyph. 131 if (spaceOffset >= glyphBufferSize) 132 continue; 126 133 const OriginalAdvancesForCharacterTreatedAsSpace& originalAdvances = charactersTreatedAsSpace[i].second; 127 134 if (spaceOffset && !originalAdvances.characterIsSpace) -
trunk/Source/WebCore/platform/graphics/WidthIterator.h
r204400 r254534 36 36 struct OriginalAdvancesForCharacterTreatedAsSpace; 37 37 38 typedef Vector<std::pair< int, OriginalAdvancesForCharacterTreatedAsSpace>, 64> CharactersTreatedAsSpace;38 typedef Vector<std::pair<unsigned, OriginalAdvancesForCharacterTreatedAsSpace>, 64> CharactersTreatedAsSpace; 39 39 40 40 struct WidthIterator { -
trunk/Source/WebCore/platform/graphics/cocoa/FontCocoa.mm
r252701 r254534 544 544 } 545 545 546 void Font::applyTransforms(GlyphBuffer& glyphBuffer, unsigned beginningIndex, bool enableKerning, bool requiresShaping, const AtomString& locale) const 547 { 548 // FIXME: Implement GlyphBuffer initial advance. 549 CTFontTransformOptions options = (enableKerning ? kCTFontTransformApplyPositioning : 0) | (requiresShaping ? kCTFontTransformApplyShaping : 0); 550 #if HAVE(CTFONTTRANSFORMGLYPHSWITHLANGUAGE) 551 auto handler = ^(CFRange range, CGGlyph** newGlyphsPointer, CGSize** newAdvancesPointer) { 552 range.location = std::min(std::max(range.location, static_cast<CFIndex>(0)), static_cast<CFIndex>(glyphBuffer.size())); 553 if (range.length < 0) { 554 range.length = std::min(range.location, -range.length); 555 range.location = range.location - range.length; 556 glyphBuffer.remove(beginningIndex + range.location, range.length); 557 } else 558 glyphBuffer.makeHole(beginningIndex + range.location, range.length, this); 559 *newGlyphsPointer = glyphBuffer.glyphs(beginningIndex); 560 *newAdvancesPointer = glyphBuffer.advances(beginningIndex); 561 }; 562 CTFontTransformGlyphsWithLanguage(m_platformData.ctFont(), glyphBuffer.glyphs(beginningIndex), reinterpret_cast<CGSize*>(glyphBuffer.advances(beginningIndex)), glyphBuffer.size() - beginningIndex, options, locale.string().createCFString().get(), handler); 563 #else 564 UNUSED_PARAM(locale); 565 CTFontTransformGlyphs(m_platformData.ctFont(), glyphBuffer.glyphs(beginningIndex), reinterpret_cast<CGSize*>(glyphBuffer.advances(beginningIndex)), glyphBuffer.size() - beginningIndex, options); 566 #endif 567 } 568 546 569 static int extractNumber(CFNumberRef number) 547 570 { -
trunk/Source/WebCore/platform/graphics/mac/ComplexTextControllerCoreText.mm
r250173 r254534 129 129 if (!font) 130 130 font = &m_font.fallbackRangesAt(0).fontForFirstRange(); 131 stringAttributes = adoptCF(CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, font->getCFStringAttributes(m_font.enableKerning(), font->platformData().orientation() )));131 stringAttributes = adoptCF(CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, font->getCFStringAttributes(m_font.enableKerning(), font->platformData().orientation(), m_font.fontDescription().locale()).get())); 132 132 // We don't know which font should be used to render this grapheme cluster, so enable CoreText's fallback mechanism by using the CTFont which doesn't have CoreText's fallback disabled. 133 133 CFDictionarySetValue(const_cast<CFMutableDictionaryRef>(stringAttributes.get()), kCTFontAttributeName, font->platformData().font()); 134 134 } else 135 stringAttributes = font->getCFStringAttributes(m_font.enableKerning(), font->platformData().orientation() );135 stringAttributes = font->getCFStringAttributes(m_font.enableKerning(), font->platformData().orientation(), m_font.fontDescription().locale()); 136 136 137 137 RetainPtr<CTLineRef> line; -
trunk/Source/WebCore/platform/graphics/mac/SimpleFontDataCoreText.cpp
r247674 r254534 33 33 namespace WebCore { 34 34 35 CFDictionaryRef Font::getCFStringAttributes(bool enableKerning, FontOrientation orientation) const35 RetainPtr<CFDictionaryRef> Font::getCFStringAttributes(bool enableKerning, FontOrientation orientation, const AtomString& locale) const 36 36 { 37 auto& attributesDictionary = enableKerning ? m_kernedCFStringAttributes : m_nonKernedCFStringAttributes; 38 if (attributesDictionary) 39 return attributesDictionary.get(); 40 41 attributesDictionary = adoptCF(CFDictionaryCreateMutable(kCFAllocatorDefault, 4, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); 37 auto attributesDictionary = adoptCF(CFDictionaryCreateMutable(kCFAllocatorDefault, 4, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); 42 38 43 39 CFDictionarySetValue(attributesDictionary.get(), kCTFontAttributeName, platformData().ctFont()); 40 #if HAVE(CTFONTTRANSFORMGLYPHSWITHLANGUAGE) 41 if (!locale.isEmpty()) 42 CFDictionarySetValue(attributesDictionary.get(), kCTLanguageAttributeName, locale.string().createCFString().get()); 43 #else 44 UNUSED_PARAM(locale); 45 #endif 44 46 auto paragraphStyle = adoptCF(CTParagraphStyleCreate(nullptr, 0)); 45 47 CTParagraphStyleSetCompositionLanguage(paragraphStyle.get(), kCTCompositionLanguageNone); … … 55 57 CFDictionarySetValue(attributesDictionary.get(), kCTVerticalFormsAttributeName, kCFBooleanTrue); 56 58 57 return attributesDictionary .get();59 return attributesDictionary; 58 60 } 59 61
Note: See TracChangeset
for help on using the changeset viewer.