mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 757329: Support changing transforms while emitting path instructions. r=roc
This commit is contained in:
parent
f3ad70ed18
commit
94bed9e6d8
@ -140,7 +140,7 @@ public:
|
||||
/* Returns true if the matrix is a rectilinear transformation (i.e.
|
||||
* grid-aligned rectangles are transformed to grid-aligned rectangles)
|
||||
*/
|
||||
bool IsRectilinear() {
|
||||
bool IsRectilinear() const {
|
||||
if (FuzzyEqual(_12, 0) && FuzzyEqual(_21, 0)) {
|
||||
return true;
|
||||
} else if (FuzzyEqual(_22, 0) && FuzzyEqual(_11, 0)) {
|
||||
|
@ -210,6 +210,9 @@ gfxContext::Restore()
|
||||
mStateStack.RemoveElementAt(mStateStack.Length() - 1);
|
||||
|
||||
if (mPathBuilder || mPath || mPathIsRect) {
|
||||
// Support here isn't fully correct if the path is continued -after-
|
||||
// the restore. We don't currently have users that do this and we should
|
||||
// make sure there will not be any. Sadly we can't assert this easily.
|
||||
mTransformChanged = true;
|
||||
mPathTransform = mDT->GetTransform();
|
||||
}
|
||||
@ -551,11 +554,9 @@ gfxContext::Translate(const gfxPoint& pt)
|
||||
if (mCairo) {
|
||||
cairo_translate(mCairo, pt.x, pt.y);
|
||||
} else {
|
||||
MOZ_ASSERT(!mPathBuilder);
|
||||
|
||||
Matrix newMatrix = mDT->GetTransform();
|
||||
TransformWillChange();
|
||||
mDT->SetTransform(newMatrix.Translate(Float(pt.x), Float(pt.y)));
|
||||
|
||||
ChangeTransform(newMatrix.Translate(Float(pt.x), Float(pt.y)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -565,11 +566,9 @@ gfxContext::Scale(gfxFloat x, gfxFloat y)
|
||||
if (mCairo) {
|
||||
cairo_scale(mCairo, x, y);
|
||||
} else {
|
||||
MOZ_ASSERT(!mPathBuilder);
|
||||
|
||||
Matrix newMatrix = mDT->GetTransform();
|
||||
TransformWillChange();
|
||||
mDT->SetTransform(newMatrix.Scale(Float(x), Float(y)));
|
||||
|
||||
ChangeTransform(newMatrix.Scale(Float(x), Float(y)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -579,11 +578,8 @@ gfxContext::Rotate(gfxFloat angle)
|
||||
if (mCairo) {
|
||||
cairo_rotate(mCairo, angle);
|
||||
} else {
|
||||
MOZ_ASSERT(!mPathBuilder);
|
||||
|
||||
TransformWillChange();
|
||||
Matrix rotation = Matrix::Rotation(Float(angle));
|
||||
mDT->SetTransform(rotation * mDT->GetTransform());
|
||||
ChangeTransform(rotation * mDT->GetTransform());
|
||||
}
|
||||
}
|
||||
|
||||
@ -594,10 +590,7 @@ gfxContext::Multiply(const gfxMatrix& matrix)
|
||||
const cairo_matrix_t& mat = reinterpret_cast<const cairo_matrix_t&>(matrix);
|
||||
cairo_transform(mCairo, &mat);
|
||||
} else {
|
||||
MOZ_ASSERT(!mPathBuilder);
|
||||
|
||||
TransformWillChange();
|
||||
mDT->SetTransform(ToMatrix(matrix) * mDT->GetTransform());
|
||||
ChangeTransform(ToMatrix(matrix) * mDT->GetTransform());
|
||||
}
|
||||
}
|
||||
|
||||
@ -608,10 +601,7 @@ gfxContext::SetMatrix(const gfxMatrix& matrix)
|
||||
const cairo_matrix_t& mat = reinterpret_cast<const cairo_matrix_t&>(matrix);
|
||||
cairo_set_matrix(mCairo, &mat);
|
||||
} else {
|
||||
MOZ_ASSERT(!mPathBuilder);
|
||||
|
||||
TransformWillChange();
|
||||
mDT->SetTransform(ToMatrix(matrix));
|
||||
ChangeTransform(ToMatrix(matrix));
|
||||
}
|
||||
}
|
||||
|
||||
@ -621,10 +611,7 @@ gfxContext::IdentityMatrix()
|
||||
if (mCairo) {
|
||||
cairo_identity_matrix(mCairo);
|
||||
} else {
|
||||
MOZ_ASSERT(!mPathBuilder);
|
||||
|
||||
TransformWillChange();
|
||||
mDT->SetTransform(Matrix());
|
||||
ChangeTransform(Matrix());
|
||||
}
|
||||
}
|
||||
|
||||
@ -2075,7 +2062,7 @@ gfxContext::GetOp()
|
||||
* if the pattern is actually used.
|
||||
*/
|
||||
void
|
||||
gfxContext::TransformWillChange()
|
||||
gfxContext::ChangeTransform(Matrix &aNewMatrix)
|
||||
{
|
||||
AzureState &state = CurrentState();
|
||||
|
||||
@ -2084,4 +2071,32 @@ gfxContext::TransformWillChange()
|
||||
state.patternTransform = mDT->GetTransform();
|
||||
state.patternTransformChanged = true;
|
||||
}
|
||||
|
||||
if (mPathBuilder || mPathIsRect) {
|
||||
Matrix invMatrix = aNewMatrix;
|
||||
|
||||
invMatrix.Invert();
|
||||
|
||||
Matrix toNewUS = mDT->GetTransform() * invMatrix;
|
||||
|
||||
if (toNewUS.IsRectilinear() && mPathIsRect) {
|
||||
mRect = toNewUS.TransformBounds(mRect);
|
||||
} else if (mPathIsRect) {
|
||||
mPathBuilder = mDT->CreatePathBuilder(CurrentState().fillRule);
|
||||
|
||||
mPathBuilder->MoveTo(toNewUS * mRect.TopLeft());
|
||||
mPathBuilder->LineTo(toNewUS * mRect.TopRight());
|
||||
mPathBuilder->LineTo(toNewUS * mRect.BottomRight());
|
||||
mPathBuilder->LineTo(toNewUS * mRect.BottomLeft());
|
||||
mPathBuilder->Close();
|
||||
} else {
|
||||
RefPtr<Path> path = mPathBuilder->Finish();
|
||||
// Create path in device space.
|
||||
mPathBuilder = path->TransformedCopyToBuilder(toNewUS);
|
||||
}
|
||||
// No need to consider the transform changed now!
|
||||
mTransformChanged = false;
|
||||
}
|
||||
|
||||
mDT->SetTransform(aNewMatrix);
|
||||
}
|
@ -741,7 +741,7 @@ private:
|
||||
void FillAzure(mozilla::gfx::Float aOpacity);
|
||||
void PushClipsToDT(mozilla::gfx::DrawTarget *aDT);
|
||||
CompositionOp GetOp();
|
||||
void TransformWillChange();
|
||||
void ChangeTransform(mozilla::gfx::Matrix &aNewMatrix);
|
||||
|
||||
bool mPathIsRect;
|
||||
bool mTransformChanged;
|
||||
|
Loading…
Reference in New Issue
Block a user