Bug 1456555 - Fix bugs in DrawTargetOffset. r=mstange
authorMatt Woodrow <mwoodrow@mozilla.com>
Tue, 06 Nov 2018 21:03:29 +0000
changeset 487796 c6c46594d92aa56f7fa35c29ad061669f6a6bef7
parent 487795 774f5ab895af83c5afae387e800d7fbf081af4f5
child 487797 d92ef360413ca38911769f7f11747fca5c391a88
push idunknown
push userunknown
push dateunknown
reviewersmstange
bugs1456555
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1456555 - Fix bugs in DrawTargetOffset. r=mstange MozReview-Commit-ID: I4XFoTp1szZ Depends on D10033 Differential Revision: https://phabricator.services.mozilla.com/D10036
gfx/2d/DrawTargetOffset.cpp
gfx/2d/DrawTargetOffset.h
--- a/gfx/2d/DrawTargetOffset.cpp
+++ b/gfx/2d/DrawTargetOffset.cpp
@@ -78,30 +78,37 @@ OFFSET_COMMAND4(MaskSurface, const Patte
 OFFSET_COMMAND4(FillGlyphs, ScaledFont*, const GlyphBuffer&, const Pattern&, const DrawOptions&)
 OFFSET_COMMAND3(Mask, const Pattern&, const Pattern&, const DrawOptions&)
 
 void
 DrawTargetOffset::DrawFilter(FilterNode* aNode, const Rect& aSourceRect, const Point& aDestPoint, const DrawOptions& aOptions)
 {
   auto clone = mTransform;
   bool invertible = clone.Invert();
-  auto src = aSourceRect;
+  // aSourceRect is in filter space. The filter outputs from aSourceRect need
+  // to be drawn at aDestPoint in user space.
+  Rect userSpaceSource = Rect(aDestPoint, aSourceRect.Size());
   if (invertible) {
     // Try to reduce the source rect so that it's not much bigger
     // than the draw target. The result is not minimal. Examples
     // are left as an exercise for the reader.
     auto destRect = Rect(mOrigin.x,
                          mOrigin.y,
                          mDrawTarget->GetSize().width,
                          mDrawTarget->GetSize().height);
-    auto dtBounds = clone.TransformBounds(destRect);
-    src = aSourceRect.Intersect(dtBounds);
+    Rect userSpaceBounds = clone.TransformBounds(destRect);
+    userSpaceSource = userSpaceSource.Intersect(userSpaceBounds);
   }
-  auto shift = src.TopLeft() - aSourceRect.TopLeft();
-  mDrawTarget->DrawFilter(aNode, src, aDestPoint + shift, aOptions);
+
+  // Compute how much we moved the top-left of the source rect by, and use that
+  // to compute the new dest point, and move our intersected source rect back
+  // into the (new) filter space.
+  Point shift = userSpaceSource.TopLeft() - aDestPoint;
+  Rect filterSpaceSource = Rect(aSourceRect.TopLeft() + shift, userSpaceSource.Size());
+  mDrawTarget->DrawFilter(aNode, filterSpaceSource, aDestPoint + shift, aOptions);
 }
 
 void
 DrawTargetOffset::PushClip(const Path* aPath)
 {
   mDrawTarget->PushClip(aPath);
 }
 
@@ -179,34 +186,37 @@ DrawTargetOffset::Fill(const Path* aPath
   mDrawTarget->Fill(aPath, aPattern, aDrawOptions);
 }
 
 void
 DrawTargetOffset::PushLayer(bool aOpaque, Float aOpacity, SourceSurface* aMask,
                            const Matrix& aMaskTransform, const IntRect& aBounds,
                            bool aCopyBackground)
 {
-  IntRect bounds = aBounds;
-  bounds.MoveBy(mOrigin);
+  IntRect bounds = aBounds - mOrigin;
+
   mDrawTarget->PushLayer(aOpaque, aOpacity, aMask, aMaskTransform, bounds, aCopyBackground);
+  SetPermitSubpixelAA(mDrawTarget->GetPermitSubpixelAA());
 }
 
 void
 DrawTargetOffset::PushLayerWithBlend(bool aOpaque, Float aOpacity,
                                     SourceSurface* aMask,
                                     const Matrix& aMaskTransform,
                                     const IntRect& aBounds,
                                     bool aCopyBackground,
                                     CompositionOp aOp)
 {
-  IntRect bounds = aBounds;
-  bounds.MoveBy(mOrigin);
+  IntRect bounds = aBounds - mOrigin;
+
   mDrawTarget->PushLayerWithBlend(aOpaque, aOpacity, aMask, aMaskTransform, bounds, aCopyBackground, aOp);
+  SetPermitSubpixelAA(mDrawTarget->GetPermitSubpixelAA());
 }
 
 void
 DrawTargetOffset::PopLayer()
 {
   mDrawTarget->PopLayer();
+  SetPermitSubpixelAA(mDrawTarget->GetPermitSubpixelAA());
 }
 
 } // namespace gfx
 } // namespace mozilla
--- a/gfx/2d/DrawTargetOffset.h
+++ b/gfx/2d/DrawTargetOffset.h
@@ -33,17 +33,17 @@ public:
   virtual DrawTargetType GetType() const override { return mDrawTarget->GetType(); }
   virtual BackendType GetBackendType() const override { return mDrawTarget->GetBackendType(); }
   virtual already_AddRefed<SourceSurface> Snapshot() override;
   virtual void DetachAllSnapshots() override;
   virtual IntSize GetSize() const override {
     return mDrawTarget->GetSize();
   }
   virtual IntRect GetRect() const override {
-    return mDrawTarget->GetRect();
+    return IntRect(mOrigin, GetSize());
   }
 
   virtual void Flush() override;
   virtual void DrawSurface(SourceSurface *aSurface,
                            const Rect &aDest,
                            const Rect &aSource,
                            const DrawSurfaceOptions &aSurfOptions,
                            const DrawOptions &aOptions) override;