Diff
Modified: trunk/Source/WebCore/ChangeLog (283198 => 283199)
--- trunk/Source/WebCore/ChangeLog 2021-09-28 22:06:15 UTC (rev 283198)
+++ trunk/Source/WebCore/ChangeLog 2021-09-28 22:19:15 UTC (rev 283199)
@@ -1,3 +1,34 @@
+2021-09-28 Devin Rousso <[email protected]>
+
+ Move `DrawGlyphsRecorder` outside of `DisplayList`
+ https://bugs.webkit.org/show_bug.cgi?id=230912
+
+ Reviewed by Myles Maxfield.
+
+ There's really nothing about `DrawGlyphsRecorder` that's specific to display lists other
+ than it's currently only being used by `DisplayList::Recorder`.
+
+ This patch moves `DrawGlyphsRecorder` outside of `namespace DisplayList` (and the related
+ folder in the source tree). The next patch (<https://webkit.org/b/230913>) will generalize
+ it to allow any `GraphicsContext` instead of just `DisplayList::Recorder`. This is being
+ done to make `<attachment>` drawing work in the GPUProcess (<https://webkit.org/b/230781>).
+
+ * platform/graphics/DrawGlyphsRecorder.h: Renamed from Source/WebCore/platform/graphics/displaylists/DisplayListDrawGlyphsRecorder.h.
+ * platform/graphics/coretext/DrawGlyphsRecorderCoreText.cpp: Renamed from Source/WebCore/platform/graphics/displaylists/DisplayListDrawGlyphsRecorderCoreText.cpp.
+ * platform/graphics/harfbuzz/DrawGlyphsRecorderHarfBuzz.cpp: Renamed from Source/WebCore/platform/graphics/displaylists/DisplayListDrawGlyphsRecorderHarfBuzz.cpp.
+ * platform/graphics/win/DrawGlyphsRecorderWin.cpp: Renamed from Source/WebCore/platform/graphics/displaylists/DisplayListDrawGlyphsRecorderWin.cpp.
+
+ * platform/graphics/FontCascade.cpp:
+ (WebCore::FontCascade::displayListForTextRun const):
+ * platform/graphics/displaylists/DisplayListRecorder.h:
+
+ * Headers.cmake:
+ * PlatformAppleWin.cmake:
+ * PlatformWinCairo.cmake:
+ * SourcesCocoa.txt:
+ * WebCore.xcodeproj/project.pbxproj:
+ * platform/FreeType.cmake:
+
2021-09-28 Myles C. Maxfield <[email protected]>
Negative integers in @font-palette-values are invalid
Modified: trunk/Source/WebCore/Headers.cmake (283198 => 283199)
--- trunk/Source/WebCore/Headers.cmake 2021-09-28 22:06:15 UTC (rev 283198)
+++ trunk/Source/WebCore/Headers.cmake 2021-09-28 22:19:15 UTC (rev 283199)
@@ -1244,6 +1244,7 @@
platform/graphics/DisplayRefreshMonitorFactory.h
platform/graphics/DisplayRefreshMonitorManager.h
platform/graphics/DisplayUpdate.h
+ platform/graphics/DrawGlyphsRecorder.h
platform/graphics/ExtensionsGL.h
platform/graphics/FloatLine.h
platform/graphics/FloatPoint.h
@@ -1375,7 +1376,6 @@
platform/graphics/angle/GraphicsContextGLANGLEUtilities.h
platform/graphics/displaylists/DisplayList.h
- platform/graphics/displaylists/DisplayListDrawGlyphsRecorder.h
platform/graphics/displaylists/DisplayListDrawingContext.h
platform/graphics/displaylists/DisplayListFlushIdentifier.h
platform/graphics/displaylists/DisplayListImageBuffer.h
Modified: trunk/Source/WebCore/PlatformAppleWin.cmake (283198 => 283199)
--- trunk/Source/WebCore/PlatformAppleWin.cmake 2021-09-28 22:06:15 UTC (rev 283198)
+++ trunk/Source/WebCore/PlatformAppleWin.cmake 2021-09-28 22:19:15 UTC (rev 283199)
@@ -30,8 +30,7 @@
platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp
platform/graphics/avfoundation/cf/WebCoreAVCFResourceLoader.cpp
- platform/graphics/displaylists/DisplayListDrawGlyphsRecorderWin.cpp
-
+ platform/graphics/win/DrawGlyphsRecorderWin.cpp
platform/graphics/win/FontCustomPlatformData.cpp
platform/network/cf/AuthenticationCF.cpp
Modified: trunk/Source/WebCore/PlatformWinCairo.cmake (283198 => 283199)
--- trunk/Source/WebCore/PlatformWinCairo.cmake 2021-09-28 22:06:15 UTC (rev 283198)
+++ trunk/Source/WebCore/PlatformWinCairo.cmake 2021-09-28 22:19:15 UTC (rev 283199)
@@ -22,7 +22,7 @@
platform/graphics/GLContext.cpp
platform/graphics/PlatformDisplay.cpp
- platform/graphics/displaylists/DisplayListDrawGlyphsRecorderHarfBuzz.cpp
+ platform/graphics/harfbuzz/DrawGlyphsRecorderHarfBuzz.cpp
platform/graphics/win/FontCustomPlatformDataCairo.cpp
platform/graphics/win/FontPlatformDataCairoWin.cpp
Modified: trunk/Source/WebCore/SourcesCocoa.txt (283198 => 283199)
--- trunk/Source/WebCore/SourcesCocoa.txt 2021-09-28 22:06:15 UTC (rev 283198)
+++ trunk/Source/WebCore/SourcesCocoa.txt 2021-09-28 22:19:15 UTC (rev 283199)
@@ -387,6 +387,7 @@
platform/graphics/cocoa/WebCoreDecompressionSession.mm
platform/graphics/cocoa/WebGLLayer.mm
platform/graphics/cocoa/VideoTrackPrivateWebM.cpp
+platform/graphics/coretext/DrawGlyphsRecorderCoreText.cpp
platform/graphics/coretext/FontCascadeCoreText.cpp
platform/graphics/coretext/FontCoreText.cpp
platform/graphics/coretext/FontPlatformDataCoreText.cpp
@@ -396,7 +397,6 @@
platform/graphics/cv/PixelBufferConformerCV.cpp
platform/graphics/cv/GraphicsContextGLCVANGLE.cpp
platform/graphics/coreimage/FilterEffectRendererCoreImage.mm
-platform/graphics/displaylists/DisplayListDrawGlyphsRecorderCoreText.cpp
platform/graphics/gpu/cocoa/GPUDeviceMetal.mm
platform/graphics/ios/DisplayRefreshMonitorIOS.mm
platform/graphics/ios/IconIOS.mm
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (283198 => 283199)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2021-09-28 22:06:15 UTC (rev 283198)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2021-09-28 22:19:15 UTC (rev 283199)
@@ -647,7 +647,7 @@
1CAF34810A6C405200ABE06E /* WebScriptObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 1CAF347E0A6C405200ABE06E /* WebScriptObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
1CAF34820A6C405200ABE06E /* WebScriptObject.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1CAF347F0A6C405200ABE06E /* WebScriptObject.mm */; };
1CAF34830A6C405200ABE06E /* WebScriptObjectPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 1CAF34800A6C405200ABE06E /* WebScriptObjectPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 1CAF56DB25301AC80017B472 /* DisplayListDrawGlyphsRecorder.h in Headers */ = {isa = PBXBuildFile; fileRef = 1CAF56D8253014570017B472 /* DisplayListDrawGlyphsRecorder.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 1CAF56DB25301AC80017B472 /* DrawGlyphsRecorder.h in Headers */ = {isa = PBXBuildFile; fileRef = 1CAF56D8253014570017B472 /* DrawGlyphsRecorder.h */; settings = {ATTRIBUTES = (Private, ); }; };
1CCD81502231F83E0065FC2B /* WebCoreResourceHandleAsOperationQueueDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = E152551416FD234F003D7ADB /* WebCoreResourceHandleAsOperationQueueDelegate.mm */; };
1CCDF5BE1990332400BCEBAD /* SVGToOTFFontConversion.h in Headers */ = {isa = PBXBuildFile; fileRef = 1CCDF5BC1990332400BCEBAD /* SVGToOTFFontConversion.h */; };
1CE8864126105BF2000C816C /* InMemoryDisplayList.h in Headers */ = {isa = PBXBuildFile; fileRef = 1CE8863F26105A5F000C816C /* InMemoryDisplayList.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -7018,8 +7018,8 @@
1CAF347E0A6C405200ABE06E /* WebScriptObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebScriptObject.h; sourceTree = "<group>"; };
1CAF347F0A6C405200ABE06E /* WebScriptObject.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebScriptObject.mm; sourceTree = "<group>"; };
1CAF34800A6C405200ABE06E /* WebScriptObjectPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebScriptObjectPrivate.h; sourceTree = "<group>"; };
- 1CAF56D8253014570017B472 /* DisplayListDrawGlyphsRecorder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DisplayListDrawGlyphsRecorder.h; sourceTree = "<group>"; };
- 1CAF56DE2530245A0017B472 /* DisplayListDrawGlyphsRecorderCoreText.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DisplayListDrawGlyphsRecorderCoreText.cpp; sourceTree = "<group>"; };
+ 1CAF56D8253014570017B472 /* DrawGlyphsRecorder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DrawGlyphsRecorder.h; sourceTree = "<group>"; };
+ 1CAF56DE2530245A0017B472 /* DrawGlyphsRecorderCoreText.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DrawGlyphsRecorderCoreText.cpp; sourceTree = "<group>"; };
1CB6B4F8217B83930093B9CD /* TextDecorationThickness.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TextDecorationThickness.h; sourceTree = "<group>"; };
1CB6B4FB217B83940093B9CD /* TextUnderlineOffset.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TextUnderlineOffset.h; sourceTree = "<group>"; };
1CCDF5BB1990332400BCEBAD /* SVGToOTFFontConversion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGToOTFFontConversion.cpp; sourceTree = "<group>"; };
@@ -18113,8 +18113,6 @@
children = (
0FE5FBCA1C3DD51E0007A2CA /* DisplayList.cpp */,
0FE5FBCB1C3DD51E0007A2CA /* DisplayList.h */,
- 1CAF56D8253014570017B472 /* DisplayListDrawGlyphsRecorder.h */,
- 1CAF56DE2530245A0017B472 /* DisplayListDrawGlyphsRecorderCoreText.cpp */,
55C0A29523FE2CE000F2CB93 /* DisplayListDrawingContext.cpp */,
72EA09F923FCCC6A008504A5 /* DisplayListDrawingContext.h */,
7242AC9525758FE0005A9CF1 /* DisplayListFlushIdentifier.h */,
@@ -18958,6 +18956,7 @@
1C6FD920250CCA6400D6E920 /* coretext */ = {
isa = PBXGroup;
children = (
+ 1CAF56DE2530245A0017B472 /* DrawGlyphsRecorderCoreText.cpp */,
1C6FD8AE250A311500D6E920 /* FontCascadeCoreText.cpp */,
1C6FD8AF250A33CF00D6E920 /* FontCoreText.cpp */,
1C6FD8AC250A294D00D6E920 /* FontPlatformDataCoreText.cpp */,
@@ -26961,6 +26960,7 @@
2D29ECC4192ECC8300984B78 /* DisplayRefreshMonitorManager.h */,
0FBB5FC9260E9B430054572C /* DisplayUpdate.cpp */,
0FBB5FCB260E9B440054572C /* DisplayUpdate.h */,
+ 1CAF56D8253014570017B472 /* DrawGlyphsRecorder.h */,
6E67D2A81280E8BD008758F7 /* ExtensionsGL.h */,
2E888CA925F6A4110057914A /* FloatLine.cpp */,
2E888CA825F6A4110057914A /* FloatLine.h */,
@@ -32209,7 +32209,6 @@
F47A09D120A93A9700240FAE /* DisabledAdaptations.h in Headers */,
7EDAAFC919A2CCDC0034DFD1 /* DiskCacheMonitorCocoa.h in Headers */,
0FE5FBD31C3DD51E0007A2CA /* DisplayList.h in Headers */,
- 1CAF56DB25301AC80017B472 /* DisplayListDrawGlyphsRecorder.h in Headers */,
55AD09402408964000DE4D2F /* DisplayListDrawingContext.h in Headers */,
7242AC9725758FE1005A9CF1 /* DisplayListFlushIdentifier.h in Headers */,
55AD093E2408963500DE4D2F /* DisplayListImageBuffer.h in Headers */,
@@ -32318,6 +32317,7 @@
A7CFB3D20B7ED10A0070C32D /* DragImage.h in Headers */,
1AF5E4D91E5677A9004A1F01 /* DragItem.h in Headers */,
81F65FF613788FAA00FF6F2D /* DragState.h in Headers */,
+ 1CAF56DB25301AC80017B472 /* DrawGlyphsRecorder.h in Headers */,
510A91F624D32DDC00BFD89C /* Dualshock3HIDGamepad.h in Headers */,
93D6B7A82551D41F0058DD3A /* DummySpeechRecognitionProvider.h in Headers */,
93085DF826E822C7000EC6A7 /* DummyStorageProvider.h in Headers */,
Modified: trunk/Source/WebCore/platform/FreeType.cmake (283198 => 283199)
--- trunk/Source/WebCore/platform/FreeType.cmake 2021-09-28 22:06:15 UTC (rev 283198)
+++ trunk/Source/WebCore/platform/FreeType.cmake 2021-09-28 22:19:15 UTC (rev 283199)
@@ -5,8 +5,6 @@
)
list(APPEND WebCore_SOURCES
- platform/graphics/displaylists/DisplayListDrawGlyphsRecorderHarfBuzz.cpp
-
platform/graphics/freetype/FontCacheFreeType.cpp
platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp
platform/graphics/freetype/FontPlatformDataFreeType.cpp
@@ -15,6 +13,7 @@
platform/graphics/freetype/SimpleFontDataFreeType.cpp
platform/graphics/harfbuzz/ComplexTextControllerHarfBuzz.cpp
+ platform/graphics/harfbuzz/DrawGlyphsRecorderHarfBuzz.cpp
platform/graphics/harfbuzz/FontDescriptionHarfBuzz.cpp
)
Copied: trunk/Source/WebCore/platform/graphics/DrawGlyphsRecorder.h (from rev 283198, trunk/Source/WebCore/platform/graphics/displaylists/DisplayListDrawGlyphsRecorder.h) (0 => 283199)
--- trunk/Source/WebCore/platform/graphics/DrawGlyphsRecorder.h (rev 0)
+++ trunk/Source/WebCore/platform/graphics/DrawGlyphsRecorder.h 2021-09-28 22:19:15 UTC (rev 283199)
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2020-2021 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. ``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
+ * 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.
+ */
+
+#pragma once
+
+#include "AffineTransform.h"
+#include "Color.h"
+#include "Gradient.h"
+#include "GraphicsContext.h"
+#include "Pattern.h"
+#include "TextFlags.h"
+#include <wtf/UniqueRef.h>
+
+#if USE(CORE_TEXT)
+#include <CoreGraphics/CoreGraphics.h>
+#include <pal/spi/cg/CoreGraphicsSPI.h>
+#endif
+
+namespace WebCore {
+
+class FloatPoint;
+class Font;
+class GlyphBuffer;
+class GraphicsContext;
+
+namespace DisplayList {
+class Recorder;
+}
+
+class DrawGlyphsRecorder {
+public:
+ enum class DrawGlyphsDeconstruction {
+ Deconstruct,
+ DontDeconstruct
+ };
+ explicit DrawGlyphsRecorder(DisplayList::Recorder&, DrawGlyphsDeconstruction);
+
+ void drawGlyphs(const Font&, const GlyphBufferGlyph*, const GlyphBufferAdvance*, unsigned numGlyphs, const FloatPoint& anchorPoint, FontSmoothingMode);
+
+#if USE(CORE_TEXT) && !PLATFORM(WIN)
+ void recordBeginLayer(CGRenderingStateRef, CGGStateRef, CGRect);
+ void recordEndLayer(CGRenderingStateRef, CGGStateRef);
+ void recordDrawGlyphs(CGRenderingStateRef, CGGStateRef, const CGAffineTransform*, const CGGlyph[], const CGPoint positions[], size_t count);
+ void recordDrawImage(CGRenderingStateRef, CGGStateRef, CGRect, CGImageRef);
+#endif
+
+ DrawGlyphsDeconstruction drawGlyphsDeconstruction() const { return m_drawGlyphsDeconstruction; }
+
+private:
+#if USE(CORE_TEXT) && !PLATFORM(WIN)
+ UniqueRef<GraphicsContext> createInternalContext();
+#endif
+
+ void populateInternalState(const GraphicsContextState&);
+ void populateInternalContext(const GraphicsContextState&);
+ void prepareInternalContext(const Font&, FontSmoothingMode);
+ void concludeInternalContext();
+
+ void updateFillColor(const Color&, Gradient* = nullptr, Pattern* = nullptr);
+ void updateStrokeColor(const Color&, Gradient* = nullptr, Pattern* = nullptr);
+ void updateCTM(const AffineTransform&);
+ enum class ShadowsIgnoreTransforms {
+ Unspecified,
+ Yes,
+ No
+ };
+ void updateShadow(const FloatSize& shadowOffset, float shadowBlur, const Color& shadowColor, ShadowsIgnoreTransforms);
+
+#if USE(CORE_TEXT) && !PLATFORM(WIN)
+ void updateShadow(CGStyleRef);
+#endif
+
+ DisplayList::Recorder& m_owner;
+ DrawGlyphsDeconstruction m_drawGlyphsDeconstruction;
+
+#if USE(CORE_TEXT) && !PLATFORM(WIN)
+ UniqueRef<GraphicsContext> m_internalContext;
+#endif
+
+ const Font* m_originalFont { nullptr };
+ FontSmoothingMode m_smoothingMode { FontSmoothingMode::AutoSmoothing };
+ AffineTransform m_originalTextMatrix;
+
+ struct State {
+ struct Style {
+ Color color;
+ RefPtr<Gradient> gradient;
+ AffineTransform gradientSpaceTransform;
+ RefPtr<Pattern> pattern;
+ };
+ Style fillStyle;
+ Style strokeStyle;
+
+ AffineTransform ctm;
+
+ struct ShadowState {
+ FloatSize offset;
+ float blur { 0 };
+ Color color;
+ bool ignoreTransforms { false };
+ };
+ ShadowState shadow;
+ };
+ State m_originalState;
+ State m_currentState;
+};
+
+} // namespace WebCore
Modified: trunk/Source/WebCore/platform/graphics/FontCascade.cpp (283198 => 283199)
--- trunk/Source/WebCore/platform/graphics/FontCascade.cpp 2021-09-28 22:06:15 UTC (rev 283198)
+++ trunk/Source/WebCore/platform/graphics/FontCascade.cpp 2021-09-28 22:19:15 UTC (rev 283199)
@@ -213,7 +213,7 @@
return nullptr;
std::unique_ptr<DisplayList::InMemoryDisplayList> displayList = makeUnique<DisplayList::InMemoryDisplayList>();
- DisplayList::Recorder recordingContext(*displayList, context.state(), FloatRect(), AffineTransform(), nullptr, DisplayList::DrawGlyphsRecorder::DrawGlyphsDeconstruction::DontDeconstruct);
+ DisplayList::Recorder recordingContext(*displayList, context.state(), FloatRect(), AffineTransform(), nullptr, DrawGlyphsRecorder::DrawGlyphsDeconstruction::DontDeconstruct);
FloatPoint startPoint = toFloatPoint(WebCore::size(glyphBuffer.initialAdvance()));
drawGlyphBuffer(recordingContext, glyphBuffer, startPoint, customFontNotReadyAction);
Copied: trunk/Source/WebCore/platform/graphics/coretext/DrawGlyphsRecorderCoreText.cpp (from rev 283198, trunk/Source/WebCore/platform/graphics/displaylists/DisplayListDrawGlyphsRecorderCoreText.cpp) (0 => 283199)
--- trunk/Source/WebCore/platform/graphics/coretext/DrawGlyphsRecorderCoreText.cpp (rev 0)
+++ trunk/Source/WebCore/platform/graphics/coretext/DrawGlyphsRecorderCoreText.cpp 2021-09-28 22:19:15 UTC (rev 283199)
@@ -0,0 +1,432 @@
+/*
+ * Copyright (C) 2020-2021 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. ``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
+ * 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 "DrawGlyphsRecorder.h"
+
+#include "BitmapImage.h"
+#include "Color.h"
+#include "DisplayListItems.h"
+#include "DisplayListRecorder.h"
+#include "FloatPoint.h"
+#include "Font.h"
+#include "FontCascade.h"
+#include "GlyphBuffer.h"
+#include "GraphicsContextCG.h"
+
+#include <CoreText/CoreText.h>
+#include <wtf/Vector.h>
+
+#if PLATFORM(WIN)
+#include <pal/spi/win/CoreTextSPIWin.h>
+#endif
+
+namespace WebCore {
+
+static CGContextDelegateRef beginLayer(CGContextDelegateRef delegate, CGRenderingStateRef rstate, CGGStateRef gstate, CGRect rect, CFDictionaryRef, CGContextDelegateRef)
+{
+ DrawGlyphsRecorder& recorder = *static_cast<DrawGlyphsRecorder*>(CGContextDelegateGetInfo(delegate));
+ recorder.recordBeginLayer(rstate, gstate, rect);
+ return delegate;
+}
+
+static CGContextDelegateRef endLayer(CGContextDelegateRef delegate, CGRenderingStateRef rstate, CGGStateRef gstate)
+{
+ DrawGlyphsRecorder& recorder = *static_cast<DrawGlyphsRecorder*>(CGContextDelegateGetInfo(delegate));
+ recorder.recordEndLayer(rstate, gstate);
+ return delegate;
+}
+
+static CGError drawGlyphs(CGContextDelegateRef delegate, CGRenderingStateRef rstate, CGGStateRef gstate, const CGAffineTransform* tm, const CGGlyph glyphs[], const CGPoint positions[], size_t count)
+{
+ if (CGGStateGetAlpha(gstate) > 0) {
+ DrawGlyphsRecorder& recorder = *static_cast<DrawGlyphsRecorder*>(CGContextDelegateGetInfo(delegate));
+ recorder.recordDrawGlyphs(rstate, gstate, tm, glyphs, positions, count);
+ }
+ return kCGErrorSuccess;
+}
+
+static CGError drawImage(CGContextDelegateRef delegate, CGRenderingStateRef rstate, CGGStateRef gstate, CGRect rect, CGImageRef image)
+{
+ DrawGlyphsRecorder& recorder = *static_cast<DrawGlyphsRecorder*>(CGContextDelegateGetInfo(delegate));
+ recorder.recordDrawImage(rstate, gstate, rect, image);
+ return kCGErrorSuccess;
+}
+
+UniqueRef<GraphicsContext> DrawGlyphsRecorder::createInternalContext()
+{
+ auto contextDelegate = adoptCF(CGContextDelegateCreate(this));
+ CGContextDelegateSetCallback(contextDelegate.get(), deBeginLayer, reinterpret_cast<CGContextDelegateCallback>(&beginLayer));
+ CGContextDelegateSetCallback(contextDelegate.get(), deEndLayer, reinterpret_cast<CGContextDelegateCallback>(&endLayer));
+ CGContextDelegateSetCallback(contextDelegate.get(), deDrawGlyphs, reinterpret_cast<CGContextDelegateCallback>(&WebCore::drawGlyphs));
+ CGContextDelegateSetCallback(contextDelegate.get(), deDrawImage, reinterpret_cast<CGContextDelegateCallback>(&drawImage));
+ auto context = adoptCF(CGContextCreateWithDelegate(contextDelegate.get(), kCGContextTypeUnknown, nullptr, nullptr));
+ return makeUniqueRef<GraphicsContextCG>(context.get());
+}
+
+DrawGlyphsRecorder::DrawGlyphsRecorder(DisplayList::Recorder& owner, DrawGlyphsDeconstruction drawGlyphsDeconstruction)
+ : m_owner(owner)
+ , m_drawGlyphsDeconstruction(drawGlyphsDeconstruction)
+ , m_internalContext(createInternalContext())
+{
+}
+
+void DrawGlyphsRecorder::populateInternalState(const GraphicsContextState& contextState)
+{
+ m_originalState.fillStyle.color = contextState.fillColor;
+ m_originalState.fillStyle.gradient = contextState.fillGradient;
+ m_originalState.fillStyle.gradientSpaceTransform = contextState.fillGradientSpaceTransform;
+ m_originalState.fillStyle.pattern = contextState.fillPattern;
+
+ m_originalState.strokeStyle.color = contextState.strokeColor;
+ m_originalState.strokeStyle.gradient = contextState.strokeGradient;
+ m_originalState.strokeStyle.gradientSpaceTransform = contextState.strokeGradientSpaceTransform;
+ m_originalState.strokeStyle.pattern = contextState.strokePattern;
+
+ m_originalState.ctm = m_owner.currentState().ctm; // FIXME: Deal with base CTM.
+
+ m_originalState.shadow.offset = contextState.shadowOffset;
+ m_originalState.shadow.blur = contextState.shadowBlur;
+ m_originalState.shadow.color = contextState.shadowColor;
+ m_originalState.shadow.ignoreTransforms = contextState.shadowsIgnoreTransforms;
+
+ m_currentState = m_originalState;
+}
+
+void DrawGlyphsRecorder::populateInternalContext(const GraphicsContextState& contextState)
+{
+ if (m_originalState.fillStyle.color.isValid())
+ m_internalContext->setFillColor(m_originalState.fillStyle.color);
+ else if (m_originalState.fillStyle.gradient)
+ m_internalContext->setFillGradient(*m_originalState.fillStyle.gradient, m_originalState.fillStyle.gradientSpaceTransform);
+ else {
+ ASSERT(m_originalState.fillStyle.pattern);
+ if (m_originalState.fillStyle.pattern)
+ m_internalContext->setFillPattern(*m_originalState.fillStyle.pattern);
+ }
+
+ if (m_originalState.strokeStyle.color.isValid())
+ m_internalContext->setStrokeColor(m_originalState.strokeStyle.color);
+ else if (m_originalState.strokeStyle.gradient)
+ m_internalContext->setStrokeGradient(*m_originalState.strokeStyle.gradient, m_originalState.strokeStyle.gradientSpaceTransform);
+ else {
+ ASSERT(m_originalState.strokeStyle.pattern);
+ if (m_originalState.strokeStyle.pattern)
+ m_internalContext->setStrokePattern(*m_originalState.strokeStyle.pattern);
+ }
+
+ m_internalContext->setCTM(m_originalState.ctm);
+
+ m_internalContext->setShadowsIgnoreTransforms(m_originalState.shadow.ignoreTransforms);
+ m_internalContext->setShadow(m_originalState.shadow.offset, m_originalState.shadow.blur, m_originalState.shadow.color, contextState.shadowRadiusMode);
+
+ m_internalContext->setTextDrawingMode(contextState.textDrawingMode);
+}
+
+void DrawGlyphsRecorder::prepareInternalContext(const Font& font, FontSmoothingMode smoothingMode)
+{
+ ASSERT(CGAffineTransformIsIdentity(CTFontGetMatrix(font.platformData().ctFont())));
+
+ m_originalFont = &font;
+ m_smoothingMode = smoothingMode;
+
+ m_originalTextMatrix = computeOverallTextMatrix(font);
+ if (font.platformData().orientation() == FontOrientation::Vertical)
+ m_originalTextMatrix = computeVerticalTextMatrix(font, m_originalTextMatrix);
+
+ auto& contextState = m_owner.currentState().stateChange.m_state;
+ populateInternalState(contextState);
+ populateInternalContext(contextState);
+}
+
+void DrawGlyphsRecorder::concludeInternalContext()
+{
+ updateCTM(m_originalState.ctm);
+ updateFillColor(m_originalState.fillStyle.color, m_originalState.fillStyle.gradient.get(), m_originalState.fillStyle.pattern.get());
+ updateStrokeColor(m_originalState.strokeStyle.color, m_originalState.strokeStyle.gradient.get(), m_originalState.strokeStyle.pattern.get());
+ updateShadow(m_originalState.shadow.offset, m_originalState.shadow.blur, m_originalState.shadow.color, m_originalState.shadow.ignoreTransforms ? ShadowsIgnoreTransforms::Yes : ShadowsIgnoreTransforms::No);
+}
+
+void DrawGlyphsRecorder::updateFillColor(const Color& newColor, Gradient* newGradient, Pattern* newPattern)
+{
+ // This check looks wrong but it actually isn't, for our limited use.
+ // CT will only ever set this to a solid color, which this is the correct check for.
+ // In concludeInternalContext() we set it back to what it was originally, which this check works correctly for too.
+ if (newColor == m_currentState.fillStyle.color)
+ return;
+
+ GraphicsContextState newState;
+ newState.fillColor = newColor;
+ if (newGradient)
+ newState.fillGradient = newGradient;
+ if (newPattern)
+ newState.fillPattern = newPattern;
+ m_owner.updateState(newState, { GraphicsContextState::FillColorChange });
+ m_currentState.fillStyle.color = newColor;
+}
+
+void DrawGlyphsRecorder::updateStrokeColor(const Color& newColor, Gradient* newGradient, Pattern* newPattern)
+{
+ // This check looks wrong but it actually isn't, for our limited use.
+ // CT will only ever set this to a solid color, which this is the correct check for.
+ // In concludeInternalContext() we set it back to what it was originally, which this check works correctly for too.
+ if (newColor == m_currentState.strokeStyle.color)
+ return;
+
+ GraphicsContextState newState;
+ newState.strokeColor = newColor;
+ if (newGradient)
+ newState.strokeGradient = newGradient;
+ if (newPattern)
+ newState.strokePattern = newPattern;
+ m_owner.updateState(newState, { GraphicsContextState::StrokeColorChange });
+ m_currentState.strokeStyle.color = newColor;
+}
+
+void DrawGlyphsRecorder::updateCTM(const AffineTransform& ctm)
+{
+ if (ctm == m_currentState.ctm)
+ return;
+
+ m_owner.setCTM(ctm);
+ m_currentState.ctm = ctm;
+}
+
+static bool shadowIsCleared(const FloatSize& shadowOffset, float shadowBlur)
+{
+ return shadowOffset == FloatSize() && !shadowBlur;
+}
+
+void DrawGlyphsRecorder::updateShadow(const FloatSize& shadowOffset, float shadowBlur, const Color& shadowColor, ShadowsIgnoreTransforms shadowsIgnoreTransforms)
+{
+ // We don't need to consider shadowsIgnoreTransforms if nobody has any shadows.
+ if (shadowIsCleared(shadowOffset, shadowBlur) && shadowIsCleared(m_currentState.shadow.offset, m_currentState.shadow.blur))
+ return;
+
+ GraphicsContextState newState;
+ GraphicsContextState::StateChangeFlags stateChangeFlags;
+
+ if (shadowOffset != m_currentState.shadow.offset || shadowBlur != m_currentState.shadow.blur || shadowColor != m_currentState.shadow.color) {
+ newState.shadowOffset = shadowOffset;
+ newState.shadowBlur = shadowBlur;
+ newState.shadowColor = shadowColor;
+ stateChangeFlags.add(GraphicsContextState::ShadowChange);
+ }
+ if (shadowsIgnoreTransforms != ShadowsIgnoreTransforms::Unspecified && (shadowsIgnoreTransforms == ShadowsIgnoreTransforms::Yes) != m_currentState.shadow.ignoreTransforms) {
+ newState.shadowsIgnoreTransforms = (shadowsIgnoreTransforms == ShadowsIgnoreTransforms::Yes);
+ stateChangeFlags.add(GraphicsContextState::ShadowsIgnoreTransformsChange);
+ }
+ if (stateChangeFlags.isEmpty())
+ return;
+ m_owner.updateState(newState, stateChangeFlags);
+
+ m_currentState.shadow.offset = shadowOffset;
+ m_currentState.shadow.blur = shadowBlur;
+ m_currentState.shadow.color = shadowColor;
+ m_currentState.shadow.ignoreTransforms = (shadowsIgnoreTransforms == ShadowsIgnoreTransforms::Yes);
+}
+
+void DrawGlyphsRecorder::updateShadow(CGStyleRef style)
+{
+ if (CGStyleGetType(style) != kCGStyleShadow) {
+ // FIXME: Support more kinds of CGStyles.
+ updateShadow({0, 0}, 0, Color(), ShadowsIgnoreTransforms::Unspecified);
+ return;
+ }
+
+ const auto& shadowStyle = *static_cast<const CGShadowStyle*>(CGStyleGetData(style));
+ auto rad = deg2rad(shadowStyle.azimuth - 180);
+ auto shadowOffset = FloatSize(std::cos(rad), std::sin(rad)) * shadowStyle.height;
+ auto shadowColor = CGStyleGetColor(style);
+ updateShadow(shadowOffset, shadowStyle.radius, Color::createAndPreserveColorSpace(shadowColor), ShadowsIgnoreTransforms::Yes);
+}
+
+void DrawGlyphsRecorder::recordBeginLayer(CGRenderingStateRef, CGGStateRef gstate, CGRect)
+{
+ updateCTM(*CGGStateGetCTM(gstate));
+ auto alpha = CGGStateGetAlpha(gstate);
+ m_owner.beginTransparencyLayer(alpha);
+}
+
+void DrawGlyphsRecorder::recordEndLayer(CGRenderingStateRef, CGGStateRef gstate)
+{
+ updateCTM(*CGGStateGetCTM(gstate));
+ m_owner.endTransparencyLayer();
+}
+
+static Vector<CGSize> computeAdvancesFromPositions(const CGPoint positions[], size_t count, const CGAffineTransform& textMatrix)
+{
+ Vector<CGSize> result;
+ for (size_t i = 0; i < count - 1; ++i) {
+ auto nextPosition = positions[i + 1];
+ auto currentPosition = positions[i];
+ auto advance = CGSizeMake(nextPosition.x - currentPosition.x, nextPosition.y - currentPosition.y);
+ result.append(CGSizeApplyAffineTransform(advance, textMatrix));
+ }
+ result.constructAndAppend(CGSizeMake(0, 0));
+ return result;
+}
+
+void DrawGlyphsRecorder::recordDrawGlyphs(CGRenderingStateRef, CGGStateRef gstate, const CGAffineTransform*, const CGGlyph glyphs[], const CGPoint positions[], size_t count)
+{
+ if (!count)
+ return;
+
+ CGFontRef usedFont = CGGStateGetFont(gstate);
+ if (usedFont != adoptCF(CTFontCopyGraphicsFont(m_originalFont->platformData().ctFont(), nullptr)).get())
+ return;
+
+#if ASSERT_ENABLED
+ auto textPosition = CGContextGetTextPosition(m_internalContext->platformContext());
+ ASSERT(!textPosition.x);
+ ASSERT(!textPosition.y);
+#endif
+
+ updateCTM(*CGGStateGetCTM(gstate));
+
+ // We want the replayer's CTM and text matrix to match the current CTM and text matrix.
+ // The current text matrix is a concatenation of whatever WebKit sets it to and whatever
+ // Core Text appends to it. So, we have
+ // CTM * m_originalTextMatrix * Core Text's text matrix.
+ // However, CGContextGetTextMatrix() just tells us what the whole text matrix is, so
+ // m_originalTextMatrix * Core Text's text matrix = currentTextMatrix.
+ // The only way we can emulate Core Text's text matrix is by modifying the CTM here.
+ // So, if we do that, the GPU process will have
+ // CTM * X * m_originalTextMatrix
+ // If you set these two equal to each other, and solve for X, you get
+ // CTM * currentTextMatrix = CTM * X * m_originalTextMatrix
+ // currentTextMatrix * inverse(m_originalTextMatrix) = X
+ AffineTransform currentTextMatrix = CGContextGetTextMatrix(m_internalContext->platformContext());
+ AffineTransform ctmFixup;
+ if (auto invertedOriginalTextMatrix = m_originalTextMatrix.inverse())
+ ctmFixup = currentTextMatrix * invertedOriginalTextMatrix.value();
+ AffineTransform inverseCTMFixup;
+ if (auto inverse = ctmFixup.inverse())
+ inverseCTMFixup = inverse.value();
+ else
+ ctmFixup = AffineTransform();
+ m_owner.concatCTM(ctmFixup);
+
+ auto fillColor = CGGStateGetFillColor(gstate);
+ auto strokeColor = CGGStateGetStrokeColor(gstate);
+ updateFillColor(Color::createAndPreserveColorSpace(fillColor));
+ updateStrokeColor(Color::createAndPreserveColorSpace(strokeColor));
+ updateShadow(CGGStateGetStyle(gstate));
+
+ m_owner.appendDrawGlyphsItemWithCachedFont(*m_originalFont, glyphs, computeAdvancesFromPositions(positions, count, currentTextMatrix).data(), count, currentTextMatrix.mapPoint(positions[0]), m_smoothingMode);
+
+ m_owner.concatCTM(inverseCTMFixup);
+}
+
+void DrawGlyphsRecorder::recordDrawImage(CGRenderingStateRef, CGGStateRef gstate, CGRect rect, CGImageRef cgImage)
+{
+ updateCTM(*CGGStateGetCTM(gstate));
+ updateShadow(CGGStateGetStyle(gstate));
+
+ // Core Graphics assumes a "y up" coordinate system, but in WebKit, we use a "y-down" coordinate system.
+ // This means that WebKit's drawing routines (GraphicsContext::drawImage()) intentionally draw images upside-down from Core Graphics's point of view.
+ // (There's a y-flip inside the implementation of GraphicsContext::drawImage().)
+ // The rect has the right bounds, but we need to transform from CG's coordinate system to WebKit's by performing our own y-flip so images are drawn the right-side-up.
+ // We do this at the boundary between the two APIs, which is right here.
+ m_owner.translate(0, rect.size.height + 2 * rect.origin.y);
+ m_owner.scale(FloatSize(1, -1));
+
+ auto image = NativeImage::create(cgImage);
+ m_owner.drawNativeImage(*image, image->size(), FloatRect(rect), FloatRect {{ }, image->size()}, ImagePaintingOptions { ImageOrientation::OriginTopLeft });
+
+ // Undo the above y-flip to restore the context.
+ m_owner.scale(FloatSize(1, -1));
+ m_owner.translate(0, -(rect.size.height + 2 * rect.origin.y));
+}
+
+struct GlyphsAndAdvancesStorage {
+ Vector<GlyphBufferGlyph> glyphs;
+ Vector<GlyphBufferAdvance> advances;
+};
+
+struct GlyphsAndAdvances {
+ const GlyphBufferGlyph* glyphs;
+ const GlyphBufferAdvance* advances;
+ unsigned numGlyphs;
+ GlyphBufferAdvance initialAdvance;
+ std::optional<GlyphsAndAdvancesStorage> storage;
+};
+
+static GlyphsAndAdvances filterOutOTSVGGlyphs(const Font& font, const GlyphBufferGlyph* glyphs, const GlyphBufferAdvance* advances, unsigned numGlyphs)
+{
+ auto otsvgGlyphs = font.findOTSVGGlyphs(glyphs, numGlyphs);
+ if (!otsvgGlyphs)
+ return { glyphs, advances, numGlyphs, makeGlyphBufferAdvance(), { }};
+
+ ASSERT(otsvgGlyphs->size() >= numGlyphs);
+
+ GlyphsAndAdvances result;
+ result.initialAdvance = makeGlyphBufferAdvance();
+ result.storage = GlyphsAndAdvancesStorage();
+
+ result.storage->glyphs.reserveInitialCapacity(numGlyphs);
+ result.storage->advances.reserveInitialCapacity(numGlyphs);
+
+ for (unsigned i = 0; i < numGlyphs; ++i) {
+ ASSERT(result.storage->glyphs.size() == result.storage->advances.size());
+ if (otsvgGlyphs->quickGet(i)) {
+ if (result.storage->advances.isEmpty())
+ result.initialAdvance = makeGlyphBufferAdvance(size(result.initialAdvance) + size(advances[i]));
+ else
+ result.storage->advances.last() = makeGlyphBufferAdvance(size(result.storage->advances.last()) + size(advances[i]));
+ } else {
+ result.storage->glyphs.uncheckedAppend(glyphs[i]);
+ result.storage->advances.uncheckedAppend(advances[i]);
+ }
+ ASSERT(result.storage->glyphs.size() == result.storage->advances.size());
+ }
+
+ result.glyphs = result.storage->glyphs.data();
+ result.advances = result.storage->advances.data();
+ result.numGlyphs = result.storage->glyphs.size();
+
+ return result;
+}
+
+void DrawGlyphsRecorder::drawGlyphs(const Font& font, const GlyphBufferGlyph* glyphs, const GlyphBufferAdvance* advances, unsigned numGlyphs, const FloatPoint& startPoint, FontSmoothingMode smoothingMode)
+{
+ if (m_drawGlyphsDeconstruction == DrawGlyphsDeconstruction::DontDeconstruct) {
+ m_owner.appendDrawGlyphsItemWithCachedFont(font, glyphs, advances, numGlyphs, startPoint, smoothingMode);
+ return;
+ }
+
+ ASSERT(m_drawGlyphsDeconstruction == DrawGlyphsDeconstruction::Deconstruct);
+
+ // FIXME: <rdar://problem/70166552> Record OTSVG glyphs.
+ GlyphsAndAdvances glyphsAndAdvancesWithoutOTSVGGlyphs = filterOutOTSVGGlyphs(font, glyphs, advances, numGlyphs);
+ ASSERT(glyphsAndAdvancesWithoutOTSVGGlyphs.glyphs == glyphs || glyphsAndAdvancesWithoutOTSVGGlyphs.glyphs == glyphsAndAdvancesWithoutOTSVGGlyphs.storage->glyphs.data());
+ ASSERT(glyphsAndAdvancesWithoutOTSVGGlyphs.advances == advances || glyphsAndAdvancesWithoutOTSVGGlyphs.advances == glyphsAndAdvancesWithoutOTSVGGlyphs.storage->advances.data());
+
+ prepareInternalContext(font, smoothingMode);
+ FontCascade::drawGlyphs(m_internalContext, font, glyphsAndAdvancesWithoutOTSVGGlyphs.glyphs, glyphsAndAdvancesWithoutOTSVGGlyphs.advances, glyphsAndAdvancesWithoutOTSVGGlyphs.numGlyphs, startPoint + size(glyphsAndAdvancesWithoutOTSVGGlyphs.initialAdvance), smoothingMode);
+ concludeInternalContext();
+}
+
+} // namespace WebCore
Deleted: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListDrawGlyphsRecorder.h (283198 => 283199)
--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListDrawGlyphsRecorder.h 2021-09-28 22:06:15 UTC (rev 283198)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListDrawGlyphsRecorder.h 2021-09-28 22:19:15 UTC (rev 283199)
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2020-2021 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. ``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
- * 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.
- */
-
-#pragma once
-
-#include "AffineTransform.h"
-#include "Color.h"
-#include "Gradient.h"
-#include "GraphicsContext.h"
-#include "Pattern.h"
-#include "TextFlags.h"
-#include <wtf/UniqueRef.h>
-
-#if USE(CORE_TEXT)
-#include <CoreGraphics/CoreGraphics.h>
-#include <pal/spi/cg/CoreGraphicsSPI.h>
-#endif
-
-namespace WebCore {
-
-class FloatPoint;
-class Font;
-class GlyphBuffer;
-class GraphicsContext;
-
-namespace DisplayList {
-
-class Recorder;
-
-class DrawGlyphsRecorder {
-public:
- enum class DrawGlyphsDeconstruction {
- Deconstruct,
- DontDeconstruct
- };
- explicit DrawGlyphsRecorder(Recorder&, DrawGlyphsDeconstruction);
-
- void drawGlyphs(const Font&, const GlyphBufferGlyph*, const GlyphBufferAdvance*, unsigned numGlyphs, const FloatPoint& anchorPoint, FontSmoothingMode);
-
-#if USE(CORE_TEXT) && !PLATFORM(WIN)
- void recordBeginLayer(CGRenderingStateRef, CGGStateRef, CGRect);
- void recordEndLayer(CGRenderingStateRef, CGGStateRef);
- void recordDrawGlyphs(CGRenderingStateRef, CGGStateRef, const CGAffineTransform*, const CGGlyph[], const CGPoint positions[], size_t count);
- void recordDrawImage(CGRenderingStateRef, CGGStateRef, CGRect, CGImageRef);
-#endif
-
- DrawGlyphsDeconstruction drawGlyphsDeconstruction() const { return m_drawGlyphsDeconstruction; }
-
-private:
-#if USE(CORE_TEXT) && !PLATFORM(WIN)
- UniqueRef<GraphicsContext> createInternalContext();
-#endif
-
- void populateInternalState(const GraphicsContextState&);
- void populateInternalContext(const GraphicsContextState&);
- void prepareInternalContext(const Font&, FontSmoothingMode);
- void concludeInternalContext();
-
- void updateFillColor(const Color&, Gradient* = nullptr, Pattern* = nullptr);
- void updateStrokeColor(const Color&, Gradient* = nullptr, Pattern* = nullptr);
- void updateCTM(const AffineTransform&);
- enum class ShadowsIgnoreTransforms {
- Unspecified,
- Yes,
- No
- };
- void updateShadow(const FloatSize& shadowOffset, float shadowBlur, const Color& shadowColor, ShadowsIgnoreTransforms);
-
-#if USE(CORE_TEXT) && !PLATFORM(WIN)
- void updateShadow(CGStyleRef);
-#endif
-
- Recorder& m_owner;
- DrawGlyphsDeconstruction m_drawGlyphsDeconstruction;
-
-#if USE(CORE_TEXT) && !PLATFORM(WIN)
- UniqueRef<GraphicsContext> m_internalContext;
-#endif
-
- const Font* m_originalFont { nullptr };
- FontSmoothingMode m_smoothingMode { FontSmoothingMode::AutoSmoothing };
- AffineTransform m_originalTextMatrix;
-
- struct State {
- struct Style {
- Color color;
- RefPtr<Gradient> gradient;
- AffineTransform gradientSpaceTransform;
- RefPtr<Pattern> pattern;
- };
- Style fillStyle;
- Style strokeStyle;
-
- AffineTransform ctm;
-
- struct ShadowState {
- FloatSize offset;
- float blur { 0 };
- Color color;
- bool ignoreTransforms { false };
- };
- ShadowState shadow;
- };
- State m_originalState;
- State m_currentState;
-};
-
-}
-
-}
Deleted: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListDrawGlyphsRecorderCoreText.cpp (283198 => 283199)
--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListDrawGlyphsRecorderCoreText.cpp 2021-09-28 22:06:15 UTC (rev 283198)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListDrawGlyphsRecorderCoreText.cpp 2021-09-28 22:19:15 UTC (rev 283199)
@@ -1,436 +0,0 @@
-/*
- * Copyright (C) 2020-2021 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. ``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
- * 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 "DisplayListDrawGlyphsRecorder.h"
-
-#include "BitmapImage.h"
-#include "Color.h"
-#include "DisplayListItems.h"
-#include "DisplayListRecorder.h"
-#include "FloatPoint.h"
-#include "Font.h"
-#include "FontCascade.h"
-#include "GlyphBuffer.h"
-#include "GraphicsContextCG.h"
-
-#include <CoreText/CoreText.h>
-#include <wtf/Vector.h>
-
-#if PLATFORM(WIN)
-#include <pal/spi/win/CoreTextSPIWin.h>
-#endif
-
-namespace WebCore {
-
-namespace DisplayList {
-
-static CGContextDelegateRef beginLayer(CGContextDelegateRef delegate, CGRenderingStateRef rstate, CGGStateRef gstate, CGRect rect, CFDictionaryRef, CGContextDelegateRef)
-{
- DrawGlyphsRecorder& recorder = *static_cast<DrawGlyphsRecorder*>(CGContextDelegateGetInfo(delegate));
- recorder.recordBeginLayer(rstate, gstate, rect);
- return delegate;
-}
-
-static CGContextDelegateRef endLayer(CGContextDelegateRef delegate, CGRenderingStateRef rstate, CGGStateRef gstate)
-{
- DrawGlyphsRecorder& recorder = *static_cast<DrawGlyphsRecorder*>(CGContextDelegateGetInfo(delegate));
- recorder.recordEndLayer(rstate, gstate);
- return delegate;
-}
-
-static CGError drawGlyphs(CGContextDelegateRef delegate, CGRenderingStateRef rstate, CGGStateRef gstate, const CGAffineTransform* tm, const CGGlyph glyphs[], const CGPoint positions[], size_t count)
-{
- if (CGGStateGetAlpha(gstate) > 0) {
- DrawGlyphsRecorder& recorder = *static_cast<DrawGlyphsRecorder*>(CGContextDelegateGetInfo(delegate));
- recorder.recordDrawGlyphs(rstate, gstate, tm, glyphs, positions, count);
- }
- return kCGErrorSuccess;
-}
-
-static CGError drawImage(CGContextDelegateRef delegate, CGRenderingStateRef rstate, CGGStateRef gstate, CGRect rect, CGImageRef image)
-{
- DrawGlyphsRecorder& recorder = *static_cast<DrawGlyphsRecorder*>(CGContextDelegateGetInfo(delegate));
- recorder.recordDrawImage(rstate, gstate, rect, image);
- return kCGErrorSuccess;
-}
-
-UniqueRef<GraphicsContext> DrawGlyphsRecorder::createInternalContext()
-{
- auto contextDelegate = adoptCF(CGContextDelegateCreate(this));
- CGContextDelegateSetCallback(contextDelegate.get(), deBeginLayer, reinterpret_cast<CGContextDelegateCallback>(&beginLayer));
- CGContextDelegateSetCallback(contextDelegate.get(), deEndLayer, reinterpret_cast<CGContextDelegateCallback>(&endLayer));
- CGContextDelegateSetCallback(contextDelegate.get(), deDrawGlyphs, reinterpret_cast<CGContextDelegateCallback>(&WebCore::DisplayList::drawGlyphs));
- CGContextDelegateSetCallback(contextDelegate.get(), deDrawImage, reinterpret_cast<CGContextDelegateCallback>(&drawImage));
- auto context = adoptCF(CGContextCreateWithDelegate(contextDelegate.get(), kCGContextTypeUnknown, nullptr, nullptr));
- return makeUniqueRef<GraphicsContextCG>(context.get());
-}
-
-DrawGlyphsRecorder::DrawGlyphsRecorder(Recorder& owner, DrawGlyphsDeconstruction drawGlyphsDeconstruction)
- : m_owner(owner)
- , m_drawGlyphsDeconstruction(drawGlyphsDeconstruction)
- , m_internalContext(createInternalContext())
-{
-}
-
-void DrawGlyphsRecorder::populateInternalState(const GraphicsContextState& contextState)
-{
- m_originalState.fillStyle.color = contextState.fillColor;
- m_originalState.fillStyle.gradient = contextState.fillGradient;
- m_originalState.fillStyle.gradientSpaceTransform = contextState.fillGradientSpaceTransform;
- m_originalState.fillStyle.pattern = contextState.fillPattern;
-
- m_originalState.strokeStyle.color = contextState.strokeColor;
- m_originalState.strokeStyle.gradient = contextState.strokeGradient;
- m_originalState.strokeStyle.gradientSpaceTransform = contextState.strokeGradientSpaceTransform;
- m_originalState.strokeStyle.pattern = contextState.strokePattern;
-
- m_originalState.ctm = m_owner.currentState().ctm; // FIXME: Deal with base CTM.
-
- m_originalState.shadow.offset = contextState.shadowOffset;
- m_originalState.shadow.blur = contextState.shadowBlur;
- m_originalState.shadow.color = contextState.shadowColor;
- m_originalState.shadow.ignoreTransforms = contextState.shadowsIgnoreTransforms;
-
- m_currentState = m_originalState;
-}
-
-void DrawGlyphsRecorder::populateInternalContext(const GraphicsContextState& contextState)
-{
- if (m_originalState.fillStyle.color.isValid())
- m_internalContext->setFillColor(m_originalState.fillStyle.color);
- else if (m_originalState.fillStyle.gradient)
- m_internalContext->setFillGradient(*m_originalState.fillStyle.gradient, m_originalState.fillStyle.gradientSpaceTransform);
- else {
- ASSERT(m_originalState.fillStyle.pattern);
- if (m_originalState.fillStyle.pattern)
- m_internalContext->setFillPattern(*m_originalState.fillStyle.pattern);
- }
-
- if (m_originalState.strokeStyle.color.isValid())
- m_internalContext->setStrokeColor(m_originalState.strokeStyle.color);
- else if (m_originalState.strokeStyle.gradient)
- m_internalContext->setStrokeGradient(*m_originalState.strokeStyle.gradient, m_originalState.strokeStyle.gradientSpaceTransform);
- else {
- ASSERT(m_originalState.strokeStyle.pattern);
- if (m_originalState.strokeStyle.pattern)
- m_internalContext->setStrokePattern(*m_originalState.strokeStyle.pattern);
- }
-
- m_internalContext->setCTM(m_originalState.ctm);
-
- m_internalContext->setShadowsIgnoreTransforms(m_originalState.shadow.ignoreTransforms);
- m_internalContext->setShadow(m_originalState.shadow.offset, m_originalState.shadow.blur, m_originalState.shadow.color, contextState.shadowRadiusMode);
-
- m_internalContext->setTextDrawingMode(contextState.textDrawingMode);
-}
-
-void DrawGlyphsRecorder::prepareInternalContext(const Font& font, FontSmoothingMode smoothingMode)
-{
- ASSERT(CGAffineTransformIsIdentity(CTFontGetMatrix(font.platformData().ctFont())));
-
- m_originalFont = &font;
- m_smoothingMode = smoothingMode;
-
- m_originalTextMatrix = computeOverallTextMatrix(font);
- if (font.platformData().orientation() == FontOrientation::Vertical)
- m_originalTextMatrix = computeVerticalTextMatrix(font, m_originalTextMatrix);
-
- auto& contextState = m_owner.currentState().stateChange.m_state;
- populateInternalState(contextState);
- populateInternalContext(contextState);
-}
-
-void DrawGlyphsRecorder::concludeInternalContext()
-{
- updateCTM(m_originalState.ctm);
- updateFillColor(m_originalState.fillStyle.color, m_originalState.fillStyle.gradient.get(), m_originalState.fillStyle.pattern.get());
- updateStrokeColor(m_originalState.strokeStyle.color, m_originalState.strokeStyle.gradient.get(), m_originalState.strokeStyle.pattern.get());
- updateShadow(m_originalState.shadow.offset, m_originalState.shadow.blur, m_originalState.shadow.color, m_originalState.shadow.ignoreTransforms ? ShadowsIgnoreTransforms::Yes : ShadowsIgnoreTransforms::No);
-}
-
-void DrawGlyphsRecorder::updateFillColor(const Color& newColor, Gradient* newGradient, Pattern* newPattern)
-{
- // This check looks wrong but it actually isn't, for our limited use.
- // CT will only ever set this to a solid color, which this is the correct check for.
- // In concludeInternalContext() we set it back to what it was originally, which this check works correctly for too.
- if (newColor == m_currentState.fillStyle.color)
- return;
-
- GraphicsContextState newState;
- newState.fillColor = newColor;
- if (newGradient)
- newState.fillGradient = newGradient;
- if (newPattern)
- newState.fillPattern = newPattern;
- m_owner.updateState(newState, { GraphicsContextState::FillColorChange });
- m_currentState.fillStyle.color = newColor;
-}
-
-void DrawGlyphsRecorder::updateStrokeColor(const Color& newColor, Gradient* newGradient, Pattern* newPattern)
-{
- // This check looks wrong but it actually isn't, for our limited use.
- // CT will only ever set this to a solid color, which this is the correct check for.
- // In concludeInternalContext() we set it back to what it was originally, which this check works correctly for too.
- if (newColor == m_currentState.strokeStyle.color)
- return;
-
- GraphicsContextState newState;
- newState.strokeColor = newColor;
- if (newGradient)
- newState.strokeGradient = newGradient;
- if (newPattern)
- newState.strokePattern = newPattern;
- m_owner.updateState(newState, { GraphicsContextState::StrokeColorChange });
- m_currentState.strokeStyle.color = newColor;
-}
-
-void DrawGlyphsRecorder::updateCTM(const AffineTransform& ctm)
-{
- if (ctm == m_currentState.ctm)
- return;
-
- m_owner.setCTM(ctm);
- m_currentState.ctm = ctm;
-}
-
-static bool shadowIsCleared(const FloatSize& shadowOffset, float shadowBlur)
-{
- return shadowOffset == FloatSize() && !shadowBlur;
-}
-
-void DrawGlyphsRecorder::updateShadow(const FloatSize& shadowOffset, float shadowBlur, const Color& shadowColor, ShadowsIgnoreTransforms shadowsIgnoreTransforms)
-{
- // We don't need to consider shadowsIgnoreTransforms if nobody has any shadows.
- if (shadowIsCleared(shadowOffset, shadowBlur) && shadowIsCleared(m_currentState.shadow.offset, m_currentState.shadow.blur))
- return;
-
- GraphicsContextState newState;
- GraphicsContextState::StateChangeFlags stateChangeFlags;
-
- if (shadowOffset != m_currentState.shadow.offset || shadowBlur != m_currentState.shadow.blur || shadowColor != m_currentState.shadow.color) {
- newState.shadowOffset = shadowOffset;
- newState.shadowBlur = shadowBlur;
- newState.shadowColor = shadowColor;
- stateChangeFlags.add(GraphicsContextState::ShadowChange);
- }
- if (shadowsIgnoreTransforms != ShadowsIgnoreTransforms::Unspecified && (shadowsIgnoreTransforms == ShadowsIgnoreTransforms::Yes) != m_currentState.shadow.ignoreTransforms) {
- newState.shadowsIgnoreTransforms = (shadowsIgnoreTransforms == ShadowsIgnoreTransforms::Yes);
- stateChangeFlags.add(GraphicsContextState::ShadowsIgnoreTransformsChange);
- }
- if (stateChangeFlags.isEmpty())
- return;
- m_owner.updateState(newState, stateChangeFlags);
-
- m_currentState.shadow.offset = shadowOffset;
- m_currentState.shadow.blur = shadowBlur;
- m_currentState.shadow.color = shadowColor;
- m_currentState.shadow.ignoreTransforms = (shadowsIgnoreTransforms == ShadowsIgnoreTransforms::Yes);
-}
-
-void DrawGlyphsRecorder::updateShadow(CGStyleRef style)
-{
- if (CGStyleGetType(style) != kCGStyleShadow) {
- // FIXME: Support more kinds of CGStyles.
- updateShadow({0, 0}, 0, Color(), ShadowsIgnoreTransforms::Unspecified);
- return;
- }
-
- const auto& shadowStyle = *static_cast<const CGShadowStyle*>(CGStyleGetData(style));
- auto rad = deg2rad(shadowStyle.azimuth - 180);
- auto shadowOffset = FloatSize(std::cos(rad), std::sin(rad)) * shadowStyle.height;
- auto shadowColor = CGStyleGetColor(style);
- updateShadow(shadowOffset, shadowStyle.radius, Color::createAndPreserveColorSpace(shadowColor), ShadowsIgnoreTransforms::Yes);
-}
-
-void DrawGlyphsRecorder::recordBeginLayer(CGRenderingStateRef, CGGStateRef gstate, CGRect)
-{
- updateCTM(*CGGStateGetCTM(gstate));
- auto alpha = CGGStateGetAlpha(gstate);
- m_owner.beginTransparencyLayer(alpha);
-}
-
-void DrawGlyphsRecorder::recordEndLayer(CGRenderingStateRef, CGGStateRef gstate)
-{
- updateCTM(*CGGStateGetCTM(gstate));
- m_owner.endTransparencyLayer();
-}
-
-static Vector<CGSize> computeAdvancesFromPositions(const CGPoint positions[], size_t count, const CGAffineTransform& textMatrix)
-{
- Vector<CGSize> result;
- for (size_t i = 0; i < count - 1; ++i) {
- auto nextPosition = positions[i + 1];
- auto currentPosition = positions[i];
- auto advance = CGSizeMake(nextPosition.x - currentPosition.x, nextPosition.y - currentPosition.y);
- result.append(CGSizeApplyAffineTransform(advance, textMatrix));
- }
- result.constructAndAppend(CGSizeMake(0, 0));
- return result;
-}
-
-void DrawGlyphsRecorder::recordDrawGlyphs(CGRenderingStateRef, CGGStateRef gstate, const CGAffineTransform*, const CGGlyph glyphs[], const CGPoint positions[], size_t count)
-{
- if (!count)
- return;
-
- CGFontRef usedFont = CGGStateGetFont(gstate);
- if (usedFont != adoptCF(CTFontCopyGraphicsFont(m_originalFont->platformData().ctFont(), nullptr)).get())
- return;
-
-#if ASSERT_ENABLED
- auto textPosition = CGContextGetTextPosition(m_internalContext->platformContext());
- ASSERT(!textPosition.x);
- ASSERT(!textPosition.y);
-#endif
-
- updateCTM(*CGGStateGetCTM(gstate));
-
- // We want the replayer's CTM and text matrix to match the current CTM and text matrix.
- // The current text matrix is a concatenation of whatever WebKit sets it to and whatever
- // Core Text appends to it. So, we have
- // CTM * m_originalTextMatrix * Core Text's text matrix.
- // However, CGContextGetTextMatrix() just tells us what the whole text matrix is, so
- // m_originalTextMatrix * Core Text's text matrix = currentTextMatrix.
- // The only way we can emulate Core Text's text matrix is by modifying the CTM here.
- // So, if we do that, the GPU process will have
- // CTM * X * m_originalTextMatrix
- // If you set these two equal to each other, and solve for X, you get
- // CTM * currentTextMatrix = CTM * X * m_originalTextMatrix
- // currentTextMatrix * inverse(m_originalTextMatrix) = X
- AffineTransform currentTextMatrix = CGContextGetTextMatrix(m_internalContext->platformContext());
- AffineTransform ctmFixup;
- if (auto invertedOriginalTextMatrix = m_originalTextMatrix.inverse())
- ctmFixup = currentTextMatrix * invertedOriginalTextMatrix.value();
- AffineTransform inverseCTMFixup;
- if (auto inverse = ctmFixup.inverse())
- inverseCTMFixup = inverse.value();
- else
- ctmFixup = AffineTransform();
- m_owner.concatCTM(ctmFixup);
-
- auto fillColor = CGGStateGetFillColor(gstate);
- auto strokeColor = CGGStateGetStrokeColor(gstate);
- updateFillColor(Color::createAndPreserveColorSpace(fillColor));
- updateStrokeColor(Color::createAndPreserveColorSpace(strokeColor));
- updateShadow(CGGStateGetStyle(gstate));
-
- m_owner.appendDrawGlyphsItemWithCachedFont(*m_originalFont, glyphs, computeAdvancesFromPositions(positions, count, currentTextMatrix).data(), count, currentTextMatrix.mapPoint(positions[0]), m_smoothingMode);
-
- m_owner.concatCTM(inverseCTMFixup);
-}
-
-void DrawGlyphsRecorder::recordDrawImage(CGRenderingStateRef, CGGStateRef gstate, CGRect rect, CGImageRef cgImage)
-{
- updateCTM(*CGGStateGetCTM(gstate));
- updateShadow(CGGStateGetStyle(gstate));
-
- // Core Graphics assumes a "y up" coordinate system, but in WebKit, we use a "y-down" coordinate system.
- // This means that WebKit's drawing routines (GraphicsContext::drawImage()) intentionally draw images upside-down from Core Graphics's point of view.
- // (There's a y-flip inside the implementation of GraphicsContext::drawImage().)
- // The rect has the right bounds, but we need to transform from CG's coordinate system to WebKit's by performing our own y-flip so images are drawn the right-side-up.
- // We do this at the boundary between the two APIs, which is right here.
- m_owner.translate(0, rect.size.height + 2 * rect.origin.y);
- m_owner.scale(FloatSize(1, -1));
-
- auto image = NativeImage::create(cgImage);
- m_owner.drawNativeImage(*image, image->size(), FloatRect(rect), FloatRect {{ }, image->size()}, ImagePaintingOptions { ImageOrientation::OriginTopLeft });
-
- // Undo the above y-flip to restore the context.
- m_owner.scale(FloatSize(1, -1));
- m_owner.translate(0, -(rect.size.height + 2 * rect.origin.y));
-}
-
-struct GlyphsAndAdvancesStorage {
- Vector<GlyphBufferGlyph> glyphs;
- Vector<GlyphBufferAdvance> advances;
-};
-
-struct GlyphsAndAdvances {
- const GlyphBufferGlyph* glyphs;
- const GlyphBufferAdvance* advances;
- unsigned numGlyphs;
- GlyphBufferAdvance initialAdvance;
- std::optional<GlyphsAndAdvancesStorage> storage;
-};
-
-static GlyphsAndAdvances filterOutOTSVGGlyphs(const Font& font, const GlyphBufferGlyph* glyphs, const GlyphBufferAdvance* advances, unsigned numGlyphs)
-{
- auto otsvgGlyphs = font.findOTSVGGlyphs(glyphs, numGlyphs);
- if (!otsvgGlyphs)
- return { glyphs, advances, numGlyphs, makeGlyphBufferAdvance(), { }};
-
- ASSERT(otsvgGlyphs->size() >= numGlyphs);
-
- GlyphsAndAdvances result;
- result.initialAdvance = makeGlyphBufferAdvance();
- result.storage = GlyphsAndAdvancesStorage();
-
- result.storage->glyphs.reserveInitialCapacity(numGlyphs);
- result.storage->advances.reserveInitialCapacity(numGlyphs);
-
- for (unsigned i = 0; i < numGlyphs; ++i) {
- ASSERT(result.storage->glyphs.size() == result.storage->advances.size());
- if (otsvgGlyphs->quickGet(i)) {
- if (result.storage->advances.isEmpty())
- result.initialAdvance = makeGlyphBufferAdvance(size(result.initialAdvance) + size(advances[i]));
- else
- result.storage->advances.last() = makeGlyphBufferAdvance(size(result.storage->advances.last()) + size(advances[i]));
- } else {
- result.storage->glyphs.uncheckedAppend(glyphs[i]);
- result.storage->advances.uncheckedAppend(advances[i]);
- }
- ASSERT(result.storage->glyphs.size() == result.storage->advances.size());
- }
-
- result.glyphs = result.storage->glyphs.data();
- result.advances = result.storage->advances.data();
- result.numGlyphs = result.storage->glyphs.size();
-
- return result;
-}
-
-void DrawGlyphsRecorder::drawGlyphs(const Font& font, const GlyphBufferGlyph* glyphs, const GlyphBufferAdvance* advances, unsigned numGlyphs, const FloatPoint& startPoint, FontSmoothingMode smoothingMode)
-{
- if (m_drawGlyphsDeconstruction == DrawGlyphsDeconstruction::DontDeconstruct) {
- m_owner.appendDrawGlyphsItemWithCachedFont(font, glyphs, advances, numGlyphs, startPoint, smoothingMode);
- return;
- }
-
- ASSERT(m_drawGlyphsDeconstruction == DrawGlyphsDeconstruction::Deconstruct);
-
- // FIXME: <rdar://problem/70166552> Record OTSVG glyphs.
- GlyphsAndAdvances glyphsAndAdvancesWithoutOTSVGGlyphs = filterOutOTSVGGlyphs(font, glyphs, advances, numGlyphs);
- ASSERT(glyphsAndAdvancesWithoutOTSVGGlyphs.glyphs == glyphs || glyphsAndAdvancesWithoutOTSVGGlyphs.glyphs == glyphsAndAdvancesWithoutOTSVGGlyphs.storage->glyphs.data());
- ASSERT(glyphsAndAdvancesWithoutOTSVGGlyphs.advances == advances || glyphsAndAdvancesWithoutOTSVGGlyphs.advances == glyphsAndAdvancesWithoutOTSVGGlyphs.storage->advances.data());
-
- prepareInternalContext(font, smoothingMode);
- FontCascade::drawGlyphs(m_internalContext, font, glyphsAndAdvancesWithoutOTSVGGlyphs.glyphs, glyphsAndAdvancesWithoutOTSVGGlyphs.advances, glyphsAndAdvancesWithoutOTSVGGlyphs.numGlyphs, startPoint + size(glyphsAndAdvancesWithoutOTSVGGlyphs.initialAdvance), smoothingMode);
- concludeInternalContext();
-}
-
-} // namespace DisplayList
-
-} // namespace WebCore
Deleted: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListDrawGlyphsRecorderHarfBuzz.cpp (283198 => 283199)
--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListDrawGlyphsRecorderHarfBuzz.cpp 2021-09-28 22:06:15 UTC (rev 283198)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListDrawGlyphsRecorderHarfBuzz.cpp 2021-09-28 22:19:15 UTC (rev 283199)
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2020-2021 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. ``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
- * 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 "DisplayListDrawGlyphsRecorder.h"
-
-#include "DisplayListItems.h"
-#include "DisplayListRecorder.h"
-#include "FloatPoint.h"
-#include "Font.h"
-#include "GlyphBuffer.h"
-
-namespace WebCore {
-
-namespace DisplayList {
-
-DrawGlyphsRecorder::DrawGlyphsRecorder(Recorder& owner, DrawGlyphsDeconstruction)
- : m_owner(owner)
-{
-}
-
-void DrawGlyphsRecorder::drawGlyphs(const Font& font, const GlyphBufferGlyph* glyphs, const GlyphBufferAdvance* advances, unsigned numGlyphs, const FloatPoint& startPoint, FontSmoothingMode smoothingMode)
-{
- m_owner.appendDrawGlyphsItemWithCachedFont(font, glyphs, advances, numGlyphs, startPoint, smoothingMode);
-}
-
-} // namespace DisplayList
-
-} // namespace WebCore
Deleted: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListDrawGlyphsRecorderWin.cpp (283198 => 283199)
--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListDrawGlyphsRecorderWin.cpp 2021-09-28 22:06:15 UTC (rev 283198)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListDrawGlyphsRecorderWin.cpp 2021-09-28 22:19:15 UTC (rev 283199)
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2020-2021 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. ``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
- * 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 "DisplayListDrawGlyphsRecorder.h"
-
-#include "DisplayListItems.h"
-#include "DisplayListRecorder.h"
-#include "FloatPoint.h"
-#include "Font.h"
-#include "GlyphBuffer.h"
-
-namespace WebCore {
-
-namespace DisplayList {
-
-DrawGlyphsRecorder::DrawGlyphsRecorder(Recorder& owner, DrawGlyphsDeconstruction)
- : m_owner(owner)
-{
-}
-
-void DrawGlyphsRecorder::drawGlyphs(const Font& font, const GlyphBufferGlyph* glyphs, const GlyphBufferAdvance* advances, unsigned numGlyphs, const FloatPoint& startPoint, FontSmoothingMode smoothingMode)
-{
- m_owner.appendDrawGlyphsItemWithCachedFont(font, glyphs, advances, numGlyphs, startPoint, m_smoothingMode);
-}
-
-} // namespace DisplayList
-
-} // namespace WebCore
Modified: trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.h (283198 => 283199)
--- trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.h 2021-09-28 22:06:15 UTC (rev 283198)
+++ trunk/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.h 2021-09-28 22:19:15 UTC (rev 283199)
@@ -26,8 +26,8 @@
#pragma once
#include "DisplayList.h"
-#include "DisplayListDrawGlyphsRecorder.h"
#include "DisplayListItems.h"
+#include "DrawGlyphsRecorder.h"
#include "GraphicsContext.h"
#include "Image.h" // For Image::TileRule.
#include "TextFlags.h"
@@ -77,7 +77,7 @@
void flushContext(FlushIdentifier identifier) { append<FlushContext>(identifier); }
private:
- friend class DrawGlyphsRecorder;
+ friend class WebCore::DrawGlyphsRecorder;
Recorder(Recorder& parent, const GraphicsContextState&, const FloatRect& initialClip, const AffineTransform& initialCTM);
bool hasPlatformContext() const final { return false; }
Copied: trunk/Source/WebCore/platform/graphics/harfbuzz/DrawGlyphsRecorderHarfBuzz.cpp (from rev 283198, trunk/Source/WebCore/platform/graphics/displaylists/DisplayListDrawGlyphsRecorderHarfBuzz.cpp) (0 => 283199)
--- trunk/Source/WebCore/platform/graphics/harfbuzz/DrawGlyphsRecorderHarfBuzz.cpp (rev 0)
+++ trunk/Source/WebCore/platform/graphics/harfbuzz/DrawGlyphsRecorderHarfBuzz.cpp 2021-09-28 22:19:15 UTC (rev 283199)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2020-2021 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. ``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
+ * 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 "DrawGlyphsRecorder.h"
+
+#include "DisplayListItems.h"
+#include "DisplayListRecorder.h"
+#include "FloatPoint.h"
+#include "Font.h"
+#include "GlyphBuffer.h"
+
+namespace WebCore {
+
+DrawGlyphsRecorder::DrawGlyphsRecorder(DisplayList::Recorder& owner, DrawGlyphsDeconstruction)
+ : m_owner(owner)
+{
+}
+
+void DrawGlyphsRecorder::drawGlyphs(const Font& font, const GlyphBufferGlyph* glyphs, const GlyphBufferAdvance* advances, unsigned numGlyphs, const FloatPoint& startPoint, FontSmoothingMode smoothingMode)
+{
+ m_owner.appendDrawGlyphsItemWithCachedFont(font, glyphs, advances, numGlyphs, startPoint, smoothingMode);
+}
+
+} // namespace WebCore
Copied: trunk/Source/WebCore/platform/graphics/win/DrawGlyphsRecorderWin.cpp (from rev 283198, trunk/Source/WebCore/platform/graphics/displaylists/DisplayListDrawGlyphsRecorderWin.cpp) (0 => 283199)
--- trunk/Source/WebCore/platform/graphics/win/DrawGlyphsRecorderWin.cpp (rev 0)
+++ trunk/Source/WebCore/platform/graphics/win/DrawGlyphsRecorderWin.cpp 2021-09-28 22:19:15 UTC (rev 283199)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2020-2021 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. ``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
+ * 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 "DrawGlyphsRecorder.h"
+
+#include "DisplayListItems.h"
+#include "DisplayListRecorder.h"
+#include "FloatPoint.h"
+#include "Font.h"
+#include "GlyphBuffer.h"
+
+namespace WebCore {
+
+DrawGlyphsRecorder::DrawGlyphsRecorder(DisplayList::Recorder& owner, DrawGlyphsDeconstruction)
+ : m_owner(owner)
+{
+}
+
+void DrawGlyphsRecorder::drawGlyphs(const Font& font, const GlyphBufferGlyph* glyphs, const GlyphBufferAdvance* advances, unsigned numGlyphs, const FloatPoint& startPoint, FontSmoothingMode smoothingMode)
+{
+ m_owner.appendDrawGlyphsItemWithCachedFont(font, glyphs, advances, numGlyphs, startPoint, m_smoothingMode);
+}
+
+} // namespace WebCore