Bug 1638136 [wpt PR 23617] - Clipboard API Tests: Move permissions tests to WPT....
[gecko.git] / gfx / 2d / DrawTargetDual.cpp
blob6f09ce7a8c89c74366afc307ca7c6e041b618cf4
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "DrawTargetDual.h"
8 #include "Tools.h"
9 #include "Logging.h"
11 namespace mozilla {
12 namespace gfx {
14 class DualSurface {
15 public:
16 inline explicit DualSurface(SourceSurface* aSurface) {
17 if (!aSurface) {
18 mA = mB = nullptr;
19 return;
22 if (aSurface->GetType() != SurfaceType::DUAL_DT) {
23 mA = mB = aSurface;
24 return;
27 SourceSurfaceDual* ssDual = static_cast<SourceSurfaceDual*>(aSurface);
28 mA = ssDual->mA;
29 mB = ssDual->mB;
32 SourceSurface* mA;
33 SourceSurface* mB;
36 /* This only needs to split patterns up for SurfacePatterns. Only in that
37 * case can we be dealing with a 'dual' source (SourceSurfaceDual) and do
38 * we need to pass separate patterns into our destination DrawTargets.
40 class DualPattern final {
41 public:
42 inline explicit DualPattern(const Pattern& aPattern)
43 : mPatternsInitialized(false) {
44 if (aPattern.GetType() != PatternType::SURFACE) {
45 mA = mB = &aPattern;
46 return;
49 const SurfacePattern* surfPat =
50 static_cast<const SurfacePattern*>(&aPattern);
52 if (surfPat->mSurface->GetType() != SurfaceType::DUAL_DT) {
53 mA = mB = &aPattern;
54 return;
57 const SourceSurfaceDual* ssDual =
58 static_cast<const SourceSurfaceDual*>(surfPat->mSurface.get());
59 mA = new (mSurfPatA.addr())
60 SurfacePattern(ssDual->mA, surfPat->mExtendMode, surfPat->mMatrix,
61 surfPat->mSamplingFilter);
62 mB = new (mSurfPatB.addr())
63 SurfacePattern(ssDual->mB, surfPat->mExtendMode, surfPat->mMatrix,
64 surfPat->mSamplingFilter);
65 mPatternsInitialized = true;
68 inline ~DualPattern() {
69 if (mPatternsInitialized) {
70 mA->~Pattern();
71 mB->~Pattern();
75 ClassStorage<SurfacePattern> mSurfPatA;
76 ClassStorage<SurfacePattern> mSurfPatB;
78 const Pattern* mA;
79 const Pattern* mB;
81 bool mPatternsInitialized;
84 void DrawTargetDual::DetachAllSnapshots() {
85 mA->DetachAllSnapshots();
86 mB->DetachAllSnapshots();
89 void DrawTargetDual::DrawSurface(SourceSurface* aSurface, const Rect& aDest,
90 const Rect& aSource,
91 const DrawSurfaceOptions& aSurfOptions,
92 const DrawOptions& aOptions) {
93 DualSurface surface(aSurface);
94 mA->DrawSurface(surface.mA, aDest, aSource, aSurfOptions, aOptions);
95 mB->DrawSurface(surface.mB, aDest, aSource, aSurfOptions, aOptions);
98 void DrawTargetDual::DrawSurfaceWithShadow(SourceSurface* aSurface,
99 const Point& aDest,
100 const DeviceColor& aColor,
101 const Point& aOffset, Float aSigma,
102 CompositionOp aOp) {
103 DualSurface surface(aSurface);
104 mA->DrawSurfaceWithShadow(surface.mA, aDest, aColor, aOffset, aSigma, aOp);
105 mB->DrawSurfaceWithShadow(surface.mB, aDest, aColor, aOffset, aSigma, aOp);
108 void DrawTargetDual::MaskSurface(const Pattern& aSource, SourceSurface* aMask,
109 Point aOffset, const DrawOptions& aOptions) {
110 DualPattern source(aSource);
111 DualSurface mask(aMask);
112 mA->MaskSurface(*source.mA, mask.mA, aOffset, aOptions);
113 mB->MaskSurface(*source.mB, mask.mB, aOffset, aOptions);
116 void DrawTargetDual::ClearRect(const Rect& aRect) {
117 mA->FillRect(aRect, ColorPattern(DeviceColor::MaskOpaqueBlack()));
118 mB->FillRect(aRect, ColorPattern(DeviceColor::MaskOpaqueWhite()));
121 void DrawTargetDual::CopySurface(SourceSurface* aSurface,
122 const IntRect& aSourceRect,
123 const IntPoint& aDestination) {
124 DualSurface surface(aSurface);
125 mA->CopySurface(surface.mA, aSourceRect, aDestination);
126 mB->CopySurface(surface.mB, aSourceRect, aDestination);
129 void DrawTargetDual::FillRect(const Rect& aRect, const Pattern& aPattern,
130 const DrawOptions& aOptions) {
131 DualPattern pattern(aPattern);
132 mA->FillRect(aRect, *pattern.mA, aOptions);
133 mB->FillRect(aRect, *pattern.mB, aOptions);
136 void DrawTargetDual::StrokeRect(const Rect& aRect, const Pattern& aPattern,
137 const StrokeOptions& aStrokeOptions,
138 const DrawOptions& aOptions) {
139 DualPattern pattern(aPattern);
140 mA->StrokeRect(aRect, *pattern.mA, aStrokeOptions, aOptions);
141 mB->StrokeRect(aRect, *pattern.mB, aStrokeOptions, aOptions);
144 void DrawTargetDual::StrokeLine(const Point& aStart, const Point& aEnd,
145 const Pattern& aPattern,
146 const StrokeOptions& aStrokeOptions,
147 const DrawOptions& aOptions) {
148 DualPattern pattern(aPattern);
149 mA->StrokeLine(aStart, aEnd, *pattern.mA, aStrokeOptions, aOptions);
150 mB->StrokeLine(aStart, aEnd, *pattern.mB, aStrokeOptions, aOptions);
153 void DrawTargetDual::Stroke(const Path* aPath, const Pattern& aPattern,
154 const StrokeOptions& aStrokeOptions,
155 const DrawOptions& aOptions) {
156 DualPattern pattern(aPattern);
157 mA->Stroke(aPath, *pattern.mA, aStrokeOptions, aOptions);
158 mB->Stroke(aPath, *pattern.mB, aStrokeOptions, aOptions);
161 void DrawTargetDual::Fill(const Path* aPath, const Pattern& aPattern,
162 const DrawOptions& aOptions) {
163 DualPattern pattern(aPattern);
164 mA->Fill(aPath, *pattern.mA, aOptions);
165 mB->Fill(aPath, *pattern.mB, aOptions);
168 void DrawTargetDual::FillGlyphs(ScaledFont* aScaledFont,
169 const GlyphBuffer& aBuffer,
170 const Pattern& aPattern,
171 const DrawOptions& aOptions) {
172 DualPattern pattern(aPattern);
173 mA->FillGlyphs(aScaledFont, aBuffer, *pattern.mA, aOptions);
174 mB->FillGlyphs(aScaledFont, aBuffer, *pattern.mB, aOptions);
177 void DrawTargetDual::Mask(const Pattern& aSource, const Pattern& aMask,
178 const DrawOptions& aOptions) {
179 DualPattern source(aSource);
180 DualPattern mask(aMask);
181 mA->Mask(*source.mA, *mask.mA, aOptions);
182 mB->Mask(*source.mB, *mask.mB, aOptions);
185 void DrawTargetDual::PushLayer(bool aOpaque, Float aOpacity,
186 SourceSurface* aMask,
187 const Matrix& aMaskTransform,
188 const IntRect& aBounds, bool aCopyBackground) {
189 DualSurface mask(aMask);
190 mA->PushLayer(aOpaque, aOpacity, mask.mA, aMaskTransform, aBounds,
191 aCopyBackground);
192 mB->PushLayer(aOpaque, aOpacity, mask.mB, aMaskTransform, aBounds,
193 aCopyBackground);
196 already_AddRefed<DrawTarget> DrawTargetDual::CreateSimilarDrawTarget(
197 const IntSize& aSize, SurfaceFormat aFormat) const {
198 /* Now that we have PushLayer there a very few cases where a user of
199 * DrawTargetDual wants to have a DualTarget when creating a similar one. */
200 return mA->CreateSimilarDrawTarget(aSize, aFormat);
203 RefPtr<DrawTarget> DrawTargetDual::CreateClippedDrawTarget(
204 const Rect& aBounds, SurfaceFormat aFormat) {
205 /* The user probably doesn't want a DualDrawTarget here. */
206 return mA->CreateClippedDrawTarget(aBounds, aFormat);
209 bool DrawTargetDual::CanCreateSimilarDrawTarget(const IntSize& aSize,
210 SurfaceFormat aFormat) const {
211 return mA->CanCreateSimilarDrawTarget(aSize, aFormat);
214 } // namespace gfx
215 } // namespace mozilla