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