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 "DrawTargetCapture.h"
7 : #include "DrawCommand.h"
8 :
9 : namespace mozilla {
10 : namespace gfx {
11 :
12 :
13 0 : DrawTargetCaptureImpl::~DrawTargetCaptureImpl()
14 : {
15 0 : uint8_t* start = &mDrawCommandStorage.front();
16 :
17 0 : uint8_t* current = start;
18 :
19 0 : while (current < start + mDrawCommandStorage.size()) {
20 0 : reinterpret_cast<DrawingCommand*>(current + sizeof(uint32_t))->~DrawingCommand();
21 0 : current += *(uint32_t*)current;
22 : }
23 0 : }
24 :
25 : bool
26 0 : DrawTargetCaptureImpl::Init(const IntSize& aSize, DrawTarget* aRefDT)
27 : {
28 0 : if (!aRefDT) {
29 0 : return false;
30 : }
31 :
32 0 : mRefDT = aRefDT;
33 :
34 0 : mSize = aSize;
35 0 : return true;
36 : }
37 :
38 : already_AddRefed<SourceSurface>
39 0 : DrawTargetCaptureImpl::Snapshot()
40 : {
41 0 : RefPtr<DrawTarget> dt = mRefDT->CreateSimilarDrawTarget(mSize, mRefDT->GetFormat());
42 :
43 0 : ReplayToDrawTarget(dt, Matrix());
44 :
45 0 : return dt->Snapshot();
46 : }
47 :
48 : void
49 0 : DrawTargetCaptureImpl::DetachAllSnapshots()
50 0 : {}
51 :
52 : #define AppendCommand(arg) new (AppendToCommandList<arg>()) arg
53 :
54 : void
55 0 : DrawTargetCaptureImpl::DrawSurface(SourceSurface *aSurface,
56 : const Rect &aDest,
57 : const Rect &aSource,
58 : const DrawSurfaceOptions &aSurfOptions,
59 : const DrawOptions &aOptions)
60 : {
61 0 : aSurface->GuaranteePersistance();
62 0 : AppendCommand(DrawSurfaceCommand)(aSurface, aDest, aSource, aSurfOptions, aOptions);
63 0 : }
64 :
65 : void
66 0 : DrawTargetCaptureImpl::DrawFilter(FilterNode *aNode,
67 : const Rect &aSourceRect,
68 : const Point &aDestPoint,
69 : const DrawOptions &aOptions)
70 : {
71 : // @todo XXX - this won't work properly long term yet due to filternodes not
72 : // being immutable.
73 0 : AppendCommand(DrawFilterCommand)(aNode, aSourceRect, aDestPoint, aOptions);
74 0 : }
75 :
76 : void
77 0 : DrawTargetCaptureImpl::ClearRect(const Rect &aRect)
78 : {
79 0 : AppendCommand(ClearRectCommand)(aRect);
80 0 : }
81 :
82 : void
83 0 : DrawTargetCaptureImpl::MaskSurface(const Pattern &aSource,
84 : SourceSurface *aMask,
85 : Point aOffset,
86 : const DrawOptions &aOptions)
87 : {
88 0 : aMask->GuaranteePersistance();
89 0 : AppendCommand(MaskSurfaceCommand)(aSource, aMask, aOffset, aOptions);
90 0 : }
91 :
92 : void
93 0 : DrawTargetCaptureImpl::CopySurface(SourceSurface* aSurface,
94 : const IntRect& aSourceRect,
95 : const IntPoint& aDestination)
96 : {
97 0 : aSurface->GuaranteePersistance();
98 0 : AppendCommand(CopySurfaceCommand)(aSurface, aSourceRect, aDestination);
99 0 : }
100 :
101 : void
102 0 : DrawTargetCaptureImpl::FillRect(const Rect& aRect,
103 : const Pattern& aPattern,
104 : const DrawOptions& aOptions)
105 : {
106 0 : AppendCommand(FillRectCommand)(aRect, aPattern, aOptions);
107 0 : }
108 :
109 : void
110 0 : DrawTargetCaptureImpl::StrokeRect(const Rect& aRect,
111 : const Pattern& aPattern,
112 : const StrokeOptions& aStrokeOptions,
113 : const DrawOptions& aOptions)
114 : {
115 0 : AppendCommand(StrokeRectCommand)(aRect, aPattern, aStrokeOptions, aOptions);
116 0 : }
117 :
118 : void
119 0 : DrawTargetCaptureImpl::StrokeLine(const Point& aStart,
120 : const Point& aEnd,
121 : const Pattern& aPattern,
122 : const StrokeOptions& aStrokeOptions,
123 : const DrawOptions& aOptions)
124 : {
125 0 : AppendCommand(StrokeLineCommand)(aStart, aEnd, aPattern, aStrokeOptions, aOptions);
126 0 : }
127 :
128 : void
129 0 : DrawTargetCaptureImpl::Stroke(const Path* aPath,
130 : const Pattern& aPattern,
131 : const StrokeOptions& aStrokeOptions,
132 : const DrawOptions& aOptions)
133 : {
134 0 : AppendCommand(StrokeCommand)(aPath, aPattern, aStrokeOptions, aOptions);
135 0 : }
136 :
137 : void
138 0 : DrawTargetCaptureImpl::Fill(const Path* aPath,
139 : const Pattern& aPattern,
140 : const DrawOptions& aOptions)
141 : {
142 0 : AppendCommand(FillCommand)(aPath, aPattern, aOptions);
143 0 : }
144 :
145 : void
146 0 : DrawTargetCaptureImpl::FillGlyphs(ScaledFont* aFont,
147 : const GlyphBuffer& aBuffer,
148 : const Pattern& aPattern,
149 : const DrawOptions& aOptions,
150 : const GlyphRenderingOptions* aRenderingOptions)
151 : {
152 0 : AppendCommand(FillGlyphsCommand)(aFont, aBuffer, aPattern, aOptions, aRenderingOptions);
153 0 : }
154 :
155 : void
156 0 : DrawTargetCaptureImpl::Mask(const Pattern &aSource,
157 : const Pattern &aMask,
158 : const DrawOptions &aOptions)
159 : {
160 0 : AppendCommand(MaskCommand)(aSource, aMask, aOptions);
161 0 : }
162 :
163 : void
164 0 : DrawTargetCaptureImpl::PushClip(const Path* aPath)
165 : {
166 0 : AppendCommand(PushClipCommand)(aPath);
167 0 : }
168 :
169 : void
170 0 : DrawTargetCaptureImpl::PushClipRect(const Rect& aRect)
171 : {
172 0 : AppendCommand(PushClipRectCommand)(aRect);
173 0 : }
174 :
175 : void
176 0 : DrawTargetCaptureImpl::PushLayer(bool aOpaque,
177 : Float aOpacity,
178 : SourceSurface* aMask,
179 : const Matrix& aMaskTransform,
180 : const IntRect& aBounds,
181 : bool aCopyBackground)
182 : {
183 : AppendCommand(PushLayerCommand)(aOpaque,
184 : aOpacity,
185 : aMask,
186 : aMaskTransform,
187 : aBounds,
188 0 : aCopyBackground);
189 0 : }
190 :
191 : void
192 0 : DrawTargetCaptureImpl::PopLayer()
193 : {
194 0 : AppendCommand(PopLayerCommand)();
195 0 : }
196 :
197 : void
198 0 : DrawTargetCaptureImpl::PopClip()
199 : {
200 0 : AppendCommand(PopClipCommand)();
201 0 : }
202 :
203 : void
204 0 : DrawTargetCaptureImpl::SetTransform(const Matrix& aTransform)
205 : {
206 0 : AppendCommand(SetTransformCommand)(aTransform);
207 :
208 : // Have to update the transform for this DT
209 : // because some code paths query the current transform
210 : // to render specific things.
211 0 : DrawTarget::SetTransform(aTransform);
212 0 : }
213 :
214 : void
215 0 : DrawTargetCaptureImpl::ReplayToDrawTarget(DrawTarget* aDT, const Matrix& aTransform)
216 : {
217 0 : uint8_t* start = &mDrawCommandStorage.front();
218 :
219 0 : uint8_t* current = start;
220 :
221 0 : while (current < start + mDrawCommandStorage.size()) {
222 0 : reinterpret_cast<DrawingCommand*>(current + sizeof(uint32_t))->ExecuteOnDT(aDT, &aTransform);
223 0 : current += *(uint32_t*)current;
224 : }
225 0 : }
226 :
227 : bool
228 0 : DrawTargetCaptureImpl::ContainsOnlyColoredGlyphs(RefPtr<ScaledFont>& aScaledFont,
229 : Color& aColor,
230 : std::vector<Glyph>& aGlyphs)
231 : {
232 0 : uint8_t* start = &mDrawCommandStorage.front();
233 0 : uint8_t* current = start;
234 0 : bool result = false;
235 :
236 0 : while (current < start + mDrawCommandStorage.size()) {
237 : DrawingCommand* command =
238 0 : reinterpret_cast<DrawingCommand*>(current + sizeof(uint32_t));
239 0 : current += *(uint32_t*)current;
240 :
241 0 : if (command->GetType() != CommandType::FILLGLYPHS &&
242 0 : command->GetType() != CommandType::SETTRANSFORM) {
243 0 : return false;
244 : }
245 :
246 0 : if (command->GetType() == CommandType::SETTRANSFORM) {
247 0 : SetTransformCommand* transform = static_cast<SetTransformCommand*>(command);
248 0 : if (transform->mTransform != Matrix()) {
249 0 : return false;
250 : }
251 0 : continue;
252 : }
253 :
254 0 : FillGlyphsCommand* fillGlyphs = static_cast<FillGlyphsCommand*>(command);
255 0 : if (aScaledFont && fillGlyphs->mFont != aScaledFont) {
256 0 : return false;
257 : }
258 0 : aScaledFont = fillGlyphs->mFont;
259 :
260 0 : Pattern& pat = fillGlyphs->mPattern;
261 :
262 0 : if (pat.GetType() != PatternType::COLOR) {
263 0 : return false;
264 : }
265 :
266 0 : ColorPattern* colorPat = static_cast<ColorPattern*>(&pat);
267 0 : if (aColor != Color() && colorPat->mColor != aColor) {
268 0 : return false;
269 : }
270 0 : aColor = colorPat->mColor;
271 :
272 0 : if (fillGlyphs->mOptions.mCompositionOp != CompositionOp::OP_OVER ||
273 0 : fillGlyphs->mOptions.mAlpha != 1.0f) {
274 0 : return false;
275 : }
276 :
277 : //TODO: Deal with AA on the DrawOptions, and the GlyphRenderingOptions
278 :
279 0 : aGlyphs.insert(aGlyphs.end(),
280 : fillGlyphs->mGlyphs.begin(),
281 0 : fillGlyphs->mGlyphs.end());
282 0 : result = true;
283 : }
284 0 : return result;
285 : }
286 :
287 : } // namespace gfx
288 : } // namespace mozilla
|