Title: [227381] trunk/Source/WebCore
Revision
227381
Author
mmaxfi...@apple.com
Date
2018-01-22 18:09:22 -0800 (Mon, 22 Jan 2018)

Log Message

[Cocoa] Support font collections
https://bugs.webkit.org/show_bug.cgi?id=181826
<rdar://problem/36455137>

Reviewed by Dean Jackson.

Source/WebCore:

Use the CoreText call CTFontManagerCreateFontDescriptorsFromData() to get all the descriptors inside
the collection file. We select which one by using the fragment identifier at the end of the url linking
to the remote font. For example, to select the 4th font inside a TTC file, the @font-face block would
look like:

@font-face {
    font-family: "MyFont";
    src: url("path/to/font.ttc#4");
}

Note that these numbers are 1-indexed.

The CSS Fonts spec states:
> Fragment identifiers are used to indicate which font to load. If a container format lacks a defined
> fragment identifier scheme, implementations should use a simple 1-based indexing scheme (e.g.
> "font-collection#1" for the first font, "font-collection#2" for the second font).

Not only are TTC font collections supported, but WOFF2 font collections are also supported, which is
increasingly important web standard.

No new tests because I don't have a font collection file with the appropriate license for the
WebKit repository. I tested manually.

* css/CSSFontFaceSource.cpp:
(WebCore::CSSFontFaceSource::load):
* loader/cache/CachedFont.cpp:
(WebCore::CachedFont::calculateIndex const):
(WebCore::CachedFont::ensureCustomFontData):
(WebCore::CachedFont::createCustomFontData):
* loader/cache/CachedFont.h:
* platform/graphics/cairo/FontCustomPlatformData.h:
* platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp:
(WebCore::createFontCustomPlatformData):
* platform/graphics/mac/FontCustomPlatformData.cpp:
(WebCore::createFontCustomPlatformData):
* platform/graphics/mac/FontCustomPlatformData.h:
* platform/graphics/win/FontCustomPlatformData.cpp:
(WebCore::createFontCustomPlatformData):
* platform/graphics/win/FontCustomPlatformData.h:
* platform/graphics/win/FontCustomPlatformDataCairo.cpp:
(WebCore::createFontCustomPlatformData):

Source/WebCore/PAL:

* pal/spi/cocoa/CoreTextSPI.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (227380 => 227381)


--- trunk/Source/WebCore/ChangeLog	2018-01-23 02:04:57 UTC (rev 227380)
+++ trunk/Source/WebCore/ChangeLog	2018-01-23 02:09:22 UTC (rev 227381)
@@ -1,3 +1,53 @@
+2018-01-22  Myles C. Maxfield  <mmaxfi...@apple.com>
+
+        [Cocoa] Support font collections
+        https://bugs.webkit.org/show_bug.cgi?id=181826
+        <rdar://problem/36455137>
+
+        Reviewed by Dean Jackson.
+
+        Use the CoreText call CTFontManagerCreateFontDescriptorsFromData() to get all the descriptors inside
+        the collection file. We select which one by using the fragment identifier at the end of the url linking
+        to the remote font. For example, to select the 4th font inside a TTC file, the @font-face block would
+        look like:
+
+        @font-face {
+            font-family: "MyFont";
+            src: url("path/to/font.ttc#4");
+        }
+
+        Note that these numbers are 1-indexed.
+
+        The CSS Fonts spec states:
+        > Fragment identifiers are used to indicate which font to load. If a container format lacks a defined
+        > fragment identifier scheme, implementations should use a simple 1-based indexing scheme (e.g.
+        > "font-collection#1" for the first font, "font-collection#2" for the second font).
+
+        Not only are TTC font collections supported, but WOFF2 font collections are also supported, which is
+        increasingly important web standard.
+
+        No new tests because I don't have a font collection file with the appropriate license for the
+        WebKit repository. I tested manually.
+
+        * css/CSSFontFaceSource.cpp:
+        (WebCore::CSSFontFaceSource::load):
+        * loader/cache/CachedFont.cpp:
+        (WebCore::CachedFont::calculateIndex const):
+        (WebCore::CachedFont::ensureCustomFontData):
+        (WebCore::CachedFont::createCustomFontData):
+        * loader/cache/CachedFont.h:
+        * platform/graphics/cairo/FontCustomPlatformData.h:
+        * platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp:
+        (WebCore::createFontCustomPlatformData):
+        * platform/graphics/mac/FontCustomPlatformData.cpp:
+        (WebCore::createFontCustomPlatformData):
+        * platform/graphics/mac/FontCustomPlatformData.h:
+        * platform/graphics/win/FontCustomPlatformData.cpp:
+        (WebCore::createFontCustomPlatformData):
+        * platform/graphics/win/FontCustomPlatformData.h:
+        * platform/graphics/win/FontCustomPlatformDataCairo.cpp:
+        (WebCore::createFontCustomPlatformData):
+
 2018-01-22  Simon Fraser  <simon.fra...@apple.com>
 
         REGRESSION (r227011): fast/frames/hidpi-position-iframe-on-device-pixel.html times out

Modified: trunk/Source/WebCore/PAL/ChangeLog (227380 => 227381)


--- trunk/Source/WebCore/PAL/ChangeLog	2018-01-23 02:04:57 UTC (rev 227380)
+++ trunk/Source/WebCore/PAL/ChangeLog	2018-01-23 02:09:22 UTC (rev 227381)
@@ -1,3 +1,13 @@
+2018-01-22  Myles C. Maxfield  <mmaxfi...@apple.com>
+
+        [Cocoa] Support font collections
+        https://bugs.webkit.org/show_bug.cgi?id=181826
+        <rdar://problem/36455137>
+
+        Reviewed by Dean Jackson.
+
+        * pal/spi/cocoa/CoreTextSPI.h:
+
 2018-01-21  Wenson Hsieh  <wenson_hs...@apple.com>
 
         Add a new feature flag for EXTRA_ZOOM_MODE and reintroduce AdditionalFeatureDefines.h

Modified: trunk/Source/WebCore/PAL/pal/spi/cocoa/CoreTextSPI.h (227380 => 227381)


--- trunk/Source/WebCore/PAL/pal/spi/cocoa/CoreTextSPI.h	2018-01-23 02:04:57 UTC (rev 227380)
+++ trunk/Source/WebCore/PAL/pal/spi/cocoa/CoreTextSPI.h	2018-01-23 02:09:22 UTC (rev 227381)
@@ -84,6 +84,8 @@
 CTFontDescriptorRef CTFontDescriptorCreateWithAttributesAndOptions(CFDictionaryRef attributes, CTFontDescriptorOptions);
 CTFontDescriptorRef CTFontDescriptorCreateLastResort();
 
+CFArrayRef CTFontManagerCreateFontDescriptorsFromData(CFDataRef);
+
 extern const CFStringRef kCTFontCSSWeightAttribute;
 extern const CFStringRef kCTFontCSSWidthAttribute;
 extern const CFStringRef kCTFontDescriptorTextStyleAttribute;

Modified: trunk/Source/WebCore/css/CSSFontFaceSource.cpp (227380 => 227381)


--- trunk/Source/WebCore/css/CSSFontFaceSource.cpp	2018-01-23 02:04:57 UTC (rev 227380)
+++ trunk/Source/WebCore/css/CSSFontFaceSource.cpp	2018-01-23 02:09:22 UTC (rev 227381)
@@ -159,7 +159,7 @@
                 if (auto otfFont = convertSVGToOTFFont(fontElement))
                     m_generatedOTFBuffer = SharedBuffer::create(WTFMove(otfFont.value()));
                 if (m_generatedOTFBuffer) {
-                    m_inDocumentCustomPlatformData = createFontCustomPlatformData(*m_generatedOTFBuffer);
+                    m_inDocumentCustomPlatformData = createFontCustomPlatformData(*m_generatedOTFBuffer, 0);
                     success = static_cast<bool>(m_inDocumentCustomPlatformData);
                 }
             }
@@ -170,7 +170,7 @@
             bool wrapping;
             RefPtr<SharedBuffer> buffer = SharedBuffer::create(static_cast<const char*>(m_immediateSource->baseAddress()), m_immediateSource->byteLength());
             ASSERT(buffer);
-            m_immediateFontCustomPlatformData = CachedFont::createCustomFontData(*buffer, wrapping);
+            m_immediateFontCustomPlatformData = CachedFont::createCustomFontData(*buffer, 0, wrapping);
             success = static_cast<bool>(m_immediateFontCustomPlatformData);
         } else {
             // We are only interested in whether or not fontForFamily() returns null or not. Luckily, none of

Modified: trunk/Source/WebCore/loader/cache/CachedFont.cpp (227380 => 227381)


--- trunk/Source/WebCore/loader/cache/CachedFont.cpp	2018-01-23 02:04:57 UTC (rev 227380)
+++ trunk/Source/WebCore/loader/cache/CachedFont.cpp	2018-01-23 02:09:22 UTC (rev 227381)
@@ -88,11 +88,27 @@
     return ensureCustomFontData(m_data.get());
 }
 
+unsigned CachedFont::calculateIndex() const
+{
+    auto& url = ""
+    if (!url.hasFragmentIdentifier())
+        return 0;
+    const auto& fragment = url.fragmentIdentifier();
+    unsigned result = 0;
+    for (unsigned i = 0; i < fragment.length(); ++i) {
+        UChar c = fragment[i];
+        if (c < '0' || c > '9')
+            return 0;
+        result = result * 10 + (c - '0');
+    }
+    return result;
+}
+
 bool CachedFont::ensureCustomFontData(SharedBuffer* data)
 {
     if (!m_fontCustomPlatformData && !errorOccurred() && !isLoading() && data) {
         bool wrapping;
-        m_fontCustomPlatformData = createCustomFontData(*data, wrapping);
+        m_fontCustomPlatformData = createCustomFontData(*data, calculateIndex(), wrapping);
         m_hasCreatedFontDataWrappingResource = m_fontCustomPlatformData && wrapping;
         if (!m_fontCustomPlatformData)
             setStatus(DecodeError);
@@ -101,7 +117,7 @@
     return m_fontCustomPlatformData.get();
 }
 
-std::unique_ptr<FontCustomPlatformData> CachedFont::createCustomFontData(SharedBuffer& bytes, bool& wrapping)
+std::unique_ptr<FontCustomPlatformData> CachedFont::createCustomFontData(SharedBuffer& bytes, unsigned index, bool& wrapping)
 {
     wrapping = true;
 
@@ -113,11 +129,11 @@
             return nullptr;
 
         auto buffer = SharedBuffer::create(WTFMove(convertedFont));
-        return createFontCustomPlatformData(buffer);
+        return createFontCustomPlatformData(buffer, index);
     }
 #endif
 
-    return createFontCustomPlatformData(bytes);
+    return createFontCustomPlatformData(bytes, index);
 }
 
 RefPtr<Font> CachedFont::createFont(const FontDescription& fontDescription, const AtomicString&, bool syntheticBold, bool syntheticItalic, const FontFeatureSettings& fontFaceFeatures, const FontVariantSettings& fontFaceVariantSettings, FontSelectionSpecifiedCapabilities fontFaceCapabilities)

Modified: trunk/Source/WebCore/loader/cache/CachedFont.h (227380 => 227381)


--- trunk/Source/WebCore/loader/cache/CachedFont.h	2018-01-23 02:04:57 UTC (rev 227380)
+++ trunk/Source/WebCore/loader/cache/CachedFont.h	2018-01-23 02:09:22 UTC (rev 227381)
@@ -52,7 +52,7 @@
     bool stillNeedsLoad() const override { return !m_loadInitiated; }
 
     virtual bool ensureCustomFontData(const AtomicString& remoteURI);
-    static std::unique_ptr<FontCustomPlatformData> createCustomFontData(SharedBuffer&, bool& wrapping);
+    static std::unique_ptr<FontCustomPlatformData> createCustomFontData(SharedBuffer&, unsigned index, bool& wrapping);
     static FontPlatformData platformDataFromCustomData(FontCustomPlatformData&, const FontDescription&, bool bold, bool italic, const FontFeatureSettings&, const FontVariantSettings&, FontSelectionSpecifiedCapabilities);
 
     virtual RefPtr<Font> createFont(const FontDescription&, const AtomicString& remoteURI, bool syntheticBold, bool syntheticItalic, const FontFeatureSettings&, const FontVariantSettings&, FontSelectionSpecifiedCapabilities);
@@ -63,6 +63,8 @@
     bool ensureCustomFontData(SharedBuffer* data);
 
 private:
+    unsigned calculateIndex() const;
+
     void checkNotify() override;
     bool mayTryReplaceEncodedData() const override;
 

Modified: trunk/Source/WebCore/platform/graphics/cairo/FontCustomPlatformData.h (227380 => 227381)


--- trunk/Source/WebCore/platform/graphics/cairo/FontCustomPlatformData.h	2018-01-23 02:04:57 UTC (rev 227380)
+++ trunk/Source/WebCore/platform/graphics/cairo/FontCustomPlatformData.h	2018-01-23 02:09:22 UTC (rev 227381)
@@ -48,7 +48,7 @@
     cairo_font_face_t* m_fontFace;
 };
 
-std::unique_ptr<FontCustomPlatformData> createFontCustomPlatformData(SharedBuffer&);
+std::unique_ptr<FontCustomPlatformData> createFontCustomPlatformData(SharedBuffer&, unsigned);
 
 } // namespace WebCore
 

Modified: trunk/Source/WebCore/platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp (227380 => 227381)


--- trunk/Source/WebCore/platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp	2018-01-23 02:04:57 UTC (rev 227380)
+++ trunk/Source/WebCore/platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp	2018-01-23 02:09:22 UTC (rev 227381)
@@ -90,7 +90,7 @@
     return true;
 }
 
-std::unique_ptr<FontCustomPlatformData> createFontCustomPlatformData(SharedBuffer& buffer)
+std::unique_ptr<FontCustomPlatformData> createFontCustomPlatformData(SharedBuffer& buffer, unsigned)
 {
     static FT_Library library;
     if (!library && !initializeFreeTypeLibrary(library)) {

Modified: trunk/Source/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp (227380 => 227381)


--- trunk/Source/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp	2018-01-23 02:04:57 UTC (rev 227380)
+++ trunk/Source/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp	2018-01-23 02:09:22 UTC (rev 227381)
@@ -25,8 +25,10 @@
 #include "FontDescription.h"
 #include "FontPlatformData.h"
 #include "SharedBuffer.h"
+#include <CoreFoundation/CoreFoundation.h>
 #include <CoreGraphics/CoreGraphics.h>
 #include <CoreText/CoreText.h>
+#include <pal/spi/cocoa/CoreTextSPI.h>
 
 namespace WebCore {
 
@@ -43,11 +45,27 @@
     return FontPlatformData(font.get(), size, bold, italic, orientation, widthVariant, fontDescription.textRenderingMode());
 }
 
-std::unique_ptr<FontCustomPlatformData> createFontCustomPlatformData(SharedBuffer& buffer)
+std::unique_ptr<FontCustomPlatformData> createFontCustomPlatformData(SharedBuffer& buffer, unsigned index)
 {
     RetainPtr<CFDataRef> bufferData = buffer.createCFData();
 
-    RetainPtr<CTFontDescriptorRef> fontDescriptor = adoptCF(CTFontManagerCreateFontDescriptorFromData(bufferData.get()));
+    RetainPtr<CTFontDescriptorRef> fontDescriptor;
+#if (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101300) || (PLATFORM(IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 110000)
+    auto array = adoptCF(CTFontManagerCreateFontDescriptorsFromData(bufferData.get()));
+    if (!array)
+        return nullptr;
+    auto length = CFArrayGetCount(array.get());
+    if (length <= 0)
+        return nullptr;
+    if (index > 0)
+        --index;
+    if (index >= static_cast<unsigned>(length))
+        index = 0;
+    fontDescriptor = static_cast<CTFontDescriptorRef>(CFArrayGetValueAtIndex(array.get(), index));
+#else
+    UNUSED_PARAM(index);
+    fontDescriptor = adoptCF(CTFontManagerCreateFontDescriptorFromData(bufferData.get()));
+#endif
     if (!fontDescriptor)
         return nullptr;
 

Modified: trunk/Source/WebCore/platform/graphics/mac/FontCustomPlatformData.h (227380 => 227381)


--- trunk/Source/WebCore/platform/graphics/mac/FontCustomPlatformData.h	2018-01-23 02:04:57 UTC (rev 227380)
+++ trunk/Source/WebCore/platform/graphics/mac/FontCustomPlatformData.h	2018-01-23 02:09:22 UTC (rev 227381)
@@ -57,7 +57,7 @@
     RetainPtr<CTFontDescriptorRef> m_fontDescriptor;
 };
 
-std::unique_ptr<FontCustomPlatformData> createFontCustomPlatformData(SharedBuffer&);
+std::unique_ptr<FontCustomPlatformData> createFontCustomPlatformData(SharedBuffer&, unsigned index);
 
 }
 

Modified: trunk/Source/WebCore/platform/graphics/win/FontCustomPlatformData.cpp (227380 => 227381)


--- trunk/Source/WebCore/platform/graphics/win/FontCustomPlatformData.cpp	2018-01-23 02:04:57 UTC (rev 227380)
+++ trunk/Source/WebCore/platform/graphics/win/FontCustomPlatformData.cpp	2018-01-23 02:09:22 UTC (rev 227381)
@@ -97,7 +97,7 @@
     return fontName;
 }
 
-std::unique_ptr<FontCustomPlatformData> createFontCustomPlatformData(SharedBuffer& buffer)
+std::unique_ptr<FontCustomPlatformData> createFontCustomPlatformData(SharedBuffer& buffer, unsigned)
 {
     String fontName = createUniqueFontName();
     HANDLE fontReference;

Modified: trunk/Source/WebCore/platform/graphics/win/FontCustomPlatformData.h (227380 => 227381)


--- trunk/Source/WebCore/platform/graphics/win/FontCustomPlatformData.h	2018-01-23 02:04:57 UTC (rev 227380)
+++ trunk/Source/WebCore/platform/graphics/win/FontCustomPlatformData.h	2018-01-23 02:09:22 UTC (rev 227381)
@@ -54,7 +54,7 @@
     String m_name;
 };
 
-std::unique_ptr<FontCustomPlatformData> createFontCustomPlatformData(SharedBuffer&);
+std::unique_ptr<FontCustomPlatformData> createFontCustomPlatformData(SharedBuffer&, unsigned);
 
 }
 

Modified: trunk/Source/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.cpp (227380 => 227381)


--- trunk/Source/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.cpp	2018-01-23 02:04:57 UTC (rev 227380)
+++ trunk/Source/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.cpp	2018-01-23 02:09:22 UTC (rev 227381)
@@ -85,7 +85,7 @@
     return fontName;
 }
 
-std::unique_ptr<FontCustomPlatformData> createFontCustomPlatformData(SharedBuffer& buffer)
+std::unique_ptr<FontCustomPlatformData> createFontCustomPlatformData(SharedBuffer& buffer, unsigned)
 {
     String fontName = createUniqueFontName();
     HANDLE fontReference = renameAndActivateFont(buffer, fontName);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to