Line data Source code
1 : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 : * This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #include "DrawTargetDual.h"
7 : #include "Tools.h"
8 : #include "Logging.h"
9 :
10 : namespace mozilla {
11 : namespace gfx {
12 :
13 : class DualSurface
14 : {
15 : public:
16 0 : inline explicit DualSurface(SourceSurface *aSurface)
17 0 : {
18 0 : if (!aSurface) {
19 0 : mA = mB = nullptr;
20 0 : return;
21 : }
22 :
23 0 : if (aSurface->GetType() != SurfaceType::DUAL_DT) {
24 0 : mA = mB = aSurface;
25 0 : return;
26 : }
27 :
28 : SourceSurfaceDual *ssDual =
29 0 : static_cast<SourceSurfaceDual*>(aSurface);
30 0 : mA = ssDual->mA;
31 0 : mB = ssDual->mB;
32 : }
33 :
34 : SourceSurface *mA;
35 : SourceSurface *mB;
36 : };
37 :
38 : /* This only needs to split patterns up for SurfacePatterns. Only in that
39 : * case can we be dealing with a 'dual' source (SourceSurfaceDual) and do
40 : * we need to pass separate patterns into our destination DrawTargets.
41 : */
42 : class DualPattern
43 : {
44 : public:
45 0 : inline explicit DualPattern(const Pattern &aPattern)
46 0 : : mPatternsInitialized(false)
47 : {
48 0 : if (aPattern.GetType() != PatternType::SURFACE) {
49 0 : mA = mB = &aPattern;
50 0 : return;
51 : }
52 :
53 : const SurfacePattern *surfPat =
54 0 : static_cast<const SurfacePattern*>(&aPattern);
55 :
56 0 : if (surfPat->mSurface->GetType() != SurfaceType::DUAL_DT) {
57 0 : mA = mB = &aPattern;
58 0 : return;
59 : }
60 :
61 : const SourceSurfaceDual *ssDual =
62 0 : static_cast<const SourceSurfaceDual*>(surfPat->mSurface.get());
63 0 : mA = new (mSurfPatA.addr()) SurfacePattern(ssDual->mA, surfPat->mExtendMode,
64 : surfPat->mMatrix,
65 0 : surfPat->mSamplingFilter);
66 0 : mB = new (mSurfPatB.addr()) SurfacePattern(ssDual->mB, surfPat->mExtendMode,
67 : surfPat->mMatrix,
68 0 : surfPat->mSamplingFilter);
69 0 : mPatternsInitialized = true;
70 : }
71 :
72 0 : inline ~DualPattern()
73 0 : {
74 0 : if (mPatternsInitialized) {
75 0 : mA->~Pattern();
76 0 : mB->~Pattern();
77 : }
78 0 : }
79 :
80 : ClassStorage<SurfacePattern> mSurfPatA;
81 : ClassStorage<SurfacePattern> mSurfPatB;
82 :
83 : const Pattern *mA;
84 : const Pattern *mB;
85 :
86 : bool mPatternsInitialized;
87 : };
88 :
89 : void
90 0 : DrawTargetDual::DetachAllSnapshots()
91 : {
92 0 : mA->DetachAllSnapshots();
93 0 : mB->DetachAllSnapshots();
94 0 : }
95 :
96 : void
97 0 : DrawTargetDual::DrawSurface(SourceSurface *aSurface, const Rect &aDest, const Rect &aSource,
98 : const DrawSurfaceOptions &aSurfOptions, const DrawOptions &aOptions)
99 : {
100 0 : DualSurface surface(aSurface);
101 0 : mA->DrawSurface(surface.mA, aDest, aSource, aSurfOptions, aOptions);
102 0 : mB->DrawSurface(surface.mB, aDest, aSource, aSurfOptions, aOptions);
103 0 : }
104 :
105 : void
106 0 : DrawTargetDual::DrawSurfaceWithShadow(SourceSurface *aSurface, const Point &aDest,
107 : const Color &aColor, const Point &aOffset,
108 : Float aSigma, CompositionOp aOp)
109 : {
110 0 : DualSurface surface(aSurface);
111 0 : mA->DrawSurfaceWithShadow(surface.mA, aDest, aColor, aOffset, aSigma, aOp);
112 0 : mB->DrawSurfaceWithShadow(surface.mB, aDest, aColor, aOffset, aSigma, aOp);
113 0 : }
114 :
115 : void
116 0 : DrawTargetDual::MaskSurface(const Pattern &aSource,
117 : SourceSurface *aMask,
118 : Point aOffset,
119 : const DrawOptions &aOptions)
120 : {
121 0 : DualPattern source(aSource);
122 0 : DualSurface mask(aMask);
123 0 : mA->MaskSurface(*source.mA, mask.mA, aOffset, aOptions);
124 0 : mB->MaskSurface(*source.mB, mask.mB, aOffset, aOptions);
125 0 : }
126 :
127 : void
128 0 : DrawTargetDual::CopySurface(SourceSurface *aSurface, const IntRect &aSourceRect,
129 : const IntPoint &aDestination)
130 : {
131 0 : DualSurface surface(aSurface);
132 0 : mA->CopySurface(surface.mA, aSourceRect, aDestination);
133 0 : mB->CopySurface(surface.mB, aSourceRect, aDestination);
134 0 : }
135 :
136 : void
137 0 : DrawTargetDual::FillRect(const Rect &aRect, const Pattern &aPattern, const DrawOptions &aOptions)
138 : {
139 0 : DualPattern pattern(aPattern);
140 0 : mA->FillRect(aRect, *pattern.mA, aOptions);
141 0 : mB->FillRect(aRect, *pattern.mB, aOptions);
142 0 : }
143 :
144 : void
145 0 : DrawTargetDual::StrokeRect(const Rect &aRect, const Pattern &aPattern,
146 : const StrokeOptions &aStrokeOptions, const DrawOptions &aOptions)
147 : {
148 0 : DualPattern pattern(aPattern);
149 0 : mA->StrokeRect(aRect, *pattern.mA, aStrokeOptions, aOptions);
150 0 : mB->StrokeRect(aRect, *pattern.mB, aStrokeOptions, aOptions);
151 0 : }
152 :
153 : void
154 0 : DrawTargetDual::StrokeLine(const Point &aStart, const Point &aEnd, const Pattern &aPattern,
155 : const StrokeOptions &aStrokeOptions, const DrawOptions &aOptions)
156 : {
157 0 : DualPattern pattern(aPattern);
158 0 : mA->StrokeLine(aStart, aEnd, *pattern.mA, aStrokeOptions, aOptions);
159 0 : mB->StrokeLine(aStart, aEnd, *pattern.mB, aStrokeOptions, aOptions);
160 0 : }
161 :
162 : void
163 0 : DrawTargetDual::Stroke(const Path *aPath, const Pattern &aPattern,
164 : const StrokeOptions &aStrokeOptions, const DrawOptions &aOptions)
165 : {
166 0 : DualPattern pattern(aPattern);
167 0 : mA->Stroke(aPath, *pattern.mA, aStrokeOptions, aOptions);
168 0 : mB->Stroke(aPath, *pattern.mB, aStrokeOptions, aOptions);
169 0 : }
170 :
171 : void
172 0 : DrawTargetDual::Fill(const Path *aPath, const Pattern &aPattern, const DrawOptions &aOptions)
173 : {
174 0 : DualPattern pattern(aPattern);
175 0 : mA->Fill(aPath, *pattern.mA, aOptions);
176 0 : mB->Fill(aPath, *pattern.mB, aOptions);
177 0 : }
178 :
179 : void
180 0 : DrawTargetDual::FillGlyphs(ScaledFont *aScaledFont, const GlyphBuffer &aBuffer,
181 : const Pattern &aPattern, const DrawOptions &aOptions,
182 : const GlyphRenderingOptions *aRenderingOptions)
183 : {
184 0 : DualPattern pattern(aPattern);
185 0 : mA->FillGlyphs(aScaledFont, aBuffer, *pattern.mA, aOptions, aRenderingOptions);
186 0 : mB->FillGlyphs(aScaledFont, aBuffer, *pattern.mB, aOptions, aRenderingOptions);
187 0 : }
188 :
189 : void
190 0 : DrawTargetDual::Mask(const Pattern &aSource, const Pattern &aMask, const DrawOptions &aOptions)
191 : {
192 0 : DualPattern source(aSource);
193 0 : DualPattern mask(aMask);
194 0 : mA->Mask(*source.mA, *mask.mA, aOptions);
195 0 : mB->Mask(*source.mB, *mask.mB, aOptions);
196 0 : }
197 :
198 : void
199 0 : DrawTargetDual::PushLayer(bool aOpaque, Float aOpacity, SourceSurface* aMask,
200 : const Matrix& aMaskTransform, const IntRect& aBounds,
201 : bool aCopyBackground)
202 : {
203 0 : DualSurface mask(aMask);
204 0 : mA->PushLayer(aOpaque, aOpacity, mask.mA, aMaskTransform, aBounds, aCopyBackground);
205 0 : mB->PushLayer(aOpaque, aOpacity, mask.mB, aMaskTransform, aBounds, aCopyBackground);
206 0 : }
207 :
208 : already_AddRefed<DrawTarget>
209 0 : DrawTargetDual::CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const
210 : {
211 : /* Now that we have PushLayer there a very few cases where a user of DrawTargetDual
212 : * wants to have a DualTarget when creating a similar one. */
213 0 : return mA->CreateSimilarDrawTarget(aSize, aFormat);
214 : }
215 :
216 : } // namespace gfx
217 : } // namespace mozilla
|