mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 738690: Properly convert patterns to userspace in the Azure-Thebes wrapper. r=jrmuizel
This commit is contained in:
parent
c367e0d9b4
commit
eaa02a2931
@ -73,10 +73,19 @@ public:
|
||||
gfxContext::AzureState &state = mContext->CurrentState();
|
||||
|
||||
if (state.pattern) {
|
||||
return *state.pattern->GetPattern(mContext->mDT);
|
||||
return *state.pattern->GetPattern(mContext->mDT, state.patternTransformChanged ? &state.patternTransform : nsnull);
|
||||
} else if (state.sourceSurface) {
|
||||
Matrix transform = state.surfTransform;
|
||||
|
||||
if (state.patternTransformChanged) {
|
||||
Matrix mat = state.patternTransform;
|
||||
mat.Invert();
|
||||
|
||||
transform = mat * mContext->mDT->GetTransform() * transform;
|
||||
}
|
||||
|
||||
mPattern = new (mSurfacePattern.addr())
|
||||
SurfacePattern(state.sourceSurface, EXTEND_CLAMP, state.surfTransform);
|
||||
SurfacePattern(state.sourceSurface, EXTEND_CLAMP, transform);
|
||||
return *mPattern;
|
||||
} else {
|
||||
mPattern = new (mColorPattern.addr())
|
||||
@ -575,6 +584,7 @@ gfxContext::Translate(const gfxPoint& pt)
|
||||
MOZ_ASSERT(!mPathBuilder);
|
||||
|
||||
Matrix newMatrix = mDT->GetTransform();
|
||||
TransformWillChange();
|
||||
mDT->SetTransform(newMatrix.Translate(Float(pt.x), Float(pt.y)));
|
||||
}
|
||||
}
|
||||
@ -588,6 +598,7 @@ gfxContext::Scale(gfxFloat x, gfxFloat y)
|
||||
MOZ_ASSERT(!mPathBuilder);
|
||||
|
||||
Matrix newMatrix = mDT->GetTransform();
|
||||
TransformWillChange();
|
||||
mDT->SetTransform(newMatrix.Scale(Float(x), Float(y)));
|
||||
}
|
||||
}
|
||||
@ -600,6 +611,7 @@ gfxContext::Rotate(gfxFloat angle)
|
||||
} else {
|
||||
MOZ_ASSERT(!mPathBuilder);
|
||||
|
||||
TransformWillChange();
|
||||
Matrix rotation = Matrix::Rotation(Float(angle));
|
||||
mDT->SetTransform(rotation * mDT->GetTransform());
|
||||
}
|
||||
@ -614,6 +626,7 @@ gfxContext::Multiply(const gfxMatrix& matrix)
|
||||
} else {
|
||||
MOZ_ASSERT(!mPathBuilder);
|
||||
|
||||
TransformWillChange();
|
||||
mDT->SetTransform(ToMatrix(matrix) * mDT->GetTransform());
|
||||
}
|
||||
}
|
||||
@ -627,6 +640,7 @@ gfxContext::SetMatrix(const gfxMatrix& matrix)
|
||||
} else {
|
||||
MOZ_ASSERT(!mPathBuilder);
|
||||
|
||||
TransformWillChange();
|
||||
mDT->SetTransform(ToMatrix(matrix));
|
||||
}
|
||||
}
|
||||
@ -639,6 +653,7 @@ gfxContext::IdentityMatrix()
|
||||
} else {
|
||||
MOZ_ASSERT(!mPathBuilder);
|
||||
|
||||
TransformWillChange();
|
||||
mDT->SetTransform(Matrix());
|
||||
}
|
||||
}
|
||||
@ -1369,6 +1384,7 @@ gfxContext::SetSource(gfxASurface *surface, const gfxPoint& offset)
|
||||
} else {
|
||||
CurrentState().surfTransform = Matrix(1.0f, 0, 0, 1.0f, Float(offset.x), Float(offset.y));
|
||||
CurrentState().pattern = NULL;
|
||||
CurrentState().patternTransformChanged = false;
|
||||
CurrentState().sourceSurface =
|
||||
gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(mDT, surface);
|
||||
}
|
||||
@ -1381,6 +1397,7 @@ gfxContext::SetPattern(gfxPattern *pattern)
|
||||
cairo_set_source(mCairo, pattern->CairoPattern());
|
||||
} else {
|
||||
CurrentState().sourceSurface = NULL;
|
||||
CurrentState().patternTransformChanged = false;
|
||||
CurrentState().pattern = pattern;
|
||||
}
|
||||
}
|
||||
@ -1582,6 +1599,7 @@ gfxContext::PopGroupToSource()
|
||||
Restore();
|
||||
CurrentState().sourceSurface = src;
|
||||
CurrentState().pattern = NULL;
|
||||
CurrentState().patternTransformChanged = false;
|
||||
|
||||
Matrix mat = mDT->GetTransform();
|
||||
mat.Invert();
|
||||
@ -2055,3 +2073,21 @@ gfxContext::GetOp()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* SVG font code can change the transform after having set the pattern on the
|
||||
* context. When the pattern is set it is in user space, if the transform is
|
||||
* changed after doing so the pattern needs to be converted back into userspace.
|
||||
* We just store the old pattern here so that we only do the work needed here
|
||||
* if the pattern is actually used.
|
||||
*/
|
||||
void
|
||||
gfxContext::TransformWillChange()
|
||||
{
|
||||
AzureState &state = CurrentState();
|
||||
|
||||
if ((state.pattern || state.sourceSurface)
|
||||
&& !state.patternTransformChanged) {
|
||||
state.patternTransform = mDT->GetTransform();
|
||||
state.patternTransformChanged = true;
|
||||
}
|
||||
}
|
@ -737,6 +737,7 @@ private:
|
||||
, clipWasReset(false)
|
||||
, fillRule(mozilla::gfx::FILL_WINDING)
|
||||
, aaMode(mozilla::gfx::AA_SUBPIXEL)
|
||||
, patternTransformChanged(false)
|
||||
{}
|
||||
|
||||
mozilla::gfx::CompositionOp op;
|
||||
@ -759,6 +760,8 @@ private:
|
||||
mozilla::RefPtr<DrawTarget> drawTarget;
|
||||
mozilla::RefPtr<DrawTarget> parentTarget;
|
||||
mozilla::gfx::AntialiasMode aaMode;
|
||||
bool patternTransformChanged;
|
||||
Matrix patternTransform;
|
||||
};
|
||||
|
||||
// This ensures mPath contains a valid path (in user space!)
|
||||
@ -768,6 +771,7 @@ private:
|
||||
void FillAzure(mozilla::gfx::Float aOpacity);
|
||||
void PushClipsToDT(mozilla::gfx::DrawTarget *aDT);
|
||||
CompositionOp GetOp();
|
||||
void TransformWillChange();
|
||||
|
||||
bool mPathIsRect;
|
||||
bool mTransformChanged;
|
||||
|
@ -148,7 +148,7 @@ gfxPattern::GetMatrix() const
|
||||
}
|
||||
|
||||
Pattern*
|
||||
gfxPattern::GetPattern(mozilla::gfx::DrawTarget *aTarget)
|
||||
gfxPattern::GetPattern(DrawTarget *aTarget, Matrix *aPatternTransform)
|
||||
{
|
||||
if (!mPattern) {
|
||||
mGfxPattern = new (mSurfacePattern.addr())
|
||||
@ -185,6 +185,9 @@ gfxPattern::GetPattern(mozilla::gfx::DrawTarget *aTarget)
|
||||
|
||||
if (mSourceSurface) {
|
||||
Matrix newMat = ToMatrix(matrix);
|
||||
|
||||
AdjustTransformForPattern(newMat, aTarget->GetTransform(), aPatternTransform);
|
||||
|
||||
newMat.Invert();
|
||||
double x, y;
|
||||
cairo_surface_get_device_offset(surf, &x, &y);
|
||||
@ -224,6 +227,9 @@ gfxPattern::GetPattern(mozilla::gfx::DrawTarget *aTarget)
|
||||
gfxMatrix matrix(*reinterpret_cast<gfxMatrix*>(&mat));
|
||||
|
||||
Matrix newMat = ToMatrix(matrix);
|
||||
|
||||
AdjustTransformForPattern(newMat, aTarget->GetTransform(), aPatternTransform);
|
||||
|
||||
newMat.Invert();
|
||||
|
||||
mGfxPattern = new (mLinearGradientPattern.addr())
|
||||
@ -260,6 +266,9 @@ gfxPattern::GetPattern(mozilla::gfx::DrawTarget *aTarget)
|
||||
gfxMatrix matrix(*reinterpret_cast<gfxMatrix*>(&mat));
|
||||
|
||||
Matrix newMat = ToMatrix(matrix);
|
||||
|
||||
AdjustTransformForPattern(newMat, aTarget->GetTransform(), aPatternTransform);
|
||||
|
||||
newMat.Invert();
|
||||
|
||||
double x1, y1, x2, y2, r1, r2;
|
||||
@ -423,3 +432,18 @@ gfxPattern::CairoStatus()
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gfxPattern::AdjustTransformForPattern(Matrix &aPatternTransform,
|
||||
const Matrix &aCurrentTransform,
|
||||
const Matrix *aOriginalTransform)
|
||||
{
|
||||
if (!aOriginalTransform) {
|
||||
return;
|
||||
}
|
||||
|
||||
Matrix mat = *aOriginalTransform;
|
||||
mat.Invert();
|
||||
|
||||
aPatternTransform = mat * aCurrentTransform * aPatternTransform;
|
||||
}
|
@ -73,7 +73,13 @@ public:
|
||||
void SetMatrix(const gfxMatrix& matrix);
|
||||
gfxMatrix GetMatrix() const;
|
||||
|
||||
mozilla::gfx::Pattern *GetPattern(mozilla::gfx::DrawTarget *aTarget);
|
||||
/* Get an Azure Pattern for the current Cairo pattern. aPattern transform
|
||||
* specifies the transform that was set on the DrawTarget when the pattern
|
||||
* was set. When this is NULL it is assumed the transform is identical
|
||||
* to the current transform.
|
||||
*/
|
||||
mozilla::gfx::Pattern *GetPattern(mozilla::gfx::DrawTarget *aTarget,
|
||||
mozilla::gfx::Matrix *aPatternTransform = nsnull);
|
||||
bool IsOpaque();
|
||||
|
||||
enum GraphicsExtend {
|
||||
@ -128,6 +134,10 @@ public:
|
||||
protected:
|
||||
cairo_pattern_t *mPattern;
|
||||
|
||||
void AdjustTransformForPattern(mozilla::gfx::Matrix &aPatternTransform,
|
||||
const mozilla::gfx::Matrix &aCurrentTransform,
|
||||
const mozilla::gfx::Matrix *aOriginalTransform);
|
||||
|
||||
union {
|
||||
mozilla::AlignedStorage2<mozilla::gfx::ColorPattern> mColorPattern;
|
||||
mozilla::AlignedStorage2<mozilla::gfx::LinearGradientPattern> mLinearGradientPattern;
|
||||
|
Loading…
Reference in New Issue
Block a user