WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
bug-152816-20160106180918.patch (text/plain), 144.53 KB, created by
Simon Fraser (smfr)
on 2016-01-06 18:09:50 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Simon Fraser (smfr)
Created:
2016-01-06 18:09:50 PST
Size:
144.53 KB
patch
obsolete
>Subversion Revision: 194684 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 4e85dfa48203da7c62b627f10edac2d12facb1f0..d432b3aa0d332ffd1875a3e528390c1f86a5ce51 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,5 +1,46 @@ > 2016-01-06 Simon Fraser <simon.fraser@apple.com> > >+ Initial implementation files for display-list recording and playback >+ https://bugs.webkit.org/show_bug.cgi?id=152816 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Add files for: >+ - DisplayList, a class that holds a vector of display items, and in future will hold metadata >+ on the list for optimizations etc. >+ - DisplayList::Recorder, the outward-facing recording API which GraphicsContext will >+ call into. >+ - DisplayList::Replayer, which plays back a DisplayList, possibly applying optimizations. >+ - Various DisplayList::Items, one type for each display list operation. They cover most of the >+ GraphicsContext functionality, other than clipping to an image buffer. Text drawing is stubbed >+ out for now. >+ >+ Added a "DisplayLists" log channel. >+ >+ Added GraphicsContextState functions for tracking state deltas with change bits. It may >+ make sense to combine GraphicsContextStateChange and GraphicsContextState, and use the >+ dirty bits in non-display-list drawing as well. >+ >+ * CMakeLists.txt: >+ * WebCore.xcodeproj/project.pbxproj: >+ * platform/Logging.h: >+ * platform/graphics/GraphicsContext.h: >+ * platform/graphics/displaylists/DisplayList.cpp: Added. >+ (WebCore::DisplayList::DisplayList::description): >+ (WebCore::DisplayList::DisplayList::dump): >+ (WebCore::operator<<): >+ * platform/graphics/displaylists/DisplayListItems.cpp: Added. >+ * platform/graphics/displaylists/DisplayListItems.h: Added. >+ * platform/graphics/displaylists/DisplayListRecorder.cpp: Added. >+ * platform/graphics/displaylists/DisplayListRecorder.h: Added. >+ * platform/graphics/displaylists/DisplayListReplayer.cpp: Added. >+ (WebCore::DisplayList::Replayer::Replayer): >+ (WebCore::DisplayList::Replayer::~Replayer): >+ (WebCore::DisplayList::Replayer::replay): >+ * platform/graphics/displaylists/DisplayListReplayer.h: Added. >+ >+2016-01-06 Simon Fraser <simon.fraser@apple.com> >+ > Sort the project file. > > * WebCore.xcodeproj/project.pbxproj: >diff --git a/Source/WebCore/CMakeLists.txt b/Source/WebCore/CMakeLists.txt >index 84c6d580666c02a72296d1db2f6fd810fb4cb6a6..cf6780e5dac30663de0209d156cba2e900b71d90 100644 >--- a/Source/WebCore/CMakeLists.txt >+++ b/Source/WebCore/CMakeLists.txt >@@ -70,6 +70,7 @@ set(WebCore_INCLUDE_DIRECTORIES > "${WEBCORE_DIR}/platform/graphics" > "${WEBCORE_DIR}/platform/graphics/cpu/arm" > "${WEBCORE_DIR}/platform/graphics/cpu/arm/filters" >+ "${WEBCORE_DIR}/platform/graphics/displaylists" > "${WEBCORE_DIR}/platform/graphics/filters" > "${WEBCORE_DIR}/platform/graphics/filters/texmap" > "${WEBCORE_DIR}/platform/graphics/harfbuzz" >@@ -2215,6 +2216,11 @@ set(WebCore_SOURCES > > platform/graphics/cpu/arm/filters/FELightingNEON.cpp > >+ platform/graphics/displaylists/DisplayList.cpp >+ platform/graphics/displaylists/DisplayListItems.cpp >+ platform/graphics/displaylists/DisplayListRecorder.cpp >+ platform/graphics/displaylists/DisplayListReplayer.cpp >+ > platform/graphics/filters/DistantLightSource.cpp > platform/graphics/filters/FEBlend.cpp > platform/graphics/filters/FEColorMatrix.cpp >diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >index 18d65f0fb645eb936439f0e32b55172141670278..664eeddc8c26125a574a2d201cc92aa65a012543 100644 >--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj >+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >@@ -550,6 +550,14 @@ > 0FDF45A91BD1C82500E4FA8C /* TimingFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FDF45A81BD1C82500E4FA8C /* TimingFunction.cpp */; }; > 0FE5806319327A6200DE32EB /* ScrollingTreeMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE5806119327A6200DE32EB /* ScrollingTreeMac.cpp */; }; > 0FE5806419327A6200DE32EB /* ScrollingTreeMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE5806219327A6200DE32EB /* ScrollingTreeMac.h */; }; >+ 0FE5FBD21C3DD51E0007A2CA /* DisplayList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE5FBCA1C3DD51E0007A2CA /* DisplayList.cpp */; }; >+ 0FE5FBD31C3DD51E0007A2CA /* DisplayList.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE5FBCB1C3DD51E0007A2CA /* DisplayList.h */; }; >+ 0FE5FBD41C3DD51E0007A2CA /* DisplayListItems.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE5FBCC1C3DD51E0007A2CA /* DisplayListItems.cpp */; }; >+ 0FE5FBD51C3DD51E0007A2CA /* DisplayListItems.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE5FBCD1C3DD51E0007A2CA /* DisplayListItems.h */; }; >+ 0FE5FBD61C3DD51E0007A2CA /* DisplayListRecorder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE5FBCE1C3DD51E0007A2CA /* DisplayListRecorder.cpp */; }; >+ 0FE5FBD71C3DD51E0007A2CA /* DisplayListRecorder.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE5FBCF1C3DD51E0007A2CA /* DisplayListRecorder.h */; }; >+ 0FE5FBD81C3DD51E0007A2CA /* DisplayListReplayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE5FBD01C3DD51E0007A2CA /* DisplayListReplayer.cpp */; }; >+ 0FE5FBD91C3DD51E0007A2CA /* DisplayListReplayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE5FBD11C3DD51E0007A2CA /* DisplayListReplayer.h */; }; > 0FE71405142170B800DB33BA /* ScrollbarThemeMock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE71403142170B800DB33BA /* ScrollbarThemeMock.cpp */; }; > 0FE71406142170B800DB33BA /* ScrollbarThemeMock.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE71404142170B800DB33BA /* ScrollbarThemeMock.h */; }; > 0FEA3E7B191B2FC5000F1B55 /* ScrollingStateFrameScrollingNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEA3E79191B2FC5000F1B55 /* ScrollingStateFrameScrollingNode.h */; settings = {ATTRIBUTES = (Private, ); }; }; >@@ -7839,6 +7847,14 @@ > 0FDF45A81BD1C82500E4FA8C /* TimingFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TimingFunction.cpp; sourceTree = "<group>"; }; > 0FE5806119327A6200DE32EB /* ScrollingTreeMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollingTreeMac.cpp; sourceTree = "<group>"; }; > 0FE5806219327A6200DE32EB /* ScrollingTreeMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollingTreeMac.h; sourceTree = "<group>"; }; >+ 0FE5FBCA1C3DD51E0007A2CA /* DisplayList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DisplayList.cpp; path = displaylists/DisplayList.cpp; sourceTree = "<group>"; }; >+ 0FE5FBCB1C3DD51E0007A2CA /* DisplayList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DisplayList.h; path = displaylists/DisplayList.h; sourceTree = "<group>"; }; >+ 0FE5FBCC1C3DD51E0007A2CA /* DisplayListItems.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DisplayListItems.cpp; path = displaylists/DisplayListItems.cpp; sourceTree = "<group>"; }; >+ 0FE5FBCD1C3DD51E0007A2CA /* DisplayListItems.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DisplayListItems.h; path = displaylists/DisplayListItems.h; sourceTree = "<group>"; }; >+ 0FE5FBCE1C3DD51E0007A2CA /* DisplayListRecorder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DisplayListRecorder.cpp; path = displaylists/DisplayListRecorder.cpp; sourceTree = "<group>"; }; >+ 0FE5FBCF1C3DD51E0007A2CA /* DisplayListRecorder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DisplayListRecorder.h; path = displaylists/DisplayListRecorder.h; sourceTree = "<group>"; }; >+ 0FE5FBD01C3DD51E0007A2CA /* DisplayListReplayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DisplayListReplayer.cpp; path = displaylists/DisplayListReplayer.cpp; sourceTree = "<group>"; }; >+ 0FE5FBD11C3DD51E0007A2CA /* DisplayListReplayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DisplayListReplayer.h; path = displaylists/DisplayListReplayer.h; sourceTree = "<group>"; }; > 0FE71403142170B800DB33BA /* ScrollbarThemeMock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollbarThemeMock.cpp; sourceTree = "<group>"; }; > 0FE71404142170B800DB33BA /* ScrollbarThemeMock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollbarThemeMock.h; sourceTree = "<group>"; }; > 0FE71415142189FC00DB33BA /* ScrollbarTheme.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollbarTheme.cpp; sourceTree = "<group>"; }; >@@ -15654,6 +15670,21 @@ > path = ios; > sourceTree = "<group>"; > }; >+ 0FE5FBC91C3DD5060007A2CA /* displaylists */ = { >+ isa = PBXGroup; >+ children = ( >+ 0FE5FBCA1C3DD51E0007A2CA /* DisplayList.cpp */, >+ 0FE5FBCB1C3DD51E0007A2CA /* DisplayList.h */, >+ 0FE5FBCC1C3DD51E0007A2CA /* DisplayListItems.cpp */, >+ 0FE5FBCD1C3DD51E0007A2CA /* DisplayListItems.h */, >+ 0FE5FBCE1C3DD51E0007A2CA /* DisplayListRecorder.cpp */, >+ 0FE5FBCF1C3DD51E0007A2CA /* DisplayListRecorder.h */, >+ 0FE5FBD01C3DD51E0007A2CA /* DisplayListReplayer.cpp */, >+ 0FE5FBD11C3DD51E0007A2CA /* DisplayListReplayer.h */, >+ ); >+ name = displaylists; >+ sourceTree = "<group>"; >+ }; > 14DFB33F0A7DF7630018F769 /* Derived Sources */ = { > isa = PBXGroup; > children = ( >@@ -21529,6 +21560,7 @@ > B27535290B053814002CE64F /* cg */, > B5320D68122A24E9002D1440 /* cocoa */, > 9332AB3B16515D7700D827EC /* cpu */, >+ 0FE5FBC91C3DD5060007A2CA /* displaylists */, > A75E8B7F0E1DE2B0007F2481 /* filters */, > 498770C11242C50D002226BA /* gpu */, > 441AF0A70EBA7BBF0044ED4B /* ios */, >@@ -25068,6 +25100,10 @@ > 2D5646B01B8F8493003C4994 /* DictionaryPopupInfo.h in Headers */, > FDAF19991513D131008DB0C3 /* DirectConvolver.h in Headers */, > 7EDAAFC919A2CCDC0034DFD1 /* DiskCacheMonitorCocoa.h in Headers */, >+ 0FE5FBD31C3DD51E0007A2CA /* DisplayList.h in Headers */, >+ 0FE5FBD51C3DD51E0007A2CA /* DisplayListItems.h in Headers */, >+ 0FE5FBD71C3DD51E0007A2CA /* DisplayListRecorder.h in Headers */, >+ 0FE5FBD91C3DD51E0007A2CA /* DisplayListReplayer.h in Headers */, > 49AF2D6914435D050016A784 /* DisplayRefreshMonitor.h in Headers */, > 2D29ECC6192ECC8300984B78 /* DisplayRefreshMonitorClient.h in Headers */, > 2D29ECCA192F1F1D00984B78 /* DisplayRefreshMonitorIOS.h in Headers */, >@@ -28902,6 +28938,10 @@ > 937FF3D71A10131B008EBA31 /* DictionaryLookup.mm in Sources */, > FDAF19981513D131008DB0C3 /* DirectConvolver.cpp in Sources */, > 7E4DE10D198B10B60051CB02 /* DiskCacheMonitorCocoa.mm in Sources */, >+ 0FE5FBD21C3DD51E0007A2CA /* DisplayList.cpp in Sources */, >+ 0FE5FBD41C3DD51E0007A2CA /* DisplayListItems.cpp in Sources */, >+ 0FE5FBD61C3DD51E0007A2CA /* DisplayListRecorder.cpp in Sources */, >+ 0FE5FBD81C3DD51E0007A2CA /* DisplayListReplayer.cpp in Sources */, > 49FC7A501444AF5F00A5D864 /* DisplayRefreshMonitor.cpp in Sources */, > 2D29ECC5192ECC8300984B78 /* DisplayRefreshMonitorClient.cpp in Sources */, > 0F97A658155DA81E00FADD4C /* DisplayRefreshMonitorIOS.mm in Sources */, >diff --git a/Source/WebCore/platform/Logging.h b/Source/WebCore/platform/Logging.h >index 3f0fd7ac1657f82d284658cb48b6a631bc3f627a..3bddaf28ae419483c3c213c2bd8ee342443d45d9 100644 >--- a/Source/WebCore/platform/Logging.h >+++ b/Source/WebCore/platform/Logging.h >@@ -48,6 +48,7 @@ namespace WebCore { > M(Archives) \ > M(Compositing) \ > M(ContentFiltering) \ >+ M(DisplayLists) \ > M(DOMTimers) \ > M(Editing) \ > M(Events) \ >diff --git a/Source/WebCore/platform/graphics/GraphicsContext.cpp b/Source/WebCore/platform/graphics/GraphicsContext.cpp >index 0d6b300e75285c185ed2d529b8642a1fafdd7b70..c2b87593fa5e4e08bd136ee444893c32455bb9e9 100644 >--- a/Source/WebCore/platform/graphics/GraphicsContext.cpp >+++ b/Source/WebCore/platform/graphics/GraphicsContext.cpp >@@ -34,6 +34,7 @@ > #include "IntRect.h" > #include "RoundedRect.h" > #include "TextRun.h" >+#include "TextStream.h" > > namespace WebCore { > >@@ -98,6 +99,267 @@ private: > bool m_interpolationQualityChanged; > }; > >+ >+#define CHECK_FOR_CHANGED_PROPERTY(flag, property) \ >+ if ((m_changeFlags & GraphicsContextState::flag) && (m_state.property != state.property)) \ >+ changeFlags |= GraphicsContextState::flag; >+ >+GraphicsContextState::StateChangeFlags GraphicsContextStateChange::changesFromState(const GraphicsContextState& state) const >+{ >+ GraphicsContextState::StateChangeFlags changeFlags = 0; >+ >+ CHECK_FOR_CHANGED_PROPERTY(StrokeGradientChange, strokeGradient); >+ CHECK_FOR_CHANGED_PROPERTY(StrokePatternChange, strokePattern); >+ CHECK_FOR_CHANGED_PROPERTY(FillGradientChange, fillGradient); >+ CHECK_FOR_CHANGED_PROPERTY(FillPatternChange, fillPattern); >+ >+ if ((m_changeFlags & GraphicsContextState::ShadowChange) >+ && (m_state.shadowOffset != state.shadowOffset >+ || m_state.shadowBlur != state.shadowBlur >+ || m_state.shadowColor != state.shadowColor)) >+ changeFlags |= GraphicsContextState::ShadowChange; >+ >+ CHECK_FOR_CHANGED_PROPERTY(StrokeThicknessChange, strokeThickness); >+ CHECK_FOR_CHANGED_PROPERTY(TextDrawingModeChange, textDrawingMode); >+ CHECK_FOR_CHANGED_PROPERTY(StrokeColorChange, strokeColor); >+ CHECK_FOR_CHANGED_PROPERTY(FillColorChange, fillColor); >+ CHECK_FOR_CHANGED_PROPERTY(StrokeStyleChange, strokeStyle); >+ CHECK_FOR_CHANGED_PROPERTY(FillRuleChange, fillRule); >+ CHECK_FOR_CHANGED_PROPERTY(AlphaChange, alpha); >+ >+ if ((m_changeFlags & (GraphicsContextState::CompositeOperationChange | GraphicsContextState::BlendModeChange)) >+ && (m_state.compositeOperator != state.compositeOperator || m_state.blendMode != state.blendMode)) >+ changeFlags |= (GraphicsContextState::CompositeOperationChange | GraphicsContextState::BlendModeChange); >+ >+ CHECK_FOR_CHANGED_PROPERTY(ShouldAntialiasChange, shouldAntialias); >+ CHECK_FOR_CHANGED_PROPERTY(ShouldSmoothFontsChange, shouldSmoothFonts); >+ CHECK_FOR_CHANGED_PROPERTY(AntialiasedFontDilationEnabledChange, antialiasedFontDilationEnabled); >+ CHECK_FOR_CHANGED_PROPERTY(ShouldSubpixelQuantizeFontsChange, shouldSubpixelQuantizeFonts); >+ CHECK_FOR_CHANGED_PROPERTY(ShadowsIgnoreTransformsChange, shadowsIgnoreTransforms); >+ CHECK_FOR_CHANGED_PROPERTY(DrawLuminanceMaskChange, drawLuminanceMask); >+ CHECK_FOR_CHANGED_PROPERTY(ImageInterpolationQualityChange, imageInterpolationQuality); >+ >+ return changeFlags; >+} >+ >+void GraphicsContextStateChange::accumulate(const GraphicsContextState& state, GraphicsContextState::StateChangeFlags flags) >+{ >+ // FIXME: this code should move to GraphicsContextState. >+ if (flags & GraphicsContextState::StrokeGradientChange) >+ m_state.strokeGradient = state.strokeGradient; >+ >+ if (flags & GraphicsContextState::StrokePatternChange) >+ m_state.strokePattern = state.strokePattern; >+ >+ if (flags & GraphicsContextState::FillGradientChange) >+ m_state.fillGradient = state.fillGradient; >+ >+ if (flags & GraphicsContextState::FillPatternChange) >+ m_state.fillPattern = state.fillPattern; >+ >+ if (flags & GraphicsContextState::ShadowChange) { >+ // FIXME: deal with state.shadowsUseLegacyRadius) >+ m_state.shadowOffset = state.shadowOffset; >+ m_state.shadowBlur = state.shadowBlur; >+ m_state.shadowColor = state.shadowColor; >+ } >+ >+ if (flags & GraphicsContextState::StrokeThicknessChange) >+ m_state.strokeThickness = state.strokeThickness; >+ >+ if (flags & GraphicsContextState::TextDrawingModeChange) >+ m_state.textDrawingMode = state.textDrawingMode; >+ >+ if (flags & GraphicsContextState::StrokeColorChange) >+ m_state.strokeColor = state.strokeColor; >+ >+ if (flags & GraphicsContextState::FillColorChange) >+ m_state.fillColor = state.fillColor; >+ >+ if (flags & GraphicsContextState::StrokeStyleChange) >+ m_state.strokeStyle = state.strokeStyle; >+ >+ if (flags & GraphicsContextState::FillRuleChange) >+ m_state.fillRule = state.fillRule; >+ >+ if (flags & GraphicsContextState::AlphaChange) >+ m_state.alpha = state.alpha; >+ >+ if (flags & (GraphicsContextState::CompositeOperationChange | GraphicsContextState::BlendModeChange)) { >+ m_state.compositeOperator = state.compositeOperator; >+ m_state.blendMode = state.blendMode; >+ } >+ >+ if (flags & GraphicsContextState::ShouldAntialiasChange) >+ m_state.shouldAntialias = state.shouldAntialias; >+ >+ if (flags & GraphicsContextState::ShouldSmoothFontsChange) >+ m_state.shouldSmoothFonts = state.shouldSmoothFonts; >+ >+ if (flags & GraphicsContextState::AntialiasedFontDilationEnabledChange) >+ m_state.antialiasedFontDilationEnabled = state.antialiasedFontDilationEnabled; >+ >+ if (flags & GraphicsContextState::ShouldSubpixelQuantizeFontsChange) >+ m_state.shouldSubpixelQuantizeFonts = state.shouldSubpixelQuantizeFonts; >+ >+ if (flags & GraphicsContextState::ShadowsIgnoreTransformsChange) >+ m_state.shadowsIgnoreTransforms = state.shadowsIgnoreTransforms; >+ >+ if (flags & GraphicsContextState::DrawLuminanceMaskChange) >+ m_state.drawLuminanceMask = state.drawLuminanceMask; >+ >+ if (flags & GraphicsContextState::ImageInterpolationQualityChange) >+ m_state.imageInterpolationQuality = state.imageInterpolationQuality; >+ >+ m_changeFlags |= flags; >+} >+ >+void GraphicsContextStateChange::apply(GraphicsContext& context) const >+{ >+ if (m_changeFlags & GraphicsContextState::StrokeGradientChange) >+ context.setStrokeGradient(*m_state.strokeGradient); >+ >+ if (m_changeFlags & GraphicsContextState::StrokePatternChange) >+ context.setStrokePattern(*m_state.strokePattern); >+ >+ if (m_changeFlags & GraphicsContextState::FillGradientChange) >+ context.setFillGradient(*m_state.fillGradient); >+ >+ if (m_changeFlags & GraphicsContextState::FillPatternChange) >+ context.setFillPattern(*m_state.fillPattern); >+ >+ if (m_changeFlags & GraphicsContextState::ShadowChange) { >+#if USE(CG) >+ if (m_state.shadowsUseLegacyRadius) >+ context.setLegacyShadow(m_state.shadowOffset, m_state.shadowBlur, m_state.shadowColor); >+ else >+#endif >+ context.setShadow(m_state.shadowOffset, m_state.shadowBlur, m_state.shadowColor); >+ } >+ >+ if (m_changeFlags & GraphicsContextState::StrokeThicknessChange) >+ context.setStrokeThickness(m_state.strokeThickness); >+ >+ if (m_changeFlags & GraphicsContextState::TextDrawingModeChange) >+ context.setTextDrawingMode(m_state.textDrawingMode); >+ >+ if (m_changeFlags & GraphicsContextState::StrokeColorChange) >+ context.setStrokeColor(m_state.strokeColor); >+ >+ if (m_changeFlags & GraphicsContextState::FillColorChange) >+ context.setFillColor(m_state.fillColor); >+ >+ if (m_changeFlags & GraphicsContextState::StrokeStyleChange) >+ context.setStrokeStyle(m_state.strokeStyle); >+ >+ if (m_changeFlags & GraphicsContextState::FillRuleChange) >+ context.setFillRule(m_state.fillRule); >+ >+ if (m_changeFlags & GraphicsContextState::AlphaChange) >+ context.setAlpha(m_state.alpha); >+ >+ if (m_changeFlags & (GraphicsContextState::CompositeOperationChange | GraphicsContextState::BlendModeChange)) >+ context.setCompositeOperation(m_state.compositeOperator, m_state.blendMode); >+ >+ if (m_changeFlags & GraphicsContextState::ShouldAntialiasChange) >+ context.setShouldAntialias(m_state.shouldAntialias); >+ >+ if (m_changeFlags & GraphicsContextState::ShouldSmoothFontsChange) >+ context.setShouldSmoothFonts(m_state.shouldSmoothFonts); >+ >+ if (m_changeFlags & GraphicsContextState::AntialiasedFontDilationEnabledChange) >+ context.setAntialiasedFontDilationEnabled(m_state.antialiasedFontDilationEnabled); >+ >+ if (m_changeFlags & GraphicsContextState::ShouldSubpixelQuantizeFontsChange) >+ context.setShouldSubpixelQuantizeFonts(m_state.shouldSubpixelQuantizeFonts); >+ >+ if (m_changeFlags & GraphicsContextState::ShadowsIgnoreTransformsChange) >+ context.setShadowsIgnoreTransforms(m_state.shadowsIgnoreTransforms); >+ >+ if (m_changeFlags & GraphicsContextState::DrawLuminanceMaskChange) >+ context.setDrawLuminanceMask(m_state.drawLuminanceMask); >+ >+ if (m_changeFlags & GraphicsContextState::ImageInterpolationQualityChange) >+ context.setImageInterpolationQuality(m_state.imageInterpolationQuality); >+} >+ >+void GraphicsContextStateChange::dump(TextStream& ts) const >+{ >+ ts.dumpProperty("change-flags", m_changeFlags); >+ >+ if (m_changeFlags & GraphicsContextState::StrokeGradientChange) >+ ts.dumpProperty("stroke-gradient", m_state.strokeGradient.get()); >+ >+ if (m_changeFlags & GraphicsContextState::StrokePatternChange) >+ ts.dumpProperty("stroke-pattern", m_state.strokePattern.get()); >+ >+ if (m_changeFlags & GraphicsContextState::FillGradientChange) >+ ts.dumpProperty("fill-gradient", m_state.fillGradient.get()); >+ >+ if (m_changeFlags & GraphicsContextState::FillPatternChange) >+ ts.dumpProperty("fill-pattern", m_state.fillPattern.get()); >+ >+ if (m_changeFlags & GraphicsContextState::ShadowChange) { >+ ts.dumpProperty("shadow-blur", m_state.shadowBlur); >+ ts.dumpProperty("shadow-offset", m_state.shadowOffset); >+#if USE(CG) >+ ts.dumpProperty("shadows-use-legacy-radius", m_state.shadowsUseLegacyRadius); >+#endif >+ } >+ >+ if (m_changeFlags & GraphicsContextState::StrokeThicknessChange) >+ ts.dumpProperty("stroke-thickness", m_state.strokeThickness); >+ >+ if (m_changeFlags & GraphicsContextState::TextDrawingModeChange) >+ ts.dumpProperty("text-drawing-mode", m_state.textDrawingMode); >+ >+ if (m_changeFlags & GraphicsContextState::StrokeColorChange) >+ ts.dumpProperty("stroke-color", m_state.strokeColor); >+ >+ if (m_changeFlags & GraphicsContextState::FillColorChange) >+ ts.dumpProperty("fill-color", m_state.fillColor); >+ >+ if (m_changeFlags & GraphicsContextState::StrokeStyleChange) >+ ts.dumpProperty("stroke-style", m_state.strokeStyle); >+ >+ if (m_changeFlags & GraphicsContextState::FillRuleChange) >+ ts.dumpProperty("fill-rule", m_state.fillRule); >+ >+ if (m_changeFlags & GraphicsContextState::AlphaChange) >+ ts.dumpProperty("alpha", m_state.alpha); >+ >+ if (m_changeFlags & GraphicsContextState::CompositeOperationChange) >+ ts.dumpProperty("composite-operator", m_state.compositeOperator); >+ >+ if (m_changeFlags & GraphicsContextState::BlendModeChange) >+ ts.dumpProperty("blend-mode", m_state.blendMode); >+ >+ if (m_changeFlags & GraphicsContextState::ShouldAntialiasChange) >+ ts.dumpProperty("should-antialias", m_state.shouldAntialias); >+ >+ if (m_changeFlags & GraphicsContextState::ShouldSmoothFontsChange) >+ ts.dumpProperty("should-smooth-fonts", m_state.shouldSmoothFonts); >+ >+ if (m_changeFlags & GraphicsContextState::AntialiasedFontDilationEnabledChange) >+ ts.dumpProperty("antialiased-font-dilation-enabled", m_state.antialiasedFontDilationEnabled); >+ >+ if (m_changeFlags & GraphicsContextState::ShouldSubpixelQuantizeFontsChange) >+ ts.dumpProperty("should-subpixel-quantize-fonts", m_state.shouldSubpixelQuantizeFonts); >+ >+ if (m_changeFlags & GraphicsContextState::ShadowsIgnoreTransformsChange) >+ ts.dumpProperty("shadows-ignore-transforms", m_state.shadowsIgnoreTransforms); >+ >+ if (m_changeFlags & GraphicsContextState::DrawLuminanceMaskChange) >+ ts.dumpProperty("draw-luminance-mask", m_state.drawLuminanceMask); >+} >+ >+TextStream& operator<<(TextStream& ts, const GraphicsContextStateChange& stateChange) >+{ >+ stateChange.dump(ts); >+ return ts; >+} >+ >+ > GraphicsContext::GraphicsContext(PlatformGraphicsContext* platformGraphicsContext) > : m_updatingControlTints(false) > , m_transparencyCount(0) >diff --git a/Source/WebCore/platform/graphics/GraphicsContext.h b/Source/WebCore/platform/graphics/GraphicsContext.h >index 52b1ad82b2f8a58708e99e366a76e25620b23de0..d9b1f9942a2933c0f2378a3c137fcf63ad13adc5 100644 >--- a/Source/WebCore/platform/graphics/GraphicsContext.h >+++ b/Source/WebCore/platform/graphics/GraphicsContext.h >@@ -127,6 +127,33 @@ struct GraphicsContextState { > { > } > >+ enum Change : uint32_t { >+ NoChange = 0, >+ StrokeGradientChange = 1 << 1, >+ StrokePatternChange = 1 << 2, >+ FillGradientChange = 1 << 3, >+ FillPatternChange = 1 << 4, >+ StrokeThicknessChange = 1 << 5, >+ StrokeColorChange = 1 << 6, >+ StrokeStyleChange = 1 << 7, >+ FillColorChange = 1 << 8, >+ FillRuleChange = 1 << 9, >+ ShadowChange = 1 << 10, >+ ShadowColorChange = 1 << 11, >+ ShadowsIgnoreTransformsChange = 1 << 12, >+ AlphaChange = 1 << 13, >+ CompositeOperationChange = 1 << 14, >+ BlendModeChange = 1 << 15, >+ TextDrawingModeChange = 1 << 16, >+ ShouldAntialiasChange = 1 << 17, >+ ShouldSmoothFontsChange = 1 << 18, >+ AntialiasedFontDilationEnabledChange = 1 << 19, >+ ShouldSubpixelQuantizeFontsChange = 1 << 20, >+ DrawLuminanceMaskChange = 1 << 21, >+ ImageInterpolationQualityChange = 1 << 22, >+ }; >+ typedef uint32_t StateChangeFlags; >+ > RefPtr<Gradient> strokeGradient; > RefPtr<Pattern> strokePattern; > >@@ -195,6 +222,28 @@ struct ImagePaintingOptions { > bool m_useLowQualityScale; > }; > >+struct GraphicsContextStateChange { >+ GraphicsContextStateChange() = default; >+ GraphicsContextStateChange(const GraphicsContextState& state, GraphicsContextState::StateChangeFlags flags) >+ : m_state(state) >+ , m_changeFlags(flags) >+ { >+ } >+ >+ GraphicsContextState::StateChangeFlags changesFromState(const GraphicsContextState&) const; >+ >+ void accumulate(const GraphicsContextState&, GraphicsContextState::StateChangeFlags); >+ void apply(GraphicsContext&) const; >+ >+ void dump(TextStream&) const; >+ >+ GraphicsContextState m_state; >+ GraphicsContextState::StateChangeFlags m_changeFlags { 0 }; >+}; >+ >+TextStream& operator<<(TextStream&, const GraphicsContextStateChange&); >+ >+ > class GraphicsContext { > WTF_MAKE_NONCOPYABLE(GraphicsContext); WTF_MAKE_FAST_ALLOCATED; > public: >diff --git a/Source/WebCore/platform/graphics/displaylists/DisplayList.cpp b/Source/WebCore/platform/graphics/displaylists/DisplayList.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..9462bdebed7bb5ad6928f299552d00af6ae97679 >--- /dev/null >+++ b/Source/WebCore/platform/graphics/displaylists/DisplayList.cpp >@@ -0,0 +1,230 @@ >+/* >+ * Copyright (C) 2016 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 "DisplayList.h" >+ >+#include "Logging.h" >+#include "TextStream.h" >+#include <wtf/StdLibExtras.h> >+ >+namespace WebCore { >+namespace DisplayList { >+ >+#if !defined(NDEBUG) || !LOG_DISABLED >+WTF::CString DisplayList::description() const >+{ >+ TextStream ts; >+ ts << *this; >+ return ts.release().utf8(); >+} >+ >+void DisplayList::dump() const >+{ >+ fprintf(stderr, "%s", description().data()); >+} >+#endif >+ >+void DisplayList::dump(TextStream& ts) const >+{ >+ TextStream::GroupScope group(ts); >+ ts << "display list"; >+ >+ size_t numItems = m_list.size(); >+ for (size_t i = 0; i < numItems; ++i) { >+ TextStream::GroupScope scope(ts); >+ ts << i << " " << m_list[i].get(); >+ } >+ ts.startGroup(); >+ ts << "size in bytes: " << sizeInBytes(); >+ ts.endGroup(); >+} >+ >+size_t DisplayList::sizeInBytes() const >+{ >+ size_t result = 0; >+ for (auto& ref : m_list) { >+ switch (ref->type()) { >+ case ItemType::Save: >+ result += sizeof(downcast<Save>(ref.get())); >+ break; >+ case ItemType::Restore: >+ result += sizeof(downcast<Restore>(ref.get())); >+ break; >+ case ItemType::Translate: >+ result += sizeof(downcast<Translate>(ref.get())); >+ break; >+ case ItemType::Rotate: >+ result += sizeof(downcast<Rotate>(ref.get())); >+ break; >+ case ItemType::Scale: >+ result += sizeof(downcast<Scale>(ref.get())); >+ break; >+ case ItemType::ConcatenateCTM: >+ result += sizeof(downcast<ConcatenateCTM>(ref.get())); >+ break; >+ case ItemType::SetState: >+ result += sizeof(downcast<SetState>(ref.get())); >+ break; >+ case ItemType::SetLineCap: >+ result += sizeof(downcast<SetLineCap>(ref.get())); >+ break; >+ case ItemType::SetLineDash: >+ result += sizeof(downcast<SetLineDash>(ref.get())); >+ break; >+ case ItemType::SetLineJoin: >+ result += sizeof(downcast<SetLineJoin>(ref.get())); >+ break; >+ case ItemType::SetMiterLimit: >+ result += sizeof(downcast<SetMiterLimit>(ref.get())); >+ break; >+ case ItemType::ClearShadow: >+ result += sizeof(downcast<ClearShadow>(ref.get())); >+ break; >+ case ItemType::Clip: >+ result += sizeof(downcast<Clip>(ref.get())); >+ break; >+ case ItemType::ClipOut: >+ result += sizeof(downcast<ClipOut>(ref.get())); >+ break; >+ case ItemType::ClipOutToPath: >+ result += sizeof(downcast<ClipOutToPath>(ref.get())); >+ break; >+ case ItemType::ClipPath: >+ result += sizeof(downcast<ClipPath>(ref.get())); >+ break; >+ case ItemType::ClipConvexPolygon: >+ result += sizeof(downcast<ClipConvexPolygon>(ref.get())); >+ break; >+ case ItemType::DrawGlyphs: >+ result += sizeof(downcast<DrawGlyphs>(ref.get())); >+ break; >+ case ItemType::DrawImage: >+ result += sizeof(downcast<DrawImage>(ref.get())); >+ break; >+ case ItemType::DrawTiledImage: >+ result += sizeof(downcast<DrawTiledImage>(ref.get())); >+ break; >+ case ItemType::DrawTiledScaledImage: >+ result += sizeof(downcast<DrawTiledScaledImage>(ref.get())); >+ break; >+ case ItemType::DrawNativeImage: >+ result += sizeof(downcast<DrawNativeImage>(ref.get())); >+ break; >+ case ItemType::DrawPattern: >+ result += sizeof(downcast<DrawPattern>(ref.get())); >+ break; >+ case ItemType::DrawRect: >+ result += sizeof(downcast<DrawRect>(ref.get())); >+ break; >+ case ItemType::DrawLine: >+ result += sizeof(downcast<DrawLine>(ref.get())); >+ break; >+ case ItemType::DrawLinesForText: >+ result += sizeof(downcast<DrawLinesForText>(ref.get())); >+ break; >+ case ItemType::DrawLineForDocumentMarker: >+ result += sizeof(downcast<DrawLineForDocumentMarker>(ref.get())); >+ break; >+ case ItemType::DrawEllipse: >+ result += sizeof(downcast<DrawEllipse>(ref.get())); >+ break; >+ case ItemType::DrawConvexPolygon: >+ result += sizeof(downcast<DrawConvexPolygon>(ref.get())); >+ break; >+ case ItemType::DrawPath: >+ result += sizeof(downcast<DrawPath>(ref.get())); >+ break; >+ case ItemType::DrawFocusRingPath: >+ result += sizeof(downcast<DrawFocusRingPath>(ref.get())); >+ break; >+ case ItemType::DrawFocusRingRects: >+ result += sizeof(downcast<DrawFocusRingRects>(ref.get())); >+ break; >+ case ItemType::FillRect: >+ result += sizeof(downcast<FillRect>(ref.get())); >+ break; >+ case ItemType::FillRectWithColor: >+ result += sizeof(downcast<FillRectWithColor>(ref.get())); >+ break; >+ case ItemType::FillRectWithGradient: >+ result += sizeof(downcast<FillRectWithGradient>(ref.get())); >+ break; >+ case ItemType::FillCompositedRect: >+ result += sizeof(downcast<FillCompositedRect>(ref.get())); >+ break; >+ case ItemType::FillRoundedRect: >+ result += sizeof(downcast<FillRoundedRect>(ref.get())); >+ break; >+ case ItemType::FillRectWithRoundedHole: >+ result += sizeof(downcast<FillRectWithRoundedHole>(ref.get())); >+ break; >+ case ItemType::FillPath: >+ result += sizeof(downcast<FillPath>(ref.get())); >+ break; >+ case ItemType::FillEllipse: >+ result += sizeof(downcast<FillEllipse>(ref.get())); >+ break; >+ case ItemType::StrokeRect: >+ result += sizeof(downcast<StrokeRect>(ref.get())); >+ break; >+ case ItemType::StrokePath: >+ result += sizeof(downcast<StrokePath>(ref.get())); >+ break; >+ case ItemType::StrokeEllipse: >+ result += sizeof(downcast<StrokeEllipse>(ref.get())); >+ break; >+ case ItemType::ClearRect: >+ result += sizeof(downcast<ClearRect>(ref.get())); >+ break; >+ case ItemType::BeginTransparencyLayer: >+ result += sizeof(downcast<BeginTransparencyLayer>(ref.get())); >+ break; >+ case ItemType::EndTransparencyLayer: >+ result += sizeof(downcast<EndTransparencyLayer>(ref.get())); >+ break; >+ case ItemType::ApplyStrokePattern: >+ result += sizeof(downcast<ApplyStrokePattern>(ref.get())); >+ break; >+ case ItemType::ApplyFillPattern: >+ result += sizeof(downcast<ApplyFillPattern>(ref.get())); >+ break; >+ case ItemType::ApplyDeviceScaleFactor: >+ result += sizeof(downcast<ApplyDeviceScaleFactor>(ref.get())); >+ break; >+ } >+ } >+ return result; >+} >+ >+} // namespace DisplayList >+ >+TextStream& operator<<(TextStream& ts, const DisplayList::DisplayList& displayList) >+{ >+ displayList.dump(ts); >+ return ts; >+} >+ >+} // namespace WebCore >diff --git a/Source/WebCore/platform/graphics/displaylists/DisplayList.h b/Source/WebCore/platform/graphics/displaylists/DisplayList.h >new file mode 100644 >index 0000000000000000000000000000000000000000..76128a25310b3c99bd1dfd9ae63460c08627e580 >--- /dev/null >+++ b/Source/WebCore/platform/graphics/displaylists/DisplayList.h >@@ -0,0 +1,95 @@ >+/* >+ * Copyright (C) 2016 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. >+ */ >+ >+#ifndef DisplayList_h >+#define DisplayList_h >+ >+#include "DisplayListItems.h" >+#include <wtf/FastMalloc.h> >+#include <wtf/Noncopyable.h> >+#include <wtf/text/WTFString.h> >+ >+namespace WebCore { >+ >+class FloatRect; >+class GraphicsContext; >+class TextStream; >+ >+namespace DisplayList { >+ >+class DisplayList { >+ WTF_MAKE_NONCOPYABLE(DisplayList); >+ friend class Recorder; >+public: >+ DisplayList() = default; >+ DisplayList(DisplayList&&) = default; >+ >+ DisplayList& operator=(DisplayList&&) = default; >+ >+ void dump(TextStream&) const; >+ >+ const Vector<Ref<Item>>& list() const { return m_list; } >+ Item& itemAt(size_t index) >+ { >+ ASSERT(index < m_list.size()); >+ return m_list[index].get(); >+ } >+ >+ void clear() { m_list.clear(); } >+ size_t size() const { return m_list.size(); } >+ >+ void removeItemsFromIndex(size_t index) >+ { >+ m_list.resize(index); >+ } >+ >+ size_t sizeInBytes() const; >+ >+#if !defined(NDEBUG) || !LOG_DISABLED >+ WTF::CString description() const; >+ void dump() const; >+#endif >+ >+private: >+ Item& append(Ref<Item>&& item) >+ { >+ m_list.append(WTFMove(item)); >+ return m_list.last().get(); >+ } >+ >+ Vector<Ref<Item>>& list() { return m_list; } >+ >+ Vector<Ref<Item>> m_list; >+}; >+ >+} // DisplayList >+ >+TextStream& operator<<(TextStream&, const DisplayList::DisplayList&); >+ >+} // WebCore >+ >+using WebCore::DisplayList::DisplayList; >+ >+#endif /* DisplayList_h */ >diff --git a/Source/WebCore/platform/graphics/displaylists/DisplayListItems.cpp b/Source/WebCore/platform/graphics/displaylists/DisplayListItems.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..09d430697bf7367905e2572830a03f013fa96b77 >--- /dev/null >+++ b/Source/WebCore/platform/graphics/displaylists/DisplayListItems.cpp >@@ -0,0 +1,1088 @@ >+/* >+ * Copyright (C) 2015 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 "DisplayListItems.h" >+ >+#include "FontCascade.h" >+#include "TextStream.h" >+ >+namespace WebCore { >+namespace DisplayList { >+ >+// Should match RenderTheme::platformFocusRingWidth() >+static const float platformFocusRingWidth = 3; >+ >+#if !defined(NDEBUG) || !LOG_DISABLED >+WTF::CString Item::description() const >+{ >+ TextStream ts; >+ ts << *this; >+ return ts.release().utf8(); >+} >+#endif >+ >+static TextStream& operator<<(TextStream& ts, const DrawingItem& item) >+{ >+ ts.startGroup(); >+ ts << "extent "; >+ if (item.extentKnown()) >+ ts << item.extent(); >+ else >+ ts << "unknown"; >+ >+ ts.endGroup(); >+ return ts; >+} >+ >+void Save::apply(GraphicsContext& context) const >+{ >+ context.save(); >+} >+ >+static TextStream& operator<<(TextStream& ts, const Save& item) >+{ >+ ts.dumpProperty("restore-index", item.restoreIndex()); >+ return ts; >+} >+ >+void Restore::apply(GraphicsContext& context) const >+{ >+ context.restore(); >+} >+ >+void Translate::apply(GraphicsContext& context) const >+{ >+ context.translate(m_x, m_y); >+} >+ >+static TextStream& operator<<(TextStream& ts, const Translate& item) >+{ >+ ts.dumpProperty("x", item.x()); >+ ts.dumpProperty("y", item.y()); >+ >+ return ts; >+} >+ >+void Rotate::apply(GraphicsContext& context) const >+{ >+ context.rotate(m_angle); >+} >+ >+static TextStream& operator<<(TextStream& ts, const Rotate& item) >+{ >+ ts.dumpProperty("angle", item.angle()); >+ >+ return ts; >+} >+ >+void Scale::apply(GraphicsContext& context) const >+{ >+ context.scale(m_size); >+} >+ >+static TextStream& operator<<(TextStream& ts, const Scale& item) >+{ >+ ts.dumpProperty("size", item.amount()); >+ >+ return ts; >+} >+ >+ConcatenateCTM::ConcatenateCTM(const AffineTransform& transform) >+ : Item(ItemType::ConcatenateCTM) >+ , m_transform(transform) >+{ >+} >+ >+void ConcatenateCTM::apply(GraphicsContext& context) const >+{ >+ context.concatCTM(m_transform); >+} >+ >+static TextStream& operator<<(TextStream& ts, const ConcatenateCTM& item) >+{ >+ ts.dumpProperty("ctm", item.transform()); >+ >+ return ts; >+} >+ >+void SetState::apply(GraphicsContext& context) const >+{ >+ m_state.apply(context); >+} >+ >+void SetState::accumulate(const GraphicsContextState& state, GraphicsContextState::StateChangeFlags flags) >+{ >+ m_state.accumulate(state, flags); >+} >+ >+static TextStream& operator<<(TextStream& ts, const SetState& state) >+{ >+ ts << state.state(); >+ return ts; >+} >+ >+void SetLineCap::apply(GraphicsContext& context) const >+{ >+ context.setLineCap(m_lineCap); >+} >+ >+static TextStream& operator<<(TextStream& ts, const SetLineCap& lineCap) >+{ >+ ts.dumpProperty("line-cap", lineCap.lineCap()); >+ return ts; >+} >+ >+void SetLineDash::apply(GraphicsContext& context) const >+{ >+ context.setLineDash(m_dashArray, m_dashOffset); >+} >+ >+static TextStream& operator<<(TextStream& ts, const SetLineDash& lineDash) >+{ >+ ts.dumpProperty("dash-array", lineDash.dashArray()); >+ ts.dumpProperty("dash-offset", lineDash.dashOffset()); >+ return ts; >+} >+ >+void SetLineJoin::apply(GraphicsContext& context) const >+{ >+ context.setLineJoin(m_lineJoin); >+} >+ >+static TextStream& operator<<(TextStream& ts, const SetLineJoin& lineJoin) >+{ >+ ts.dumpProperty("line-join", lineJoin.lineJoin()); >+ return ts; >+} >+ >+void SetMiterLimit::apply(GraphicsContext& context) const >+{ >+ context.setMiterLimit(m_miterLimit); >+} >+ >+static TextStream& operator<<(TextStream& ts, const SetMiterLimit& miterLimit) >+{ >+ ts.dumpProperty("mitre-limit", miterLimit.miterLimit()); >+ return ts; >+} >+ >+void ClearShadow::apply(GraphicsContext& context) const >+{ >+ context.clearShadow(); >+} >+ >+void Clip::apply(GraphicsContext& context) const >+{ >+ context.clip(m_rect); >+} >+ >+static TextStream& operator<<(TextStream& ts, const Clip& item) >+{ >+ ts.dumpProperty("rect", item.rect()); >+ return ts; >+} >+ >+void ClipOut::apply(GraphicsContext& context) const >+{ >+ context.clipOut(m_rect); >+} >+ >+static TextStream& operator<<(TextStream& ts, const ClipOut& item) >+{ >+ ts.dumpProperty("rect", item.rect()); >+ return ts; >+} >+ >+void ClipOutToPath::apply(GraphicsContext& context) const >+{ >+ context.clipOut(m_path); >+} >+ >+static TextStream& operator<<(TextStream& ts, const ClipOutToPath&) >+{ >+// ts.dumpProperty("path", item.path()); // FIXME: path logging. >+ return ts; >+} >+ >+void ClipPath::apply(GraphicsContext& context) const >+{ >+ context.clipPath(m_path, m_windRule); >+} >+ >+static TextStream& operator<<(TextStream& ts, const ClipPath& item) >+{ >+// ts.dumpProperty("path", item.path()); // FIXME: path logging. >+ ts.dumpProperty("wind-rule", item.windRule()); >+ return ts; >+} >+ >+ClipConvexPolygon::ClipConvexPolygon(size_t numberOfPoints, const FloatPoint* points, bool antialiased) >+ : Item(ItemType::ClipConvexPolygon) >+ , m_antialias(antialiased) >+{ >+ for (size_t i = 0; i < numberOfPoints; ++i) >+ m_points.append(points[i]); >+} >+ >+void ClipConvexPolygon::apply(GraphicsContext& context) const >+{ >+ context.clipConvexPolygon(m_points.size(), m_points.data(), m_antialias); >+} >+ >+static TextStream& operator<<(TextStream& ts, const ClipConvexPolygon& item) >+{ >+ ts.dumpProperty("points", item.points()); >+ ts.dumpProperty("antialias", item.antialias()); >+ return ts; >+} >+ >+DrawGlyphs::DrawGlyphs(const Font& font, const GlyphBufferGlyph* glyphs, const GlyphBufferAdvance* advances, unsigned count, const FloatPoint& blockLocation, const FloatSize& localAnchor, FontSmoothingMode smoothingMode) >+ : DrawingItem(ItemType::DrawGlyphs) >+ , m_font(const_cast<Font&>(font)) >+ , m_blockLocation(blockLocation) >+ , m_localAnchor(localAnchor) >+ , m_smoothingMode(smoothingMode) >+{ >+ m_glyphs.reserveInitialCapacity(count); >+ m_advances.reserveInitialCapacity(count); >+ for (unsigned i = 0; i < count; ++i) { >+ m_glyphs.uncheckedAppend(glyphs[i]); >+ m_advances.uncheckedAppend(advances[i]); >+ } >+ computeBounds(); >+} >+ >+inline GlyphBuffer DrawGlyphs::generateGlyphBuffer() const >+{ >+ GlyphBuffer result; >+ for (unsigned i = 0; i < m_glyphs.size(); ++i) >+ result.add(m_glyphs[i], &m_font.get(), m_advances[i]); >+ return result; >+} >+ >+void DrawGlyphs::apply(GraphicsContext&) const >+{ >+ // FIXME: implement. >+ UNUSED_PARAM(m_smoothingMode); >+} >+ >+void DrawGlyphs::computeBounds() >+{ >+ // FIXME: This code doesn't actually take the extents of the glyphs into consideration. It assumes that >+ // the glyph lies entirely within its (ascent+descent x advance) rect. >+ float ascent = m_font->fontMetrics().floatAscent(); >+ float descent = m_font->fontMetrics().floatDescent(); >+ FloatPoint current = toFloatPoint(localAnchor()); >+ for (size_t i = 0; i < m_glyphs.size(); ++i) { >+ GlyphBufferAdvance advance = m_advances[i]; >+ FloatRect glyphRect = FloatRect(current.x(), current.y() - ascent, advance.width(), ascent + descent); >+ m_bounds.unite(glyphRect); >+ >+ current += FloatSize(advance); >+ } >+} >+ >+Optional<FloatRect> DrawGlyphs::localBounds(const GraphicsContext&) const >+{ >+ FloatRect localBounds = m_bounds; >+ localBounds.move(m_blockLocation.x(), m_blockLocation.y()); >+ return localBounds; >+} >+ >+static TextStream& operator<<(TextStream& ts, const DrawGlyphs& item) >+{ >+ ts << static_cast<const DrawingItem&>(item); >+ // FIXME: dump more stuff. >+ ts.dumpProperty("block-location", item.blockLocation()); >+ ts.dumpProperty("local-anchor", item.localAnchor()); >+ ts.dumpProperty("anchor-point", item.anchorPoint()); >+ ts.dumpProperty("length", item.glyphs().size()); >+ >+ return ts; >+} >+ >+DrawImage::DrawImage(Image& image, const FloatRect& destination, const FloatRect& source, const ImagePaintingOptions& imagePaintingOptions) >+ : DrawingItem(ItemType::DrawImage) >+ , m_image(image) >+ , m_destination(destination) >+ , m_source(source) >+ , m_imagePaintingOptions(imagePaintingOptions) >+{ >+} >+ >+void DrawImage::apply(GraphicsContext& context) const >+{ >+ context.drawImage(m_image.get(), m_destination, m_source, m_imagePaintingOptions); >+} >+ >+static TextStream& operator<<(TextStream& ts, const DrawImage& item) >+{ >+ ts << static_cast<const DrawingItem&>(item); >+ ts.dumpProperty("image", item.image()); >+ ts.dumpProperty("source-rect", item.source()); >+ ts.dumpProperty("dest-rect", item.destination()); >+ return ts; >+} >+ >+DrawTiledImage::DrawTiledImage(Image& image, const FloatRect& destination, const FloatPoint& source, const FloatSize& tileSize, const FloatSize& spacing, const ImagePaintingOptions& imagePaintingOptions) >+ : DrawingItem(ItemType::DrawTiledImage) >+ , m_image(image) >+ , m_destination(destination) >+ , m_source(source) >+ , m_tileSize(tileSize) >+ , m_spacing(spacing) >+ , m_imagePaintingOptions(imagePaintingOptions) >+{ >+} >+ >+void DrawTiledImage::apply(GraphicsContext& context) const >+{ >+ context.drawTiledImage(m_image.get(), m_destination, m_source, m_tileSize, m_spacing, m_imagePaintingOptions); >+} >+ >+static TextStream& operator<<(TextStream& ts, const DrawTiledImage& item) >+{ >+ ts << static_cast<const DrawingItem&>(item); >+ ts.dumpProperty("image", item.image()); >+ ts.dumpProperty("source-point", item.source()); >+ ts.dumpProperty("dest-rect", item.destination()); >+ ts.dumpProperty("tile-size", item.tileSize()); >+ ts.dumpProperty("spacing", item.spacing()); >+ return ts; >+} >+ >+DrawTiledScaledImage::DrawTiledScaledImage(Image& image, const FloatRect& destination, const FloatRect& source, const FloatSize& tileScaleFactor, Image::TileRule hRule, Image::TileRule vRule, const ImagePaintingOptions& imagePaintingOptions) >+ : DrawingItem(ItemType::DrawTiledScaledImage) >+ , m_image(image) >+ , m_destination(destination) >+ , m_source(source) >+ , m_tileScaleFactor(tileScaleFactor) >+ , m_hRule(hRule) >+ , m_vRule(vRule) >+ , m_imagePaintingOptions(imagePaintingOptions) >+{ >+} >+ >+void DrawTiledScaledImage::apply(GraphicsContext& context) const >+{ >+ context.drawTiledImage(m_image.get(), m_destination, m_source, m_tileScaleFactor, m_hRule, m_vRule, m_imagePaintingOptions); >+} >+ >+static TextStream& operator<<(TextStream& ts, const DrawTiledScaledImage& item) >+{ >+ ts << static_cast<const DrawingItem&>(item); >+ ts.dumpProperty("image", item.image()); >+ ts.dumpProperty("source-rect", item.source()); >+ ts.dumpProperty("dest-rect", item.destination()); >+ return ts; >+} >+ >+DrawNativeImage::DrawNativeImage(PassNativeImagePtr imagePtr, const FloatSize& imageSize, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator op, BlendMode blendMode, ImageOrientation orientation) >+ : DrawingItem(ItemType::DrawNativeImage) >+ , m_imagePtr(imagePtr) >+ , m_imageSize(imageSize) >+ , m_destination(destRect) >+ , m_srcRect(srcRect) >+ , m_op(op) >+ , m_blendMode(blendMode) >+ , m_orientation(orientation) >+{ >+} >+ >+void DrawNativeImage::apply(GraphicsContext& context) const >+{ >+#if USE(CG) >+ auto imagePtr = m_imagePtr.get(); >+#endif >+ context.drawNativeImage(imagePtr, m_imageSize, m_destination, m_srcRect, m_op, m_blendMode, m_orientation); >+} >+ >+static TextStream& operator<<(TextStream& ts, const DrawNativeImage& item) >+{ >+ ts << static_cast<const DrawingItem&>(item); >+ // FIXME: dump more stuff. >+ ts.dumpProperty("source-rect", item.source()); >+ ts.dumpProperty("dest-rect", item.destination()); >+ return ts; >+} >+ >+DrawPattern::DrawPattern(Image& image, const FloatRect& tileRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, CompositeOperator op, const FloatRect& destRect, BlendMode blendMode) >+ : DrawingItem(ItemType::DrawPattern) >+ , m_image(image) >+ , m_patternTransform(patternTransform) >+ , m_tileRect(tileRect) >+ , m_destination(destRect) >+ , m_phase(phase) >+ , m_spacing(spacing) >+ , m_op(op) >+ , m_blendMode(blendMode) >+{ >+} >+ >+void DrawPattern::apply(GraphicsContext& context) const >+{ >+ context.drawPattern(m_image.get(), m_tileRect, m_patternTransform, m_phase, m_spacing, m_op, m_destination, m_blendMode); >+} >+ >+static TextStream& operator<<(TextStream& ts, const DrawPattern& item) >+{ >+ ts << static_cast<const DrawingItem&>(item); >+ ts.dumpProperty("image", item.image()); >+ ts.dumpProperty("pattern-transform", item.patternTransform()); >+ ts.dumpProperty("tile-rect", item.tileRect()); >+ ts.dumpProperty("dest-rect", item.destRect()); >+ ts.dumpProperty("phase", item.phase()); >+ ts.dumpProperty("spacing", item.spacing()); >+ return ts; >+} >+ >+void DrawRect::apply(GraphicsContext& context) const >+{ >+ context.drawRect(m_rect, m_borderThickness); >+} >+ >+static TextStream& operator<<(TextStream& ts, const DrawRect& item) >+{ >+ ts << static_cast<const DrawingItem&>(item); >+ ts.dumpProperty("rect", item.rect()); >+ ts.dumpProperty("border-thickness", item.borderThickness()); >+ return ts; >+} >+ >+Optional<FloatRect> DrawLine::localBounds(const GraphicsContext&) const >+{ >+ FloatRect bounds; >+ bounds.fitToPoints(m_point1, m_point2); >+ return bounds; >+} >+ >+void DrawLine::apply(GraphicsContext& context) const >+{ >+ context.drawLine(m_point1, m_point2); >+} >+ >+static TextStream& operator<<(TextStream& ts, const DrawLine& item) >+{ >+ ts << static_cast<const DrawingItem&>(item); >+ ts.dumpProperty("point-1", item.point1()); >+ ts.dumpProperty("point-2", item.point2()); >+ return ts; >+} >+ >+void DrawLinesForText::apply(GraphicsContext& context) const >+{ >+ context.drawLinesForText(point(), m_widths, m_printing, m_doubleLines); >+} >+ >+Optional<FloatRect> DrawLinesForText::localBounds(const GraphicsContext&) const >+{ >+ // This function needs to return a value equal to or enclosing what GraphicsContext::computeLineBoundsAndAntialiasingModeForText() returns. >+ >+ if (!m_widths.size()) >+ return FloatRect(); >+ >+ FloatRect result(point(), FloatSize(m_widths.last(), m_strokeWidth)); >+ result.inflate(1); // Account for pixel snapping. FIXME: This isn't perfect, as it doesn't take the CTM into account. >+ return result; >+} >+ >+static TextStream& operator<<(TextStream& ts, const DrawLinesForText& item) >+{ >+ ts << static_cast<const DrawingItem&>(item); >+ ts.dumpProperty("block-location", item.blockLocation()); >+ ts.dumpProperty("local-anchor", item.localAnchor()); >+ ts.dumpProperty("point", item.point()); >+ ts.dumpProperty("double", item.doubleLines()); >+ ts.dumpProperty("widths", item.widths()); >+ ts.dumpProperty("is-printing", item.isPrinting()); >+ ts.dumpProperty("double", item.doubleLines()); >+ return ts; >+} >+ >+void DrawLineForDocumentMarker::apply(GraphicsContext& context) const >+{ >+ context.drawLineForDocumentMarker(m_point, m_width, m_style); >+} >+ >+Optional<FloatRect> DrawLineForDocumentMarker::localBounds(const GraphicsContext&) const >+{ >+ // This function needs to return a value equal to or enclosing what GraphicsContext::drawLineForDocumentMarker() returns. >+ >+ FloatRect result(m_point, FloatSize(m_width, cMisspellingLineThickness)); >+ result.inflate(cMisspellingLineThickness); // Account for "misspelling dot" snapping. >+ return result; >+} >+ >+static TextStream& operator<<(TextStream& ts, const DrawLineForDocumentMarker& item) >+{ >+ ts << static_cast<const DrawingItem&>(item); >+ ts.dumpProperty("point", item.point()); >+ ts.dumpProperty("width", item.width()); >+ return ts; >+} >+ >+void DrawEllipse::apply(GraphicsContext& context) const >+{ >+ context.drawEllipse(m_rect); >+} >+ >+static TextStream& operator<<(TextStream& ts, const DrawEllipse& item) >+{ >+ ts.dumpProperty("rect", item.rect()); >+ return ts; >+} >+ >+// FIXME: share this code. >+void addConvexPolygonToPath(Path& path, size_t numPoints, const FloatPoint* points) >+{ >+ ASSERT(numPoints > 0); >+ >+ path.moveTo(points[0]); >+ for (size_t i = 1; i < numPoints; ++i) >+ path.addLineTo(points[i]); >+ path.closeSubpath(); >+} >+ >+DrawConvexPolygon::DrawConvexPolygon(size_t numberOfPoints, const FloatPoint* points, bool antialiased) >+ : DrawingItem(ItemType::DrawConvexPolygon) >+ , m_antialiased(antialiased) >+{ >+ for (size_t i = 0; i < numberOfPoints; ++i) >+ m_points.append(points[i]); >+} >+ >+Optional<FloatRect> DrawConvexPolygon::localBounds(const GraphicsContext&) const >+{ >+ FloatRect result; >+ for (auto& point : m_points) >+ result.extend(point); >+ result.inflate(m_antialiased ? 1 : 0); // Account for antialiasing >+ return result; >+} >+ >+void DrawConvexPolygon::apply(GraphicsContext& context) const >+{ >+ context.drawConvexPolygon(m_points.size(), m_points.data(), m_antialiased); >+} >+ >+static TextStream& operator<<(TextStream& ts, const DrawConvexPolygon& item) >+{ >+ ts << static_cast<const DrawingItem&>(item); >+ ts.dumpProperty("points", item.points()); >+ ts.dumpProperty("antialiased", item.antialiased()); >+ return ts; >+} >+ >+void DrawPath::apply(GraphicsContext& context) const >+{ >+ context.drawPath(m_path); >+} >+ >+static TextStream& operator<<(TextStream& ts, const DrawPath& item) >+{ >+ ts << static_cast<const DrawingItem&>(item); >+// ts.dumpProperty("path", item.path()); // FIXME: add logging for paths. >+ return ts; >+} >+ >+void DrawFocusRingPath::apply(GraphicsContext& context) const >+{ >+ context.drawFocusRing(m_path, m_width, m_offset, m_color); >+} >+ >+Optional<FloatRect> DrawFocusRingPath::localBounds(const GraphicsContext&) const >+{ >+ FloatRect result = m_path.fastBoundingRect(); >+ result.inflate(platformFocusRingWidth); >+ return result; >+} >+ >+static TextStream& operator<<(TextStream& ts, const DrawFocusRingPath& item) >+{ >+ ts << static_cast<const DrawingItem&>(item); >+// ts.dumpProperty("path", item.path()); // FIXME: add logging for paths. >+ ts.dumpProperty("width", item.width()); >+ ts.dumpProperty("offset", item.offset()); >+ ts.dumpProperty("color", item.color()); >+ return ts; >+} >+ >+void DrawFocusRingRects::apply(GraphicsContext& context) const >+{ >+ context.drawFocusRing(m_rects, m_width, m_offset, m_color); >+} >+ >+Optional<FloatRect> DrawFocusRingRects::localBounds(const GraphicsContext&) const >+{ >+ FloatRect result; >+ for (auto& rect : m_rects) >+ result.unite(rect); >+ result.inflate(platformFocusRingWidth); >+ return result; >+} >+ >+static TextStream& operator<<(TextStream& ts, const DrawFocusRingRects& item) >+{ >+ ts << static_cast<const DrawingItem&>(item); >+ ts.dumpProperty("rects", item.rects()); >+ ts.dumpProperty("width", item.width()); >+ ts.dumpProperty("offset", item.offset()); >+ ts.dumpProperty("color", item.color()); >+ return ts; >+} >+ >+void FillRect::apply(GraphicsContext& context) const >+{ >+ context.fillRect(m_rect); >+} >+ >+static TextStream& operator<<(TextStream& ts, const FillRect& item) >+{ >+ ts << static_cast<const DrawingItem&>(item); >+ ts.dumpProperty("rect", item.rect()); >+ return ts; >+} >+ >+void FillRectWithColor::apply(GraphicsContext& context) const >+{ >+ context.fillRect(m_rect, m_color); >+} >+ >+static TextStream& operator<<(TextStream& ts, const FillRectWithColor& item) >+{ >+ ts << static_cast<const DrawingItem&>(item); >+ ts.dumpProperty("rect", item.rect()); >+ ts.dumpProperty("color", item.color()); >+ return ts; >+} >+ >+void FillRectWithGradient::apply(GraphicsContext& context) const >+{ >+ context.fillRect(m_rect, m_gradient.get()); >+} >+ >+static TextStream& operator<<(TextStream& ts, const FillRectWithGradient& item) >+{ >+ ts << static_cast<const DrawingItem&>(item); >+ // FIXME: log gradient. >+ ts.dumpProperty("rect", item.rect()); >+ return ts; >+} >+ >+void FillCompositedRect::apply(GraphicsContext& context) const >+{ >+ context.fillRect(m_rect, m_color, m_op, m_blendMode); >+} >+ >+static TextStream& operator<<(TextStream& ts, const FillCompositedRect& item) >+{ >+ ts << static_cast<const DrawingItem&>(item); >+ ts.dumpProperty("rect", item.rect()); >+ ts.dumpProperty("color", item.color()); >+ ts.dumpProperty("composite-operation", item.compositeOperator()); >+ ts.dumpProperty("blend-mode", item.blendMode()); >+ return ts; >+} >+ >+void FillRoundedRect::apply(GraphicsContext& context) const >+{ >+ context.fillRoundedRect(m_rect, m_color, m_blendMode); >+} >+ >+static TextStream& operator<<(TextStream& ts, const FillRoundedRect& item) >+{ >+ ts << static_cast<const DrawingItem&>(item); >+ ts.dumpProperty("rect", item.roundedRect()); >+ ts.dumpProperty("color", item.color()); >+ ts.dumpProperty("blend-mode", item.blendMode()); >+ return ts; >+} >+ >+void FillRectWithRoundedHole::apply(GraphicsContext& context) const >+{ >+ context.fillRectWithRoundedHole(m_rect, m_roundedHoleRect, m_color); >+} >+ >+static TextStream& operator<<(TextStream& ts, const FillRectWithRoundedHole& item) >+{ >+ ts << static_cast<const DrawingItem&>(item); >+ ts.dumpProperty("rect", item.rect()); >+ ts.dumpProperty("rounded-hole-rect", item.roundedHoleRect()); >+ ts.dumpProperty("color", item.color()); >+ return ts; >+} >+ >+void FillPath::apply(GraphicsContext& context) const >+{ >+ context.fillPath(m_path); >+} >+ >+static TextStream& operator<<(TextStream& ts, const FillPath& item) >+{ >+ ts << static_cast<const DrawingItem&>(item); >+// ts.dumpProperty("path", item.path()); // FIXME: path logging. >+ return ts; >+} >+ >+void FillEllipse::apply(GraphicsContext& context) const >+{ >+ context.fillEllipse(m_rect); >+} >+ >+static TextStream& operator<<(TextStream& ts, const FillEllipse& item) >+{ >+ ts << static_cast<const DrawingItem&>(item); >+ ts.dumpProperty("rect", item.rect()); >+ return ts; >+} >+ >+Optional<FloatRect> StrokeRect::localBounds(const GraphicsContext&) const >+{ >+ FloatRect bounds = m_rect; >+ bounds.expand(m_lineWidth, m_lineWidth); >+ return bounds; >+} >+ >+void StrokeRect::apply(GraphicsContext& context) const >+{ >+ context.strokeRect(m_rect, m_lineWidth); >+} >+ >+static TextStream& operator<<(TextStream& ts, const StrokeRect& item) >+{ >+ ts << static_cast<const DrawingItem&>(item); >+ ts.dumpProperty("rect", item.rect()); >+ ts.dumpProperty("line-width", item.lineWidth()); >+ return ts; >+} >+ >+Optional<FloatRect> StrokePath::localBounds(const GraphicsContext& context) const >+{ >+ // FIXME: Need to take stroke thickness into account correctly, via CGPathByStrokingPath(). >+ float strokeThickness = context.strokeThickness(); >+ >+ FloatRect bounds = m_path.boundingRect(); >+ bounds.expand(strokeThickness, strokeThickness); >+ bounds.moveBy(m_blockLocation); >+ return bounds; >+} >+ >+void StrokePath::apply(GraphicsContext& context) const >+{ >+ FloatSize offset = toFloatSize(m_blockLocation); >+ m_path.translate(offset); >+ context.strokePath(m_path); >+ m_path.translate(-offset); >+} >+ >+static TextStream& operator<<(TextStream& ts, const StrokePath& item) >+{ >+ ts << static_cast<const DrawingItem&>(item); >+ ts.dumpProperty("block-location", item.blockLocation()); >+// ts.dumpProperty("path", item.path()); // FIXME: path logging. >+ return ts; >+} >+ >+Optional<FloatRect> StrokeEllipse::localBounds(const GraphicsContext& context) const >+{ >+ float strokeThickness = context.strokeThickness(); >+ >+ FloatRect bounds = m_rect; >+ bounds.expand(strokeThickness, strokeThickness); >+ return bounds; >+} >+ >+void StrokeEllipse::apply(GraphicsContext& context) const >+{ >+ context.strokeEllipse(m_rect); >+} >+ >+static TextStream& operator<<(TextStream& ts, const StrokeEllipse& item) >+{ >+ ts << static_cast<const DrawingItem&>(item); >+ ts.dumpProperty("rect", item.rect()); >+ return ts; >+} >+ >+void ClearRect::apply(GraphicsContext& context) const >+{ >+ context.clearRect(m_rect); >+} >+ >+static TextStream& operator<<(TextStream& ts, const ClearRect& item) >+{ >+ ts << static_cast<const DrawingItem&>(item); >+ ts.dumpProperty("rect", item.rect()); >+ return ts; >+} >+ >+void BeginTransparencyLayer::apply(GraphicsContext& context) const >+{ >+ context.beginTransparencyLayer(m_opacity); >+} >+ >+static TextStream& operator<<(TextStream& ts, const BeginTransparencyLayer& item) >+{ >+ ts << static_cast<const DrawingItem&>(item); >+ ts.dumpProperty("opacity", item.opacity()); >+ return ts; >+} >+ >+void EndTransparencyLayer::apply(GraphicsContext& context) const >+{ >+ context.endTransparencyLayer(); >+} >+ >+void ApplyStrokePattern::apply(GraphicsContext& context) const >+{ >+ context.applyStrokePattern(); >+} >+ >+void ApplyFillPattern::apply(GraphicsContext& context) const >+{ >+ context.applyFillPattern(); >+} >+ >+void ApplyDeviceScaleFactor::apply(GraphicsContext& context) const >+{ >+ context.applyDeviceScaleFactor(m_scaleFactor); >+} >+ >+static TextStream& operator<<(TextStream& ts, const ApplyDeviceScaleFactor& item) >+{ >+ ts.dumpProperty("scale-factor", item.scaleFactor()); >+ return ts; >+} >+ >+static TextStream& operator<<(TextStream& ts, const ItemType& type) >+{ >+ switch (type) { >+ case ItemType::Save: ts << "save"; break; >+ case ItemType::Restore: ts << "restore"; break; >+ case ItemType::Translate: ts << "translate"; break; >+ case ItemType::Rotate: ts << "rotate"; break; >+ case ItemType::Scale: ts << "scale"; break; >+ case ItemType::ConcatenateCTM: ts << "concatentate-ctm"; break; >+ case ItemType::SetState: ts << "set-state"; break; >+ case ItemType::SetLineCap: ts << "set-line-cap"; break; >+ case ItemType::SetLineDash: ts << "set-line-dash"; break; >+ case ItemType::SetLineJoin: ts << "set-line-join"; break; >+ case ItemType::SetMiterLimit: ts << "set-miter-limit"; break; >+ case ItemType::Clip: ts << "clip"; break; >+ case ItemType::ClipOut: ts << "clip-out"; break; >+ case ItemType::ClipOutToPath: ts << "clip-out-to-path"; break; >+ case ItemType::ClipPath: ts << "clip-path"; break; >+ case ItemType::ClipConvexPolygon: ts << "clip-convex-polygon"; break; >+ case ItemType::DrawGlyphs: ts << "draw-glyphs"; break; >+ case ItemType::DrawImage: ts << "draw-image"; break; >+ case ItemType::DrawTiledImage: ts << "draw-tiled-image"; break; >+ case ItemType::DrawTiledScaledImage: ts << "draw-tiled-scaled-image"; break; >+ case ItemType::DrawNativeImage: ts << "draw-native-image"; break; >+ case ItemType::DrawPattern: ts << "draw-pattern"; break; >+ case ItemType::DrawRect: ts << "draw-rect"; break; >+ case ItemType::DrawLine: ts << "draw-line"; break; >+ case ItemType::DrawLinesForText: ts << "draw-lines-for-text"; break; >+ case ItemType::DrawLineForDocumentMarker: ts << "draw-lines-for-document-marker"; break; >+ case ItemType::DrawEllipse: ts << "draw-ellipse"; break; >+ case ItemType::DrawConvexPolygon: ts << "draw-convex-polgon"; break; >+ case ItemType::DrawPath: ts << "draw-path"; break; >+ case ItemType::DrawFocusRingPath: ts << "draw-focus-ring-path"; break; >+ case ItemType::DrawFocusRingRects: ts << "draw-focus-ring-rects"; break; >+ case ItemType::FillRect: ts << "fill-rect"; break; >+ case ItemType::FillRectWithColor: ts << "fill-rect-with-color"; break; >+ case ItemType::FillRectWithGradient: ts << "fill-rect-with-gradient"; break; >+ case ItemType::FillCompositedRect: ts << "fill-composited-rect"; break; >+ case ItemType::FillRoundedRect: ts << "fill-rounded-rect"; break; >+ case ItemType::FillRectWithRoundedHole: ts << "fill-rect-with-rounded-hole"; break; >+ case ItemType::FillPath: ts << "fill-path"; break; >+ case ItemType::FillEllipse: ts << "fill-ellipse"; break; >+ case ItemType::StrokeRect: ts << "stroke-rect"; break; >+ case ItemType::StrokePath: ts << "stroke-path"; break; >+ case ItemType::StrokeEllipse: ts << "stroke-ellipse"; break; >+ case ItemType::ClearRect: ts << "clear-rect"; break; >+ case ItemType::BeginTransparencyLayer: ts << "begin-transparency-layer"; break; >+ case ItemType::EndTransparencyLayer: ts << "end-transparency-layer"; break; >+ case ItemType::ApplyStrokePattern: ts << "apply-stroke-pattern"; break; >+ case ItemType::ApplyFillPattern: ts << "apply-fill-pattern"; break; >+ case ItemType::ApplyDeviceScaleFactor: ts << "apply-device-scale-factor"; break; >+ case ItemType::ClearShadow: ts << "clear-shadow"; break; >+ } >+ return ts; >+} >+ >+TextStream& operator<<(TextStream& ts, const Item& item) >+{ >+ TextStream::GroupScope group(ts); >+ ts << item.type(); >+ >+ // FIXME: Make a macro which takes a macro for all these enumeration switches >+ switch (item.type()) { >+ case ItemType::Save: >+ ts << downcast<Save>(item); >+ break; >+ case ItemType::Translate: >+ ts << downcast<Translate>(item); >+ break; >+ case ItemType::Rotate: >+ ts << downcast<Rotate>(item); >+ break; >+ case ItemType::Scale: >+ ts << downcast<Scale>(item); >+ break; >+ case ItemType::ConcatenateCTM: >+ ts << downcast<ConcatenateCTM>(item); >+ break; >+ case ItemType::SetState: >+ ts << downcast<SetState>(item); >+ break; >+ case ItemType::SetLineCap: >+ ts << downcast<SetLineCap>(item); >+ break; >+ case ItemType::SetLineDash: >+ ts << downcast<SetLineDash>(item); >+ break; >+ case ItemType::SetLineJoin: >+ ts << downcast<SetLineJoin>(item); >+ break; >+ case ItemType::SetMiterLimit: >+ ts << downcast<SetMiterLimit>(item); >+ break; >+ case ItemType::Clip: >+ ts << downcast<Clip>(item); >+ break; >+ case ItemType::ClipOut: >+ ts << downcast<ClipOut>(item); >+ break; >+ case ItemType::ClipOutToPath: >+ ts << downcast<ClipOutToPath>(item); >+ break; >+ case ItemType::ClipPath: >+ ts << downcast<ClipPath>(item); >+ break; >+ case ItemType::ClipConvexPolygon: >+ ts << downcast<ClipConvexPolygon>(item); >+ break; >+ case ItemType::DrawGlyphs: >+ ts << downcast<DrawGlyphs>(item); >+ break; >+ case ItemType::DrawImage: >+ ts << downcast<DrawImage>(item); >+ break; >+ case ItemType::DrawTiledImage: >+ ts << downcast<DrawTiledImage>(item); >+ break; >+ case ItemType::DrawTiledScaledImage: >+ ts << downcast<DrawTiledScaledImage>(item); >+ break; >+ case ItemType::DrawNativeImage: >+ ts << downcast<DrawNativeImage>(item); >+ break; >+ case ItemType::DrawPattern: >+ ts << downcast<DrawPattern>(item); >+ break; >+ case ItemType::DrawRect: >+ ts << downcast<DrawRect>(item); >+ break; >+ case ItemType::DrawLine: >+ ts << downcast<DrawLine>(item); >+ break; >+ case ItemType::DrawLinesForText: >+ ts << downcast<DrawLinesForText>(item); >+ break; >+ case ItemType::DrawLineForDocumentMarker: >+ ts << downcast<DrawLineForDocumentMarker>(item); >+ break; >+ case ItemType::DrawEllipse: >+ ts << downcast<DrawEllipse>(item); >+ break; >+ case ItemType::DrawConvexPolygon: >+ ts << downcast<DrawConvexPolygon>(item); >+ break; >+ case ItemType::DrawPath: >+ ts << downcast<DrawPath>(item); >+ break; >+ case ItemType::DrawFocusRingPath: >+ ts << downcast<DrawFocusRingPath>(item); >+ break; >+ case ItemType::DrawFocusRingRects: >+ ts << downcast<DrawFocusRingRects>(item); >+ break; >+ case ItemType::FillRect: >+ ts << downcast<FillRect>(item); >+ break; >+ case ItemType::FillRectWithColor: >+ ts << downcast<FillRectWithColor>(item); >+ break; >+ case ItemType::FillRectWithGradient: >+ ts << downcast<FillRectWithGradient>(item); >+ break; >+ case ItemType::FillCompositedRect: >+ ts << downcast<FillCompositedRect>(item); >+ break; >+ case ItemType::FillRoundedRect: >+ ts << downcast<FillRoundedRect>(item); >+ break; >+ case ItemType::FillRectWithRoundedHole: >+ ts << downcast<FillRectWithRoundedHole>(item); >+ break; >+ case ItemType::FillPath: >+ ts << downcast<FillPath>(item); >+ break; >+ case ItemType::FillEllipse: >+ ts << downcast<FillEllipse>(item); >+ break; >+ case ItemType::StrokeRect: >+ ts << downcast<StrokeRect>(item); >+ break; >+ case ItemType::StrokePath: >+ ts << downcast<StrokePath>(item); >+ break; >+ case ItemType::StrokeEllipse: >+ ts << downcast<StrokeEllipse>(item); >+ break; >+ case ItemType::ClearRect: >+ ts << downcast<ClearRect>(item); >+ break; >+ case ItemType::BeginTransparencyLayer: >+ ts << downcast<BeginTransparencyLayer>(item); >+ break; >+ case ItemType::ApplyDeviceScaleFactor: >+ ts << downcast<ApplyDeviceScaleFactor>(item); >+ break; >+ >+ // Items with no additional data. >+ case ItemType::Restore: >+ case ItemType::EndTransparencyLayer: >+ case ItemType::ApplyStrokePattern: >+ case ItemType::ApplyFillPattern: >+ case ItemType::ClearShadow: >+ break; >+ } >+ return ts; >+} >+ >+} >+} >diff --git a/Source/WebCore/platform/graphics/displaylists/DisplayListItems.h b/Source/WebCore/platform/graphics/displaylists/DisplayListItems.h >new file mode 100644 >index 0000000000000000000000000000000000000000..ace2dc3d207a5dac9c472ea790021c47a0926086 >--- /dev/null >+++ b/Source/WebCore/platform/graphics/displaylists/DisplayListItems.h >@@ -0,0 +1,1422 @@ >+/* >+ * Copyright (C) 2015 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. >+ */ >+ >+#ifndef DisplayListItems_h >+#define DisplayListItems_h >+ >+#include "FloatPoint.h" >+#include "FloatRect.h" >+#include "FloatRoundedRect.h" >+#include "Font.h" >+#include "GlyphBuffer.h" >+#include "GraphicsContext.h" >+#include "Image.h" >+#include <wtf/RefCounted.h> >+#include <wtf/TypeCasts.h> >+ >+#if USE(CG) >+#include "GraphicsContextPlatformPrivateCG.h" >+#endif >+ >+namespace WebCore { >+ >+class TextStream; >+struct ImagePaintingOptions; >+ >+namespace DisplayList { >+ >+enum class ItemType { >+ Save, >+ Restore, >+ Translate, >+ Rotate, >+ Scale, >+ ConcatenateCTM, >+ SetState, >+ SetLineCap, >+ SetLineDash, >+ SetLineJoin, >+ SetMiterLimit, >+ ClearShadow, >+ Clip, >+ ClipOut, >+ ClipOutToPath, >+ ClipPath, >+ ClipConvexPolygon, >+ DrawGlyphs, >+ DrawImage, >+ DrawTiledImage, >+ DrawTiledScaledImage, >+ DrawNativeImage, >+ DrawPattern, >+ DrawRect, >+ DrawLine, >+ DrawLinesForText, >+ DrawLineForDocumentMarker, >+ DrawEllipse, >+ DrawConvexPolygon, >+ DrawPath, >+ DrawFocusRingPath, >+ DrawFocusRingRects, >+ FillRect, >+ FillRectWithColor, >+ FillRectWithGradient, >+ FillCompositedRect, >+ FillRoundedRect, >+ FillRectWithRoundedHole, >+ FillPath, >+ FillEllipse, >+ StrokeRect, >+ StrokePath, >+ StrokeEllipse, >+ ClearRect, >+ BeginTransparencyLayer, >+ EndTransparencyLayer, >+ ApplyStrokePattern, // FIXME: should not be a recorded item. >+ ApplyFillPattern, // FIXME: should not be a recorded item. >+ ApplyDeviceScaleFactor, >+}; >+ >+class Item : public RefCounted<Item> { >+public: >+ Item() = delete; >+ >+ Item(ItemType type) >+ : m_type(type) >+ { >+ } >+ >+ virtual ~Item() { } >+ >+ ItemType type() const >+ { >+ return m_type; >+ } >+ >+ virtual void apply(GraphicsContext&) const = 0; >+ >+ static constexpr bool isDisplayListItem = true; >+ >+ virtual bool isDrawingItem() const { return false; } >+ >+ // A state item is one preserved by Save/Restore. >+ bool isStateItem() const >+ { >+ return isStateItemType(m_type); >+ } >+ >+ static bool isStateItemType(ItemType itemType) >+ { >+ switch (itemType) { >+ case ItemType:: Translate: >+ case ItemType:: Rotate: >+ case ItemType:: Scale: >+ case ItemType:: ConcatenateCTM: >+ case ItemType:: SetState: >+ case ItemType:: SetLineCap: >+ case ItemType:: SetLineDash: >+ case ItemType:: SetLineJoin: >+ case ItemType:: SetMiterLimit: >+ case ItemType:: ClearShadow: >+ return true; >+ default: >+ return false; >+ } >+ return false; >+ } >+ >+#if !defined(NDEBUG) || !LOG_DISABLED >+ WTF::CString description() const; >+#endif >+ >+private: >+ ItemType m_type; >+}; >+ >+class DrawingItem : public Item { >+public: >+ DrawingItem(ItemType type) >+ : Item(type) >+ { >+ } >+ >+ void setExtent(const FloatRect& r) { m_extent = r; } >+ const FloatRect& extent() const { return m_extent.value(); } >+ >+ bool extentKnown() const { return static_cast<bool>(m_extent); } >+ >+ // Return bounds of this drawing operation in local coordinates. >+ // Does not include effets of transform, shadow etc in the state. >+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const { return Nullopt; } >+ >+private: >+ virtual bool isDrawingItem() const { return true; } >+ >+ Optional<FloatRect> m_extent; // In base coordinates, taking shadows and transforms into account. >+}; >+ >+class Save : public Item { >+public: >+ static Ref<Save> create() >+ { >+ return adoptRef(*new Save); >+ } >+ >+ // Index in the display list of the corresponding Restore item. 0 if unmatched. >+ size_t restoreIndex() const { return m_restoreIndex; } >+ void setRestoreIndex(size_t index) { m_restoreIndex = index; } >+ >+private: >+ Save() >+ : Item(ItemType::Save) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+ >+ size_t m_restoreIndex { 0 }; >+}; >+ >+class Restore : public Item { >+public: >+ static Ref<Restore> create() >+ { >+ return adoptRef(*new Restore); >+ } >+ >+private: >+ Restore() >+ : Item(ItemType::Restore) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+}; >+ >+class Translate : public Item { >+public: >+ static Ref<Translate> create(float x, float y) >+ { >+ return adoptRef(*new Translate(x, y)); >+ } >+ >+ float x() const { return m_x; } >+ float y() const { return m_y; } >+ >+private: >+ Translate(float x, float y) >+ : Item(ItemType::Translate) >+ , m_x(x) >+ , m_y(y) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+ >+ float m_x; >+ float m_y; >+}; >+ >+class Rotate : public Item { >+public: >+ static Ref<Rotate> create(float angleInRadians) >+ { >+ return adoptRef(*new Rotate(angleInRadians)); >+ } >+ >+ float angle() const { return m_angle; } >+ >+private: >+ Rotate(float angle) >+ : Item(ItemType::Rotate) >+ , m_angle(angle) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+ >+ float m_angle; // In radians. >+}; >+ >+class Scale : public Item { >+public: >+ static Ref<Scale> create(const FloatSize& size) >+ { >+ return adoptRef(*new Scale(size)); >+ } >+ >+ const FloatSize& amount() const { return m_size; } >+ >+private: >+ Scale(const FloatSize& size) >+ : Item(ItemType::Scale) >+ , m_size(size) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+ >+ FloatSize m_size; >+}; >+ >+class ConcatenateCTM : public Item { >+public: >+ static Ref<ConcatenateCTM> create(const AffineTransform& matrix) >+ { >+ return adoptRef(*new ConcatenateCTM(matrix)); >+ } >+ >+ const AffineTransform& transform() const { return m_transform; } >+ >+private: >+ ConcatenateCTM(const AffineTransform&); >+ >+ virtual void apply(GraphicsContext&) const override; >+ >+ AffineTransform m_transform; >+}; >+ >+class SetState : public Item { >+public: >+ static Ref<SetState> create(const GraphicsContextState& state, GraphicsContextState::StateChangeFlags flags) >+ { >+ return adoptRef(*new SetState(state, flags)); >+ } >+ >+ const GraphicsContextStateChange& state() const { return m_state; } >+ >+ void accumulate(const GraphicsContextState&, GraphicsContextState::StateChangeFlags); >+ >+ void accumulate(GraphicsContextState&) const; >+ >+ static void applyState(GraphicsContext&, const GraphicsContextState&, GraphicsContextState::StateChangeFlags); >+ >+ static void dumpStateChanges(TextStream&, const GraphicsContextState&, GraphicsContextState::StateChangeFlags); >+private: >+ SetState(const GraphicsContextState& state, GraphicsContextState::StateChangeFlags flags) >+ : Item(ItemType::SetState) >+ , m_state(state, flags) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+ >+ GraphicsContextStateChange m_state; >+}; >+ >+class SetLineCap : public Item { >+public: >+ static Ref<SetLineCap> create(LineCap lineCap) >+ { >+ return adoptRef(*new SetLineCap(lineCap)); >+ } >+ >+ LineCap lineCap() const { return m_lineCap; } >+ >+private: >+ SetLineCap(LineCap lineCap) >+ : Item(ItemType::SetLineCap) >+ , m_lineCap(lineCap) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+ >+ LineCap m_lineCap; >+}; >+ >+class SetLineDash : public Item { >+public: >+ static Ref<SetLineDash> create(const DashArray& dashArray, float dashOffset) >+ { >+ return adoptRef(*new SetLineDash(dashArray, dashOffset)); >+ } >+ >+ const DashArray& dashArray() const { return m_dashArray; } >+ float dashOffset() const { return m_dashOffset; } >+ >+private: >+ SetLineDash(const DashArray& dashArray, float dashOffset) >+ : Item(ItemType::SetLineDash) >+ , m_dashArray(dashArray) >+ , m_dashOffset(dashOffset) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+ >+ DashArray m_dashArray; >+ float m_dashOffset; >+}; >+ >+class SetLineJoin : public Item { >+public: >+ static Ref<SetLineJoin> create(LineJoin lineJoin) >+ { >+ return adoptRef(*new SetLineJoin(lineJoin)); >+ } >+ >+ LineJoin lineJoin() const { return m_lineJoin; } >+ >+private: >+ SetLineJoin(LineJoin lineJoin) >+ : Item(ItemType::SetLineJoin) >+ , m_lineJoin(lineJoin) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+ >+ LineJoin m_lineJoin; >+}; >+ >+class SetMiterLimit : public Item { >+public: >+ static Ref<SetMiterLimit> create(float limit) >+ { >+ return adoptRef(*new SetMiterLimit(limit)); >+ } >+ >+ float miterLimit() const { return m_miterLimit; } >+ >+private: >+ SetMiterLimit(float miterLimit) >+ : Item(ItemType::SetMiterLimit) >+ , m_miterLimit(miterLimit) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+ >+ float m_miterLimit; >+}; >+ >+class ClearShadow : public Item { >+public: >+ static Ref<ClearShadow> create() >+ { >+ return adoptRef(*new ClearShadow); >+ } >+ >+private: >+ ClearShadow() >+ : Item(ItemType::ClearShadow) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+}; >+ >+// FIXME: treat as DrawingItem? >+class Clip : public Item { >+public: >+ static Ref<Clip> create(const FloatRect& rect) >+ { >+ return adoptRef(*new Clip(rect)); >+ } >+ >+ FloatRect rect() const { return m_rect; } >+ >+private: >+ Clip(const FloatRect& rect) >+ : Item(ItemType::Clip) >+ , m_rect(rect) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+ >+ FloatRect m_rect; >+}; >+ >+class ClipOut : public Item { >+public: >+ static Ref<ClipOut> create(const FloatRect& rect) >+ { >+ return adoptRef(*new ClipOut(rect)); >+ } >+ >+ FloatRect rect() const { return m_rect; } >+ >+private: >+ ClipOut(const FloatRect& rect) >+ : Item(ItemType::ClipOut) >+ , m_rect(rect) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+ >+ FloatRect m_rect; >+}; >+ >+class ClipOutToPath : public Item { >+public: >+ static Ref<ClipOutToPath> create(const Path& path) >+ { >+ return adoptRef(*new ClipOutToPath(path)); >+ } >+ >+ const Path& path() const { return m_path; } >+ >+private: >+ ClipOutToPath(const Path& path) >+ : Item(ItemType::ClipOutToPath) >+ , m_path(path) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+ >+ Path m_path; >+}; >+ >+class ClipPath : public Item { >+public: >+ static Ref<ClipPath> create(const Path& path, WindRule windRule) >+ { >+ return adoptRef(*new ClipPath(path, windRule)); >+ } >+ >+ const Path& path() const { return m_path; } >+ WindRule windRule() const { return m_windRule; } >+ >+private: >+ ClipPath(const Path& path, WindRule windRule) >+ : Item(ItemType::ClipPath) >+ , m_path(path) >+ , m_windRule(windRule) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+ >+ Path m_path; >+ WindRule m_windRule; >+}; >+ >+class ClipConvexPolygon : public Item { >+public: >+ static Ref<ClipConvexPolygon> create(size_t numberOfPoints, const FloatPoint* points, bool antialiased) >+ { >+ return adoptRef(*new ClipConvexPolygon(numberOfPoints, points, antialiased)); >+ } >+ >+ const Vector<FloatPoint>& points() const { return m_points; } >+ bool antialias() const { return m_antialias; } >+ >+private: >+ ClipConvexPolygon(size_t numberOfPoints, const FloatPoint*, bool antialiased); >+ >+ virtual void apply(GraphicsContext&) const override; >+ >+ Vector<FloatPoint> m_points; >+ bool m_antialias; >+}; >+ >+class DrawGlyphs : public DrawingItem { >+public: >+ static Ref<DrawGlyphs> create(const Font& font, const GlyphBufferGlyph* glyphs, const GlyphBufferAdvance* advances, unsigned count, const FloatPoint& blockLocation, const FloatSize& localAnchor, FontSmoothingMode smoothingMode) >+ { >+ return adoptRef(*new DrawGlyphs(font, glyphs, advances, count, blockLocation, localAnchor, smoothingMode)); >+ } >+ >+ const FloatPoint& blockLocation() const { return m_blockLocation; } >+ void setBlockLocation(const FloatPoint& blockLocation) { m_blockLocation = blockLocation; } >+ >+ const FloatSize& localAnchor() const { return m_localAnchor; } >+ >+ FloatPoint anchorPoint() const { return m_blockLocation + m_localAnchor; } >+ >+ const Vector<GlyphBufferGlyph, 128>& glyphs() const { return m_glyphs; } >+ >+private: >+ DrawGlyphs(const Font&, const GlyphBufferGlyph*, const GlyphBufferAdvance*, unsigned count, const FloatPoint& blockLocation, const FloatSize& localAnchor, FontSmoothingMode); >+ >+ void computeBounds(); >+ >+ virtual void apply(GraphicsContext&) const override; >+ >+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override; >+ >+ GlyphBuffer generateGlyphBuffer() const; >+ >+ Ref<Font> m_font; >+ Vector<GlyphBufferGlyph, 128> m_glyphs; >+ Vector<GlyphBufferAdvance, 128> m_advances; >+ FloatRect m_bounds; >+ FloatPoint m_blockLocation; >+ FloatSize m_localAnchor; >+ FontSmoothingMode m_smoothingMode; >+}; >+ >+class DrawImage : public DrawingItem { >+public: >+ static Ref<DrawImage> create(Image& image, const FloatRect& destination, const FloatRect& source, const ImagePaintingOptions& imagePaintingOptions) >+ { >+ return adoptRef(*new DrawImage(image, destination, source, imagePaintingOptions)); >+ } >+ >+ const Image& image() const { return m_image.get(); } >+ FloatRect source() const { return m_source; } >+ FloatRect destination() const { return m_destination; } >+ >+private: >+ DrawImage(Image&, const FloatRect& destination, const FloatRect& source, const ImagePaintingOptions&); >+ >+ virtual void apply(GraphicsContext&) const override; >+ >+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_destination; } >+ >+ mutable Ref<Image> m_image; // FIXME: Drawing images can cause their animations to progress. This shouldn't have to be mutable. >+ FloatRect m_destination; >+ FloatRect m_source; >+ ImagePaintingOptions m_imagePaintingOptions; >+}; >+ >+class DrawTiledImage : public DrawingItem { >+public: >+ static Ref<DrawTiledImage> create(Image& image, const FloatRect& destination, const FloatPoint& source, const FloatSize& tileSize, const FloatSize& spacing, const ImagePaintingOptions& imagePaintingOptions) >+ { >+ return adoptRef(*new DrawTiledImage(image, destination, source, tileSize, spacing, imagePaintingOptions)); >+ } >+ >+ const Image& image() const { return m_image.get(); } >+ FloatPoint source() const { return m_source; } >+ FloatRect destination() const { return m_destination; } >+ >+ FloatSize tileSize() const { return m_tileSize; } >+ FloatSize spacing() const { return m_spacing; } >+ >+private: >+ DrawTiledImage(Image&, const FloatRect& destination, const FloatPoint& source, const FloatSize& tileSize, const FloatSize& spacing, const ImagePaintingOptions&); >+ >+ virtual void apply(GraphicsContext&) const override; >+ >+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_destination; } >+ >+ mutable Ref<Image> m_image; // FIXME: Drawing images can cause their animations to progress. This shouldn't have to be mutable. >+ FloatRect m_destination; >+ FloatPoint m_source; >+ FloatSize m_tileSize; >+ FloatSize m_spacing; >+ ImagePaintingOptions m_imagePaintingOptions; >+}; >+ >+class DrawTiledScaledImage : public DrawingItem { >+public: >+ static Ref<DrawTiledScaledImage> create(Image& image, const FloatRect& destination, const FloatRect& source, const FloatSize& tileScaleFactor, Image::TileRule hRule, Image::TileRule vRule, const ImagePaintingOptions& imagePaintingOptions) >+ { >+ return adoptRef(*new DrawTiledScaledImage(image, destination, source, tileScaleFactor, hRule, vRule, imagePaintingOptions)); >+ } >+ >+ const Image& image() const { return m_image.get(); } >+ FloatRect source() const { return m_source; } >+ FloatRect destination() const { return m_destination; } >+ >+private: >+ DrawTiledScaledImage(Image&, const FloatRect& destination, const FloatRect& source, const FloatSize& tileScaleFactor, Image::TileRule hRule, Image::TileRule vRule, const ImagePaintingOptions&); >+ >+ virtual void apply(GraphicsContext&) const override; >+ >+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_destination; } >+ >+ mutable Ref<Image> m_image; // FIXME: Drawing images can cause their animations to progress. This shouldn't have to be mutable. >+ FloatRect m_destination; >+ FloatRect m_source; >+ FloatSize m_tileScaleFactor; >+ Image::TileRule m_hRule; >+ Image::TileRule m_vRule; >+ ImagePaintingOptions m_imagePaintingOptions; >+}; >+ >+class DrawNativeImage : public DrawingItem { >+public: >+ static Ref<DrawNativeImage> create(PassNativeImagePtr imagePtr, const FloatSize& imageSize, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator op, BlendMode blendMode, ImageOrientation orientation) >+ { >+ return adoptRef(*new DrawNativeImage(imagePtr, imageSize, destRect, srcRect, op, blendMode, orientation)); >+ } >+ >+ FloatRect source() const { return m_srcRect; } >+ FloatRect destination() const { return m_destination; } >+ >+private: >+ DrawNativeImage(PassNativeImagePtr, const FloatSize& selfSize, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator, BlendMode, ImageOrientation); >+ >+ virtual void apply(GraphicsContext&) const override; >+ >+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_destination; } >+ >+#if USE(CG) >+ RetainPtr<CGImageRef> m_imagePtr; >+#endif >+ FloatSize m_imageSize; >+ FloatRect m_destination; >+ FloatRect m_srcRect; >+ CompositeOperator m_op; >+ BlendMode m_blendMode; >+ ImageOrientation m_orientation; >+}; >+ >+class DrawPattern : public DrawingItem { >+public: >+ static Ref<DrawPattern> create(Image& image, const FloatRect& tileRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, CompositeOperator op, const FloatRect& destRect, BlendMode blendMode) >+ { >+ return adoptRef(*new DrawPattern(image, tileRect, patternTransform, phase, spacing, op, destRect, blendMode)); >+ } >+ >+ const Image& image() const { return m_image.get(); } >+ const AffineTransform& patternTransform() const { return m_patternTransform; } >+ FloatRect tileRect() const { return m_tileRect; } >+ FloatRect destRect() const { return m_destination; } >+ FloatPoint phase() const { return m_phase; } >+ FloatSize spacing() const { return m_spacing; } >+ >+private: >+ DrawPattern(Image&, const FloatRect& srcRect, const AffineTransform&, const FloatPoint& phase, const FloatSize& spacing, CompositeOperator, const FloatRect& destRect, BlendMode = BlendModeNormal); >+ >+ virtual void apply(GraphicsContext&) const override; >+ >+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_destination; } >+ >+ mutable Ref<Image> m_image; // FIXME: Drawing images can cause their animations to progress. This shouldn't have to be mutable. >+ AffineTransform m_patternTransform; >+ FloatRect m_tileRect; >+ FloatRect m_destination; >+ FloatPoint m_phase; >+ FloatSize m_spacing; >+ CompositeOperator m_op; >+ BlendMode m_blendMode; >+}; >+ >+// Is DrawingItem because the size of the transparency layer is implicitly the clip bounds. >+class BeginTransparencyLayer : public DrawingItem { >+public: >+ static Ref<BeginTransparencyLayer> create(float opacity) >+ { >+ return adoptRef(*new BeginTransparencyLayer(opacity)); >+ } >+ >+ float opacity() const { return m_opacity; } >+ >+private: >+ BeginTransparencyLayer(float opacity) >+ : DrawingItem(ItemType::BeginTransparencyLayer) >+ , m_opacity(opacity) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+ >+ float m_opacity; >+}; >+ >+class EndTransparencyLayer : public DrawingItem { >+public: >+ static Ref<EndTransparencyLayer> create() >+ { >+ return adoptRef(*new EndTransparencyLayer); >+ } >+ >+private: >+ EndTransparencyLayer() >+ : DrawingItem(ItemType::EndTransparencyLayer) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+}; >+ >+class DrawRect : public DrawingItem { >+public: >+ static Ref<DrawRect> create(const FloatRect& rect, float borderThickness) >+ { >+ return adoptRef(*new DrawRect(rect, borderThickness)); >+ } >+ >+ FloatRect rect() const { return m_rect; } >+ float borderThickness() const { return m_borderThickness; } >+ >+private: >+ DrawRect(const FloatRect& rect, float borderThickness) >+ : DrawingItem(ItemType::DrawRect) >+ , m_rect(rect) >+ , m_borderThickness(borderThickness) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_rect; } >+ >+ FloatRect m_rect; >+ float m_borderThickness; >+}; >+ >+class DrawLine : public DrawingItem { >+public: >+ static Ref<DrawLine> create(const FloatPoint& point1, const FloatPoint& point2) >+ { >+ return adoptRef(*new DrawLine(point1, point2)); >+ } >+ >+ FloatPoint point1() const { return m_point1; } >+ FloatPoint point2() const { return m_point2; } >+ >+private: >+ DrawLine(const FloatPoint& point1, const FloatPoint& point2) >+ : DrawingItem(ItemType::DrawLine) >+ , m_point1(point1) >+ , m_point2(point2) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override; >+ >+ FloatPoint m_point1; >+ FloatPoint m_point2; >+}; >+ >+class DrawLinesForText : public DrawingItem { >+public: >+ static Ref<DrawLinesForText> create(const FloatPoint& blockLocation, const FloatSize& localAnchor, const DashArray& widths, bool printing, bool doubleLines, float strokeWidth) >+ { >+ return adoptRef(*new DrawLinesForText(blockLocation, localAnchor, widths, printing, doubleLines, strokeWidth)); >+ } >+ >+ void setBlockLocation(const FloatPoint& blockLocation) { m_blockLocation = blockLocation; } >+ const FloatPoint& blockLocation() const { return m_blockLocation; } >+ const FloatSize& localAnchor() const { return m_localAnchor; } >+ FloatPoint point() const { return m_blockLocation + m_localAnchor; } >+ const DashArray& widths() const { return m_widths; } >+ bool isPrinting() const { return m_printing; } >+ bool doubleLines() const { return m_doubleLines; } >+ >+private: >+ DrawLinesForText(const FloatPoint& blockLocation, const FloatSize& localAnchor, const DashArray& widths, bool printing, bool doubleLines, float strokeWidth) >+ : DrawingItem(ItemType::DrawLinesForText) >+ , m_blockLocation(blockLocation) >+ , m_localAnchor(localAnchor) >+ , m_widths(widths) >+ , m_strokeWidth(strokeWidth) >+ , m_printing(printing) >+ , m_doubleLines(doubleLines) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+ >+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override; >+ >+ FloatPoint m_blockLocation; >+ FloatSize m_localAnchor; >+ DashArray m_widths; >+ float m_strokeWidth; >+ bool m_printing; >+ bool m_doubleLines; >+}; >+ >+class DrawLineForDocumentMarker : public DrawingItem { >+public: >+ static Ref<DrawLineForDocumentMarker> create(const FloatPoint& point, float width, GraphicsContext::DocumentMarkerLineStyle style) >+ { >+ return adoptRef(*new DrawLineForDocumentMarker(point, width, style)); >+ } >+ >+ FloatPoint point() const { return m_point; } >+ float width() const { return m_width; } >+ >+private: >+ DrawLineForDocumentMarker(const FloatPoint& point, float width, GraphicsContext::DocumentMarkerLineStyle style) >+ : DrawingItem(ItemType::DrawLineForDocumentMarker) >+ , m_point(point) >+ , m_width(width) >+ , m_style(style) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+ >+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override; >+ >+ FloatPoint m_point; >+ float m_width; >+ GraphicsContext::DocumentMarkerLineStyle m_style; >+}; >+ >+class DrawEllipse : public DrawingItem { >+public: >+ static Ref<DrawEllipse> create(const FloatRect& rect) >+ { >+ return adoptRef(*new DrawEllipse(rect)); >+ } >+ >+ FloatRect rect() const { return m_rect; } >+ >+private: >+ DrawEllipse(const FloatRect& rect) >+ : DrawingItem(ItemType::DrawEllipse) >+ , m_rect(rect) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_rect; } >+ >+ FloatRect m_rect; >+}; >+ >+class DrawConvexPolygon : public DrawingItem { >+public: >+ static Ref<DrawConvexPolygon> create(size_t numberOfPoints, const FloatPoint* points, bool antialiased) >+ { >+ return adoptRef(*new DrawConvexPolygon(numberOfPoints, points, antialiased)); >+ } >+ >+ const Vector<FloatPoint>& points() const { return m_points; } >+ bool antialiased() const { return m_antialiased; } >+ >+private: >+ DrawConvexPolygon(size_t numberOfPoints, const FloatPoint*, bool antialiased); >+ >+ virtual void apply(GraphicsContext&) const override; >+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override; >+ >+ Vector<FloatPoint> m_points; >+ bool m_antialiased; >+}; >+ >+class DrawPath : public DrawingItem { >+public: >+ static Ref<DrawPath> create(const Path& path) >+ { >+ return adoptRef(*new DrawPath(path)); >+ } >+ >+ const Path& path() const { return m_path; } >+ >+private: >+ DrawPath(const Path& path) >+ : DrawingItem(ItemType::DrawPath) >+ , m_path(path) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+ >+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_path.fastBoundingRect(); } >+ >+ Path m_path; >+}; >+ >+class DrawFocusRingPath : public DrawingItem { >+public: >+ static Ref<DrawFocusRingPath> create(const Path& path, int width, int offset, const Color& color) >+ { >+ return adoptRef(*new DrawFocusRingPath(path, width, offset, color)); >+ } >+ >+ const Path& path() const { return m_path; } >+ int width() const { return m_width; } >+ int offset() const { return m_offset; } >+ Color color() const { return m_color; } >+ >+private: >+ DrawFocusRingPath(const Path& path, int width, int offset, const Color& color) >+ : DrawingItem(ItemType::DrawFocusRingPath) >+ , m_path(path) >+ , m_width(width) >+ , m_offset(offset) >+ , m_color(color) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+ >+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override; >+ >+ Path m_path; >+ int m_width; >+ int m_offset; >+ Color m_color; >+}; >+ >+class DrawFocusRingRects : public DrawingItem { >+public: >+ static Ref<DrawFocusRingRects> create(const Vector<IntRect>& rects, int width, int offset, const Color& color) >+ { >+ return adoptRef(*new DrawFocusRingRects(rects, width, offset, color)); >+ } >+ >+ const Vector<IntRect> rects() const { return m_rects; } >+ int width() const { return m_width; } >+ int offset() const { return m_offset; } >+ Color color() const { return m_color; } >+ >+private: >+ DrawFocusRingRects(const Vector<IntRect>& rects, int width, int offset, const Color& color) >+ : DrawingItem(ItemType::DrawFocusRingRects) >+ , m_rects(rects) >+ , m_width(width) >+ , m_offset(offset) >+ , m_color(color) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+ >+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override; >+ >+ Vector<IntRect> m_rects; >+ int m_width; >+ int m_offset; >+ Color m_color; >+}; >+ >+class FillRect : public DrawingItem { >+public: >+ static Ref<FillRect> create(const FloatRect& rect) >+ { >+ return adoptRef(*new FillRect(rect)); >+ } >+ >+ FloatRect rect() const { return m_rect; } >+ >+private: >+ FillRect(const FloatRect& rect) >+ : DrawingItem(ItemType::FillRect) >+ , m_rect(rect) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_rect; } >+ >+ FloatRect m_rect; >+}; >+ >+// FIXME: Make these inherit from FillRect proper. >+class FillRectWithColor : public DrawingItem { >+public: >+ static Ref<FillRectWithColor> create(const FloatRect& rect, const Color& color) >+ { >+ return adoptRef(*new FillRectWithColor(rect, color)); >+ } >+ >+ FloatRect rect() const { return m_rect; } >+ Color color() const { return m_color; } >+ >+private: >+ FillRectWithColor(const FloatRect& rect, const Color& color) >+ : DrawingItem(ItemType::FillRectWithColor) >+ , m_rect(rect) >+ , m_color(color) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_rect; } >+ >+ FloatRect m_rect; >+ Color m_color; >+}; >+ >+class FillRectWithGradient : public DrawingItem { >+public: >+ static Ref<FillRectWithGradient> create(const FloatRect& rect, Gradient& gradient) >+ { >+ return adoptRef(*new FillRectWithGradient(rect, gradient)); >+ } >+ >+ FloatRect rect() const { return m_rect; } >+ >+private: >+ FillRectWithGradient(const FloatRect& rect, Gradient& gradient) >+ : DrawingItem(ItemType::FillRectWithGradient) >+ , m_rect(rect) >+ , m_gradient(gradient) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_rect; } >+ >+ FloatRect m_rect; >+ mutable Ref<Gradient> m_gradient; // FIXME: Make this not mutable >+}; >+ >+class FillCompositedRect : public DrawingItem { >+public: >+ static Ref<FillCompositedRect> create(const FloatRect& rect, const Color& color, CompositeOperator op, BlendMode blendMode) >+ { >+ return adoptRef(*new FillCompositedRect(rect, color, op, blendMode)); >+ } >+ >+ FloatRect rect() const { return m_rect; } >+ Color color() const { return m_color; } >+ CompositeOperator compositeOperator() const { return m_op; } >+ BlendMode blendMode() const { return m_blendMode; } >+ >+private: >+ FillCompositedRect(const FloatRect& rect, const Color& color, CompositeOperator op, BlendMode blendMode) >+ : DrawingItem(ItemType::FillCompositedRect) >+ , m_rect(rect) >+ , m_color(color) >+ , m_op(op) >+ , m_blendMode(blendMode) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_rect; } >+ >+ FloatRect m_rect; >+ Color m_color; >+ CompositeOperator m_op; >+ BlendMode m_blendMode; >+}; >+ >+class FillRoundedRect : public DrawingItem { >+public: >+ static Ref<FillRoundedRect> create(const FloatRoundedRect& rect, const Color& color, BlendMode blendMode) >+ { >+ return adoptRef(*new FillRoundedRect(rect, color, blendMode)); >+ } >+ >+ const FloatRoundedRect& roundedRect() const { return m_rect; } >+ Color color() const { return m_color; } >+ BlendMode blendMode() const { return m_blendMode; } >+ >+private: >+ FillRoundedRect(const FloatRoundedRect& rect, const Color& color, BlendMode blendMode) >+ : DrawingItem(ItemType::FillRoundedRect) >+ , m_rect(rect) >+ , m_color(color) >+ , m_blendMode(blendMode) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_rect.rect(); } >+ >+ FloatRoundedRect m_rect; >+ Color m_color; >+ BlendMode m_blendMode; >+}; >+ >+class FillRectWithRoundedHole : public DrawingItem { >+public: >+ static Ref<FillRectWithRoundedHole> create(const FloatRect& rect, const FloatRoundedRect& roundedHoleRect, const Color& color) >+ { >+ return adoptRef(*new FillRectWithRoundedHole(rect, roundedHoleRect, color)); >+ } >+ >+ const FloatRect& rect() const { return m_rect; } >+ const FloatRoundedRect& roundedHoleRect() const { return m_roundedHoleRect; } >+ Color color() const { return m_color; } >+ >+private: >+ FillRectWithRoundedHole(const FloatRect& rect, const FloatRoundedRect& roundedHoleRect, const Color& color) >+ : DrawingItem(ItemType::FillRectWithRoundedHole) >+ , m_rect(rect) >+ , m_roundedHoleRect(roundedHoleRect) >+ , m_color(color) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_rect; } >+ >+ FloatRect m_rect; >+ FloatRoundedRect m_roundedHoleRect; >+ Color m_color; >+}; >+ >+class FillPath : public DrawingItem { >+public: >+ static Ref<FillPath> create(const Path& path) >+ { >+ return adoptRef(*new FillPath(path)); >+ } >+ >+ const Path& path() const { return m_path; } >+ >+private: >+ FillPath(const Path& path) >+ : DrawingItem(ItemType::FillPath) >+ , m_path(path) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_path.fastBoundingRect(); } >+ >+ Path m_path; >+}; >+ >+class FillEllipse : public DrawingItem { >+public: >+ static Ref<FillEllipse> create(const FloatRect& rect) >+ { >+ return adoptRef(*new FillEllipse(rect)); >+ } >+ >+ FloatRect rect() const { return m_rect; } >+ >+private: >+ FillEllipse(const FloatRect& rect) >+ : DrawingItem(ItemType::FillEllipse) >+ , m_rect(rect) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+ >+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_rect; } >+ >+ FloatRect m_rect; >+}; >+ >+class StrokeRect : public DrawingItem { >+public: >+ static Ref<StrokeRect> create(const FloatRect& rect, float lineWidth) >+ { >+ return adoptRef(*new StrokeRect(rect, lineWidth)); >+ } >+ >+ FloatRect rect() const { return m_rect; } >+ float lineWidth() const { return m_lineWidth; } >+ >+private: >+ StrokeRect(const FloatRect& rect, float lineWidth) >+ : DrawingItem(ItemType::StrokeRect) >+ , m_rect(rect) >+ , m_lineWidth(lineWidth) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override; >+ >+ FloatRect m_rect; >+ float m_lineWidth; >+}; >+ >+class StrokePath : public DrawingItem { >+public: >+ static Ref<StrokePath> create(const Path& path, const FloatPoint& m_blockLocation) >+ { >+ return adoptRef(*new StrokePath(path, m_blockLocation)); >+ } >+ >+ void setBlockLocation(const FloatPoint& blockLocation) { m_blockLocation = blockLocation; } >+ const FloatPoint& blockLocation() const { return m_blockLocation; } >+ const Path& path() const { return m_path; } >+ >+private: >+ StrokePath(const Path& path, const FloatPoint& blockLocation) >+ : DrawingItem(ItemType::StrokePath) >+ , m_path(path) >+ , m_blockLocation(blockLocation) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override; >+ >+ mutable Path m_path; >+ FloatPoint m_blockLocation; >+}; >+ >+class StrokeEllipse : public DrawingItem { >+public: >+ static Ref<StrokeEllipse> create(const FloatRect& rect) >+ { >+ return adoptRef(*new StrokeEllipse(rect)); >+ } >+ >+ FloatRect rect() const { return m_rect; } >+ >+private: >+ StrokeEllipse(const FloatRect& rect) >+ : DrawingItem(ItemType::StrokeEllipse) >+ , m_rect(rect) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override; >+ >+ FloatRect m_rect; >+}; >+ >+class ClearRect : public DrawingItem { >+public: >+ static Ref<ClearRect> create(const FloatRect& rect) >+ { >+ return adoptRef(*new ClearRect(rect)); >+ } >+ >+ FloatRect rect() const { return m_rect; } >+ >+private: >+ ClearRect(const FloatRect& rect) >+ : DrawingItem(ItemType::ClearRect) >+ , m_rect(rect) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+ virtual Optional<FloatRect> localBounds(const GraphicsContext&) const override { return m_rect; } >+ >+ FloatRect m_rect; >+}; >+ >+class ApplyStrokePattern : public Item { >+public: >+ static Ref<ApplyStrokePattern> create() >+ { >+ return adoptRef(*new ApplyStrokePattern); >+ } >+ >+private: >+ ApplyStrokePattern() >+ : Item(ItemType::ApplyStrokePattern) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+}; >+ >+class ApplyFillPattern : public Item { >+public: >+ static Ref<ApplyFillPattern> create() >+ { >+ return adoptRef(*new ApplyFillPattern); >+ } >+ >+private: >+ ApplyFillPattern() >+ : Item(ItemType::ApplyFillPattern) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+}; >+ >+ >+class ApplyDeviceScaleFactor : public Item { >+public: >+ static Ref<ApplyDeviceScaleFactor> create(float scaleFactor) >+ { >+ return adoptRef(*new ApplyDeviceScaleFactor(scaleFactor)); >+ } >+ >+ float scaleFactor() const { return m_scaleFactor; } >+ >+private: >+ ApplyDeviceScaleFactor(float scaleFactor) >+ : Item(ItemType::ApplyDeviceScaleFactor) >+ , m_scaleFactor(scaleFactor) >+ { >+ } >+ >+ virtual void apply(GraphicsContext&) const override; >+ >+ float m_scaleFactor; >+}; >+ >+// FIXME: this needs to move. >+void addConvexPolygonToPath(Path&, size_t numPoints, const FloatPoint*); >+ >+TextStream& operator<<(TextStream&, const Item&); >+ >+} // namespace DisplayList >+} // namespace WebCore >+ >+ >+#define SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_DRAWINGITEM(ToValueTypeName, predicate) \ >+SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::DisplayList::ToValueTypeName) \ >+ static bool isType(const WebCore::DisplayList::Item& object) { return object.predicate; } \ >+SPECIALIZE_TYPE_TRAITS_END() >+ >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_DRAWINGITEM(DrawingItem, isDrawingItem()) >+ >+#define SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(ToValueTypeName) \ >+SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::DisplayList::ToValueTypeName) \ >+ static bool isType(const WebCore::DisplayList::Item& item) { return item.type() == WebCore::DisplayList::ItemType::ToValueTypeName; } \ >+SPECIALIZE_TYPE_TRAITS_END() >+ >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(Save) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(Restore) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(Translate) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(Rotate) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(Scale) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(ConcatenateCTM) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(SetState) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(SetLineCap) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(SetLineDash) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(SetLineJoin) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(SetMiterLimit) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(Clip) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(ClipOut) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(ClipOutToPath) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(ClipPath) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(ClipConvexPolygon) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawGlyphs) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawImage) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawTiledImage) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawTiledScaledImage) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawNativeImage) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawPattern) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawRect) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawLine) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawLinesForText) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawLineForDocumentMarker) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawEllipse) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawConvexPolygon) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawPath) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawFocusRingPath) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(DrawFocusRingRects) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(FillRect) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(FillRectWithColor) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(FillRectWithGradient) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(FillCompositedRect) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(FillRoundedRect) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(FillRectWithRoundedHole) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(FillPath) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(FillEllipse) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(StrokeRect) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(StrokePath) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(StrokeEllipse) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(ClearRect) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(BeginTransparencyLayer) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(EndTransparencyLayer) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(ApplyStrokePattern) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(ApplyFillPattern) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(ApplyDeviceScaleFactor) >+SPECIALIZE_TYPE_TRAITS_DISPLAYLIST_ITEM(ClearShadow) >+ >+#endif // DisplayListItems_h >diff --git a/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.cpp b/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..a72207906134de281a80efe71430e57f18ac629b >--- /dev/null >+++ b/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.cpp >@@ -0,0 +1,481 @@ >+/* >+ * Copyright (C) 2015 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 "DisplayListRecorder.h" >+ >+#include "DisplayList.h" >+#include "DisplayListItems.h" >+#include "GraphicsContext.h" >+#include "Logging.h" >+#include "TextStream.h" >+#include <wtf/MathExtras.h> >+ >+namespace WebCore { >+namespace DisplayList { >+ >+Recorder::Recorder(GraphicsContext& context, DisplayList& displayList, const FloatRect& initialClip, const AffineTransform& baseCTM) >+ : m_graphicsContext(context) >+ , m_displayList(displayList) >+{ >+ LOG_WITH_STREAM(DisplayLists, stream << "\nRecording with clip " << initialClip); >+ >+ // FIXME: hook up recorder in the GraphicsContext. >+ // m_graphicsContext.setDisplayListRecorder(this); >+ m_stateStack.append(ContextState(baseCTM, initialClip)); >+} >+ >+Recorder::~Recorder() >+{ >+ ASSERT(m_stateStack.size() == 1); // If this fires, it indicates mismatched save/restore. >+ LOG(DisplayLists, "Recorded display list:\n%s", m_displayList.description().data()); >+} >+ >+void Recorder::willAppendItem(const Item& item) >+{ >+ if (item.isDrawingItem() || item.type() == ItemType::ApplyStrokePattern || item.type() == ItemType::ApplyStrokePattern) { >+ GraphicsContextStateChange& stateChanges = currentState().stateChange; >+ GraphicsContextState::StateChangeFlags changesFromLastState = stateChanges.changesFromState(currentState().lastDrawingState); >+ if (changesFromLastState) { >+ LOG_WITH_STREAM(DisplayLists, stream << "pre-drawing, saving state " << GraphicsContextStateChange(stateChanges.m_state, changesFromLastState)); >+ m_displayList.append(SetState::create(stateChanges.m_state, changesFromLastState)); >+ stateChanges.m_changeFlags = 0; >+ currentState().lastDrawingState = stateChanges.m_state; >+ } >+ currentState().wasUsedForDrawing = true; >+ } >+} >+ >+void Recorder::updateState(const GraphicsContextState& state, GraphicsContextState::StateChangeFlags flags) >+{ >+ currentState().stateChange.accumulate(state, flags); >+} >+ >+void Recorder::clearShadow() >+{ >+ appendItem(ClearShadow::create()); >+} >+ >+void Recorder::setLineCap(LineCap lineCap) >+{ >+ appendItem(SetLineCap::create(lineCap)); >+} >+ >+void Recorder::setLineDash(const DashArray& dashArray, float dashOffset) >+{ >+ appendItem(SetLineDash::create(dashArray, dashOffset)); >+} >+ >+void Recorder::setLineJoin(LineJoin lineJoin) >+{ >+ appendItem(SetLineJoin::create(lineJoin)); >+} >+ >+void Recorder::setMiterLimit(float miterLimit) >+{ >+ appendItem(SetMiterLimit::create(miterLimit)); >+} >+ >+void Recorder::drawGlyphs(const Font& font, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& startPoint, FontSmoothingMode smoothingMode) >+{ >+ FloatPoint blockLocation = m_caching ? m_blockLocation : FloatPoint(); >+ FloatSize localAnchor = startPoint - blockLocation; >+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(DrawGlyphs::create(font, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs, blockLocation, localAnchor, smoothingMode))); >+ updateItemExtent(newItem); >+} >+ >+void Recorder::drawImage(Image& image, const FloatRect& destination, const FloatRect& source, const ImagePaintingOptions& imagePaintingOptions) >+{ >+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(DrawImage::create(image, destination, source, imagePaintingOptions))); >+ updateItemExtent(newItem); >+} >+ >+void Recorder::drawTiledImage(Image& image, const FloatRect& destination, const FloatPoint& source, const FloatSize& tileSize, const FloatSize& spacing, const ImagePaintingOptions& imagePaintingOptions) >+{ >+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(DrawTiledImage::create(image, destination, source, tileSize, spacing, imagePaintingOptions))); >+ updateItemExtent(newItem); >+} >+ >+void Recorder::drawNativeImage(PassNativeImagePtr imagePtr, const FloatSize& imageSize, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator op, BlendMode blendMode, ImageOrientation orientation) >+{ >+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(DrawNativeImage::create(imagePtr, imageSize, destRect, srcRect, op, blendMode, orientation))); >+ updateItemExtent(newItem); >+} >+ >+void Recorder::drawTiledImage(Image& image, const FloatRect& destination, const FloatRect& source, const FloatSize& tileScaleFactor, Image::TileRule hRule, Image::TileRule vRule, const ImagePaintingOptions& imagePaintingOptions) >+{ >+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(DrawTiledScaledImage::create(image, destination, source, tileScaleFactor, hRule, vRule, imagePaintingOptions))); >+ updateItemExtent(newItem); >+} >+ >+void Recorder::drawPattern(Image& image, const FloatRect& tileRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, CompositeOperator op, const FloatRect& destRect, BlendMode blendMode) >+{ >+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(DrawPattern::create(image, tileRect, patternTransform, phase, spacing, op, destRect, blendMode))); >+ updateItemExtent(newItem); >+} >+ >+void Recorder::save() >+{ >+ appendItem(Save::create()); >+ m_stateStack.append(m_stateStack.last().cloneForSave(m_displayList.size() - 1)); >+} >+ >+void Recorder::restore() >+{ >+ if (!m_stateStack.size()) >+ return; >+ >+ bool stateUsedForDrawing = currentState().wasUsedForDrawing; >+ size_t saveIndex = currentState().saveItemIndex; >+ >+ m_stateStack.removeLast(); >+ // Have to avoid eliding nested Save/Restore when a descendant state contains drawing items. >+ currentState().wasUsedForDrawing |= stateUsedForDrawing; >+ >+ if (!stateUsedForDrawing && saveIndex) { >+ // This Save/Restore didn't contain any drawing items. Roll back to just before the last save. >+ m_displayList.removeItemsFromIndex(saveIndex); >+ return; >+ } >+ >+ appendItem(Restore::create()); >+ >+ if (saveIndex) { >+ Save& saveItem = downcast<Save>(m_displayList.itemAt(saveIndex)); >+ saveItem.setRestoreIndex(m_displayList.size() - 1); >+ } >+} >+ >+void Recorder::translate(float x, float y) >+{ >+ currentState().translate(x, y); >+ appendItem(Translate::create(x, y)); >+} >+ >+void Recorder::rotate(float angleInRadians) >+{ >+ currentState().rotate(angleInRadians); >+ appendItem(Rotate::create(angleInRadians)); >+} >+ >+void Recorder::scale(const FloatSize& size) >+{ >+ currentState().scale(size); >+ appendItem(Scale::create(size)); >+} >+ >+void Recorder::concatCTM(const AffineTransform& transform) >+{ >+ currentState().concatCTM(transform); >+ appendItem(ConcatenateCTM::create(transform)); >+} >+ >+void Recorder::beginTransparencyLayer(float opacity) >+{ >+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(BeginTransparencyLayer::create(opacity))); >+ updateItemExtent(newItem); >+} >+ >+void Recorder::endTransparencyLayer() >+{ >+ appendItem(EndTransparencyLayer::create()); >+} >+ >+void Recorder::drawRect(const FloatRect& rect, float borderThickness) >+{ >+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(DrawRect::create(rect, borderThickness))); >+ updateItemExtent(newItem); >+} >+ >+void Recorder::drawLine(const FloatPoint& point1, const FloatPoint& point2) >+{ >+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(DrawLine::create(point1, point2))); >+ updateItemExtent(newItem); >+} >+ >+void Recorder::drawLinesForText(const FloatPoint& point, const DashArray& widths, bool printing, bool doubleLines, float strokeThickness) >+{ >+ FloatPoint blockLocation = m_caching ? m_blockLocation : FloatPoint(); >+ FloatSize localAnchor = point - blockLocation; >+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(DrawLinesForText::create(blockLocation, localAnchor, widths, printing, doubleLines, strokeThickness))); >+ updateItemExtent(newItem); >+} >+ >+void Recorder::drawLineForDocumentMarker(const FloatPoint& point, float width, GraphicsContext::DocumentMarkerLineStyle style) >+{ >+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(DrawLineForDocumentMarker::create(point, width, style))); >+ updateItemExtent(newItem); >+} >+ >+void Recorder::drawEllipse(const FloatRect& rect) >+{ >+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(DrawEllipse::create(rect))); >+ updateItemExtent(newItem); >+} >+ >+void Recorder::drawConvexPolygon(size_t numberOfPoints, const FloatPoint* points, bool antialiased) >+{ >+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(DrawConvexPolygon::create(numberOfPoints, points, antialiased))); >+ updateItemExtent(newItem); >+} >+ >+void Recorder::drawPath(const Path& path) >+{ >+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(DrawPath::create(path))); >+ updateItemExtent(newItem); >+} >+ >+void Recorder::drawFocusRing(const Path& path, int width, int offset, const Color& color) >+{ >+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(DrawFocusRingPath::create(path, width, offset, color))); >+ updateItemExtent(newItem); >+} >+ >+void Recorder::drawFocusRing(const Vector<IntRect>& rects, int width, int offset, const Color& color) >+{ >+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(DrawFocusRingRects::create(rects, width, offset, color))); >+ updateItemExtent(newItem); >+} >+ >+void Recorder::fillRect(const FloatRect& rect) >+{ >+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(FillRect::create(rect))); >+ updateItemExtent(newItem); >+} >+ >+void Recorder::fillRect(const FloatRect& rect, const Color& color) >+{ >+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(FillRectWithColor::create(rect, color))); >+ updateItemExtent(newItem); >+} >+ >+void Recorder::fillRect(const FloatRect& rect, Gradient& gradient) >+{ >+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(FillRectWithGradient::create(rect, gradient))); >+ updateItemExtent(newItem); >+} >+ >+void Recorder::fillRect(const FloatRect& rect, const Color& color, CompositeOperator op, BlendMode blendMode) >+{ >+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(FillCompositedRect::create(rect, color, op, blendMode))); >+ updateItemExtent(newItem); >+} >+ >+void Recorder::fillRoundedRect(const FloatRoundedRect& rect, const Color& color, BlendMode blendMode) >+{ >+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(FillRoundedRect::create(rect, color, blendMode))); >+ updateItemExtent(newItem); >+} >+ >+void Recorder::fillRectWithRoundedHole(const FloatRect& rect, const FloatRoundedRect& roundedHoleRect, const Color& color) >+{ >+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(FillRectWithRoundedHole::create(rect, roundedHoleRect, color))); >+ updateItemExtent(newItem); >+} >+ >+void Recorder::fillPath(const Path& path) >+{ >+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(FillPath::create(path))); >+ updateItemExtent(newItem); >+} >+ >+void Recorder::fillEllipse(const FloatRect& rect) >+{ >+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(FillEllipse::create(rect))); >+ updateItemExtent(newItem); >+} >+ >+void Recorder::strokeRect(const FloatRect& rect, float lineWidth) >+{ >+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(StrokeRect::create(rect, lineWidth))); >+ updateItemExtent(newItem); >+} >+ >+void Recorder::strokePath(const Path& path) >+{ >+ FloatPoint blockLocation = m_caching ? m_blockLocation : FloatPoint(); >+ Path translated = path; >+ translated.translate(-FloatSize(blockLocation.x(), blockLocation.y())); >+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(StrokePath::create(path, blockLocation))); >+ updateItemExtent(newItem); >+} >+ >+void Recorder::strokeEllipse(const FloatRect& rect) >+{ >+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(StrokeEllipse::create(rect))); >+ updateItemExtent(newItem); >+} >+ >+void Recorder::clearRect(const FloatRect& rect) >+{ >+ DrawingItem& newItem = downcast<DrawingItem>(appendItem(ClearRect::create(rect))); >+ updateItemExtent(newItem); >+} >+ >+void Recorder::applyStrokePattern() >+{ >+ appendItem(ApplyStrokePattern::create()); >+} >+ >+void Recorder::applyFillPattern() >+{ >+ appendItem(ApplyFillPattern::create()); >+} >+ >+void Recorder::clip(const FloatRect& rect) >+{ >+ currentState().clipBounds.intersect(rect); >+ appendItem(Clip::create(rect)); >+} >+ >+void Recorder::clipOut(const FloatRect& rect) >+{ >+ appendItem(ClipOut::create(rect)); >+} >+ >+void Recorder::clipOut(const Path& path) >+{ >+ appendItem(ClipOutToPath::create(path)); >+} >+ >+void Recorder::clipPath(const Path& path, WindRule windRule) >+{ >+ currentState().clipBounds.intersect(path.fastBoundingRect()); >+ appendItem(ClipPath::create(path, windRule)); >+} >+ >+void Recorder::clipConvexPolygon(size_t numPoints, const FloatPoint* points, bool antialias) >+{ >+ Path polygonPath; >+ addConvexPolygonToPath(polygonPath, numPoints, points); >+ currentState().clipBounds.intersect(polygonPath.fastBoundingRect()); >+ >+ appendItem(ClipConvexPolygon::create(numPoints, points, antialias)); >+} >+ >+void Recorder::applyDeviceScaleFactor(float deviceScaleFactor) >+{ >+ // FIXME: this changes the baseCTM, which will invalidate all of our cached extents. >+ // Assert that it's only called early on? >+ appendItem(ApplyDeviceScaleFactor::create(deviceScaleFactor)); >+} >+ >+Item& Recorder::appendItem(Ref<Item>&& item) >+{ >+ willAppendItem(item.get()); >+ return m_displayList.append(WTFMove(item)); >+} >+ >+void Recorder::updateItemExtent(DrawingItem& item) const >+{ >+ if (Optional<FloatRect> rect = item.localBounds(m_graphicsContext)) >+ item.setExtent(extentFromLocalBounds(rect.value())); >+} >+ >+// FIXME: share with ShadowData >+static inline float shadowPaintingExtent(float blurRadius) >+{ >+ // Blurring uses a Gaussian function whose std. deviation is m_radius/2, and which in theory >+ // extends to infinity. In 8-bit contexts, however, rounding causes the effect to become >+ // undetectable at around 1.4x the radius. >+ const float radiusExtentMultiplier = 1.4; >+ return ceilf(blurRadius * radiusExtentMultiplier); >+} >+ >+FloatRect Recorder::extentFromLocalBounds(const FloatRect& rect) const >+{ >+ FloatRect bounds = rect; >+ const ContextState& state = currentState(); >+ >+ FloatSize shadowOffset; >+ float shadowRadius; >+ Color shadowColor; >+ if (m_graphicsContext.getShadow(shadowOffset, shadowRadius, shadowColor)) { >+ FloatRect shadowExtent= bounds; >+ shadowExtent.move(shadowOffset); >+ shadowExtent.inflate(shadowPaintingExtent(shadowRadius)); >+ bounds.unite(shadowExtent); >+ } >+ >+ FloatRect clippedExtent = intersection(state.clipBounds, bounds); >+ return state.ctm.mapRect(clippedExtent); >+} >+ >+const Recorder::ContextState& Recorder::currentState() const >+{ >+ ASSERT(m_stateStack.size()); >+ return m_stateStack.last(); >+} >+ >+Recorder::ContextState& Recorder::currentState() >+{ >+ ASSERT(m_stateStack.size()); >+ return m_stateStack.last(); >+} >+ >+const AffineTransform& Recorder::ctm() const >+{ >+ return currentState().ctm; >+} >+ >+const FloatRect& Recorder::clipBounds() const >+{ >+ return currentState().clipBounds; >+} >+ >+void Recorder::ContextState::translate(float x, float y) >+{ >+ ctm.translate(x, y); >+ clipBounds.move(-x, -y); >+} >+ >+void Recorder::ContextState::rotate(float angleInRadians) >+{ >+ double angleInDegrees = rad2deg(static_cast<double>(angleInRadians)); >+ ctm.rotate(angleInDegrees); >+ >+ AffineTransform rotation; >+ rotation.rotate(angleInDegrees); >+ >+ if (Optional<AffineTransform> inverse = rotation.inverse()) >+ clipBounds = inverse.value().mapRect(clipBounds); >+} >+ >+void Recorder::ContextState::scale(const FloatSize& size) >+{ >+ ctm.scale(size); >+ clipBounds.scale(1 / size.width(), 1 / size.height()); >+} >+ >+void Recorder::ContextState::concatCTM(const AffineTransform& matrix) >+{ >+ ctm *= matrix; >+ >+ if (Optional<AffineTransform> inverse = matrix.inverse()) >+ clipBounds = inverse.value().mapRect(clipBounds); >+} >+ >+} // namespace DisplayList >+} // namespace WebCore >diff --git a/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.h b/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.h >new file mode 100644 >index 0000000000000000000000000000000000000000..8c8e02d967cf9736561a165ddb50075de2cc06e9 >--- /dev/null >+++ b/Source/WebCore/platform/graphics/displaylists/DisplayListRecorder.h >@@ -0,0 +1,175 @@ >+/* >+ * Copyright (C) 2015 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. >+ */ >+ >+#ifndef DisplayListRecorder_h >+#define DisplayListRecorder_h >+ >+#include "DisplayList.h" >+#include "GraphicsContext.h" // For InterpolationQuality. >+#include "Image.h" // For Image::TileRule. >+#include "TextFlags.h" >+#include <wtf/Noncopyable.h> >+ >+namespace WebCore { >+ >+class FloatPoint; >+class FloatRect; >+class GlyphBuffer; >+class FloatPoint; >+class Font; >+class Image; >+ >+struct GraphicsContextState; >+struct ImagePaintingOptions; >+ >+namespace DisplayList { >+ >+class DrawingItem; >+ >+class Recorder { >+ WTF_MAKE_NONCOPYABLE(Recorder); >+public: >+ Recorder(GraphicsContext&, DisplayList&, const FloatRect& initialClip, const AffineTransform&); >+ ~Recorder(); >+ >+ void updateState(const GraphicsContextState&, GraphicsContextState::StateChangeFlags); >+ void clearShadow(); >+ >+ void setLineCap(LineCap); >+ void setLineDash(const DashArray&, float dashOffset); >+ void setLineJoin(LineJoin); >+ void setMiterLimit(float); >+ >+ void fillRect(const FloatRect&); >+ void fillRect(const FloatRect&, const Color&); >+ void fillRect(const FloatRect&, Gradient&); >+ void fillRect(const FloatRect&, const Color&, CompositeOperator, BlendMode); >+ void fillRoundedRect(const FloatRoundedRect&, const Color&, BlendMode); >+ void fillRectWithRoundedHole(const FloatRect&, const FloatRoundedRect& roundedHoleRect, const Color&); >+ void fillPath(const Path&); >+ void fillEllipse(const FloatRect&); >+ void strokeRect(const FloatRect&, float lineWidth); >+ void strokePath(const Path&); >+ void strokeEllipse(const FloatRect&); >+ void clearRect(const FloatRect&); >+ >+ void applyStrokePattern(); >+ void applyFillPattern(); >+ >+ void drawGlyphs(const Font&, const GlyphBuffer&, int from, int numGlyphs, const FloatPoint& anchorPoint, FontSmoothingMode); >+ >+ void drawImage(Image&, const FloatRect& destination, const FloatRect& source, const ImagePaintingOptions&); >+ void drawTiledImage(Image&, const FloatRect& destination, const FloatPoint& source, const FloatSize& tileSize, const FloatSize& spacing, const ImagePaintingOptions&); >+ void drawTiledImage(Image&, const FloatRect& destination, const FloatRect& source, const FloatSize& tileScaleFactor, Image::TileRule hRule, Image::TileRule vRule, const ImagePaintingOptions&); >+ void drawNativeImage(PassNativeImagePtr, const FloatSize& selfSize, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator, BlendMode, ImageOrientation); >+ void drawPattern(Image&, const FloatRect& srcRect, const AffineTransform&, const FloatPoint& phase, const FloatSize& spacing, CompositeOperator, const FloatRect& destRect, BlendMode = BlendModeNormal); >+ >+ void drawRect(const FloatRect&, float borderThickness); >+ void drawLine(const FloatPoint&, const FloatPoint&); >+ void drawLinesForText(const FloatPoint&, const DashArray& widths, bool printing, bool doubleLines, float strokeThickness); >+ void drawLineForDocumentMarker(const FloatPoint&, float width, GraphicsContext::DocumentMarkerLineStyle); >+ void drawEllipse(const FloatRect&); >+ void drawConvexPolygon(size_t numberOfPoints, const FloatPoint*, bool antialiased); >+ void drawPath(const Path&); >+ >+ void drawFocusRing(const Path&, int width, int offset, const Color&); >+ void drawFocusRing(const Vector<IntRect>&, int width, int offset, const Color&); >+ >+ void save(); >+ void restore(); >+ >+ void translate(float x, float y); >+ void rotate(float angleInRadians); >+ void scale(const FloatSize&); >+ void concatCTM(const AffineTransform&); >+ >+ void beginTransparencyLayer(float opacity); >+ void endTransparencyLayer(); >+ >+ void clip(const FloatRect&); >+ void clipOut(const FloatRect&); >+ void clipOut(const Path&); >+ void clipPath(const Path&, WindRule); >+ void clipConvexPolygon(size_t numPoints, const FloatPoint*, bool antialias); >+ >+ void applyDeviceScaleFactor(float); >+ >+ size_t size() const { return m_displayList.size(); } >+ >+private: >+ Item& appendItem(Ref<Item>&&); >+ void willAppendItem(const Item&); >+ >+ FloatRect extentFromLocalBounds(const FloatRect&) const; >+ void updateItemExtent(DrawingItem&) const; >+ >+ const AffineTransform& ctm() const; >+ const FloatRect& clipBounds() const; >+ >+ struct ContextState { >+ AffineTransform ctm; >+ FloatRect clipBounds; >+ GraphicsContextStateChange stateChange; >+ GraphicsContextState lastDrawingState; >+ bool wasUsedForDrawing { false }; >+ size_t saveItemIndex { 0 }; >+ >+ ContextState(const AffineTransform& transform, const FloatRect& clip) >+ : ctm(transform) >+ , clipBounds(clip) >+ { >+ } >+ >+ ContextState cloneForSave(size_t saveIndex) const >+ { >+ ContextState state(ctm, clipBounds); >+ state.stateChange = stateChange; >+ state.lastDrawingState = lastDrawingState; >+ state.saveItemIndex = saveIndex; >+ return state; >+ } >+ >+ void translate(float x, float y); >+ void rotate(float angleInRadians); >+ void scale(const FloatSize&); >+ void concatCTM(const AffineTransform&); >+ }; >+ >+ const ContextState& currentState() const; >+ ContextState& currentState(); >+ >+ GraphicsContext& m_graphicsContext; >+ DisplayList& m_displayList; >+ >+ bool m_caching { false }; >+ FloatPoint m_blockLocation; >+ >+ Vector<ContextState, 32> m_stateStack; >+}; >+ >+} >+} >+ >+#endif // DisplayListRecorder_h >diff --git a/Source/WebCore/platform/graphics/displaylists/DisplayListReplayer.cpp b/Source/WebCore/platform/graphics/displaylists/DisplayListReplayer.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..503876861782a5da7e70458c0ece80386559cf5e >--- /dev/null >+++ b/Source/WebCore/platform/graphics/displaylists/DisplayListReplayer.cpp >@@ -0,0 +1,62 @@ >+/* >+ * Copyright (C) 2015 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 "DisplayListReplayer.h" >+ >+#include "DisplayList.h" >+#include "DisplayListItems.h" >+#include "GraphicsContext.h" >+#include "Logging.h" >+#include "TextStream.h" >+ >+namespace WebCore { >+namespace DisplayList { >+ >+Replayer::Replayer(GraphicsContext& context, const DisplayList& displayList) >+ : m_displayList(displayList) >+ , m_context(context) >+{ >+} >+ >+Replayer::~Replayer() >+{ >+} >+ >+void Replayer::replay(const FloatRect& initialClip) >+{ >+ LOG_WITH_STREAM(DisplayLists, stream << "\nReplaying with clip " << initialClip); >+ UNUSED_PARAM(initialClip); >+ >+ size_t numItems = m_displayList.size(); >+ for (size_t i = 0; i < numItems; ++i) { >+ auto& item = m_displayList.list()[i].get(); >+ LOG_WITH_STREAM(DisplayLists, stream << "drawing " << i << " " << item); >+ item.apply(m_context); >+ } >+} >+ >+} // namespace DisplayList >+} // namespace WebCore >diff --git a/Source/WebCore/platform/graphics/displaylists/DisplayListReplayer.h b/Source/WebCore/platform/graphics/displaylists/DisplayListReplayer.h >new file mode 100644 >index 0000000000000000000000000000000000000000..51abbaef0128c41341ccaf95d984372ace3fd2c1 >--- /dev/null >+++ b/Source/WebCore/platform/graphics/displaylists/DisplayListReplayer.h >@@ -0,0 +1,57 @@ >+/* >+ * Copyright (C) 2015 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. >+ */ >+ >+#ifndef DisplayListReplayer_h >+#define DisplayListReplayer_h >+ >+#include <wtf/Noncopyable.h> >+ >+namespace WebCore { >+ >+class AffineTransform; >+class FloatRect; >+class GraphicsContext; >+ >+namespace DisplayList { >+ >+class DisplayList; >+ >+class Replayer { >+ WTF_MAKE_NONCOPYABLE(Replayer); >+public: >+ Replayer(GraphicsContext&, const DisplayList&); >+ ~Replayer(); >+ >+ void replay(const FloatRect& initialClip); >+ >+private: >+ const DisplayList& m_displayList; >+ GraphicsContext& m_context; >+}; >+ >+} >+} >+ >+#endif // DisplayListReplayer_h
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 152816
:
268429
|
268430
|
268431
|
268432
|
268433
|
268440
|
268442
|
268443