Title: [254323] trunk
Revision
254323
Author
hironori.fu...@sony.com
Date
2020-01-09 19:50:58 -0800 (Thu, 09 Jan 2020)

Log Message

[Win] Use ComplexTextController instead of UniscribeController
https://bugs.webkit.org/show_bug.cgi?id=204884

Reviewed by Brent Fulgham.

Source/WebCore:

UniscribeController doesn't support surrogate pairs and has
rendering glitches of partially selected a combining character.

Remove UniscribeController, and use ComplexTextController by
implementing `collectComplexTextRunsForCharacters` with Uniscribe.

Covered by existing tests.

* PlatformWin.cmake:
* platform/graphics/ComplexTextController.cpp:
(WebCore::ComplexTextController::collectComplexTextRunsForCharacters): Deleted.
* platform/graphics/FontCascade.cpp:
(WebCore::FontCascade::widthOfTextRange const):
(WebCore::FontCascade::getGlyphsAndAdvancesForComplexText const):
(WebCore::FontCascade::drawGlyphBuffer const):
(WebCore::FontCascade::floatWidthForComplexText const):
(WebCore::FontCascade::adjustSelectionRectForComplexText const):
(WebCore::FontCascade::offsetForPositionForComplexText const):
* platform/graphics/win/ComplexTextControllerUniscribe.cpp: Added.
(WebCore::shapeByUniscribe):
(WebCore::ComplexTextController::collectComplexTextRunsForCharacters):
* platform/graphics/win/FontCGWin.cpp:
* platform/graphics/win/FontCascadeDirect2D.cpp:
* platform/graphics/win/FontWin.cpp:
(WebCore::FontCascade::adjustSelectionRectForComplexText const): Deleted.
(WebCore::FontCascade::getGlyphsAndAdvancesForComplexText const): Deleted.
(WebCore::FontCascade::floatWidthForComplexText const): Deleted.
(WebCore::FontCascade::offsetForPositionForComplexText const): Deleted.
* platform/graphics/win/UniscribeController.cpp: Removed.
* platform/graphics/win/UniscribeController.h: Removed.

Tools:

* TestWebKitAPI/Tests/WebCore/ComplexTextController.cpp: Enabled these tests for PLATFORM(WIN).

LayoutTests:

* platform/win/TestExpectations:
* platform/win/fast/text/justify-ideograph-complex-expected.txt: Rebaselined.
* platform/wincairo/TestExpectations:

Modified Paths

Added Paths

Removed Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (254322 => 254323)


--- trunk/LayoutTests/ChangeLog	2020-01-10 03:38:43 UTC (rev 254322)
+++ trunk/LayoutTests/ChangeLog	2020-01-10 03:50:58 UTC (rev 254323)
@@ -1,3 +1,14 @@
+2020-01-09  Fujii Hironori  <hironori.fu...@sony.com>
+
+        [Win] Use ComplexTextController instead of UniscribeController
+        https://bugs.webkit.org/show_bug.cgi?id=204884
+
+        Reviewed by Brent Fulgham.
+
+        * platform/win/TestExpectations:
+        * platform/win/fast/text/justify-ideograph-complex-expected.txt: Rebaselined.
+        * platform/wincairo/TestExpectations:
+
 2020-01-09  Chris Dumez  <cdu...@apple.com>
 
         Block cross-site top-frame navigations from untrusted iframes

Modified: trunk/LayoutTests/platform/win/TestExpectations (254322 => 254323)


--- trunk/LayoutTests/platform/win/TestExpectations	2020-01-10 03:38:43 UTC (rev 254322)
+++ trunk/LayoutTests/platform/win/TestExpectations	2020-01-10 03:50:58 UTC (rev 254323)
@@ -2965,6 +2965,8 @@
 
 webkit.org/b/152009 fast/canvas/canvas-too-large-to-draw.html [ Skip ]
 
+fast/text/arabic-zwj-and-zwnj.html [ ImageOnlyFailure ]
+
 ################################################################################
 ######################### End list of UNREVIEWED failures ##########################
 ################################################################################
@@ -3426,6 +3428,7 @@
 fast/text/cursive-zh.html [ ImageOnlyFailure ]
 fast/text/emoji-single-parent-family-2.html [ ImageOnlyFailure ]
 fast/text/emoji-single-parent-family.html [ ImageOnlyFailure ]
+fast/text/emoji-with-joiner.html [ Failure ]
 http/tests/security/http-0.9/image-on-HTTP-0.9-default-port-page-allowed-ref-test.html [ ImageOnlyFailure ]
 mathml/presentation/non-bmp-operators-stretching.html [ ImageOnlyFailure ]
 security/contentSecurityPolicy/image-with-blob-url-allowed-by-img-src-star-with-AllowContentSecurityPolicySourceStarToMatchAnyProtocol-enabled.html [ ImageOnlyFailure ]
@@ -4507,6 +4510,9 @@
 
 webkit.org/b/205273 imported/blink/fast/sub-pixel/negative-composited-offset.html [ Pass ImageOnlyFailure ]
 
+webkit.org/b/205487 fast/text/selection-in-initial-advance-region.html [ Failure ]
+webkit.org/b/205485 fast/text/stale-TextLayout-from-first-line.html [ ImageOnlyFailure ]
+
 webkit.org/b/205855 http/wpt/css/css-highlight-api/highlight-text-across-elements.html [ ImageOnlyFailure ]
 webkit.org/b/205855 http/wpt/css/css-highlight-api/highlight-text-cascade.html [ ImageOnlyFailure ]
 webkit.org/b/205855 http/wpt/css/css-highlight-api/highlight-text-replace.html [ ImageOnlyFailure ]

Modified: trunk/LayoutTests/platform/win/fast/text/justify-ideograph-complex-expected.txt (254322 => 254323)


--- trunk/LayoutTests/platform/win/fast/text/justify-ideograph-complex-expected.txt	2020-01-10 03:38:43 UTC (rev 254322)
+++ trunk/LayoutTests/platform/win/fast/text/justify-ideograph-complex-expected.txt	2020-01-10 03:50:58 UTC (rev 254323)
@@ -16,8 +16,8 @@
           text run at (0,30) width 382: "\x{512A}\x{7570}\x{7684}\x{884C}\x{52D5}\x{61C9}\x{7528}\x{7A0B}\x{5F0F}\x{5E73}\x{53F0}\x{FF0C}\x{5BA2}\x{6236}\x{4E5F}\x{975E}\x{5E38}\x{559C}\x{611B}\x{958B}\x{767C}\x{4EBA}\x{54E1}\x{6240}\x{5275}\x{4F5C}\x{7684}\x{61C9}\x{7528}\x{7A0B}\x{5F0F}\x{3002}\x{300D}"
       RenderBlock {P} at (0,129) size 550x45
         RenderText {#text} at (0,0) size 550x45
-          text run at (0,0) width 550: "EA Mobile \x{7684} Worldwide Studios \x{526F}\x{7E3D}\x{88C1} Travis Boatman \x{6307}\x{51FA}\x{FF1A}\x{300C}App Store \x{4E0D}\x{50C5}\x{5FB9}\x{5E95}\x{6539}\x{8B8A}\x{4E86}\x{884C}\x{52D5}\x{904A}\x{6232}"
-          text run at (0,15) width 550: "\x{7522}\x{696D}\x{7684}\x{751F}\x{614B}\x{FF0C}\x{800C}\x{4E14}\x{9084}\x{5728}\x{6301}\x{7E8C}\x{6F14}\x{9032}\x{3002}\x{6709}\x{4E86}\x{5168}\x{7403} 5 \x{5343}\x{591A}\x{842C}\x{7684} iPhone \x{548C} iPod touch \x{5BA2}\x{6236}\x{70BA}\x{57FA}\x{790E}\x{FF0C}App Store"
+          text run at (0,0) width 550: "EA Mobile \x{7684} Worldwide Studios \x{526F}\x{7E3D}\x{88C1} Travis Boatman \x{6307}\x{51FA}\x{FF1A}\x{300C}App Store \x{4E0D}\x{50C5}\x{5FB9}\x{5E95}\x{6539}\x{8B8A}\x{4E86}\x{884C}\x{52D5}\x{904A}"
+          text run at (0,15) width 550: "\x{6232}\x{7522}\x{696D}\x{7684}\x{751F}\x{614B}\x{FF0C}\x{800C}\x{4E14}\x{9084}\x{5728}\x{6301}\x{7E8C}\x{6F14}\x{9032}\x{3002}\x{6709}\x{4E86}\x{5168}\x{7403} 5 \x{5343}\x{591A}\x{842C}\x{7684} iPhone \x{548C} iPod touch \x{5BA2}\x{6236}\x{70BA}\x{57FA}\x{790E}\x{FF0C}App Store"
           text run at (0,30) width 301: "\x{8B93}\x{6211}\x{5011}\x{80FD}\x{5920}\x{958B}\x{767C}\x{53D7}\x{5230}\x{5EE3}\x{5927}\x{7684}\x{5BA2}\x{6236}\x{559C}\x{611B}\x{7684}\x{9AD8}\x{54C1}\x{8CEA} EA \x{904A}\x{6232}\x{3002}\x{300D}"
       RenderBlock {P} at (0,186) size 550x45
         RenderText {#text} at (0,0) size 550x45

Modified: trunk/LayoutTests/platform/wincairo/TestExpectations (254322 => 254323)


--- trunk/LayoutTests/platform/wincairo/TestExpectations	2020-01-10 03:38:43 UTC (rev 254322)
+++ trunk/LayoutTests/platform/wincairo/TestExpectations	2020-01-10 03:50:58 UTC (rev 254323)
@@ -829,6 +829,9 @@
 fast/dom/Range/detach-range-during-deletecontents.html [ Pass Timeout ]
 imported/blink/fast/dom/Window/open-window-features-fuzz.html [ Pass Timeout ]
 
+webkit.org/b/205487 fast/text/selection-in-initial-advance-region.html [ Failure ]
+webkit.org/b/205485 fast/text/stale-TextLayout-from-first-line.html [ ImageOnlyFailure ]
+
 #//////////////////////////////////////////////////////////////////////////////////////////
 # http
 #//////////////////////////////////////////////////////////////////////////////////////////
@@ -1119,7 +1122,6 @@
 ################################################################################
 
 webkit.org/b/117322 fast/css/text-indent-first-line-006.html [ ImageOnlyFailure ]
-webkit.org/b/117322 fast/css/word-spacing-characters-complex-text.html [ ImageOnlyFailure ]
 fast/css/getComputedStyle/getComputedStyle-outline-shorthand.html [ Pass Timeout ]
 webkit.org/b/136484 fast/css-generated-content/initial-letter-basic.html [ Pass Failure ]
 webkit.org/b/136484 fast/css-generated-content/initial-letter-border-padding.html [ Pass Failure ]
@@ -1719,8 +1721,6 @@
 fast/text/decorations-vertical-underline.html [ ImageOnlyFailure ]
 fast/text/ellipsis-text-rtl.html [ ImageOnlyFailure ]
 fast/text/emoji-overlap.html [ ImageOnlyFailure ]
-fast/text/emoji-single-parent-family-2.html [ ImageOnlyFailure ]
-fast/text/emoji-single-parent-family.html [ ImageOnlyFailure ]
 fast/text/emoji-variation-selector.html [ ImageOnlyFailure ]
 fast/text/emoji-with-joiner.html [ Failure ]
 fast/text/emoji.html [ Failure ]
@@ -1727,7 +1727,6 @@
 fast/text/emphasis-overlap.html [ Failure ]
 fast/text/fallback-language-han-2.html [ ImageOnlyFailure ]
 fast/text/fallback-traits-fixup.html [ Failure ]
-fast/text/fitzpatrick-combination.html [ ImageOnlyFailure ]
 fast/text/font-cursive-italic-cjk.html [ ImageOnlyFailure ]
 fast/text/font-kerning.html [ ImageOnlyFailure ]
 fast/text/font-load-data-partitioned-alphabet.html [ Failure ]
@@ -1757,7 +1756,6 @@
 fast/text/justify-ideograph-simple.html [ Failure ]
 fast/text/justify-ideograph-vertical.html [ Failure ]
 fast/text/justify-nbsp.html [ Failure ]
-fast/text/kerning-with-TextLayout.html [ ImageOnlyFailure ]
 fast/text/khmer-lao-font.html [ Failure ]
 fast/text/line-break-between-text-nodes-latin1.html [ ImageOnlyFailure ]
 fast/text/line-break-between-text-nodes.html [ ImageOnlyFailure ]
@@ -1785,7 +1783,6 @@
 fast/text/soft-hyphen-as-first-breaking-opportunity.html [ ImageOnlyFailure ]
 fast/text/soft-hyphen-min-preferred-width.html [ ImageOnlyFailure ]
 fast/text/space-width.html [ ImageOnlyFailure ]
-fast/text/stale-TextLayout-from-first-line.html [ ImageOnlyFailure ]
 fast/text/svg-font-face-with-kerning.html [ Failure ]
 fast/text/synthetic-bold-transformed.html [ ImageOnlyFailure ]
 fast/text/system-font-fallback-emoji.html [ Failure ]

Modified: trunk/Source/WebCore/ChangeLog (254322 => 254323)


--- trunk/Source/WebCore/ChangeLog	2020-01-10 03:38:43 UTC (rev 254322)
+++ trunk/Source/WebCore/ChangeLog	2020-01-10 03:50:58 UTC (rev 254323)
@@ -1,3 +1,41 @@
+2020-01-09  Fujii Hironori  <hironori.fu...@sony.com>
+
+        [Win] Use ComplexTextController instead of UniscribeController
+        https://bugs.webkit.org/show_bug.cgi?id=204884
+
+        Reviewed by Brent Fulgham.
+
+        UniscribeController doesn't support surrogate pairs and has
+        rendering glitches of partially selected a combining character.
+
+        Remove UniscribeController, and use ComplexTextController by
+        implementing `collectComplexTextRunsForCharacters` with Uniscribe.
+
+        Covered by existing tests.
+
+        * PlatformWin.cmake:
+        * platform/graphics/ComplexTextController.cpp:
+        (WebCore::ComplexTextController::collectComplexTextRunsForCharacters): Deleted.
+        * platform/graphics/FontCascade.cpp:
+        (WebCore::FontCascade::widthOfTextRange const):
+        (WebCore::FontCascade::getGlyphsAndAdvancesForComplexText const):
+        (WebCore::FontCascade::drawGlyphBuffer const):
+        (WebCore::FontCascade::floatWidthForComplexText const):
+        (WebCore::FontCascade::adjustSelectionRectForComplexText const):
+        (WebCore::FontCascade::offsetForPositionForComplexText const):
+        * platform/graphics/win/ComplexTextControllerUniscribe.cpp: Added.
+        (WebCore::shapeByUniscribe):
+        (WebCore::ComplexTextController::collectComplexTextRunsForCharacters):
+        * platform/graphics/win/FontCGWin.cpp:
+        * platform/graphics/win/FontCascadeDirect2D.cpp:
+        * platform/graphics/win/FontWin.cpp:
+        (WebCore::FontCascade::adjustSelectionRectForComplexText const): Deleted.
+        (WebCore::FontCascade::getGlyphsAndAdvancesForComplexText const): Deleted.
+        (WebCore::FontCascade::floatWidthForComplexText const): Deleted.
+        (WebCore::FontCascade::offsetForPositionForComplexText const): Deleted.
+        * platform/graphics/win/UniscribeController.cpp: Removed.
+        * platform/graphics/win/UniscribeController.h: Removed.
+
 2020-01-09  Chris Dumez  <cdu...@apple.com>
 
         Block cross-site top-frame navigations from untrusted iframes

Modified: trunk/Source/WebCore/PlatformWin.cmake (254322 => 254323)


--- trunk/Source/WebCore/PlatformWin.cmake	2020-01-10 03:38:43 UTC (rev 254322)
+++ trunk/Source/WebCore/PlatformWin.cmake	2020-01-10 03:50:58 UTC (rev 254323)
@@ -50,6 +50,7 @@
 
     platform/graphics/win/ColorDirect2D.cpp
     platform/graphics/win/ComplexTextControllerDirectWrite.cpp
+    platform/graphics/win/ComplexTextControllerUniscribe.cpp
     platform/graphics/win/DIBPixelData.cpp
     platform/graphics/win/FloatPointDirect2D.cpp
     platform/graphics/win/FloatRectDirect2D.cpp
@@ -68,7 +69,6 @@
     platform/graphics/win/SimpleFontDataWin.cpp
     platform/graphics/win/TransformationMatrixDirect2D.cpp
     platform/graphics/win/TransformationMatrixWin.cpp
-    platform/graphics/win/UniscribeController.cpp
 
     platform/network/win/DownloadBundleWin.cpp
     platform/network/win/NetworkStateNotifierWin.cpp

Modified: trunk/Source/WebCore/platform/graphics/ComplexTextController.cpp (254322 => 254323)


--- trunk/Source/WebCore/platform/graphics/ComplexTextController.cpp	2020-01-10 03:38:43 UTC (rev 254322)
+++ trunk/Source/WebCore/platform/graphics/ComplexTextController.cpp	2020-01-10 03:50:58 UTC (rev 254323)
@@ -43,34 +43,7 @@
 
 namespace WebCore {
 
-#if PLATFORM(WIN) && !USE(DIRECT2D)
-
 class TextLayout {
-};
-
-void TextLayoutDeleter::operator()(TextLayout*) const
-{
-}
-
-std::unique_ptr<TextLayout, TextLayoutDeleter> FontCascade::createLayout(RenderText&, float, bool) const
-{
-    return nullptr;
-}
-
-float FontCascade::width(TextLayout&, unsigned, unsigned, HashSet<const Font*>*)
-{
-    ASSERT_NOT_REACHED();
-    return 0;
-}
-
-void ComplexTextController::collectComplexTextRunsForCharacters(const UChar*, unsigned, unsigned, const Font*)
-{
-    ASSERT_NOT_REACHED();
-}
-
-#else
-
-class TextLayout {
     WTF_MAKE_FAST_ALLOCATED;
 public:
     static bool isNeeded(RenderText& text, const FontCascade& font)
@@ -906,6 +879,4 @@
 {
 }
 
-#endif
-
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/graphics/FontCascade.cpp (254322 => 254323)


--- trunk/Source/WebCore/platform/graphics/FontCascade.cpp	2020-01-10 03:38:43 UTC (rev 254322)
+++ trunk/Source/WebCore/platform/graphics/FontCascade.cpp	2020-01-10 03:50:58 UTC (rev 254323)
@@ -41,10 +41,6 @@
 #include <wtf/text/AtomStringHash.h>
 #include <wtf/text/StringBuilder.h>
 
-#if PLATFORM(WIN) && !USE(DIRECT2D)
-#include "UniscribeController.h"
-#endif
-
 namespace WebCore {
 
 using namespace WTF::Unicode;
@@ -350,15 +346,6 @@
 
     auto codePathToUse = codePath(run);
     if (codePathToUse == Complex) {
-#if PLATFORM(WIN) && !USE(DIRECT2D)
-        UniscribeController it(this, run);
-        it.advance(from);
-        offsetBeforeRange = it.runWidthSoFar();
-        it.advance(to);
-        offsetAfterRange = it.runWidthSoFar();
-        it.advance(to);
-        totalWidth = it.runWidthSoFar();
-#else
         ComplexTextController complexIterator(*this, run, false, fallbackFonts);
         complexIterator.advance(from, nullptr, IncludePartialGlyphs, fallbackFonts);
         offsetBeforeRange = complexIterator.runWidthSoFar();
@@ -366,7 +353,6 @@
         offsetAfterRange = complexIterator.runWidthSoFar();
         complexIterator.advance(run.length(), nullptr, IncludePartialGlyphs, fallbackFonts);
         totalWidth = complexIterator.runWidthSoFar();
-#endif
     } else {
         WidthIterator simpleIterator(this, run, fallbackFonts);
         simpleIterator.advance(from, nullptr);
@@ -1397,7 +1383,6 @@
     return initialAdvance;
 }
 
-#if !PLATFORM(WIN) || USE(DIRECT2D)
 float FontCascade::getGlyphsAndAdvancesForComplexText(const TextRun& run, unsigned from, unsigned to, GlyphBuffer& glyphBuffer, ForTextEmphasisOrNot forTextEmphasis) const
 {
     float initialAdvance;
@@ -1427,7 +1412,6 @@
 
     return initialAdvance;
 }
-#endif
 
 void FontCascade::drawEmphasisMarksForSimpleText(GraphicsContext& context, const TextRun& run, const AtomString& mark, const FloatPoint& point, unsigned from, unsigned to) const
 {
@@ -1452,13 +1436,7 @@
 {
     // Draw each contiguous run of glyphs that use the same font data.
     const Font* fontData = glyphBuffer.fontAt(0);
-#if PLATFORM(WIN)
-    FloatPoint startPoint(point.x() + glyphBuffer.initialAdvance().width(), point.y() + glyphBuffer.initialAdvance().height());
-#else
-    // FIXME: Why do we subtract the initial advance's height but not its width???
-    // We should use the line above from Windows instead.
     FloatPoint startPoint(point.x(), point.y() - glyphBuffer.initialAdvance().height());
-#endif
     float nextX = startPoint.x() + glyphBuffer.advanceAt(0).width();
     float nextY = startPoint.y() + glyphBuffer.advanceAt(0).height();
     unsigned lastFrom = 0;
@@ -1545,7 +1523,6 @@
     return it.m_runWidthSoFar;
 }
 
-#if !PLATFORM(WIN) || USE(DIRECT2D)
 float FontCascade::floatWidthForComplexText(const TextRun& run, HashSet<const Font*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
 {
     ComplexTextController controller(*this, run, true, fallbackFonts);
@@ -1557,7 +1534,6 @@
     }
     return controller.totalWidth();
 }
-#endif
 
 void FontCascade::adjustSelectionRectForSimpleText(const TextRun& run, LayoutRect& selectionRect, unsigned from, unsigned to) const
 {
@@ -1578,7 +1554,6 @@
     selectionRect.setWidth(LayoutUnit::fromFloatCeil(afterWidth - beforeWidth));
 }
 
-#if !PLATFORM(WIN) || USE(DIRECT2D)
 void FontCascade::adjustSelectionRectForComplexText(const TextRun& run, LayoutRect& selectionRect, unsigned from, unsigned to) const
 {
     ComplexTextController controller(*this, run);
@@ -1593,7 +1568,6 @@
         selectionRect.move(beforeWidth, 0);
     selectionRect.setWidth(LayoutUnit::fromFloatCeil(afterWidth - beforeWidth));
 }
-#endif
 
 int FontCascade::offsetForPositionForSimpleText(const TextRun& run, float x, bool includePartialGlyphs) const
 {
@@ -1638,13 +1612,11 @@
     return offset;
 }
 
-#if !PLATFORM(WIN) || USE(DIRECT2D)
 int FontCascade::offsetForPositionForComplexText(const TextRun& run, float x, bool includePartialGlyphs) const
 {
     ComplexTextController controller(*this, run);
     return controller.offsetForPosition(x, includePartialGlyphs);
 }
-#endif
 
 #if !PLATFORM(COCOA) && !USE(HARFBUZZ)
 // FIXME: Unify this with the macOS and iOS implementation.

Added: trunk/Source/WebCore/platform/graphics/win/ComplexTextControllerUniscribe.cpp (0 => 254323)


--- trunk/Source/WebCore/platform/graphics/win/ComplexTextControllerUniscribe.cpp	                        (rev 0)
+++ trunk/Source/WebCore/platform/graphics/win/ComplexTextControllerUniscribe.cpp	2020-01-10 03:50:58 UTC (rev 254323)
@@ -0,0 +1,189 @@
+/*
+* 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
+* are met:
+* 1. Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "config.h"
+#include "ComplexTextController.h"
+
+#if !USE(DIRECT2D)
+
+#include "FontCache.h"
+#include "FontCascade.h"
+#include "HWndDC.h"
+#include <usp10.h>
+
+namespace WebCore {
+
+static bool shapeByUniscribe(const UChar* str, int len, SCRIPT_ITEM item, const Font* fontData,
+    Vector<WORD>& glyphs, Vector<WORD>& clusters,
+    Vector<SCRIPT_VISATTR>& visualAttributes)
+{
+    HWndDC hdc;
+    HGDIOBJ oldFont = nullptr;
+    HRESULT shapeResult = E_PENDING;
+    int glyphCount = 0;
+
+    if (!fontData)
+        return false;
+
+    do {
+        shapeResult = ScriptShape(hdc, fontData->scriptCache(), wcharFrom(str), len, glyphs.size(), &item.a,
+            glyphs.data(), clusters.data(), visualAttributes.data(), &glyphCount);
+        if (shapeResult == E_PENDING) {
+            // The script cache isn't primed with enough info yet. We need to select our HFONT into
+            // a DC and pass the DC in to ScriptShape.
+            ASSERT(!hdc);
+            hdc.setHWnd(nullptr);
+            HFONT hfont = fontData->platformData().hfont();
+            oldFont = SelectObject(hdc, hfont);
+        } else if (shapeResult == E_OUTOFMEMORY) {
+            // Need to resize our buffers.
+            glyphs.resize(glyphs.size() * 2);
+            visualAttributes.resize(glyphs.size());
+        }
+    } while (shapeResult == E_PENDING || shapeResult == E_OUTOFMEMORY);
+
+    if (hdc)
+        SelectObject(hdc, oldFont);
+
+    if (FAILED(shapeResult))
+        return false;
+
+    glyphs.shrink(glyphCount);
+    visualAttributes.shrink(glyphCount);
+
+    return true;
+}
+
+void ComplexTextController::collectComplexTextRunsForCharacters(const UChar* cp, unsigned stringLength, 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, stringLength, 0, stringLength, m_run.ltr()));
+        return;
+    }
+
+    Vector<SCRIPT_ITEM> items(6);
+    int numItems = 0;
+    for (;;) {
+        SCRIPT_CONTROL control { };
+        SCRIPT_STATE state { };
+        // Set up the correct direction for the run.
+        state.uBidiLevel = m_run.rtl();
+        // Lock the correct directional override.
+        state.fOverrideDirection = m_run.directionalOverride();
+
+        // ScriptItemize may write (cMaxItems + 1) SCRIPT_ITEM.
+        HRESULT hr = ScriptItemize(wcharFrom(cp), stringLength, items.size() - 1, &control, &state, items.data(), &numItems);
+        if (hr != E_OUTOFMEMORY) {
+            ASSERT(SUCCEEDED(hr));
+            break;
+        }
+        items.resize(items.size() * 2);
+    }
+    items.resize(numItems + 1);
+
+    for (int i = 0; i < numItems; i++) {
+        // Determine the string for this item.
+        const UChar* str = cp + items[i].iCharPos;
+        int length = items[i+1].iCharPos - items[i].iCharPos;
+        SCRIPT_ITEM& item = items[i];
+
+        // Set up buffers to hold the results of shaping the item.
+        Vector<WORD> glyphs;
+        Vector<WORD> clusters;
+        Vector<SCRIPT_VISATTR> visualAttributes;
+        clusters.resize(length);
+
+        // Shape the item.
+        // The recommended size for the glyph buffer is 1.5 * the character length + 16 in the uniscribe docs.
+        // Apparently this is a good size to avoid having to make repeated calls to ScriptShape.
+        glyphs.resize(1.5 * length + 16);
+        visualAttributes.resize(glyphs.size());
+
+        if (!shapeByUniscribe(str, length, item, font, glyphs, clusters, visualAttributes))
+            continue;
+
+        // We now have a collection of glyphs.
+        Vector<GOFFSET> offsets;
+        Vector<int> advances;
+        offsets.resize(glyphs.size());
+        advances.resize(glyphs.size());
+        HRESULT placeResult = ScriptPlace(0, font->scriptCache(), glyphs.data(), glyphs.size(), visualAttributes.data(),
+            &item.a, advances.data(), offsets.data(), 0);
+        if (placeResult == E_PENDING) {
+            // The script cache isn't primed with enough info yet. We need to select our HFONT into
+            // a DC and pass the DC in to ScriptPlace.
+            HWndDC hdc(0);
+            HFONT hfont = font->platformData().hfont();
+            HGDIOBJ oldFont = SelectObject(hdc, hfont);
+            placeResult = ScriptPlace(hdc, font->scriptCache(), glyphs.data(), glyphs.size(), visualAttributes.data(),
+                &item.a, advances.data(), offsets.data(), 0);
+            SelectObject(hdc, oldFont);
+        }
+
+        if (FAILED(placeResult) || glyphs.isEmpty())
+            continue;
+
+        if (m_fallbackFonts)
+            m_fallbackFonts->add(font);
+
+        Vector<unsigned> stringIndices(glyphs.size(), item.iCharPos);
+
+        for (int k = length - 1; k >= 0; k--)
+            stringIndices[clusters[k]] = item.iCharPos + k;
+
+        Vector<FloatSize> baseAdvances;
+        Vector<FloatPoint> origins;
+        baseAdvances.reserveCapacity(glyphs.size());
+        origins.reserveCapacity(glyphs.size());
+
+        for (unsigned k = 0; k < glyphs.size(); k++) {
+            const float cLogicalScale = font->platformData().useGDI() ? 1 : 32;
+            float advance = advances[k] / cLogicalScale;
+            float offsetX = offsets[k].du / cLogicalScale;
+            float offsetY = offsets[k].dv / cLogicalScale;
+
+            // Match AppKit's rules for the integer vs. non-integer rendering modes.
+            if (!font->platformData().isSystemFont()) {
+                advance = roundf(advance);
+                offsetX = roundf(offsetX);
+                offsetY = roundf(offsetY);
+            }
+
+            // FIXME: We need to take the GOFFSETS for combining glyphs and store them in the glyph buffer
+            // as well, so that when the time comes to draw those glyphs, we can apply the appropriate
+            // translation.
+
+            baseAdvances.uncheckedAppend({ advance, 0 });
+            origins.uncheckedAppend({ offsetX, offsetY });
+        }
+        FloatSize initialAdvance = toFloatSize(origins[0]);
+        bool ltr = !item.a.fRTL;
+        m_complexTextRuns.append(ComplexTextRun::create(baseAdvances, origins, glyphs, stringIndices, initialAdvance, *font, cp, stringLocation, stringLength, item.iCharPos, items[i+1].iCharPos, ltr));
+    }
+}
+
+}
+
+#endif // !USE(DIRECT2D)

Modified: trunk/Source/WebCore/platform/graphics/win/FontCGWin.cpp (254322 => 254323)


--- trunk/Source/WebCore/platform/graphics/win/FontCGWin.cpp	2020-01-10 03:38:43 UTC (rev 254322)
+++ trunk/Source/WebCore/platform/graphics/win/FontCGWin.cpp	2020-01-10 03:50:58 UTC (rev 254323)
@@ -34,7 +34,6 @@
 #include "GlyphBuffer.h"
 #include "GraphicsContext.h"
 #include "IntRect.h"
-#include "UniscribeController.h"
 #include "WebCoreTextRenderer.h"
 #include <pal/spi/cg/CoreGraphicsSPI.h>
 #include <wtf/MathExtras.h>

Modified: trunk/Source/WebCore/platform/graphics/win/FontCascadeDirect2D.cpp (254322 => 254323)


--- trunk/Source/WebCore/platform/graphics/win/FontCascadeDirect2D.cpp	2020-01-10 03:38:43 UTC (rev 254322)
+++ trunk/Source/WebCore/platform/graphics/win/FontCascadeDirect2D.cpp	2020-01-10 03:50:58 UTC (rev 254323)
@@ -37,7 +37,6 @@
 #include "GraphicsContextPlatformPrivateDirect2D.h"
 #include "IntRect.h"
 #include "PlatformContextDirect2D.h"
-#include "UniscribeController.h"
 #include "WebCoreTextRenderer.h"
 #include <d2d1.h>
 #include <dwrite_3.h>

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


--- trunk/Source/WebCore/platform/graphics/win/FontWin.cpp	2020-01-10 03:38:43 UTC (rev 254322)
+++ trunk/Source/WebCore/platform/graphics/win/FontWin.cpp	2020-01-10 03:50:58 UTC (rev 254323)
@@ -35,10 +35,6 @@
 #include "TextRun.h"
 #include <wtf/MathExtras.h>
 
-#if !USE(DIRECT2D)
-#include "UniscribeController.h"
-#endif
-
 namespace WebCore {
 
 bool FontCascade::canReturnFallbackFontsForComplexText()
@@ -51,72 +47,4 @@
     return false;
 }
 
-#if !USE(DIRECT2D)
-
-void FontCascade::adjustSelectionRectForComplexText(const TextRun& run, LayoutRect& selectionRect, unsigned from, unsigned to) const
-{
-    UniscribeController it(this, run);
-    it.advance(from);
-    float beforeWidth = it.runWidthSoFar();
-    it.advance(to);
-    float afterWidth = it.runWidthSoFar();
-
-    if (run.rtl()) {
-        it.advance(run.length());
-        selectionRect.move(it.runWidthSoFar() - afterWidth, 0);
-    } else
-        selectionRect.move(beforeWidth, 0);
-    selectionRect.setWidth(afterWidth - beforeWidth);
 }
-
-float FontCascade::getGlyphsAndAdvancesForComplexText(const TextRun& run, unsigned from, unsigned to, GlyphBuffer& glyphBuffer, ForTextEmphasisOrNot forTextEmphasis) const
-{
-    if (forTextEmphasis) {
-        // FIXME: Add forTextEmphasis paremeter to UniscribeController and use it.
-        LOG_ERROR("Not implemented for text emphasis.");
-        return 0;
-    }
-
-    UniscribeController controller(this, run);
-    controller.advance(from);
-    float beforeWidth = controller.runWidthSoFar();
-    controller.advance(to, &glyphBuffer);
-
-    if (glyphBuffer.isEmpty())
-        return 0;
-
-    float afterWidth = controller.runWidthSoFar();
-
-    if (run.rtl()) {
-        controller.advance(run.length());
-        return controller.runWidthSoFar() - afterWidth;
-    }
-    return beforeWidth;
-}
-
-float FontCascade::floatWidthForComplexText(const TextRun& run, HashSet<const Font*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
-{
-    UniscribeController controller(this, run, fallbackFonts);
-    controller.advance(run.length());
-    if (glyphOverflow) {
-        glyphOverflow->top = std::max<int>(glyphOverflow->top, ceilf(-controller.minGlyphBoundingBoxY()) - (glyphOverflow->computeBounds ? 0 : fontMetrics().ascent()));
-        glyphOverflow->bottom = std::max<int>(glyphOverflow->bottom, ceilf(controller.maxGlyphBoundingBoxY()) - (glyphOverflow->computeBounds ? 0  : fontMetrics().descent()));
-        glyphOverflow->left = std::max<int>(0, ceilf(-controller.minGlyphBoundingBoxX()));
-        glyphOverflow->right = std::max<int>(0, ceilf(controller.maxGlyphBoundingBoxX() - controller.runWidthSoFar()));
-    }
-    return controller.runWidthSoFar();
-}
-
-int FontCascade::offsetForPositionForComplexText(const TextRun& run, float xFloat, bool includePartialGlyphs) const
-{
-    // FIXME: This truncation is not a problem for HTML, but only affects SVG, which passes floating-point numbers
-    // to FontCascade::offsetForPosition(). Bug http://webkit.org/b/40673 tracks fixing this problem.
-    int x = static_cast<int>(xFloat);
-
-    UniscribeController controller(this, run);
-    return controller.offsetForPosition(x, includePartialGlyphs);
-}
-
-#endif
-
-}

Deleted: trunk/Source/WebCore/platform/graphics/win/UniscribeController.cpp (254322 => 254323)


--- trunk/Source/WebCore/platform/graphics/win/UniscribeController.cpp	2020-01-10 03:38:43 UTC (rev 254322)
+++ trunk/Source/WebCore/platform/graphics/win/UniscribeController.cpp	2020-01-10 03:50:58 UTC (rev 254323)
@@ -1,459 +0,0 @@
-/*
- * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "UniscribeController.h"
-
-#include "Font.h"
-#include "FontCascade.h"
-#include "HWndDC.h"
-#include "TextRun.h"
-#include <wtf/MathExtras.h>
-#include <wtf/text/win/WCharStringExtras.h>
-
-namespace WebCore {
-using namespace WTF::Unicode;
-
-// FIXME: Rearchitect this to be more like WidthIterator in Font.cpp.  Have an advance() method
-// that does stuff in that method instead of doing everything in the constructor.  Have advance()
-// take the GlyphBuffer as an arg so that we don't have to populate the glyph buffer when
-// measuring.
-UniscribeController::UniscribeController(const FontCascade* font, const TextRun& run, HashSet<const Font*>* fallbackFonts)
-    : m_font(*font)
-    , m_run(run)
-    , m_fallbackFonts(fallbackFonts)
-    , m_minGlyphBoundingBoxX(std::numeric_limits<float>::max())
-    , m_maxGlyphBoundingBoxX(std::numeric_limits<float>::min())
-    , m_minGlyphBoundingBoxY(std::numeric_limits<float>::max())
-    , m_maxGlyphBoundingBoxY(std::numeric_limits<float>::min())
-    , m_currentCharacter(0)
-    , m_end(run.length())
-    , m_runWidthSoFar(0)
-    , m_padding(run.expansion())
-    , m_computingOffsetPosition(false)
-    , m_includePartialGlyphs(false)
-    , m_offsetX(0)
-    , m_offsetPosition(0)
-{
-    if (!m_padding)
-        m_padPerSpace = 0;
-    else {
-        float numSpaces = 0;
-        for (int s = 0; s < m_run.length(); s++) {
-            if (FontCascade::treatAsSpace(m_run[s]))
-                numSpaces++;
-        }
-
-        if (numSpaces == 0)
-            m_padPerSpace = 0;
-        else
-            m_padPerSpace = m_padding / numSpaces;
-    }
-
-    // Null out our uniscribe structs
-    resetControlAndState();
-}
-
-int UniscribeController::offsetForPosition(int x, bool includePartialGlyphs)
-{
-    m_computingOffsetPosition = true;
-    m_includePartialGlyphs = includePartialGlyphs;
-    m_offsetX = x;
-    m_offsetPosition = 0;
-    advance(m_run.length());
-    if (m_computingOffsetPosition) {
-        // The point is to the left or to the right of the entire run.
-        if ((m_offsetX >= m_runWidthSoFar && m_run.ltr()) || (m_offsetX < 0 && m_run.rtl()))
-            m_offsetPosition = m_end;
-    }
-    m_computingOffsetPosition = false;
-    return m_offsetPosition;
-}
-
-void UniscribeController::advance(unsigned offset, GlyphBuffer* glyphBuffer)
-{
-    // FIXME: We really want to be using a newer version of Uniscribe that supports the new OpenType
-    // functions.  Those functions would allow us to turn off kerning and ligatures.  Without being able
-    // to do that, we will have buggy line breaking and metrics when simple and complex text are close
-    // together (the complex code path will narrow the text because of kerning and ligatures and then
-    // when bidi processing splits into multiple runs, the simple portions will get wider and cause us to
-    // spill off the edge of a line).
-    if (static_cast<int>(offset) > m_end)
-        offset = m_end;
-
-    int length = offset - m_currentCharacter;
-    if (length <= 0)
-        return;
-
-    String bufferFor16BitData;
-
-    // Itemize the string.
-    const UChar* cp = nullptr;
-    if (m_run.is8Bit()) {
-        // Uniscribe only deals with 16-bit characters. Must generate them now.
-        bufferFor16BitData = String::make16BitFrom8BitSource(m_run.data8(m_currentCharacter), length);
-        cp = bufferFor16BitData.characters16();
-    } else
-        cp = m_run.data16(m_currentCharacter);
-
-    unsigned baseCharacter = m_currentCharacter;
-
-    // We break up itemization of the string by fontData and (if needed) the use of small caps.
-
-    // FIXME: It's inconsistent that we use logical order when itemizing, since this
-    // does not match normal RTL.
-
-    // FIXME: This function should decode surrogate pairs. Currently it makes little difference that
-    // it does not because the font cache on Windows does not support non-BMP characters.
-    Vector<UChar, 256> smallCapsBuffer;
-    if (m_font.isSmallCaps())
-        smallCapsBuffer.resize(length);
-
-    unsigned indexOfFontTransition = m_run.rtl() ? length - 1 : 0;
-    const UChar* curr = m_run.rtl() ? cp + length  - 1 : cp;
-    const UChar* end = m_run.rtl() ? cp - 1 : cp + length;
-
-    const Font* fontData;
-    const Font* nextFontData = m_font.glyphDataForCharacter(*curr, false).font;
-
-    UChar newC = 0;
-
-    bool isSmallCaps;
-    bool nextIsSmallCaps = m_font.isSmallCaps() && !(U_GET_GC_MASK(*curr) & U_GC_M_MASK) && (newC = u_toupper(*curr)) != *curr;
-
-    if (nextIsSmallCaps)
-        smallCapsBuffer[curr - cp] = newC;
-
-    while (true) {
-        curr = m_run.rtl() ? curr - 1 : curr + 1;
-        if (curr == end)
-            break;
-
-        fontData = nextFontData;
-        isSmallCaps = nextIsSmallCaps;
-        int index = curr - cp;
-        UChar c = *curr;
-
-        bool forceSmallCaps = isSmallCaps && (U_GET_GC_MASK(c) & U_GC_M_MASK);
-        nextFontData = m_font.glyphDataForCharacter(*curr, false, forceSmallCaps ? SmallCapsVariant : AutoVariant).font;
-        if (m_font.isSmallCaps()) {
-            nextIsSmallCaps = forceSmallCaps || (newC = u_toupper(c)) != c;
-            if (nextIsSmallCaps)
-                smallCapsBuffer[index] = forceSmallCaps ? c : newC;
-        }
-
-        if (m_fallbackFonts && fontData && nextFontData != fontData && fontData != &m_font.primaryFont())
-            m_fallbackFonts->add(fontData);
-
-        if (nextFontData != fontData || nextIsSmallCaps != isSmallCaps) {
-            int itemStart = m_run.rtl() ? index + 1 : indexOfFontTransition;
-            int itemLength = m_run.rtl() ? indexOfFontTransition - index : index - indexOfFontTransition;
-            m_currentCharacter = baseCharacter + itemStart;
-            itemizeShapeAndPlace((isSmallCaps ? smallCapsBuffer.data() : cp) + itemStart, itemStart, itemLength, fontData, glyphBuffer);
-            indexOfFontTransition = index;
-        }
-    }
-    
-    int itemLength = m_run.rtl() ? indexOfFontTransition + 1 : length - indexOfFontTransition;
-    if (itemLength) {
-        if (m_fallbackFonts && nextFontData && nextFontData != &m_font.primaryFont())
-            m_fallbackFonts->add(nextFontData);
-
-        int itemStart = m_run.rtl() ? 0 : indexOfFontTransition;
-        m_currentCharacter = baseCharacter + itemStart;
-        itemizeShapeAndPlace((nextIsSmallCaps ? smallCapsBuffer.data() : cp) + itemStart, itemStart, itemLength, nextFontData, glyphBuffer);
-    }
-
-    m_currentCharacter = baseCharacter + length;
-}
-
-void UniscribeController::itemizeShapeAndPlace(const UChar* cp, unsigned stringOffset, unsigned length, const Font* fontData, GlyphBuffer* glyphBuffer)
-{
-    // ScriptItemize (in Windows XP versions prior to SP2) can overflow by 1.  This is why there is an extra empty item
-    // hanging out at the end of the array
-    m_items.resize(6);
-    int numItems = 0;
-    HRESULT rc = S_OK;
-    while (rc = ::ScriptItemize(wcharFrom(cp), length, m_items.size() - 1, &m_control, &m_state, m_items.data(), &numItems) == E_OUTOFMEMORY) {
-        m_items.resize(m_items.size() * 2);
-        resetControlAndState();
-    }
-    if (FAILED(rc)) {
-        WTFLogAlways("UniscribeController::itemizeShapeAndPlace: ScriptItemize failed, rc=%lx", rc);
-        return;
-    }
-    m_items.resize(numItems + 1);
-
-    if (m_run.rtl()) {
-        for (int i = m_items.size() - 2; i >= 0; i--) {
-            if (!shapeAndPlaceItem(cp, stringOffset, i, fontData, glyphBuffer))
-                return;
-        }
-    } else {
-        for (unsigned i = 0; i < m_items.size() - 1; i++) {
-            if (!shapeAndPlaceItem(cp, stringOffset, i, fontData, glyphBuffer))
-                return;
-        }
-    }
-}
-
-void UniscribeController::resetControlAndState()
-{
-    memset(&m_control, 0, sizeof(SCRIPT_CONTROL));
-    memset(&m_state, 0, sizeof(SCRIPT_STATE));
-
-    // Set up the correct direction for the run.
-    m_state.uBidiLevel = m_run.rtl();
-    
-    // Lock the correct directional override.
-    m_state.fOverrideDirection = m_run.directionalOverride();
-}
-
-bool UniscribeController::shapeAndPlaceItem(const UChar* cp, unsigned stringOffset, unsigned i, const Font* fontData, GlyphBuffer* glyphBuffer)
-{
-    // Determine the string for this item.
-    const UChar* str = cp + m_items[i].iCharPos;
-    int len = m_items[i+1].iCharPos - m_items[i].iCharPos;
-    SCRIPT_ITEM item = m_items[i];
-
-    // Set up buffers to hold the results of shaping the item.
-    Vector<WORD> glyphs;
-    Vector<WORD> clusters;
-    Vector<SCRIPT_VISATTR> visualAttributes;
-    clusters.resize(len);
-     
-    // Shape the item.
-    // The recommended size for the glyph buffer is 1.5 * the character length + 16 in the uniscribe docs.
-    // Apparently this is a good size to avoid having to make repeated calls to ScriptShape.
-    glyphs.resize(1.5 * len + 16);
-    visualAttributes.resize(glyphs.size());
-
-    if (!shape(str, len, item, fontData, glyphs, clusters, visualAttributes))
-        return true;
-
-    Vector<Optional<unsigned>> stringOffsets(glyphs.size());
-    for (unsigned i = 0; i < len; ++i) {
-        if (stringOffsets[clusters[i]])
-            stringOffsets[clusters[i]] = std::min(*stringOffsets[clusters[i]], i);
-        else
-            stringOffsets[clusters[i]] = i;
-    }
-
-    // We now have a collection of glyphs.
-    Vector<GOFFSET> offsets;
-    Vector<int> advances;
-    offsets.resize(glyphs.size());
-    advances.resize(glyphs.size());
-    HRESULT placeResult = ScriptPlace(0, fontData->scriptCache(), glyphs.data(), glyphs.size(), visualAttributes.data(),
-                                      &item.a, advances.data(), offsets.data(), 0);
-    if (placeResult == E_PENDING) {
-        // The script cache isn't primed with enough info yet.  We need to select our HFONT into
-        // a DC and pass the DC in to ScriptPlace.
-        HWndDC hdc(0);
-        HFONT hfont = fontData->platformData().hfont();
-        HFONT oldFont = (HFONT)SelectObject(hdc, hfont);
-        placeResult = ScriptPlace(hdc, fontData->scriptCache(), glyphs.data(), glyphs.size(), visualAttributes.data(),
-                                  &item.a, advances.data(), offsets.data(), 0);
-        SelectObject(hdc, oldFont);
-    }
-    
-    if (FAILED(placeResult) || glyphs.isEmpty())
-        return true;
-
-    // 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.
-    Vector<int> spaceCharacters(glyphs.size());
-    spaceCharacters.fill(-1);
-
-    const float cLogicalScale = fontData->platformData().useGDI() ? 1.0f : 32.0f;
-    float spaceWidth = fontData->spaceWidth() - fontData->syntheticBoldOffset();
-    unsigned logicalSpaceWidth = spaceWidth * cLogicalScale;
-
-    for (int k = 0; k < len; k++) {
-        UChar ch = *(str + 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[clusters[k]] = fontData->spaceGlyph();
-            advances[clusters[k]] = treatAsSpace ? logicalSpaceWidth : 0;
-            if (treatAsSpace)
-                spaceCharacters[clusters[k]] = m_currentCharacter + k + item.iCharPos;
-        }
-    }
-
-    // Populate our glyph buffer with this information.
-    bool hasExtraSpacing = m_font.letterSpacing() || m_font.wordSpacing() || m_padding;
-    
-    float leftEdge = m_runWidthSoFar;
-
-    for (unsigned k = 0; k < glyphs.size(); k++) {
-        Glyph glyph = glyphs[k];
-        float advance = advances[k] / cLogicalScale;
-        float offsetX = offsets[k].du / cLogicalScale;
-        float offsetY = offsets[k].dv / cLogicalScale;
-
-        // Match AppKit's rules for the integer vs. non-integer rendering modes.
-        float roundedAdvance = roundf(advance);
-        if (!fontData->platformData().isSystemFont()) {
-            advance = roundedAdvance;
-            offsetX = roundf(offsetX);
-            offsetY = roundf(offsetY);
-        }
-
-        advance += fontData->syntheticBoldOffset();
-
-        if (hasExtraSpacing) {
-            // If we're a glyph with an advance, go ahead and add in letter-spacing.
-            // That way we weed out zero width lurkers.  This behavior matches the fast text code path.
-            if (advance && m_font.letterSpacing())
-                advance += m_font.letterSpacing();
-
-            // Handle justification and word-spacing.
-            int characterIndex = spaceCharacters[k];
-            // characterIndex is left at the initial value of -1 for glyphs that do not map back to treated-as-space characters.
-            if (characterIndex != -1) {
-                // Account for padding. WebCore uses space padding to justify text.
-                // We distribute the specified padding over the available spaces in the run.
-                if (m_padding) {
-                    // Use leftover padding if not evenly divisible by number of spaces.
-                    if (m_padding < m_padPerSpace) {
-                        advance += m_padding;
-                        m_padding = 0;
-                    } else {
-                        m_padding -= m_padPerSpace;
-                        advance += m_padPerSpace;
-                    }
-                }
-
-                // Account for word-spacing.
-                if (characterIndex > 0 && m_font.wordSpacing()) {
-                    UChar candidateSpace;
-                    if (m_run.is8Bit())
-                        candidateSpace = *(m_run.data8(characterIndex - 1));
-                    else
-                        candidateSpace = *(m_run.data16(characterIndex - 1));
-
-                    if (!FontCascade::treatAsSpace(candidateSpace))
-                        advance += m_font.wordSpacing();
-                }
-            }
-        }
-
-        m_runWidthSoFar += advance;
-
-        // FIXME: We need to take the GOFFSETS for combining glyphs and store them in the glyph buffer
-        // as well, so that when the time comes to draw those glyphs, we can apply the appropriate
-        // translation.
-        if (glyphBuffer) {
-            GlyphBufferAdvance origin(offsetX, -offsetY);
-            if (!glyphBuffer->advancesCount())
-                glyphBuffer->setInitialAdvance(origin);
-            else
-                glyphBuffer->expandLastAdvance(origin);
-            GlyphBufferAdvance glyphAdvance(-origin.width() + advance, -origin.height());
-            glyphBuffer->add(glyph, fontData, glyphAdvance, stringOffsets[k].valueOr(0) + stringOffset);
-        }
-
-        FloatRect glyphBounds = fontData->boundsForGlyph(glyph);
-        glyphBounds.move(m_glyphOrigin.x(), m_glyphOrigin.y());
-        m_minGlyphBoundingBoxX = std::min(m_minGlyphBoundingBoxX, glyphBounds.x());
-        m_maxGlyphBoundingBoxX = std::max(m_maxGlyphBoundingBoxX, glyphBounds.maxX());
-        m_minGlyphBoundingBoxY = std::min(m_minGlyphBoundingBoxY, glyphBounds.y());
-        m_maxGlyphBoundingBoxY = std::max(m_maxGlyphBoundingBoxY, glyphBounds.maxY());
-        m_glyphOrigin.move(advance + offsetX, -offsetY);
-
-        // Mutate the glyph array to contain our altered advances.
-        if (m_computingOffsetPosition)
-            advances[k] = advance;
-    }
-
-    while (m_computingOffsetPosition && m_offsetX >= leftEdge && m_offsetX < m_runWidthSoFar) {
-        // The position is somewhere inside this run.
-        int trailing = 0;
-        HRESULT rc = ::ScriptXtoCP(m_offsetX - leftEdge, clusters.size(), glyphs.size(), clusters.data(), visualAttributes.data(),
-                    advances.data(), &item.a, &m_offsetPosition, &trailing);
-        if (FAILED(rc)) {
-            WTFLogAlways("UniscribeController::shapeAndPlaceItem: ScriptXtoCP failed rc=%lx", rc);
-            return true;
-        }
-        if (trailing && m_includePartialGlyphs && m_offsetPosition < len - 1) {
-            m_offsetPosition += m_currentCharacter + m_items[i].iCharPos;
-            m_offsetX += m_run.rtl() ? -trailing : trailing;
-        } else {
-            m_computingOffsetPosition = false;
-            m_offsetPosition += m_currentCharacter + m_items[i].iCharPos;
-            if (trailing && m_includePartialGlyphs)
-               m_offsetPosition++;
-            return false;
-        }
-    }
-
-    return true;
-}
-
-bool UniscribeController::shape(const UChar* str, int len, SCRIPT_ITEM item, const Font* fontData,
-                                Vector<WORD>& glyphs, Vector<WORD>& clusters,
-                                Vector<SCRIPT_VISATTR>& visualAttributes)
-{
-    HWndDC hdc;
-    HFONT oldFont = 0;
-    HRESULT shapeResult = E_PENDING;
-    int glyphCount = 0;
-
-    if (!fontData)
-        return false;
-
-    do {
-        shapeResult = ScriptShape(hdc, fontData->scriptCache(), wcharFrom(str), len, glyphs.size(), &item.a,
-                                  glyphs.data(), clusters.data(), visualAttributes.data(), &glyphCount);
-        if (shapeResult == E_PENDING) {
-            // The script cache isn't primed with enough info yet.  We need to select our HFONT into
-            // a DC and pass the DC in to ScriptShape.
-            ASSERT(!hdc);
-            hdc.setHWnd(0);
-            HFONT hfont = fontData->platformData().hfont();
-            oldFont = (HFONT)SelectObject(hdc, hfont);
-        } else if (shapeResult == E_OUTOFMEMORY) {
-            // Need to resize our buffers.
-            glyphs.resize(glyphs.size() * 2);
-            visualAttributes.resize(glyphs.size());
-        }
-    } while (shapeResult == E_PENDING || shapeResult == E_OUTOFMEMORY);
-
-    if (hdc)
-        SelectObject(hdc, oldFont);
-
-    if (FAILED(shapeResult))
-        return false;
-
-    glyphs.shrink(glyphCount);
-    visualAttributes.shrink(glyphCount);
-
-    return true;
-}
-
-}

Deleted: trunk/Source/WebCore/platform/graphics/win/UniscribeController.h (254322 => 254323)


--- trunk/Source/WebCore/platform/graphics/win/UniscribeController.h	2020-01-10 03:38:43 UTC (rev 254322)
+++ trunk/Source/WebCore/platform/graphics/win/UniscribeController.h	2020-01-10 03:50:58 UTC (rev 254323)
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef UniscribeController_h
-#define UniscribeController_h
-
-#include "FontCascade.h"
-#include "GlyphBuffer.h"
-#include <usp10.h>
-#include <wtf/Vector.h>
-
-namespace WebCore {
-
-class UniscribeController {
-public:
-    UniscribeController(const FontCascade*, const TextRun&, HashSet<const Font*>* fallbackFonts = 0);
-
-    // Advance and measure/place up to the specified character.
-    void advance(unsigned to, GlyphBuffer* = 0);
-
-    // Compute the character offset for a given x coordinate.
-    int offsetForPosition(int x, bool includePartialGlyphs);
-
-    // Returns the width of everything we've consumed so far.
-    float runWidthSoFar() const { return m_runWidthSoFar; }
-
-    float minGlyphBoundingBoxX() const { return m_minGlyphBoundingBoxX; }
-    float maxGlyphBoundingBoxX() const { return m_maxGlyphBoundingBoxX; }
-    float minGlyphBoundingBoxY() const { return m_minGlyphBoundingBoxY; }
-    float maxGlyphBoundingBoxY() const { return m_maxGlyphBoundingBoxY; }
-
-private:    
-    void resetControlAndState();
-
-    void itemizeShapeAndPlace(const UChar*, unsigned stringOffset, unsigned length, const Font*, GlyphBuffer*);
-    bool shapeAndPlaceItem(const UChar*, unsigned stringOffset, unsigned index, const Font*, GlyphBuffer*);
-    bool shape(const UChar* str, int len, SCRIPT_ITEM, const Font*,
-               Vector<WORD>& glyphs, Vector<WORD>& clusters,
-               Vector<SCRIPT_VISATTR>& visualAttributes);
-
-    const FontCascade& m_font;
-    const TextRun& m_run;
-    HashSet<const Font*>* m_fallbackFonts;
-    FloatPoint m_glyphOrigin;
-    float m_minGlyphBoundingBoxX;
-    float m_maxGlyphBoundingBoxX;
-    float m_minGlyphBoundingBoxY;
-    float m_maxGlyphBoundingBoxY;
-
-    SCRIPT_CONTROL m_control;
-    SCRIPT_STATE m_state;
-    Vector<SCRIPT_ITEM> m_items;
- 
-    unsigned m_currentCharacter;
-    int m_end;
-
-    float m_runWidthSoFar;
-    float m_padding;
-    float m_padPerSpace;
-
-    bool m_computingOffsetPosition;
-    bool m_includePartialGlyphs;
-    float m_offsetX;
-    int m_offsetPosition;
-};
-
-}
-#endif

Modified: trunk/Tools/ChangeLog (254322 => 254323)


--- trunk/Tools/ChangeLog	2020-01-10 03:38:43 UTC (rev 254322)
+++ trunk/Tools/ChangeLog	2020-01-10 03:50:58 UTC (rev 254323)
@@ -1,3 +1,12 @@
+2020-01-09  Fujii Hironori  <hironori.fu...@sony.com>
+
+        [Win] Use ComplexTextController instead of UniscribeController
+        https://bugs.webkit.org/show_bug.cgi?id=204884
+
+        Reviewed by Brent Fulgham.
+
+        * TestWebKitAPI/Tests/WebCore/ComplexTextController.cpp: Enabled these tests for PLATFORM(WIN).
+
 2020-01-09  David Kilzer  <ddkil...@apple.com>
 
         TestController::platformLibraryPathForTesting() returns inner pointer to autoreleased NSString

Modified: trunk/Tools/TestWebKitAPI/Tests/WebCore/ComplexTextController.cpp (254322 => 254323)


--- trunk/Tools/TestWebKitAPI/Tests/WebCore/ComplexTextController.cpp	2020-01-10 03:38:43 UTC (rev 254322)
+++ trunk/Tools/TestWebKitAPI/Tests/WebCore/ComplexTextController.cpp	2020-01-10 03:50:58 UTC (rev 254323)
@@ -25,8 +25,6 @@
 
 #include "config.h"
 
-#if !PLATFORM(WIN)
-
 #include <_javascript_Core/InitializeThreading.h>
 #include <WebCore/ComplexTextController.h>
 #include <WebCore/FontCascade.h>
@@ -367,5 +365,3 @@
 }
 
 }
-
-#endif
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to