diff --git a/gfx/2d/Matrix.h b/gfx/2d/Matrix.h index 2ecc186fe2d1..b57fc97234c3 100644 --- a/gfx/2d/Matrix.h +++ b/gfx/2d/Matrix.h @@ -265,6 +265,13 @@ public: return !(*this == other); } + bool ExactlyEquals(const Matrix& o) const + { + return _11 == o._11 && _12 == o._12 && + _21 == o._21 && _22 == o._22 && + _31 == o._31 && _32 == o._32; + } + /* Verifies that the matrix contains no Infs or NaNs. */ bool IsFinite() const { diff --git a/gfx/2d/PathCairo.cpp b/gfx/2d/PathCairo.cpp index 2d78a2771159..9c7ba5874678 100644 --- a/gfx/2d/PathCairo.cpp +++ b/gfx/2d/PathCairo.cpp @@ -188,7 +188,7 @@ PathCairo::ContainsPoint(const Point &aPoint, const Matrix &aTransform) const inverse.Invert(); Point transformed = inverse * aPoint; - EnsureContainingContext(); + EnsureContainingContext(aTransform); return cairo_in_fill(mContainingContext, transformed.x, transformed.y); } @@ -202,7 +202,7 @@ PathCairo::StrokeContainsPoint(const StrokeOptions &aStrokeOptions, inverse.Invert(); Point transformed = inverse * aPoint; - EnsureContainingContext(); + EnsureContainingContext(aTransform); SetCairoStrokeOptions(mContainingContext, aStrokeOptions); @@ -212,7 +212,7 @@ PathCairo::StrokeContainsPoint(const StrokeOptions &aStrokeOptions, Rect PathCairo::GetBounds(const Matrix &aTransform) const { - EnsureContainingContext(); + EnsureContainingContext(aTransform); double x1, y1, x2, y2; @@ -225,7 +225,7 @@ Rect PathCairo::GetStrokedBounds(const StrokeOptions &aStrokeOptions, const Matrix &aTransform) const { - EnsureContainingContext(); + EnsureContainingContext(aTransform); double x1, y1, x2, y2; @@ -266,13 +266,21 @@ PathCairo::StreamToSink(PathSink *aSink) const } void -PathCairo::EnsureContainingContext() const +PathCairo::EnsureContainingContext(const Matrix &aTransform) const { if (mContainingContext) { - return; + if (mContainingTransform.ExactlyEquals(aTransform)) { + return; + } + } else { + mContainingContext = cairo_create(DrawTargetCairo::GetDummySurface()); } - mContainingContext = cairo_create(DrawTargetCairo::GetDummySurface()); + mContainingTransform = aTransform; + + cairo_matrix_t mat; + GfxMatrixToCairoMatrix(mContainingTransform, mat); + cairo_set_matrix(mContainingContext, &mat); SetPathOnContext(mContainingContext); } diff --git a/gfx/2d/PathCairo.h b/gfx/2d/PathCairo.h index 8ee76ad95bd5..70d8fbd16da8 100644 --- a/gfx/2d/PathCairo.h +++ b/gfx/2d/PathCairo.h @@ -80,11 +80,12 @@ public: void AppendPathToBuilder(PathBuilderCairo *aBuilder, const Matrix *aTransform = nullptr) const; private: - void EnsureContainingContext() const; + void EnsureContainingContext(const Matrix &aTransform) const; FillRule mFillRule; std::vector mPathData; mutable cairo_t *mContainingContext; + mutable Matrix mContainingTransform; Point mCurrentPoint; };