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 #ifndef MOZILLA_GFX_DRAWCOMMANDS_H_
8 #define MOZILLA_GFX_DRAWCOMMANDS_H_
9 
10 #include <math.h>
11 
12 #include "2D.h"
13 #include "Blur.h"
14 #include "Filters.h"
15 #include <vector>
16 #include "CaptureCommandList.h"
17 #include "DrawCommand.h"
18 #include "FilterNodeCapture.h"
19 #include "Logging.h"
20 #include "nsRegion.h"
21 
22 namespace mozilla {
23 namespace gfx {
24 
25 #define CLONE_INTO(Type) new (aList->Append<Type>()) Type
26 
27 class StrokeOptionsCommand : public DrawingCommand {
28  public:
StrokeOptionsCommand(const StrokeOptions & aStrokeOptions)29   StrokeOptionsCommand(const StrokeOptions& aStrokeOptions)
30       : mStrokeOptions(aStrokeOptions) {
31     // Stroke Options dashes are owned by the caller.
32     // Have to copy them here so they don't get freed
33     // between now and replay.
34     if (aStrokeOptions.mDashLength) {
35       mDashes.resize(aStrokeOptions.mDashLength);
36       mStrokeOptions.mDashPattern = &mDashes.front();
37       PodCopy(&mDashes.front(), aStrokeOptions.mDashPattern,
38               mStrokeOptions.mDashLength);
39     }
40   }
41 
42   virtual ~StrokeOptionsCommand() = default;
43 
44  protected:
45   StrokeOptions mStrokeOptions;
46   std::vector<Float> mDashes;
47 };
48 
49 class StoredPattern {
50  public:
StoredPattern(const Pattern & aPattern)51   explicit StoredPattern(const Pattern& aPattern) { Assign(aPattern); }
52 
Assign(const Pattern & aPattern)53   void Assign(const Pattern& aPattern) {
54     switch (aPattern.GetType()) {
55       case PatternType::COLOR:
56         new (mColor) ColorPattern(*static_cast<const ColorPattern*>(&aPattern));
57         return;
58       case PatternType::SURFACE: {
59         SurfacePattern* surfPat = new (mSurface)
60             SurfacePattern(*static_cast<const SurfacePattern*>(&aPattern));
61         surfPat->mSurface->GuaranteePersistance();
62         return;
63       }
64       case PatternType::LINEAR_GRADIENT:
65         new (mLinear) LinearGradientPattern(
66             *static_cast<const LinearGradientPattern*>(&aPattern));
67         return;
68       case PatternType::RADIAL_GRADIENT:
69         new (mRadial) RadialGradientPattern(
70             *static_cast<const RadialGradientPattern*>(&aPattern));
71         return;
72       case PatternType::CONIC_GRADIENT:
73         new (mConic) ConicGradientPattern(
74             *static_cast<const ConicGradientPattern*>(&aPattern));
75         return;
76     }
77   }
78 
~StoredPattern()79   ~StoredPattern() { reinterpret_cast<Pattern*>(mPattern)->~Pattern(); }
80 
Get()81   Pattern* Get() { return reinterpret_cast<Pattern*>(mPattern); }
82 
Get()83   const Pattern* Get() const {
84     return reinterpret_cast<const Pattern*>(mPattern);
85   }
86 
87   operator Pattern&() { return *reinterpret_cast<Pattern*>(mPattern); }
88 
89   operator const Pattern&() const {
90     return *reinterpret_cast<const Pattern*>(mPattern);
91   }
92 
StoredPattern(const StoredPattern & aPattern)93   StoredPattern(const StoredPattern& aPattern) { Assign(aPattern); }
94 
95  private:
96   StoredPattern operator=(const StoredPattern& aOther) {
97     // Block this so that we notice if someone's doing excessive assigning.
98     return *this;
99   }
100 
101   union {
102     char mPattern[sizeof(Pattern)];
103     char mColor[sizeof(ColorPattern)];
104     char mLinear[sizeof(LinearGradientPattern)];
105     char mRadial[sizeof(RadialGradientPattern)];
106     char mConic[sizeof(ConicGradientPattern)];
107     char mSurface[sizeof(SurfacePattern)];
108   };
109 };
110 
111 class DrawSurfaceCommand : public DrawingCommand {
112  public:
DrawSurfaceCommand(SourceSurface * aSurface,const Rect & aDest,const Rect & aSource,const DrawSurfaceOptions & aSurfOptions,const DrawOptions & aOptions)113   DrawSurfaceCommand(SourceSurface* aSurface, const Rect& aDest,
114                      const Rect& aSource,
115                      const DrawSurfaceOptions& aSurfOptions,
116                      const DrawOptions& aOptions)
117       : mSurface(aSurface),
118         mDest(aDest),
119         mSource(aSource),
120         mSurfOptions(aSurfOptions),
121         mOptions(aOptions) {}
122 
GetType()123   CommandType GetType() const override { return DrawSurfaceCommand::Type; }
124 
CloneInto(CaptureCommandList * aList)125   void CloneInto(CaptureCommandList* aList) override {
126     CLONE_INTO(DrawSurfaceCommand)
127     (mSurface, mDest, mSource, mSurfOptions, mOptions);
128   }
129 
ExecuteOnDT(DrawTarget * aDT,const Matrix *)130   void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
131     aDT->DrawSurface(mSurface, mDest, mSource, mSurfOptions, mOptions);
132   }
133 
Log(TreeLog<> & aStream)134   void Log(TreeLog<>& aStream) const override {
135     aStream << "[DrawSurface surf=" << mSurface;
136     aStream << " dest=" << mDest;
137     aStream << " src=" << mSource;
138     aStream << " surfOpt=" << mSurfOptions;
139     aStream << " opt=" << mOptions;
140     aStream << "]";
141   }
142 
143   static const bool AffectsSnapshot = true;
144   static const CommandType Type = CommandType::DRAWSURFACE;
145 
146  private:
147   RefPtr<SourceSurface> mSurface;
148   Rect mDest;
149   Rect mSource;
150   DrawSurfaceOptions mSurfOptions;
151   DrawOptions mOptions;
152 };
153 
154 class DrawSurfaceWithShadowCommand : public DrawingCommand {
155  public:
DrawSurfaceWithShadowCommand(SourceSurface * aSurface,const Point & aDest,const DeviceColor & aColor,const Point & aOffset,Float aSigma,CompositionOp aOperator)156   DrawSurfaceWithShadowCommand(SourceSurface* aSurface, const Point& aDest,
157                                const DeviceColor& aColor, const Point& aOffset,
158                                Float aSigma, CompositionOp aOperator)
159       : mSurface(aSurface),
160         mDest(aDest),
161         mColor(aColor),
162         mOffset(aOffset),
163         mSigma(aSigma),
164         mOperator(aOperator) {}
165 
GetType()166   CommandType GetType() const override {
167     return DrawSurfaceWithShadowCommand::Type;
168   }
169 
CloneInto(CaptureCommandList * aList)170   void CloneInto(CaptureCommandList* aList) override {
171     CLONE_INTO(DrawSurfaceWithShadowCommand)
172     (mSurface, mDest, mColor, mOffset, mSigma, mOperator);
173   }
174 
ExecuteOnDT(DrawTarget * aDT,const Matrix *)175   void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
176     aDT->DrawSurfaceWithShadow(mSurface, mDest, mColor, mOffset, mSigma,
177                                mOperator);
178   }
179 
Log(TreeLog<> & aStream)180   void Log(TreeLog<>& aStream) const override {
181     aStream << "[DrawSurfaceWithShadow surf=" << mSurface;
182     aStream << " dest=" << mDest;
183     aStream << " color=" << mColor;
184     aStream << " offset=" << mOffset;
185     aStream << " sigma=" << mSigma;
186     aStream << " op=" << mOperator;
187     aStream << "]";
188   }
189 
190   static const bool AffectsSnapshot = true;
191   static const CommandType Type = CommandType::DRAWSURFACEWITHSHADOW;
192 
193  private:
194   RefPtr<SourceSurface> mSurface;
195   Point mDest;
196   DeviceColor mColor;
197   Point mOffset;
198   Float mSigma;
199   CompositionOp mOperator;
200 };
201 
202 class DrawFilterCommand : public DrawingCommand {
203  public:
DrawFilterCommand(FilterNode * aFilter,const Rect & aSourceRect,const Point & aDestPoint,const DrawOptions & aOptions)204   DrawFilterCommand(FilterNode* aFilter, const Rect& aSourceRect,
205                     const Point& aDestPoint, const DrawOptions& aOptions)
206       : mFilter(aFilter),
207         mSourceRect(aSourceRect),
208         mDestPoint(aDestPoint),
209         mOptions(aOptions) {}
210 
GetType()211   CommandType GetType() const override { return DrawFilterCommand::Type; }
212 
CloneInto(CaptureCommandList * aList)213   void CloneInto(CaptureCommandList* aList) override {
214     CLONE_INTO(DrawFilterCommand)(mFilter, mSourceRect, mDestPoint, mOptions);
215   }
216 
ExecuteOnDT(DrawTarget * aDT,const Matrix *)217   void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
218     RefPtr<FilterNode> filter = mFilter;
219     if (mFilter->GetBackendType() == FilterBackend::FILTER_BACKEND_CAPTURE) {
220       filter = static_cast<FilterNodeCapture*>(filter.get())->Validate(aDT);
221 
222       // This can happen if the FilterNodeCapture is unable to create a
223       // backing FilterNode on the target backend. Normally this would be
224       // handled by the painting code, but here there's not much we can do.
225       if (!filter) {
226         return;
227       }
228     }
229     aDT->DrawFilter(filter, mSourceRect, mDestPoint, mOptions);
230   }
231 
Log(TreeLog<> & aStream)232   void Log(TreeLog<>& aStream) const override {
233     aStream << "[DrawFilter surf=" << mFilter;
234     aStream << " src=" << mSourceRect;
235     aStream << " dest=" << mDestPoint;
236     aStream << " opt=" << mOptions;
237     aStream << "]";
238   }
239 
240   static const bool AffectsSnapshot = true;
241   static const CommandType Type = CommandType::DRAWFILTER;
242 
243  private:
244   RefPtr<FilterNode> mFilter;
245   Rect mSourceRect;
246   Point mDestPoint;
247   DrawOptions mOptions;
248 };
249 
250 class ClearRectCommand : public DrawingCommand {
251  public:
ClearRectCommand(const Rect & aRect)252   explicit ClearRectCommand(const Rect& aRect) : mRect(aRect) {}
253 
GetType()254   CommandType GetType() const override { return ClearRectCommand::Type; }
255 
CloneInto(CaptureCommandList * aList)256   void CloneInto(CaptureCommandList* aList) override {
257     CLONE_INTO(ClearRectCommand)(mRect);
258   }
259 
ExecuteOnDT(DrawTarget * aDT,const Matrix *)260   void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
261     aDT->ClearRect(mRect);
262   }
263 
Log(TreeLog<> & aStream)264   void Log(TreeLog<>& aStream) const override {
265     aStream << "[ClearRect rect=" << mRect << "]";
266   }
267 
268   static const bool AffectsSnapshot = true;
269   static const CommandType Type = CommandType::CLEARRECT;
270 
271  private:
272   Rect mRect;
273 };
274 
275 class CopySurfaceCommand : public DrawingCommand {
276  public:
CopySurfaceCommand(SourceSurface * aSurface,const IntRect & aSourceRect,const IntPoint & aDestination)277   CopySurfaceCommand(SourceSurface* aSurface, const IntRect& aSourceRect,
278                      const IntPoint& aDestination)
279       : mSurface(aSurface),
280         mSourceRect(aSourceRect),
281         mDestination(aDestination) {}
282 
GetType()283   CommandType GetType() const override { return CopySurfaceCommand::Type; }
284 
CloneInto(CaptureCommandList * aList)285   void CloneInto(CaptureCommandList* aList) override {
286     CLONE_INTO(CopySurfaceCommand)(mSurface, mSourceRect, mDestination);
287   }
288 
ExecuteOnDT(DrawTarget * aDT,const Matrix * aTransform)289   virtual void ExecuteOnDT(DrawTarget* aDT,
290                            const Matrix* aTransform) const override {
291     MOZ_ASSERT(!aTransform || !aTransform->HasNonIntegerTranslation());
292     Point dest(Float(mDestination.x), Float(mDestination.y));
293     if (aTransform) {
294       dest = aTransform->TransformPoint(dest);
295     }
296     aDT->CopySurface(mSurface, mSourceRect,
297                      IntPoint(uint32_t(dest.x), uint32_t(dest.y)));
298   }
299 
Log(TreeLog<> & aStream)300   void Log(TreeLog<>& aStream) const override {
301     aStream << "[CopySurface surf=" << mSurface;
302     aStream << " src=" << mSourceRect;
303     aStream << " dest=" << mDestination;
304     aStream << "]";
305   }
306 
307   static const bool AffectsSnapshot = true;
308   static const CommandType Type = CommandType::COPYSURFACE;
309 
310  private:
311   RefPtr<SourceSurface> mSurface;
312   IntRect mSourceRect;
313   IntPoint mDestination;
314 };
315 
316 class CopyRectCommand : public DrawingCommand {
317  public:
CopyRectCommand(const IntRect & aSourceRect,const IntPoint & aDestination)318   CopyRectCommand(const IntRect& aSourceRect, const IntPoint& aDestination)
319       : mSourceRect(aSourceRect), mDestination(aDestination) {}
320 
GetType()321   CommandType GetType() const override { return CopyRectCommand::Type; }
322 
CloneInto(CaptureCommandList * aList)323   void CloneInto(CaptureCommandList* aList) override {
324     CLONE_INTO(CopyRectCommand)(mSourceRect, mDestination);
325   }
326 
ExecuteOnDT(DrawTarget * aDT,const Matrix * aTransform)327   virtual void ExecuteOnDT(DrawTarget* aDT,
328                            const Matrix* aTransform) const override {
329     aDT->CopyRect(mSourceRect, mDestination);
330   }
331 
Log(TreeLog<> & aStream)332   void Log(TreeLog<>& aStream) const override {
333     aStream << "[CopyRect src=" << mSourceRect;
334     aStream << " dest=" << mDestination;
335     aStream << "]";
336   }
337 
338   static const bool AffectsSnapshot = true;
339   static const CommandType Type = CommandType::COPYRECT;
340 
341  private:
342   IntRect mSourceRect;
343   IntPoint mDestination;
344 };
345 
346 class FillRectCommand : public DrawingCommand {
347  public:
FillRectCommand(const Rect & aRect,const Pattern & aPattern,const DrawOptions & aOptions)348   FillRectCommand(const Rect& aRect, const Pattern& aPattern,
349                   const DrawOptions& aOptions)
350       : mRect(aRect), mPattern(aPattern), mOptions(aOptions) {}
351 
GetType()352   CommandType GetType() const override { return FillRectCommand::Type; }
353 
CloneInto(CaptureCommandList * aList)354   void CloneInto(CaptureCommandList* aList) override {
355     CLONE_INTO(FillRectCommand)(mRect, mPattern, mOptions);
356   }
357 
ExecuteOnDT(DrawTarget * aDT,const Matrix *)358   void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
359     aDT->FillRect(mRect, mPattern, mOptions);
360   }
361 
Log(TreeLog<> & aStream)362   void Log(TreeLog<>& aStream) const override {
363     aStream << "[FillRect rect=" << mRect;
364     aStream << " pattern=" << mPattern.Get();
365     aStream << " opt=" << mOptions;
366     aStream << "]";
367   }
368 
369   static const bool AffectsSnapshot = true;
370   static const CommandType Type = CommandType::FILLRECT;
371 
372  private:
373   Rect mRect;
374   StoredPattern mPattern;
375   DrawOptions mOptions;
376 };
377 
378 class FillRoundedRectCommand : public DrawingCommand {
379  public:
FillRoundedRectCommand(const RoundedRect & aRect,const Pattern & aPattern,const DrawOptions & aOptions)380   FillRoundedRectCommand(const RoundedRect& aRect, const Pattern& aPattern,
381                          const DrawOptions& aOptions)
382       : mRect(aRect), mPattern(aPattern), mOptions(aOptions) {}
383 
GetType()384   CommandType GetType() const override { return FillRoundedRectCommand::Type; }
385 
CloneInto(CaptureCommandList * aList)386   void CloneInto(CaptureCommandList* aList) override {
387     CLONE_INTO(FillRoundedRectCommand)(mRect, mPattern, mOptions);
388   }
389 
ExecuteOnDT(DrawTarget * aDT,const Matrix *)390   void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
391     aDT->FillRoundedRect(mRect, mPattern, mOptions);
392   }
393 
Log(TreeLog<> & aStream)394   void Log(TreeLog<>& aStream) const override {
395     aStream << "[FillRoundedRect rect=" << mRect.rect;
396     aStream << " pattern=" << mPattern.Get();
397     aStream << " opt=" << mOptions;
398     aStream << "]";
399   }
400 
401   static const bool AffectsSnapshot = true;
402   static const CommandType Type = CommandType::FILLROUNDEDRECT;
403 
404  private:
405   RoundedRect mRect;
406   StoredPattern mPattern;
407   DrawOptions mOptions;
408 };
409 
410 class StrokeRectCommand : public StrokeOptionsCommand {
411  public:
StrokeRectCommand(const Rect & aRect,const Pattern & aPattern,const StrokeOptions & aStrokeOptions,const DrawOptions & aOptions)412   StrokeRectCommand(const Rect& aRect, const Pattern& aPattern,
413                     const StrokeOptions& aStrokeOptions,
414                     const DrawOptions& aOptions)
415       : StrokeOptionsCommand(aStrokeOptions),
416         mRect(aRect),
417         mPattern(aPattern),
418         mOptions(aOptions) {}
419 
GetType()420   CommandType GetType() const override { return StrokeRectCommand::Type; }
421 
CloneInto(CaptureCommandList * aList)422   void CloneInto(CaptureCommandList* aList) override {
423     CLONE_INTO(StrokeRectCommand)(mRect, mPattern, mStrokeOptions, mOptions);
424   }
425 
ExecuteOnDT(DrawTarget * aDT,const Matrix *)426   void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
427     aDT->StrokeRect(mRect, mPattern, mStrokeOptions, mOptions);
428   }
429 
Log(TreeLog<> & aStream)430   void Log(TreeLog<>& aStream) const override {
431     aStream << "[StrokeRect rect=" << mRect;
432     aStream << " pattern=" << mPattern.Get();
433     aStream << " opt=" << mOptions;
434     aStream << "]";
435   }
436 
437   static const bool AffectsSnapshot = true;
438   static const CommandType Type = CommandType::STROKERECT;
439 
440  private:
441   Rect mRect;
442   StoredPattern mPattern;
443   DrawOptions mOptions;
444 };
445 
446 class StrokeLineCommand : public StrokeOptionsCommand {
447  public:
StrokeLineCommand(const Point & aStart,const Point & aEnd,const Pattern & aPattern,const StrokeOptions & aStrokeOptions,const DrawOptions & aOptions)448   StrokeLineCommand(const Point& aStart, const Point& aEnd,
449                     const Pattern& aPattern,
450                     const StrokeOptions& aStrokeOptions,
451                     const DrawOptions& aOptions)
452       : StrokeOptionsCommand(aStrokeOptions),
453         mStart(aStart),
454         mEnd(aEnd),
455         mPattern(aPattern),
456         mOptions(aOptions) {}
457 
GetType()458   CommandType GetType() const override { return StrokeLineCommand::Type; }
459 
CloneInto(CaptureCommandList * aList)460   void CloneInto(CaptureCommandList* aList) override {
461     CLONE_INTO(StrokeLineCommand)
462     (mStart, mEnd, mPattern, mStrokeOptions, mOptions);
463   }
464 
ExecuteOnDT(DrawTarget * aDT,const Matrix *)465   void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
466     aDT->StrokeLine(mStart, mEnd, mPattern, mStrokeOptions, mOptions);
467   }
468 
Log(TreeLog<> & aStream)469   void Log(TreeLog<>& aStream) const override {
470     aStream << "[StrokeLine start=" << mStart;
471     aStream << " end=" << mEnd;
472     aStream << " pattern=" << mPattern.Get();
473     aStream << " opt=" << mOptions;
474     aStream << "]";
475   }
476 
477   static const bool AffectsSnapshot = true;
478   static const CommandType Type = CommandType::STROKELINE;
479 
480  private:
481   Point mStart;
482   Point mEnd;
483   StoredPattern mPattern;
484   DrawOptions mOptions;
485 };
486 
487 class FillCommand : public DrawingCommand {
488  public:
FillCommand(const Path * aPath,const Pattern & aPattern,const DrawOptions & aOptions)489   FillCommand(const Path* aPath, const Pattern& aPattern,
490               const DrawOptions& aOptions)
491       : mPath(const_cast<Path*>(aPath)),
492         mPattern(aPattern),
493         mOptions(aOptions) {}
494 
GetType()495   CommandType GetType() const override { return FillCommand::Type; }
496 
CloneInto(CaptureCommandList * aList)497   void CloneInto(CaptureCommandList* aList) override {
498     CLONE_INTO(FillCommand)(mPath, mPattern, mOptions);
499   }
500 
ExecuteOnDT(DrawTarget * aDT,const Matrix *)501   void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
502     aDT->Fill(mPath, mPattern, mOptions);
503   }
504 
Log(TreeLog<> & aStream)505   void Log(TreeLog<>& aStream) const override {
506     aStream << "[FillCommand path=" << mPath;
507     aStream << " pattern=" << mPattern.Get();
508     aStream << " opt=" << mOptions;
509     aStream << "]";
510   }
511 
512   static const bool AffectsSnapshot = true;
513   static const CommandType Type = CommandType::FILL;
514 
515  private:
516   RefPtr<Path> mPath;
517   StoredPattern mPattern;
518   DrawOptions mOptions;
519 };
520 
521 class StrokeCommand : public StrokeOptionsCommand {
522  public:
StrokeCommand(const Path * aPath,const Pattern & aPattern,const StrokeOptions & aStrokeOptions,const DrawOptions & aOptions)523   StrokeCommand(const Path* aPath, const Pattern& aPattern,
524                 const StrokeOptions& aStrokeOptions,
525                 const DrawOptions& aOptions)
526       : StrokeOptionsCommand(aStrokeOptions),
527         mPath(const_cast<Path*>(aPath)),
528         mPattern(aPattern),
529         mOptions(aOptions) {}
530 
GetType()531   CommandType GetType() const override { return StrokeCommand::Type; }
532 
CloneInto(CaptureCommandList * aList)533   void CloneInto(CaptureCommandList* aList) override {
534     CLONE_INTO(StrokeCommand)(mPath, mPattern, mStrokeOptions, mOptions);
535   }
536 
ExecuteOnDT(DrawTarget * aDT,const Matrix *)537   void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
538     aDT->Stroke(mPath, mPattern, mStrokeOptions, mOptions);
539   }
540 
Log(TreeLog<> & aStream)541   void Log(TreeLog<>& aStream) const override {
542     aStream << "[Stroke path=" << mPath;
543     aStream << " pattern=" << mPattern.Get();
544     aStream << " opt=" << mOptions;
545     aStream << "]";
546   }
547 
548   static const bool AffectsSnapshot = true;
549   static const CommandType Type = CommandType::STROKE;
550 
551  private:
552   RefPtr<Path> mPath;
553   StoredPattern mPattern;
554   DrawOptions mOptions;
555 };
556 
557 class FillGlyphsCommand : public DrawingCommand {
558   friend class DrawTargetCaptureImpl;
559 
560  public:
FillGlyphsCommand(ScaledFont * aFont,const GlyphBuffer & aBuffer,const Pattern & aPattern,const DrawOptions & aOptions)561   FillGlyphsCommand(ScaledFont* aFont, const GlyphBuffer& aBuffer,
562                     const Pattern& aPattern, const DrawOptions& aOptions)
563       : mFont(aFont), mPattern(aPattern), mOptions(aOptions) {
564     mGlyphs.resize(aBuffer.mNumGlyphs);
565     memcpy(&mGlyphs.front(), aBuffer.mGlyphs,
566            sizeof(Glyph) * aBuffer.mNumGlyphs);
567   }
568 
GetType()569   CommandType GetType() const override { return FillGlyphsCommand::Type; }
570 
CloneInto(CaptureCommandList * aList)571   void CloneInto(CaptureCommandList* aList) override {
572     GlyphBuffer glyphs = {
573         mGlyphs.data(),
574         (uint32_t)mGlyphs.size(),
575     };
576     CLONE_INTO(FillGlyphsCommand)(mFont, glyphs, mPattern, mOptions);
577   }
578 
ExecuteOnDT(DrawTarget * aDT,const Matrix *)579   void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
580     GlyphBuffer buf;
581     buf.mNumGlyphs = mGlyphs.size();
582     buf.mGlyphs = &mGlyphs.front();
583     aDT->FillGlyphs(mFont, buf, mPattern, mOptions);
584   }
585 
Log(TreeLog<> & aStream)586   void Log(TreeLog<>& aStream) const override {
587     aStream << "[FillGlyphs font=" << mFont;
588     aStream << " glyphCount=" << mGlyphs.size();
589     aStream << " pattern=" << mPattern.Get();
590     aStream << " opt=" << mOptions;
591     aStream << "]";
592   }
593 
594   static const bool AffectsSnapshot = true;
595   static const CommandType Type = CommandType::FILLGLYPHS;
596 
597  private:
598   RefPtr<ScaledFont> mFont;
599   std::vector<Glyph> mGlyphs;
600   StoredPattern mPattern;
601   DrawOptions mOptions;
602 };
603 
604 class StrokeGlyphsCommand : public StrokeOptionsCommand {
605   friend class DrawTargetCaptureImpl;
606 
607  public:
StrokeGlyphsCommand(ScaledFont * aFont,const GlyphBuffer & aBuffer,const Pattern & aPattern,const StrokeOptions & aStrokeOptions,const DrawOptions & aOptions)608   StrokeGlyphsCommand(ScaledFont* aFont, const GlyphBuffer& aBuffer,
609                       const Pattern& aPattern,
610                       const StrokeOptions& aStrokeOptions,
611                       const DrawOptions& aOptions)
612       : StrokeOptionsCommand(aStrokeOptions),
613         mFont(aFont),
614         mPattern(aPattern),
615         mOptions(aOptions) {
616     mGlyphs.resize(aBuffer.mNumGlyphs);
617     memcpy(&mGlyphs.front(), aBuffer.mGlyphs,
618            sizeof(Glyph) * aBuffer.mNumGlyphs);
619   }
620 
GetType()621   CommandType GetType() const override { return StrokeGlyphsCommand::Type; }
622 
CloneInto(CaptureCommandList * aList)623   void CloneInto(CaptureCommandList* aList) override {
624     GlyphBuffer glyphs = {
625         mGlyphs.data(),
626         (uint32_t)mGlyphs.size(),
627     };
628     CLONE_INTO(StrokeGlyphsCommand)
629     (mFont, glyphs, mPattern, mStrokeOptions, mOptions);
630   }
631 
ExecuteOnDT(DrawTarget * aDT,const Matrix *)632   void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
633     GlyphBuffer buf;
634     buf.mNumGlyphs = mGlyphs.size();
635     buf.mGlyphs = &mGlyphs.front();
636     aDT->StrokeGlyphs(mFont, buf, mPattern, mStrokeOptions, mOptions);
637   }
638 
Log(TreeLog<> & aStream)639   void Log(TreeLog<>& aStream) const override {
640     aStream << "[StrokeGlyphs font=" << mFont;
641     aStream << " glyphCount=" << mGlyphs.size();
642     aStream << " pattern=" << mPattern.Get();
643     aStream << " opt=" << mOptions;
644     aStream << "]";
645   }
646 
647   static const bool AffectsSnapshot = true;
648   static const CommandType Type = CommandType::STROKEGLYPHS;
649 
650  private:
651   RefPtr<ScaledFont> mFont;
652   std::vector<Glyph> mGlyphs;
653   StoredPattern mPattern;
654   DrawOptions mOptions;
655 };
656 
657 class MaskCommand : public DrawingCommand {
658  public:
MaskCommand(const Pattern & aSource,const Pattern & aMask,const DrawOptions & aOptions)659   MaskCommand(const Pattern& aSource, const Pattern& aMask,
660               const DrawOptions& aOptions)
661       : mSource(aSource), mMask(aMask), mOptions(aOptions) {}
662 
GetType()663   CommandType GetType() const override { return MaskCommand::Type; }
664 
CloneInto(CaptureCommandList * aList)665   void CloneInto(CaptureCommandList* aList) override {
666     CLONE_INTO(MaskCommand)(mSource, mMask, mOptions);
667   }
668 
ExecuteOnDT(DrawTarget * aDT,const Matrix *)669   void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
670     aDT->Mask(mSource, mMask, mOptions);
671   }
672 
Log(TreeLog<> & aStream)673   void Log(TreeLog<>& aStream) const override {
674     aStream << "[Mask source=" << mSource.Get();
675     aStream << " mask=" << mMask.Get();
676     aStream << " opt=" << mOptions;
677     aStream << "]";
678   }
679 
680   static const bool AffectsSnapshot = true;
681   static const CommandType Type = CommandType::MASK;
682 
683  private:
684   StoredPattern mSource;
685   StoredPattern mMask;
686   DrawOptions mOptions;
687 };
688 
689 class MaskSurfaceCommand : public DrawingCommand {
690  public:
MaskSurfaceCommand(const Pattern & aSource,const SourceSurface * aMask,const Point & aOffset,const DrawOptions & aOptions)691   MaskSurfaceCommand(const Pattern& aSource, const SourceSurface* aMask,
692                      const Point& aOffset, const DrawOptions& aOptions)
693       : mSource(aSource),
694         mMask(const_cast<SourceSurface*>(aMask)),
695         mOffset(aOffset),
696         mOptions(aOptions) {}
697 
GetType()698   CommandType GetType() const override { return MaskSurfaceCommand::Type; }
699 
CloneInto(CaptureCommandList * aList)700   void CloneInto(CaptureCommandList* aList) override {
701     CLONE_INTO(MaskSurfaceCommand)(mSource, mMask, mOffset, mOptions);
702   }
703 
ExecuteOnDT(DrawTarget * aDT,const Matrix *)704   void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
705     aDT->MaskSurface(mSource, mMask, mOffset, mOptions);
706   }
707 
Log(TreeLog<> & aStream)708   void Log(TreeLog<>& aStream) const override {
709     aStream << "[Mask source=" << mSource.Get();
710     aStream << " mask=" << mMask;
711     aStream << " offset=" << &mOffset;
712     aStream << " opt=" << mOptions;
713     aStream << "]";
714   }
715 
716   static const bool AffectsSnapshot = true;
717   static const CommandType Type = CommandType::MASKSURFACE;
718 
719  private:
720   StoredPattern mSource;
721   RefPtr<SourceSurface> mMask;
722   Point mOffset;
723   DrawOptions mOptions;
724 };
725 
726 class PushClipCommand : public DrawingCommand {
727  public:
PushClipCommand(const Path * aPath)728   explicit PushClipCommand(const Path* aPath)
729       : mPath(const_cast<Path*>(aPath)) {}
730 
GetType()731   CommandType GetType() const override { return PushClipCommand::Type; }
732 
CloneInto(CaptureCommandList * aList)733   void CloneInto(CaptureCommandList* aList) override {
734     CLONE_INTO(PushClipCommand)(mPath);
735   }
736 
ExecuteOnDT(DrawTarget * aDT,const Matrix *)737   void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
738     aDT->PushClip(mPath);
739   }
740 
Log(TreeLog<> & aStream)741   void Log(TreeLog<>& aStream) const override {
742     aStream << "[PushClip path=" << mPath << "]";
743   }
744 
745   static const bool AffectsSnapshot = false;
746   static const CommandType Type = CommandType::PUSHCLIP;
747 
748  private:
749   RefPtr<Path> mPath;
750 };
751 
752 class PushClipRectCommand : public DrawingCommand {
753  public:
PushClipRectCommand(const Rect & aRect)754   explicit PushClipRectCommand(const Rect& aRect) : mRect(aRect) {}
755 
GetType()756   CommandType GetType() const override { return PushClipRectCommand::Type; }
757 
CloneInto(CaptureCommandList * aList)758   void CloneInto(CaptureCommandList* aList) override {
759     CLONE_INTO(PushClipRectCommand)(mRect);
760   }
761 
ExecuteOnDT(DrawTarget * aDT,const Matrix *)762   void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
763     aDT->PushClipRect(mRect);
764   }
765 
Log(TreeLog<> & aStream)766   void Log(TreeLog<>& aStream) const override {
767     aStream << "[PushClipRect rect=" << mRect << "]";
768   }
769 
770   static const bool AffectsSnapshot = false;
771   static const CommandType Type = CommandType::PUSHCLIPRECT;
772 
773  private:
774   Rect mRect;
775 };
776 
777 class PushLayerCommand : public DrawingCommand {
778  public:
PushLayerCommand(const bool aOpaque,const Float aOpacity,SourceSurface * aMask,const Matrix & aMaskTransform,const IntRect & aBounds,bool aCopyBackground)779   PushLayerCommand(const bool aOpaque, const Float aOpacity,
780                    SourceSurface* aMask, const Matrix& aMaskTransform,
781                    const IntRect& aBounds, bool aCopyBackground)
782       : mOpaque(aOpaque),
783         mOpacity(aOpacity),
784         mMask(aMask),
785         mMaskTransform(aMaskTransform),
786         mBounds(aBounds),
787         mCopyBackground(aCopyBackground) {}
788 
GetType()789   CommandType GetType() const override { return PushLayerCommand::Type; }
790 
CloneInto(CaptureCommandList * aList)791   void CloneInto(CaptureCommandList* aList) override {
792     CLONE_INTO(PushLayerCommand)
793     (mOpaque, mOpacity, mMask, mMaskTransform, mBounds, mCopyBackground);
794   }
795 
ExecuteOnDT(DrawTarget * aDT,const Matrix *)796   void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
797     aDT->PushLayer(mOpaque, mOpacity, mMask, mMaskTransform, mBounds,
798                    mCopyBackground);
799   }
800 
Log(TreeLog<> & aStream)801   void Log(TreeLog<>& aStream) const override {
802     aStream << "[PushLayer opaque=" << mOpaque;
803     aStream << " opacity=" << mOpacity;
804     aStream << " mask=" << mMask;
805     aStream << " maskTransform=" << mMaskTransform;
806     aStream << " bounds=" << mBounds;
807     aStream << " copyBackground=" << mCopyBackground;
808     aStream << "]";
809   }
810 
811   static const bool AffectsSnapshot = false;
812   static const CommandType Type = CommandType::PUSHLAYER;
813 
814  private:
815   bool mOpaque;
816   float mOpacity;
817   RefPtr<SourceSurface> mMask;
818   Matrix mMaskTransform;
819   IntRect mBounds;
820   bool mCopyBackground;
821 };
822 
823 class PopClipCommand : public DrawingCommand {
824  public:
825   PopClipCommand() = default;
826 
GetType()827   CommandType GetType() const override { return PopClipCommand::Type; }
828 
CloneInto(CaptureCommandList * aList)829   void CloneInto(CaptureCommandList* aList) override {
830     CLONE_INTO(PopClipCommand)();
831   }
832 
ExecuteOnDT(DrawTarget * aDT,const Matrix *)833   void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
834     aDT->PopClip();
835   }
836 
Log(TreeLog<> & aStream)837   void Log(TreeLog<>& aStream) const override { aStream << "[PopClip]"; }
838 
839   static const bool AffectsSnapshot = false;
840   static const CommandType Type = CommandType::POPCLIP;
841 };
842 
843 class PopLayerCommand : public DrawingCommand {
844  public:
845   PopLayerCommand() = default;
846 
GetType()847   CommandType GetType() const override { return PopLayerCommand::Type; }
848 
CloneInto(CaptureCommandList * aList)849   void CloneInto(CaptureCommandList* aList) override {
850     CLONE_INTO(PopLayerCommand)();
851   }
852 
ExecuteOnDT(DrawTarget * aDT,const Matrix *)853   void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
854     aDT->PopLayer();
855   }
856 
Log(TreeLog<> & aStream)857   void Log(TreeLog<>& aStream) const override { aStream << "[PopLayer]"; }
858 
859   static const bool AffectsSnapshot = true;
860   static const CommandType Type = CommandType::POPLAYER;
861 };
862 
863 class SetTransformCommand : public DrawingCommand {
864   friend class DrawTargetCaptureImpl;
865 
866  public:
SetTransformCommand(const Matrix & aTransform)867   explicit SetTransformCommand(const Matrix& aTransform)
868       : mTransform(aTransform) {}
869 
GetType()870   CommandType GetType() const override { return SetTransformCommand::Type; }
871 
CloneInto(CaptureCommandList * aList)872   void CloneInto(CaptureCommandList* aList) override {
873     CLONE_INTO(SetTransformCommand)(mTransform);
874   }
875 
ExecuteOnDT(DrawTarget * aDT,const Matrix * aMatrix)876   void ExecuteOnDT(DrawTarget* aDT, const Matrix* aMatrix) const override {
877     if (aMatrix) {
878       aDT->SetTransform(mTransform * (*aMatrix));
879     } else {
880       aDT->SetTransform(mTransform);
881     }
882   }
883 
Log(TreeLog<> & aStream)884   void Log(TreeLog<>& aStream) const override {
885     aStream << "[SetTransform transform=" << mTransform << "]";
886   }
887 
888   static const bool AffectsSnapshot = false;
889   static const CommandType Type = CommandType::SETTRANSFORM;
890 
891  private:
892   Matrix mTransform;
893 };
894 
895 class SetPermitSubpixelAACommand : public DrawingCommand {
896   friend class DrawTargetCaptureImpl;
897 
898  public:
SetPermitSubpixelAACommand(bool aPermitSubpixelAA)899   explicit SetPermitSubpixelAACommand(bool aPermitSubpixelAA)
900       : mPermitSubpixelAA(aPermitSubpixelAA) {}
901 
GetType()902   CommandType GetType() const override {
903     return SetPermitSubpixelAACommand::Type;
904   }
905 
CloneInto(CaptureCommandList * aList)906   void CloneInto(CaptureCommandList* aList) override {
907     CLONE_INTO(SetPermitSubpixelAACommand)(mPermitSubpixelAA);
908   }
909 
ExecuteOnDT(DrawTarget * aDT,const Matrix * aMatrix)910   void ExecuteOnDT(DrawTarget* aDT, const Matrix* aMatrix) const override {
911     aDT->SetPermitSubpixelAA(mPermitSubpixelAA);
912   }
913 
Log(TreeLog<> & aStream)914   void Log(TreeLog<>& aStream) const override {
915     aStream << "[SetPermitSubpixelAA permitSubpixelAA=" << mPermitSubpixelAA
916             << "]";
917   }
918 
919   static const bool AffectsSnapshot = false;
920   static const CommandType Type = CommandType::SETPERMITSUBPIXELAA;
921 
922  private:
923   bool mPermitSubpixelAA;
924 };
925 
926 class FlushCommand : public DrawingCommand {
927  public:
928   FlushCommand() = default;
929 
GetType()930   CommandType GetType() const override { return FlushCommand::Type; }
931 
CloneInto(CaptureCommandList * aList)932   void CloneInto(CaptureCommandList* aList) override {
933     CLONE_INTO(FlushCommand)();
934   }
935 
ExecuteOnDT(DrawTarget * aDT,const Matrix *)936   void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
937     aDT->Flush();
938   }
939 
Log(TreeLog<> & aStream)940   void Log(TreeLog<>& aStream) const override { aStream << "[Flush]"; }
941 
942   static const bool AffectsSnapshot = false;
943   static const CommandType Type = CommandType::FLUSH;
944 };
945 
946 class BlurCommand : public DrawingCommand {
947  public:
BlurCommand(const AlphaBoxBlur & aBlur)948   explicit BlurCommand(const AlphaBoxBlur& aBlur) : mBlur(aBlur) {}
949 
GetType()950   CommandType GetType() const override { return BlurCommand::Type; }
951 
CloneInto(CaptureCommandList * aList)952   void CloneInto(CaptureCommandList* aList) override {
953     CLONE_INTO(BlurCommand)(mBlur);
954   }
955 
ExecuteOnDT(DrawTarget * aDT,const Matrix *)956   void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
957     aDT->Blur(mBlur);
958   }
959 
Log(TreeLog<> & aStream)960   void Log(TreeLog<>& aStream) const override { aStream << "[Blur]"; }
961 
962   static const bool AffectsSnapshot = true;
963   static const CommandType Type = CommandType::BLUR;
964 
965  private:
966   AlphaBoxBlur mBlur;
967 };
968 
969 class PadEdgesCommand : public DrawingCommand {
970  public:
PadEdgesCommand(const IntRegion & aRegion)971   explicit PadEdgesCommand(const IntRegion& aRegion) : mRegion(aRegion) {}
972 
GetType()973   CommandType GetType() const override { return PadEdgesCommand::Type; }
974 
CloneInto(CaptureCommandList * aList)975   void CloneInto(CaptureCommandList* aList) override {
976     CLONE_INTO(PadEdgesCommand)(IntRegion(mRegion));
977   }
978 
ExecuteOnDT(DrawTarget * aDT,const Matrix *)979   void ExecuteOnDT(DrawTarget* aDT, const Matrix*) const override {
980     aDT->PadEdges(mRegion);
981   }
982 
Log(TreeLog<> & aStream)983   void Log(TreeLog<>& aStream) const override { aStream << "[PADEDGES]"; }
984 
985   static const bool AffectsSnapshot = true;
986   static const CommandType Type = CommandType::PADEDGES;
987 
988  private:
989   IntRegion mRegion;
990 };
991 
992 #undef CLONE_INTO
993 
994 }  // namespace gfx
995 }  // namespace mozilla
996 
997 #endif /* MOZILLA_GFX_DRAWCOMMANDS_H_ */
998