mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1025553, part 3 - Give gfxMatrix::Invert() the same semantics as Moz2D's Matrix::Invert(). r=Bas
This commit is contained in:
parent
abac46757a
commit
7645116817
@ -119,11 +119,12 @@ SVGMatrix::Multiply(SVGMatrix& aMatrix)
|
||||
already_AddRefed<SVGMatrix>
|
||||
SVGMatrix::Inverse(ErrorResult& rv)
|
||||
{
|
||||
if (GetMatrix().IsSingular()) {
|
||||
gfxMatrix mat = GetMatrix();
|
||||
if (!mat.Invert()) {
|
||||
rv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
nsRefPtr<SVGMatrix> matrix = new SVGMatrix(gfxMatrix(GetMatrix()).Invert());
|
||||
nsRefPtr<SVGMatrix> matrix = new SVGMatrix(mat);
|
||||
return matrix.forget();
|
||||
}
|
||||
|
||||
|
@ -55,8 +55,11 @@ public:
|
||||
|
||||
if (state.patternTransformChanged) {
|
||||
Matrix mat = mContext->GetDTTransform();
|
||||
mat.Invert();
|
||||
|
||||
if (!mat.Invert()) {
|
||||
mPattern = new (mColorPattern.addr())
|
||||
ColorPattern(Color()); // transparent black to paint nothing
|
||||
return *mPattern;
|
||||
}
|
||||
transform = transform * state.patternTransform * mat;
|
||||
}
|
||||
|
||||
@ -360,10 +363,12 @@ gfxContext::Rectangle(const gfxRect& rect, bool snapToPixels)
|
||||
gfxRect newRect(rect);
|
||||
if (UserToDevicePixelSnapped(newRect, true)) {
|
||||
gfxMatrix mat = ThebesMatrix(mTransform);
|
||||
mat.Invert();
|
||||
|
||||
// We need the user space rect.
|
||||
rec = ToRect(mat.TransformBounds(newRect));
|
||||
if (mat.Invert()) {
|
||||
// We need the user space rect.
|
||||
rec = ToRect(mat.TransformBounds(newRect));
|
||||
} else {
|
||||
rec = Rect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,10 @@ DeviceToImageTransform(gfxContext* aContext,
|
||||
nsRefPtr<gfxASurface> currentTarget =
|
||||
aContext->CurrentSurface(&deviceX, &deviceY);
|
||||
gfxMatrix currentMatrix = aContext->CurrentMatrix();
|
||||
gfxMatrix deviceToUser = gfxMatrix(currentMatrix).Invert();
|
||||
gfxMatrix deviceToUser = currentMatrix;
|
||||
if (!deviceToUser.Invert()) {
|
||||
return gfxMatrix(0, 0, 0, 0, 0, 0); // singular
|
||||
}
|
||||
deviceToUser.Translate(-gfxPoint(-deviceX, -deviceY));
|
||||
return gfxMatrix(deviceToUser).Multiply(aUserSpaceToImageSpace);
|
||||
}
|
||||
|
@ -17,11 +17,10 @@ gfxMatrix::Reset()
|
||||
return *this;
|
||||
}
|
||||
|
||||
const gfxMatrix&
|
||||
bool
|
||||
gfxMatrix::Invert()
|
||||
{
|
||||
cairo_matrix_invert(CAIRO_MATRIX(this));
|
||||
return *this;
|
||||
return cairo_matrix_invert(CAIRO_MATRIX(this)) == CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
const gfxMatrix&
|
||||
|
@ -98,7 +98,7 @@ public:
|
||||
* XXX should this do something with the return value of
|
||||
* cairo_matrix_invert?
|
||||
*/
|
||||
const gfxMatrix& Invert();
|
||||
bool Invert();
|
||||
|
||||
/**
|
||||
* Check if matrix is singular (no inverse exists).
|
||||
|
@ -232,7 +232,9 @@ public:
|
||||
return gfxMatrix();
|
||||
}
|
||||
gfxMatrix deviceToUser = aCTM;
|
||||
deviceToUser.Invert();
|
||||
if (!deviceToUser.Invert()) {
|
||||
return gfxMatrix(0, 0, 0, 0, 0, 0); // singular
|
||||
}
|
||||
return deviceToUser * aPattern->GetMatrix();
|
||||
}
|
||||
|
||||
|
@ -496,7 +496,10 @@ DeviceToImageTransform(gfxContext* aContext,
|
||||
nsRefPtr<gfxASurface> currentTarget =
|
||||
aContext->CurrentSurface(&deviceX, &deviceY);
|
||||
gfxMatrix currentMatrix = aContext->CurrentMatrix();
|
||||
gfxMatrix deviceToUser = gfxMatrix(currentMatrix).Invert();
|
||||
gfxMatrix deviceToUser = currentMatrix;
|
||||
if (!deviceToUser.Invert()) {
|
||||
return gfxMatrix(0, 0, 0, 0, 0, 0); // singular
|
||||
}
|
||||
deviceToUser.Translate(-gfxPoint(-deviceX, -deviceY));
|
||||
return gfxMatrix(deviceToUser).Multiply(aUserSpaceToImageSpace);
|
||||
}
|
||||
|
@ -268,7 +268,10 @@ OrientedImage::GetImageSpaceInvalidationRect(const nsIntRect& aRect)
|
||||
}
|
||||
|
||||
// Transform the invalidation rect into the correct orientation.
|
||||
gfxMatrix matrix(OrientationMatrix(nsIntSize(width, height)).Invert());
|
||||
gfxMatrix matrix(OrientationMatrix(nsIntSize(width, height)));
|
||||
if (!matrix.Invert()) {
|
||||
return nsIntRect();
|
||||
}
|
||||
gfxRect invalidRect(matrix.TransformBounds(gfxRect(rect.x, rect.y,
|
||||
rect.width, rect.height)));
|
||||
invalidRect.RoundOut();
|
||||
|
@ -2600,7 +2600,9 @@ RasterImage::DrawWithPreDownscaleIfNeeded(imgFrame *aFrame,
|
||||
nsIntRect framerect = frame->GetRect();
|
||||
gfxMatrix userSpaceToImageSpace = aUserSpaceToImageSpace;
|
||||
gfxMatrix imageSpaceToUserSpace = aUserSpaceToImageSpace;
|
||||
imageSpaceToUserSpace.Invert();
|
||||
if (!imageSpaceToUserSpace.Invert()) {
|
||||
return false;
|
||||
}
|
||||
gfxSize scale = imageSpaceToUserSpace.ScaleFactors(true);
|
||||
nsIntRect subimage = aSubimage;
|
||||
RefPtr<SourceSurface> surf;
|
||||
|
@ -284,7 +284,11 @@ SVGDrawingCallback::operator()(gfxContext* aContext,
|
||||
aContext->Clip();
|
||||
|
||||
gfxContextMatrixAutoSaveRestore contextMatrixRestorer(aContext);
|
||||
aContext->Multiply(gfxMatrix(aTransform).Invert());
|
||||
gfxMatrix matrix = aTransform;
|
||||
if (!matrix.Invert()) {
|
||||
return false;
|
||||
}
|
||||
aContext->Multiply(matrix);
|
||||
aContext->Scale(1.0 / mScale.width, 1.0 / mScale.height);
|
||||
|
||||
nsPresContext* presContext = presShell->GetPresContext();
|
||||
|
@ -1064,7 +1064,10 @@ TextRenderedRun::GetCharNumAtPosition(nsPresContext* aContext,
|
||||
|
||||
// Convert the point from user space into run user space, and take
|
||||
// into account any mFontSizeScaleFactor.
|
||||
gfxMatrix m = GetTransformFromRunUserSpaceToUserSpace(aContext).Invert();
|
||||
gfxMatrix m = GetTransformFromRunUserSpaceToUserSpace(aContext);
|
||||
if (!m.Invert()) {
|
||||
return -1;
|
||||
}
|
||||
gfxPoint p = m.Transform(aPoint) / cssPxPerDevPx * mFontSizeScaleFactor;
|
||||
|
||||
// First check that the point lies vertically between the top and bottom
|
||||
@ -3033,7 +3036,9 @@ SVGTextContextPaint::Paint::GetPattern(float aOpacity,
|
||||
// m maps original-user-space to pattern space
|
||||
gfxMatrix m = pattern->GetMatrix();
|
||||
gfxMatrix deviceToOriginalUserSpace = mContextMatrix;
|
||||
deviceToOriginalUserSpace.Invert();
|
||||
if (!deviceToOriginalUserSpace.Invert()) {
|
||||
return nullptr;
|
||||
}
|
||||
// mPatternMatrix maps device space to pattern space via original user space
|
||||
mPatternMatrix = deviceToOriginalUserSpace * m;
|
||||
}
|
||||
@ -3715,7 +3720,9 @@ SVGTextFrame::GetFrameForPoint(const nsPoint& aPoint)
|
||||
|
||||
gfxMatrix m = GetCanvasTM(FOR_HIT_TESTING);
|
||||
m.PreMultiply(run.GetTransformFromRunUserSpaceToUserSpace(presContext));
|
||||
m.Invert();
|
||||
if (!m.Invert()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
gfxPoint pointInRunUserSpace = m.Transform(pointInOuterSVGUserUnits);
|
||||
gfxRect frameRect =
|
||||
@ -5364,9 +5371,11 @@ SVGTextFrame::TransformFramePointToTextChild(const gfxPoint& aPoint,
|
||||
TextRenderedRun::eNoHorizontalOverflow;
|
||||
gfxRect runRect = run.GetRunUserSpaceRect(presContext, flags).ToThebesRect();
|
||||
|
||||
gfxPoint pointInRunUserSpace =
|
||||
run.GetTransformFromRunUserSpaceToUserSpace(presContext).Invert().
|
||||
Transform(pointInUserSpace);
|
||||
gfxMatrix m = run.GetTransformFromRunUserSpaceToUserSpace(presContext);
|
||||
if (!m.Invert()) {
|
||||
return aPoint;
|
||||
}
|
||||
gfxPoint pointInRunUserSpace = m.Transform(pointInUserSpace);
|
||||
|
||||
if (Inside(runRect, pointInRunUserSpace)) {
|
||||
// The point was inside the rendered run's rect, so we choose it.
|
||||
@ -5437,8 +5446,13 @@ SVGTextFrame::TransformFrameRectToTextChild(const gfxRect& aRect,
|
||||
aChildFrame);
|
||||
for (TextRenderedRun run = it.Current(); run.mFrame; run = it.Next()) {
|
||||
// Convert the incoming rect into frame user space.
|
||||
gfxMatrix userSpaceToRunUserSpace =
|
||||
run.GetTransformFromRunUserSpaceToUserSpace(presContext);
|
||||
if (!userSpaceToRunUserSpace.Invert()) {
|
||||
return result;
|
||||
}
|
||||
gfxMatrix m;
|
||||
m.PreMultiply(run.GetTransformFromRunUserSpaceToUserSpace(presContext).Invert());
|
||||
m.PreMultiply(userSpaceToRunUserSpace);
|
||||
m.PreMultiply(run.GetTransformFromRunUserSpaceToFrameUserSpace(presContext));
|
||||
gfxRect incomingRectInFrameUserSpace =
|
||||
m.TransformBounds(incomingRectInUserSpace);
|
||||
|
@ -315,7 +315,10 @@ nsFilterInstance::BuildSourcePaint(SourceInfo *aSource,
|
||||
nsRefPtr<nsRenderingContext> tmpCtx(new nsRenderingContext());
|
||||
tmpCtx->Init(mTargetFrame->PresContext()->DeviceContext(), ctx);
|
||||
|
||||
gfxMatrix deviceToFilterSpace = GetFilterSpaceToDeviceSpaceTransform().Invert();
|
||||
gfxMatrix deviceToFilterSpace = GetFilterSpaceToDeviceSpaceTransform();
|
||||
if (!deviceToFilterSpace.Invert()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
gfxContext *gfx = tmpCtx->ThebesContext();
|
||||
gfx->Multiply(deviceToFilterSpace);
|
||||
|
||||
@ -398,7 +401,10 @@ nsFilterInstance::BuildSourceImage(DrawTarget* aTargetDT)
|
||||
// space to device space and back again). However, that would make the
|
||||
// code more complex while being hard to get right without introducing
|
||||
// subtle bugs, and in practice it probably makes no real difference.)
|
||||
gfxMatrix deviceToFilterSpace = GetFilterSpaceToDeviceSpaceTransform().Invert();
|
||||
gfxMatrix deviceToFilterSpace = GetFilterSpaceToDeviceSpaceTransform();
|
||||
if (!deviceToFilterSpace.Invert()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
tmpCtx->ThebesContext()->Multiply(deviceToFilterSpace);
|
||||
mPaintCallback->Paint(tmpCtx, mTargetFrame, &dirty, mTransformRoot);
|
||||
|
||||
|
@ -222,9 +222,8 @@ nsSVGForeignObjectFrame::PaintSVG(nsRenderingContext *aContext,
|
||||
"Display lists handle dirty rect intersection test");
|
||||
// Transform the dirty rect into app units in our userspace.
|
||||
gfxMatrix invmatrix = canvasTM;
|
||||
invmatrix.Invert();
|
||||
NS_ASSERTION(!invmatrix.IsSingular(),
|
||||
"inverse of non-singular matrix should be non-singular");
|
||||
DebugOnly<bool> ok = invmatrix.Invert();
|
||||
NS_ASSERTION(ok, "inverse of non-singular matrix should be non-singular");
|
||||
|
||||
gfxRect transDirtyRect = gfxRect(aDirtyRect->x, aDirtyRect->y,
|
||||
aDirtyRect->width, aDirtyRect->height);
|
||||
@ -297,10 +296,11 @@ nsSVGForeignObjectFrame::GetFrameForPoint(const nsPoint &aPoint)
|
||||
static_cast<nsSVGElement*>(mContent)->
|
||||
GetAnimatedLengthValues(&x, &y, &width, &height, nullptr);
|
||||
|
||||
gfxMatrix tm = GetCanvasTM(FOR_HIT_TESTING).Invert();
|
||||
if (tm.IsSingular())
|
||||
gfxMatrix tm = GetCanvasTM(FOR_HIT_TESTING);
|
||||
if (!tm.Invert()) {
|
||||
return nullptr;
|
||||
|
||||
}
|
||||
|
||||
// Convert aPoint from app units in canvas space to user space:
|
||||
|
||||
gfxPoint pt = gfxPoint(aPoint.x, aPoint.y) / PresContext()->AppUnitsPerCSSPixel();
|
||||
|
@ -264,10 +264,16 @@ nsSVGGradientFrame::GetPaintServerPattern(nsIFrame *aSource,
|
||||
|
||||
// revert the vector effect transform so that the gradient appears unchanged
|
||||
if (aFillOrStroke == &nsStyleSVG::mStroke) {
|
||||
patternMatrix.Multiply(nsSVGUtils::GetStrokeTransform(aSource).Invert());
|
||||
gfxMatrix nonScalingStrokeTM = nsSVGUtils::GetStrokeTransform(aSource);
|
||||
if (!nonScalingStrokeTM.Invert()) {
|
||||
return nullptr;
|
||||
}
|
||||
patternMatrix.Multiply(nonScalingStrokeTM);
|
||||
}
|
||||
|
||||
patternMatrix.Invert();
|
||||
if (!patternMatrix.Invert()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxPattern> gradient = CreateGradient();
|
||||
if (!gradient || gradient->CairoStatus())
|
||||
|
@ -628,7 +628,11 @@ PaintFrameCallback::operator()(gfxContext* aContext,
|
||||
aContext->Rectangle(aFillRect);
|
||||
aContext->Clip();
|
||||
|
||||
aContext->Multiply(gfxMatrix(aTransform).Invert());
|
||||
gfxMatrix invmatrix = aTransform;
|
||||
if (!invmatrix.Invert()) {
|
||||
return false;
|
||||
}
|
||||
aContext->Multiply(invmatrix);
|
||||
|
||||
// nsLayoutUtils::PaintFrame will anchor its painting at mFrame. But we want
|
||||
// to have it anchored at the top left corner of the bounding box of all of
|
||||
|
@ -270,8 +270,7 @@ nsSVGMaskFrame::GetMaskForMaskedFrame(gfxContext* aContext,
|
||||
maskSurface->Unmap();
|
||||
|
||||
// Moz2D transforms in the opposite direction to Thebes
|
||||
maskSurfaceMatrix.Invert();
|
||||
if (maskSurfaceMatrix.IsSingular()) {
|
||||
if (!maskSurfaceMatrix.Invert()) {
|
||||
return nullptr;
|
||||
}
|
||||
nsRefPtr<gfxPattern> retval =
|
||||
|
@ -302,7 +302,9 @@ nsSVGPathGeometryFrame::GetFrameForPoint(const nsPoint &aPoint)
|
||||
// coordinate system in order for non-scaled stroke to be correct.
|
||||
// Naturally we also need to transform the point into the same
|
||||
// coordinate system in order to hit-test against the path.
|
||||
nonScalingStrokeMatrix.Invert();
|
||||
if (!nonScalingStrokeMatrix.Invert()) {
|
||||
return nullptr;
|
||||
}
|
||||
userSpacePoint = ToMatrix(hitTestingTM) * nonScalingStrokeMatrix * userSpacePoint;
|
||||
RefPtr<PathBuilder> builder =
|
||||
path->TransformedCopyToBuilder(nonScalingStrokeMatrix, fillRule);
|
||||
|
@ -324,8 +324,8 @@ nsSVGPatternFrame::PaintPattern(Matrix* patternMatrix,
|
||||
|
||||
// revert the vector effect transform so that the pattern appears unchanged
|
||||
if (aFillOrStroke == &nsStyleSVG::mStroke) {
|
||||
Matrix strokeTransform = ToMatrix(nsSVGUtils::GetStrokeTransform(aSource).Invert());
|
||||
if (strokeTransform.IsSingular()) {
|
||||
Matrix strokeTransform = ToMatrix(nsSVGUtils::GetStrokeTransform(aSource));
|
||||
if (!strokeTransform.Invert()) {
|
||||
NS_WARNING("Should we get here if the stroke transform is singular?");
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -539,7 +539,10 @@ nsSVGUtils::PaintFrameWithEffects(nsRenderingContext *aContext,
|
||||
if (static_cast<nsSVGContainerFrame*>(aFrame)->
|
||||
HasChildrenOnlyTransform(&childrenOnlyTM)) {
|
||||
// Undo the children-only transform:
|
||||
tm = ThebesMatrix(childrenOnlyTM).Invert() * tm;
|
||||
if (!childrenOnlyTM.Invert()) {
|
||||
return;
|
||||
}
|
||||
tm = ThebesMatrix(childrenOnlyTM) * tm;
|
||||
}
|
||||
}
|
||||
nsIntRect bounds = TransformFrameRectToOuterSVG(overflowRect,
|
||||
|
Loading…
Reference in New Issue
Block a user