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"
16 inline explicit DualSurface(SourceSurface
* aSurface
) {
22 if (aSurface
->GetType() != SurfaceType::DUAL_DT
) {
27 SourceSurfaceDual
* ssDual
= static_cast<SourceSurfaceDual
*>(aSurface
);
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
{
42 inline explicit DualPattern(const Pattern
& aPattern
)
43 : mPatternsInitialized(false) {
44 if (aPattern
.GetType() != PatternType::SURFACE
) {
49 const SurfacePattern
* surfPat
=
50 static_cast<const SurfacePattern
*>(&aPattern
);
52 if (surfPat
->mSurface
->GetType() != SurfaceType::DUAL_DT
) {
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
) {
75 ClassStorage
<SurfacePattern
> mSurfPatA
;
76 ClassStorage
<SurfacePattern
> mSurfPatB
;
81 bool mPatternsInitialized
;
84 void DrawTargetDual::DetachAllSnapshots() {
85 mA
->DetachAllSnapshots();
86 mB
->DetachAllSnapshots();
89 void DrawTargetDual::DrawSurface(SourceSurface
* aSurface
, const Rect
& aDest
,
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
,
100 const DeviceColor
& aColor
,
101 const Point
& aOffset
, Float aSigma
,
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
,
192 mB
->PushLayer(aOpaque
, aOpacity
, mask
.mB
, aMaskTransform
, aBounds
,
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
);
215 } // namespace mozilla