Title: [251900] trunk/Source/WebCore
Revision
251900
Author
bfulg...@apple.com
Date
2019-10-31 17:53:49 -0700 (Thu, 31 Oct 2019)

Log Message

[FTW] Adopt DirectWrite in place of Uniscribe
https://bugs.webkit.org/show_bug.cgi?id=203548
<rdar://problem/56695130>

Reviewed by Fujii Hironori.

This patch switches from the Uniscribe text controller to a
DirectWrite based ComplexTextController.

* PlatformFTW.cmake:
* platform/graphics/ComplexTextController.cpp:
(WebCore::ComplexTextController::ComplexTextController): Treat Windows
like any other ComplexTextController platform.
* platform/graphics/Font.cpp:
(WebCore::Font::platformGlyphInit): Add hack for DirectWrite
zero-width space handling.
* platform/graphics/FontCascade.cpp:
(WebCore::FontCascade::widthOfTextRange const): Don't use Uniscribe.
* platform/graphics/FontPlatformData.h:
(WebCore::FontPlatformData::dwFontCollection const):
(WebCore::FontPlatformData::faceName const):
* platform/graphics/win/ComplexTextControllerDirectWrite.cpp:
(WebCore::shape): Added,
(WebCore::ComplexTextController::collectComplexTextRunsForCharacters):
Added.
* platform/graphics/win/DirectWriteUtilities.cpp:
(WebCore::DirectWrite::createWithPlatformFont): Modify to return a
pair of font and font collection.
(WebCore::DirectWrite::fontWeight): Added stub.
(WebCore::DirectWrite::fontStyle): Ditto.
(WebCore::DirectWrite::fontStretch): Ditto.
* platform/graphics/win/DirectWriteUtilities.h:
* platform/graphics/win/FontCustomPlatformData.cpp:
(WebCore::FontCustomPlatformData::fontPlatformData): Add more
information to help DirectWrite handle font styles.
* platform/graphics/win/FontPlatformDataDirect2D.cpp:
(WebCore::FontPlatformData::platformDataInit):
(WebCore::FontPlatformData::FontPlatformData):
(WebCore::FontPlatformData::createFallbackFont): Deleted.
* platform/graphics/win/FontWin.cpp:
* platform/graphics/win/GlyphPageTreeNodeDirect2D.cpp:
(WebCore::GlyphPage::fill): Update to handle multiple runs in a
given string.
* platform/graphics/win/TextAnalyzerHelper.cpp:
(WebCore::TextAnalyzerHelper::TextAnalyzerHelper): Update to handle
analysis of strings with multiple runs.
(WebCore::TextAnalyzerHelper::SetScriptAnalysis): Ditto.
* platform/graphics/win/TextAnalyzerHelper.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (251899 => 251900)


--- trunk/Source/WebCore/ChangeLog	2019-11-01 00:39:32 UTC (rev 251899)
+++ trunk/Source/WebCore/ChangeLog	2019-11-01 00:53:49 UTC (rev 251900)
@@ -1,3 +1,54 @@
+2019-10-31  Brent Fulgham  <bfulg...@apple.com>
+
+        [FTW] Adopt DirectWrite in place of Uniscribe
+        https://bugs.webkit.org/show_bug.cgi?id=203548
+        <rdar://problem/56695130>
+
+        Reviewed by Fujii Hironori.
+
+        This patch switches from the Uniscribe text controller to a
+        DirectWrite based ComplexTextController.
+
+        * PlatformFTW.cmake:
+        * platform/graphics/ComplexTextController.cpp:
+        (WebCore::ComplexTextController::ComplexTextController): Treat Windows
+        like any other ComplexTextController platform.
+        * platform/graphics/Font.cpp:
+        (WebCore::Font::platformGlyphInit): Add hack for DirectWrite
+        zero-width space handling.
+        * platform/graphics/FontCascade.cpp:
+        (WebCore::FontCascade::widthOfTextRange const): Don't use Uniscribe.
+        * platform/graphics/FontPlatformData.h:
+        (WebCore::FontPlatformData::dwFontCollection const):
+        (WebCore::FontPlatformData::faceName const):
+        * platform/graphics/win/ComplexTextControllerDirectWrite.cpp:
+        (WebCore::shape): Added,
+        (WebCore::ComplexTextController::collectComplexTextRunsForCharacters):
+        Added.
+        * platform/graphics/win/DirectWriteUtilities.cpp:
+        (WebCore::DirectWrite::createWithPlatformFont): Modify to return a
+        pair of font and font collection.
+        (WebCore::DirectWrite::fontWeight): Added stub.
+        (WebCore::DirectWrite::fontStyle): Ditto.
+        (WebCore::DirectWrite::fontStretch): Ditto.
+        * platform/graphics/win/DirectWriteUtilities.h:
+        * platform/graphics/win/FontCustomPlatformData.cpp:
+        (WebCore::FontCustomPlatformData::fontPlatformData): Add more
+        information to help DirectWrite handle font styles.
+        * platform/graphics/win/FontPlatformDataDirect2D.cpp:
+        (WebCore::FontPlatformData::platformDataInit):
+        (WebCore::FontPlatformData::FontPlatformData):
+        (WebCore::FontPlatformData::createFallbackFont): Deleted.
+        * platform/graphics/win/FontWin.cpp:
+        * platform/graphics/win/GlyphPageTreeNodeDirect2D.cpp:
+        (WebCore::GlyphPage::fill): Update to handle multiple runs in a
+        given string.
+        * platform/graphics/win/TextAnalyzerHelper.cpp:
+        (WebCore::TextAnalyzerHelper::TextAnalyzerHelper): Update to handle
+        analysis of strings with multiple runs.
+        (WebCore::TextAnalyzerHelper::SetScriptAnalysis): Ditto.
+        * platform/graphics/win/TextAnalyzerHelper.h:
+
 2019-10-31  Tim Horton  <timothy_hor...@apple.com>
 
         Turn on IOSurface support in the iOS Simulator

Modified: trunk/Source/WebCore/PlatformFTW.cmake (251899 => 251900)


--- trunk/Source/WebCore/PlatformFTW.cmake	2019-11-01 00:39:32 UTC (rev 251899)
+++ trunk/Source/WebCore/PlatformFTW.cmake	2019-11-01 00:53:49 UTC (rev 251900)
@@ -101,7 +101,6 @@
     platform/graphics/win/TextAnalyzerHelper.cpp
     platform/graphics/win/TransformationMatrixDirect2D.cpp
     platform/graphics/win/TransformationMatrixWin.cpp
-    platform/graphics/win/UniscribeController.cpp
 
     platform/network/win/CurlSSLHandleWin.cpp
     platform/network/win/DownloadBundleWin.cpp

Modified: trunk/Source/WebCore/platform/graphics/ComplexTextController.cpp (251899 => 251900)


--- trunk/Source/WebCore/platform/graphics/ComplexTextController.cpp	2019-11-01 00:39:32 UTC (rev 251899)
+++ trunk/Source/WebCore/platform/graphics/ComplexTextController.cpp	2019-11-01 00:53:49 UTC (rev 251900)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2007-2019 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -43,7 +43,7 @@
 
 namespace WebCore {
 
-#if PLATFORM(WIN)
+#if PLATFORM(WIN) && !USE(DIRECT2D)
 
 class TextLayout {
 };
@@ -63,6 +63,11 @@
     return 0;
 }
 
+void ComplexTextController::collectComplexTextRunsForCharacters(const UChar*, unsigned, unsigned, const Font*)
+{
+    ASSERT_NOT_REACHED();
+}
+
 #else
 
 class TextLayout {
@@ -146,10 +151,6 @@
     , m_mayUseNaturalWritingDirection(mayUseNaturalWritingDirection)
     , m_forTextEmphasis(forTextEmphasis)
 {
-#if PLATFORM(WIN)
-    ASSERT_NOT_REACHED();
-#endif
-
     computeExpansionOpportunity();
 
     collectComplexTextRuns();

Modified: trunk/Source/WebCore/platform/graphics/Font.cpp (251899 => 251900)


--- trunk/Source/WebCore/platform/graphics/Font.cpp	2019-11-01 00:39:32 UTC (rev 251899)
+++ trunk/Source/WebCore/platform/graphics/Font.cpp	2019-11-01 00:53:49 UTC (rev 251900)
@@ -119,13 +119,8 @@
     // every character and the space are the same width. Otherwise we round.
     if (glyphPageSpace)
         m_spaceGlyph = glyphPageSpace->glyphDataForCharacter(space).glyph;
-    float width = widthForGlyph(m_spaceGlyph);
-    m_spaceWidth = width;
     if (glyphPageCharacterZero)
         m_zeroGlyph = glyphPageCharacterZero->glyphDataForCharacter('0').glyph;
-    m_fontMetrics.setZeroWidth(widthForGlyph(m_zeroGlyph));
-    determinePitch();
-    m_adjustedSpaceWidth = m_treatAsFixedPitch ? ceilf(width) : roundf(width);
 
     // Force the glyph for ZERO WIDTH SPACE to have zero width, unless it is shared with SPACE.
     // Helvetica is an example of a non-zero width ZERO WIDTH SPACE glyph.
@@ -132,6 +127,12 @@
     // See <http://bugs.webkit.org/show_bug.cgi?id=13178> and Font::isZeroWidthSpaceGlyph()
     if (m_zeroWidthSpaceGlyph == m_spaceGlyph)
         m_zeroWidthSpaceGlyph = 0;
+
+    float width = widthForGlyph(m_spaceGlyph);
+    m_spaceWidth = width;
+    m_fontMetrics.setZeroWidth(widthForGlyph(m_zeroGlyph));
+    determinePitch();
+    m_adjustedSpaceWidth = m_treatAsFixedPitch ? ceilf(width) : roundf(width);
 }
 
 Font::~Font()

Modified: trunk/Source/WebCore/platform/graphics/FontCascade.cpp (251899 => 251900)


--- trunk/Source/WebCore/platform/graphics/FontCascade.cpp	2019-11-01 00:39:32 UTC (rev 251899)
+++ trunk/Source/WebCore/platform/graphics/FontCascade.cpp	2019-11-01 00:53:49 UTC (rev 251900)
@@ -41,7 +41,7 @@
 #include <wtf/text/AtomStringHash.h>
 #include <wtf/text/StringBuilder.h>
 
-#if PLATFORM(WIN)
+#if PLATFORM(WIN) && !USE(DIRECT2D)
 #include "UniscribeController.h"
 #endif
 
@@ -350,7 +350,7 @@
 
     auto codePathToUse = codePath(run);
     if (codePathToUse == Complex) {
-#if PLATFORM(WIN)
+#if PLATFORM(WIN) && !USE(DIRECT2D)
         UniscribeController it(this, run);
         it.advance(from);
         offsetBeforeRange = it.runWidthSoFar();
@@ -1397,7 +1397,7 @@
     return initialAdvance;
 }
 
-#if !PLATFORM(WIN)
+#if !PLATFORM(WIN) || USE(DIRECT2D)
 float FontCascade::getGlyphsAndAdvancesForComplexText(const TextRun& run, unsigned from, unsigned to, GlyphBuffer& glyphBuffer, ForTextEmphasisOrNot forTextEmphasis) const
 {
     float initialAdvance;
@@ -1545,7 +1545,7 @@
     return it.m_runWidthSoFar;
 }
 
-#if !PLATFORM(WIN)
+#if !PLATFORM(WIN) || USE(DIRECT2D)
 float FontCascade::floatWidthForComplexText(const TextRun& run, HashSet<const Font*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
 {
     ComplexTextController controller(*this, run, true, fallbackFonts);
@@ -1578,7 +1578,7 @@
     selectionRect.setWidth(LayoutUnit::fromFloatCeil(afterWidth - beforeWidth));
 }
 
-#if !PLATFORM(WIN)
+#if !PLATFORM(WIN) || USE(DIRECT2D)
 void FontCascade::adjustSelectionRectForComplexText(const TextRun& run, LayoutRect& selectionRect, unsigned from, unsigned to) const
 {
     ComplexTextController controller(*this, run);
@@ -1638,7 +1638,7 @@
     return offset;
 }
 
-#if !PLATFORM(WIN)
+#if !PLATFORM(WIN) || USE(DIRECT2D)
 int FontCascade::offsetForPositionForComplexText(const TextRun& run, float x, bool includePartialGlyphs) const
 {
     ComplexTextController controller(*this, run);

Modified: trunk/Source/WebCore/platform/graphics/FontPlatformData.h (251899 => 251900)


--- trunk/Source/WebCore/platform/graphics/FontPlatformData.h	2019-11-01 00:39:32 UTC (rev 251899)
+++ trunk/Source/WebCore/platform/graphics/FontPlatformData.h	2019-11-01 00:53:49 UTC (rev 251900)
@@ -103,7 +103,7 @@
 #endif
 
 #if PLATFORM(WIN) && USE(DIRECT2D)
-    FontPlatformData(GDIObject<HFONT>&&, IDWriteFont*, float size, bool syntheticBold, bool syntheticOblique, bool useGDI);
+    FontPlatformData(GDIObject<HFONT>&&, COMPtr<IDWriteFont>&&, float size, bool syntheticBold, bool syntheticOblique, bool useGDI);
 #endif
 
 #if PLATFORM(WIN) && USE(CAIRO)
@@ -143,9 +143,6 @@
 #if USE(DIRECT2D)
     IDWriteFont* dwFont() const { return m_dwFont.get(); }
     IDWriteFontFace* dwFontFace() const { return m_dwFontFace.get(); }
-
-    static HRESULT createFallbackFont(const LOGFONT&, IDWriteFont**);
-    static HRESULT createFallbackFont(HFONT, IDWriteFont**);
 #endif
 
     bool isFixedPitch() const;

Modified: trunk/Source/WebCore/platform/graphics/win/ComplexTextControllerDirectWrite.cpp (251899 => 251900)


--- trunk/Source/WebCore/platform/graphics/win/ComplexTextControllerDirectWrite.cpp	2019-11-01 00:39:32 UTC (rev 251899)
+++ trunk/Source/WebCore/platform/graphics/win/ComplexTextControllerDirectWrite.cpp	2019-11-01 00:53:49 UTC (rev 251900)
@@ -1,5 +1,5 @@
 /*
-* Copyright (C) 2017 Apple Inc. All rights reserved.
+* Copyright (C) 2017-2019 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
@@ -25,12 +25,157 @@
 #include "config.h"
 #include "ComplexTextController.h"
 
+#if USE(DIRECT2D)
+
+#include "DirectWriteUtilities.h"
+#include "FontCache.h"
+#include "FontCascade.h"
+#include "TextAnalyzerHelper.h"
+#include <dwrite_3.h>
+
 namespace WebCore {
 
-void ComplexTextController::collectComplexTextRunsForCharacters(const UChar*, unsigned, unsigned, const Font*)
+static bool shape(IDWriteTextAnalyzer* analyzer, const DWRITE_SCRIPT_ANALYSIS& analysis, const FontPlatformData& fontPlatformData, const WCHAR* text, unsigned length, unsigned suggestedCount, Vector<Glyph>& glyphs, Vector<Glyph>& clusterMap, Vector<DWRITE_SHAPING_TEXT_PROPERTIES>& textProperties, Vector<DWRITE_SHAPING_GLYPH_PROPERTIES>& glyphProperties, unsigned& glyphCount)
 {
-    // FIXME: Implement this.
-    ASSERT_NOT_REACHED();
+    HRESULT shapeResult = E_PENDING;
+
+    do {
+        shapeResult = analyzer->GetGlyphs(text, length, fontPlatformData.dwFontFace(), fontPlatformData.orientation() == FontOrientation::Vertical, false,
+            &analysis, nullptr, nullptr, nullptr, nullptr, 0, suggestedCount, clusterMap.data(), textProperties.data(),
+            glyphs.data(), glyphProperties.data(), &glyphCount);
+
+        if (shapeResult == E_OUTOFMEMORY) {
+            // Need to resize our buffers (except for clusterMap. It is always the length of the string).
+            glyphs.resize(glyphs.size() * 2);
+            textProperties.resize(glyphs.size());
+            glyphProperties.resize(glyphs.size());
+        }
+    } while (shapeResult == E_OUTOFMEMORY);
+
+    if (FAILED(shapeResult))
+        return false;
+
+    return true;
 }
 
+void ComplexTextController::collectComplexTextRunsForCharacters(const UChar* cp, unsigned length, unsigned stringLocation, const Font* font)
+{
+    if (!font) {
+        // Create a run of missing glyphs from the primary font.
+        m_complexTextRuns.append(ComplexTextRun::create(m_font.primaryFont(), cp, stringLocation, length, 0, length, m_run.ltr()));
+        return;
+    }
+
+    auto& fontPlatformData = font->platformData();
+
+    wchar_t localeName[LOCALE_NAME_MAX_LENGTH] = { };
+    int localeLength = GetUserDefaultLocaleName(reinterpret_cast<LPWSTR>(&localeName), LOCALE_NAME_MAX_LENGTH);
+    RELEASE_ASSERT(localeLength < LOCALE_NAME_MAX_LENGTH);
+
+    Vector<DWRITE_FONT_FEATURE> fontFeatures(1);
+    fontFeatures[0].nameTag = DWRITE_FONT_FEATURE_TAG_KERNING;
+    fontFeatures[0].parameter = m_font.enableKerning() ? 1 : 0;
+
+    if (fontPlatformData.orientation() == FontOrientation::Vertical)
+        fontFeatures.append({DWRITE_FONT_FEATURE_TAG_VERTICAL_WRITING, 1});
+
+    DWRITE_TYPOGRAPHIC_FEATURES usedFeatures;
+    usedFeatures.features = fontFeatures.data();
+    usedFeatures.featureCount = fontFeatures.size();
+
+    Vector<const DWRITE_TYPOGRAPHIC_FEATURES*> features;
+    features.append(&usedFeatures);
+
+    COMPtr<IDWriteTextAnalyzer> analyzer;
+    HRESULT hr = DirectWrite::factory()->CreateTextAnalyzer(&analyzer);
+    RELEASE_ASSERT(SUCCEEDED(hr));
+
+    TextAnalyzerHelper helper(reinterpret_cast<LPWSTR>(&localeName), reinterpret_cast<LPCWSTR>(cp), length);
+
+    hr = analyzer->AnalyzeScript(&helper, 0, length, &helper);
+    RELEASE_ASSERT(SUCCEEDED(hr));
+
+    unsigned totalSuggestedCount = (3 * length / 2 + 16);
+
+    Vector<Glyph> glyphs;
+    Vector<Glyph> clusterMap;
+    Vector<DWRITE_SHAPING_TEXT_PROPERTIES> textProperties;
+    Vector<DWRITE_SHAPING_GLYPH_PROPERTIES> glyphProperties;
+    Vector<FLOAT> glyphAdvances;
+    Vector<DWRITE_GLYPH_OFFSET> glyphOffsets;
+    Vector<FloatPoint> origins;
+    Vector<FloatSize> advances;
+    Vector<unsigned> stringIndices;
+
+    glyphs.reserveCapacity(totalSuggestedCount);
+    clusterMap.reserveCapacity(length);
+    textProperties.reserveCapacity(totalSuggestedCount);
+    glyphProperties.reserveCapacity(totalSuggestedCount);
+    glyphAdvances.reserveCapacity(totalSuggestedCount);
+    glyphOffsets.reserveCapacity(totalSuggestedCount);
+    origins.reserveCapacity(totalSuggestedCount);
+    advances.reserveCapacity(totalSuggestedCount);
+    stringIndices.reserveCapacity(totalSuggestedCount);
+
+    for (const auto& run : helper.m_analyzedRuns) {
+        const UChar* currentCP = cp + run.startPosition;
+        LPCWSTR textPosition = reinterpret_cast<LPCWSTR>(currentCP);
+
+        unsigned suggestedCount = (3 * run.length / 2 + 16);
+        glyphs.resize(suggestedCount);
+        clusterMap.resize(run.length);
+        textProperties.resize(suggestedCount);
+        glyphProperties.resize(suggestedCount);
+
+        unsigned glyphCount = 0;
+        if (!shape(analyzer.get(), run.analysis, fontPlatformData, textPosition, run.length, suggestedCount, glyphs, clusterMap, textProperties, glyphProperties, glyphCount))
+            return;
+
+        glyphs.shrink(glyphCount);
+        textProperties.shrink(glyphCount);
+        glyphProperties.shrink(glyphCount);
+        glyphAdvances.resize(glyphCount);
+        glyphOffsets.resize(glyphCount);
+
+        HRESULT placementResult = analyzer->GetGlyphPlacements(textPosition, clusterMap.data(), textProperties.data(), run.length,
+            glyphs.data(), glyphProperties.data(), glyphCount, fontPlatformData.dwFontFace(),
+            fontPlatformData.size(), fontPlatformData.orientation() == FontOrientation::Vertical, m_run.ltr(),
+            &run.analysis, reinterpret_cast<LPCWSTR>(localeName), 
+            features.data(), &run.length, 1,
+            glyphAdvances.data(), glyphOffsets.data());
+        if (FAILED(placementResult))
+            return;
+
+        // Convert all chars that should be treated as spaces to use the space glyph.
+        // We also create a map that allows us to quickly go from space glyphs back to their corresponding characters.
+        float spaceWidth = font->spaceWidth() - font->syntheticBoldOffset();
+
+        for (int k = 0; k < run.length; ++k) {
+            UChar ch = *(currentCP + k);
+            bool treatAsSpace = FontCascade::treatAsSpace(ch);
+            bool treatAsZeroWidthSpace = FontCascade::treatAsZeroWidthSpace(ch);
+            if (treatAsSpace || treatAsZeroWidthSpace) {
+                // Substitute in the space glyph at the appropriate place in the glyphs
+                // array.
+                glyphs[clusterMap[k]] = font->spaceGlyph();
+                glyphAdvances[clusterMap[k]] = treatAsSpace ? spaceWidth : 0;
+            }
+        }
+
+        origins.resize(glyphCount);
+        advances.resize(glyphCount);
+        stringIndices.resize(glyphCount);
+
+        for (size_t i = 0; i < glyphCount; ++i) {
+            stringIndices[i] = i;
+            origins[i] = FloatPoint(glyphOffsets[i].advanceOffset, glyphOffsets[i].ascenderOffset);
+            advances[i] = FloatSize(glyphAdvances[i], 0);
+        }
+
+        m_complexTextRuns.append(ComplexTextRun::create(advances, origins, glyphs, stringIndices, FloatSize(), *font, currentCP, 0, run.length, 0, run.length, m_run.ltr()));
+    }
 }
+
+}
+
+#endif

Modified: trunk/Source/WebCore/platform/graphics/win/DirectWriteUtilities.cpp (251899 => 251900)


--- trunk/Source/WebCore/platform/graphics/win/DirectWriteUtilities.cpp	2019-11-01 00:39:32 UTC (rev 251899)
+++ trunk/Source/WebCore/platform/graphics/win/DirectWriteUtilities.cpp	2019-11-01 00:53:49 UTC (rev 251900)
@@ -190,14 +190,20 @@
 
     Vector<wchar_t> localeName(LOCALE_NAME_MAX_LENGTH);
     int localeLength = GetUserDefaultLocaleName(localeName.data(), LOCALE_NAME_MAX_LENGTH);
+    RELEASE_ASSERT(localeLength <= LOCALE_NAME_MAX_LENGTH);
 
-    COMPtr<IDWriteFontFamily> fontFamily = fontFamilyForCollection(systemFontCollection.get(), localeName, logFont);
-    if (!fontFamily)
-        fontFamily = fontFamilyForCollection(webProcessFontCollection(), localeName, logFont);
+    COMPtr<IDWriteFontCollection1> collection(Query, systemFontCollection);
 
+    COMPtr<IDWriteFontFamily> fontFamily = fontFamilyForCollection(collection.get(), localeName, logFont);
     if (!fontFamily) {
+        collection = webProcessFontCollection();
+        fontFamily = fontFamilyForCollection(collection.get(), localeName, logFont);
+    }
+
+    if (!fontFamily) {
         // Just return the first system font.
-        hr = systemFontCollection->GetFontFamily(0, &fontFamily);
+        collection = COMPtr<IDWriteFontCollection1>(Query, systemFontCollection);
+        hr = collection->GetFontFamily(0, &fontFamily);
         if (FAILED(hr))
             return nullptr;
 
@@ -218,6 +224,21 @@
     return dwFont;
 }
 
+DWRITE_FONT_WEIGHT fontWeight(const FontPlatformData&)
+{
+    return DWRITE_FONT_WEIGHT_REGULAR;
+}
+
+DWRITE_FONT_STYLE fontStyle(const FontPlatformData&)
+{
+    return DWRITE_FONT_STYLE_NORMAL;
+}
+
+DWRITE_FONT_STRETCH fontStretch(const FontPlatformData&)
+{
+    return DWRITE_FONT_STRETCH_NORMAL;
+}
+
 } // namespace DirectWrite
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/graphics/win/DirectWriteUtilities.h (251899 => 251900)


--- trunk/Source/WebCore/platform/graphics/win/DirectWriteUtilities.h	2019-11-01 00:39:32 UTC (rev 251899)
+++ trunk/Source/WebCore/platform/graphics/win/DirectWriteUtilities.h	2019-11-01 00:53:49 UTC (rev 251900)
@@ -36,8 +36,13 @@
 interface IDWriteFontFamily;
 interface IDWriteGdiInterop;
 
+enum DWRITE_FONT_WEIGHT;
+enum DWRITE_FONT_STYLE;
+enum DWRITE_FONT_STRETCH;
+
 namespace WebCore {
 
+class FontPlatformData;
 class SharedBuffer;
 
 namespace DirectWrite {
@@ -52,6 +57,10 @@
 COMPtr<IDWriteFont> createWithPlatformFont(const LOGFONT&);
 Vector<wchar_t> familyNameForLocale(IDWriteFontFamily*, const Vector<wchar_t>& localeName);
 
+DWRITE_FONT_WEIGHT fontWeight(const FontPlatformData&);
+DWRITE_FONT_STYLE fontStyle(const FontPlatformData&);
+DWRITE_FONT_STRETCH fontStretch(const FontPlatformData&);
+
 } // namespace DirectWrite
 
 } // namespace WebCore

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


--- trunk/Source/WebCore/platform/graphics/win/FontCustomPlatformData.cpp	2019-11-01 00:39:32 UTC (rev 251899)
+++ trunk/Source/WebCore/platform/graphics/win/FontCustomPlatformData.cpp	2019-11-01 00:53:49 UTC (rev 251900)
@@ -53,8 +53,14 @@
 
     ASSERT(m_fontReference);
 
+    auto faceName = m_name.charactersWithNullTermination();
+    if (faceName.size() > LF_FACESIZE) {
+        faceName.resize(LF_FACESIZE);
+        faceName.last() = 0;
+    }
+
     LOGFONT logFont { };
-    memcpy(logFont.lfFaceName, m_name.charactersWithNullTermination().data(), sizeof(logFont.lfFaceName[0]) * std::min<size_t>(static_cast<size_t>(LF_FACESIZE), 1 + m_name.length()));
+    memcpy(logFont.lfFaceName, faceName.data(), sizeof(logFont.lfFaceName[0]) * std::min<size_t>(static_cast<size_t>(LF_FACESIZE), 1 + m_name.length()));
 
     logFont.lfHeight = -size;
     if (renderingMode == FontRenderingMode::Normal)
@@ -80,8 +86,8 @@
     RetainPtr<CGFontRef> cgFont = adoptCF(CGFontCreateWithPlatformFont(&logFont));
     return FontPlatformData(WTFMove(hfont), cgFont.get(), size, bold, italic, renderingMode == FontRenderingMode::Alternate);
 #else
-    COMPtr<IDWriteFont> dwFont = DirectWrite::createWithPlatformFont(logFont);
-    return FontPlatformData(WTFMove(hfont), dwFont.get(), size, bold, italic, renderingMode == FontRenderingMode::Alternate);
+    auto font = DirectWrite::createWithPlatformFont(logFont);
+    return FontPlatformData(WTFMove(hfont), WTFMove(font), size, bold, italic, renderingMode == FontRenderingMode::Alternate);
 #endif
 }
 

Modified: trunk/Source/WebCore/platform/graphics/win/FontPlatformDataDirect2D.cpp (251899 => 251900)


--- trunk/Source/WebCore/platform/graphics/win/FontPlatformDataDirect2D.cpp	2019-11-01 00:39:32 UTC (rev 251899)
+++ trunk/Source/WebCore/platform/graphics/win/FontPlatformDataDirect2D.cpp	2019-11-01 00:53:49 UTC (rev 251900)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Apple Inc.  All rights reserved.
+ * Copyright (C) 2016-2019 Apple Inc.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -53,12 +53,12 @@
         m_isSystemFont = !wcscmp(faceName, L"Lucida Grande");
 }
 
-FontPlatformData::FontPlatformData(GDIObject<HFONT>&& hfont, IDWriteFont* font, float size, bool bold, bool oblique, bool useGDI)
+FontPlatformData::FontPlatformData(GDIObject<HFONT>&& hfont, COMPtr<IDWriteFont>&& font, float size, bool bold, bool oblique, bool useGDI)
     : m_syntheticBold(bold)
     , m_syntheticOblique(oblique)
     , m_size(size)
     , m_font(SharedGDIObject<HFONT>::create(WTFMove(hfont)))
-    , m_dwFont(font)
+    , m_dwFont(WTFMove(font))
     , m_useGDI(useGDI)
 {
     HRESULT hr = m_dwFont->CreateFontFace(&m_dwFontFace);
@@ -116,55 +116,6 @@
         && fontsAreEqual(m_dwFont.get(), other.m_dwFont.get());
 }
 
-HRESULT FontPlatformData::createFallbackFont(const LOGFONT& logFont, IDWriteFont** dwFont)
-{
-    if (!dwFont)
-        return E_POINTER;
-
-    *dwFont = DirectWrite::createWithPlatformFont(logFont).get();
-
-    return S_OK;
 }
 
-HRESULT FontPlatformData::createFallbackFont(HFONT hfont, IDWriteFont** dwFont)
-{
-    if (!dwFont)
-        return E_POINTER;
-
-    COMPtr<IDWriteFontCollection> fontCollection;
-    HRESULT hr = DirectWrite::factory()->GetSystemFontCollection(&fontCollection);
-    if (FAILED(hr))
-        return hr;
-
-    HWndDC hdc(0);
-    HGDIOBJ oldFont = ::SelectObject(hdc, hfont);
-
-    COMPtr<IDWriteFontFace> fontFace;
-    hr = DirectWrite::gdiInterop()->CreateFontFaceFromHdc(hdc, &fontFace);
-    if (FAILED(hr)) {
-        ::SelectObject(hdc, oldFont);
-        return hr;
-    }
-
-    LOGFONT gdiBasedFont = { };
-    hr = DirectWrite::gdiInterop()->ConvertFontFaceToLOGFONT(fontFace.get(), &gdiBasedFont);
-    if (FAILED(hr)) {
-        ::SelectObject(hdc, oldFont);
-        return hr;
-    }
-
-    hr = fontCollection->GetFontFromFontFace(fontFace.get(), dwFont);
-
-    if (!SUCCEEDED(hr))
-        hr = DirectWrite::webProcessFontCollection()->GetFontFromFontFace(fontFace.get(), dwFont);
-
-    ::SelectObject(hdc, oldFont);
-    if (SUCCEEDED(hr))
-        return hr;
-
-    return createFallbackFont(gdiBasedFont, dwFont);
-}
-
-}
-
 #endif

Modified: trunk/Source/WebCore/platform/graphics/win/FontWin.cpp (251899 => 251900)


--- trunk/Source/WebCore/platform/graphics/win/FontWin.cpp	2019-11-01 00:39:32 UTC (rev 251899)
+++ trunk/Source/WebCore/platform/graphics/win/FontWin.cpp	2019-11-01 00:53:49 UTC (rev 251900)
@@ -33,9 +33,11 @@
 #include "LayoutRect.h"
 #include "Logging.h"
 #include "TextRun.h"
-#include "UniscribeController.h"
 #include <wtf/MathExtras.h>
 
+#if !USE(DIRECT2D)
+#include "UniscribeController.h"
+#endif
 
 namespace WebCore {
 
@@ -49,6 +51,8 @@
     return false;
 }
 
+#if !USE(DIRECT2D)
+
 void FontCascade::adjustSelectionRectForComplexText(const TextRun& run, LayoutRect& selectionRect, unsigned from, unsigned to) const
 {
     UniscribeController it(this, run);
@@ -113,4 +117,6 @@
     return controller.offsetForPosition(x, includePartialGlyphs);
 }
 
+#endif
+
 }

Modified: trunk/Source/WebCore/platform/graphics/win/GlyphPageTreeNodeDirect2D.cpp (251899 => 251900)


--- trunk/Source/WebCore/platform/graphics/win/GlyphPageTreeNodeDirect2D.cpp	2019-11-01 00:39:32 UTC (rev 251899)
+++ trunk/Source/WebCore/platform/graphics/win/GlyphPageTreeNodeDirect2D.cpp	2019-11-01 00:53:49 UTC (rev 251900)
@@ -52,7 +52,6 @@
     UChar localeName[LOCALE_NAME_MAX_LENGTH + 1] = { };
     int localeLength = GetUserDefaultLocaleName(reinterpret_cast<LPWSTR>(&localeName), LOCALE_NAME_MAX_LENGTH);
     RELEASE_ASSERT(localeLength <= LOCALE_NAME_MAX_LENGTH);
-    localeName[localeLength] = '\0';
 
     TextAnalyzerHelper helper(reinterpret_cast<LPWSTR>(&localeName), reinterpret_cast<LPWSTR>(buffer), bufferLength);
 
@@ -59,20 +58,39 @@
     hr = analyzer->AnalyzeScript(&helper, 0, bufferLength, &helper);
     RELEASE_ASSERT(SUCCEEDED(hr));
 
-    unsigned returnedCount = 0;
-    Glyph localGlyphBuffer[GlyphPage::size];
-    Glyph clusterMap[GlyphPage::size];
+    Vector<Glyph> glyphs(GlyphPage::size, 0);
+    Vector<Glyph> clusterMap(GlyphPage::size, 0);
     Vector<DWRITE_SHAPING_TEXT_PROPERTIES> textProperties(GlyphPage::size);
     Vector<DWRITE_SHAPING_GLYPH_PROPERTIES> glyphProperties(GlyphPage::size);
 
-    hr = analyzer->GetGlyphs(reinterpret_cast<LPCWSTR>(buffer), bufferLength, fontPlatformData.dwFontFace(), fontPlatformData.orientation() == FontOrientation::Vertical, false,
-        &helper.m_analysis, nullptr, nullptr, nullptr, nullptr, 0, GlyphPage::size, clusterMap, textProperties.data(),
-        localGlyphBuffer, glyphProperties.data(), &returnedCount);
-    if (!SUCCEEDED(hr))
-        return false;
+    const WCHAR* textStart = reinterpret_cast<LPCWSTR>(buffer);
+    Glyph* glyphData = glyphs.data();
+    Glyph* clusterMapData = clusterMap.data();
+    DWRITE_SHAPING_TEXT_PROPERTIES* textPropertiesData = textProperties.data();
+    DWRITE_SHAPING_GLYPH_PROPERTIES* glyphPropertiesData = glyphProperties.data();
 
-    for (unsigned i = 0; i < GlyphPage::size; i++) {
-        Glyph glyph = localGlyphBuffer[i];
+    unsigned total = 0;
+    unsigned maxGlyphCount = GlyphPage::size;
+    for (const auto& run : helper.m_analyzedRuns) {
+        RELEASE_ASSERT(total + run.length <= bufferLength);
+
+        unsigned returnedCount = 0;
+        hr = analyzer->GetGlyphs(textStart + run.startPosition, run.length, fontPlatformData.dwFontFace(), fontPlatformData.orientation() == FontOrientation::Vertical, false,
+            &run.analysis, nullptr, nullptr, nullptr, nullptr, 0, maxGlyphCount, clusterMapData, textPropertiesData,
+            glyphData, glyphPropertiesData, &returnedCount);
+
+        if (!SUCCEEDED(hr))
+            return false;
+
+        glyphData += returnedCount;
+        clusterMapData += returnedCount;
+        textPropertiesData += returnedCount;
+        glyphPropertiesData += returnedCount;
+        maxGlyphCount -= returnedCount;
+    }
+
+    for (unsigned i = 0; i < GlyphPage::size; ++i) {
+        Glyph glyph = glyphs[i];
         if (!glyph)
             setGlyphForIndex(i, 0);
         else {

Modified: trunk/Source/WebCore/platform/graphics/win/TextAnalyzerHelper.cpp (251899 => 251900)


--- trunk/Source/WebCore/platform/graphics/win/TextAnalyzerHelper.cpp	2019-11-01 00:39:32 UTC (rev 251899)
+++ trunk/Source/WebCore/platform/graphics/win/TextAnalyzerHelper.cpp	2019-11-01 00:53:49 UTC (rev 251900)
@@ -30,7 +30,7 @@
 
 namespace WebCore {
 
-TextAnalyzerHelper::TextAnalyzerHelper(WCHAR* localeName, WCHAR* buffer, unsigned bufferLength)
+TextAnalyzerHelper::TextAnalyzerHelper(const WCHAR* localeName, const WCHAR* buffer, unsigned bufferLength)
     : m_localeName(localeName)
     , m_buffer(buffer)
     , m_bufferLength(bufferLength)
@@ -122,7 +122,8 @@
 
 HRESULT TextAnalyzerHelper::SetScriptAnalysis(UINT32 textPosition, UINT32 textLength, const DWRITE_SCRIPT_ANALYSIS* analysis)
 {
-    m_analysis = *analysis;
+    AnalyzedRun current = { textPosition, textLength, *analysis };
+    m_analyzedRuns.append(WTFMove(current));
 
     return S_OK;
 }

Modified: trunk/Source/WebCore/platform/graphics/win/TextAnalyzerHelper.h (251899 => 251900)


--- trunk/Source/WebCore/platform/graphics/win/TextAnalyzerHelper.h	2019-11-01 00:39:32 UTC (rev 251899)
+++ trunk/Source/WebCore/platform/graphics/win/TextAnalyzerHelper.h	2019-11-01 00:53:49 UTC (rev 251900)
@@ -26,11 +26,18 @@
 #pragma once
 
 #include <dwrite.h>
+#include <wtf/Vector.h>
 
 namespace WebCore {
 
+struct AnalyzedRun {
+    unsigned startPosition { 0 };
+    unsigned length { 0 };
+    DWRITE_SCRIPT_ANALYSIS analysis;
+};
+
 struct TextAnalyzerHelper : public IDWriteTextAnalysisSink, IDWriteTextAnalysisSource {
-    TextAnalyzerHelper(WCHAR* localeName, WCHAR* buffer, unsigned bufferLength);
+    TextAnalyzerHelper(const WCHAR* localeName, const WCHAR* buffer, unsigned bufferLength);
 
     // IUnknown
     virtual HRESULT STDMETHODCALLTYPE QueryInterface(_In_ REFIID, _COM_Outptr_ void**);
@@ -50,10 +57,10 @@
     virtual HRESULT STDMETHODCALLTYPE SetBidiLevel(UINT32 textPosition, UINT32 textLength, UINT8 explicitLevel, UINT8 resolvedLevel);
     virtual HRESULT STDMETHODCALLTYPE SetNumberSubstitution(UINT32 textPosition, UINT32 textLength, IDWriteNumberSubstitution*);
 
-    WCHAR* m_localeName { nullptr };
-    WCHAR* m_buffer { nullptr };
+    const WCHAR* m_localeName { nullptr };
+    const WCHAR* m_buffer { nullptr };
     unsigned m_bufferLength { 0 };
-    DWRITE_SCRIPT_ANALYSIS m_analysis { };
+    Vector<AnalyzedRun> m_analyzedRuns;
     ULONG m_refCount { 0 };
 };
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to