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