Bug 1067222 - Make the gfxPattern code much easier to understand (by giving variables meaningful names, adding comments, and integrating the mysterious AdjustTransformForPattern into gfxPattern::GetPattern). r=Bas

This commit is contained in:
Jonathan Watt 2014-09-15 16:24:03 +01:00
parent c653ceb746
commit 3ef1f75536
2 changed files with 36 additions and 66 deletions

View File

@ -47,12 +47,12 @@ gfxPattern::gfxPattern(gfxFloat cx0, gfxFloat cy0, gfxFloat radius0,
} }
// Azure // Azure
gfxPattern::gfxPattern(SourceSurface *aSurface, const Matrix &aTransform) gfxPattern::gfxPattern(SourceSurface *aSurface, const Matrix &aPatternToUserSpace)
: mTransform(aTransform) : mPatternToUserSpace(aPatternToUserSpace)
, mExtend(EXTEND_NONE) , mExtend(EXTEND_NONE)
{ {
mGfxPattern = new (mSurfacePattern.addr()) mGfxPattern = new (mSurfacePattern.addr())
SurfacePattern(aSurface, ToExtendMode(mExtend), aTransform, SurfacePattern(aSurface, ToExtendMode(mExtend), Matrix(), // matrix is overridden in GetPattern()
mozilla::gfx::Filter::GOOD); mozilla::gfx::Filter::GOOD);
} }
@ -100,13 +100,13 @@ gfxPattern::CacheColorStops(DrawTarget *aDT)
} }
void void
gfxPattern::SetMatrix(const gfxMatrix& matrix) gfxPattern::SetMatrix(const gfxMatrix& aPatternToUserSpace)
{ {
mTransform = ToMatrix(matrix); mPatternToUserSpace = ToMatrix(aPatternToUserSpace);
// Cairo-pattern matrices specify the conversion from DrawTarget to pattern // Cairo-pattern matrices specify the conversion from DrawTarget to pattern
// space. Azure pattern matrices specify the conversion from pattern to // space. Azure pattern matrices specify the conversion from pattern to
// DrawTarget space. // DrawTarget space.
mTransform.Invert(); mPatternToUserSpace.Invert();
} }
gfxMatrix gfxMatrix
@ -114,7 +114,7 @@ gfxPattern::GetMatrix() const
{ {
// invert at the higher precision of gfxMatrix // invert at the higher precision of gfxMatrix
// cause we need to convert at some point anyways // cause we need to convert at some point anyways
gfxMatrix mat = ThebesMatrix(mTransform); gfxMatrix mat = ThebesMatrix(mPatternToUserSpace);
mat.Invert(); mat.Invert();
return mat; return mat;
} }
@ -122,12 +122,33 @@ gfxPattern::GetMatrix() const
gfxMatrix gfxMatrix
gfxPattern::GetInverseMatrix() const gfxPattern::GetInverseMatrix() const
{ {
return ThebesMatrix(mTransform); return ThebesMatrix(mPatternToUserSpace);
} }
Pattern* Pattern*
gfxPattern::GetPattern(DrawTarget *aTarget, Matrix *aPatternTransform) gfxPattern::GetPattern(DrawTarget *aTarget,
Matrix *aOriginalUserToDevice)
{ {
Matrix patternToUser = mPatternToUserSpace;
if (aOriginalUserToDevice &&
*aOriginalUserToDevice != aTarget->GetTransform()) {
// mPatternToUserSpace maps from pattern space to the original user space,
// but aTarget now has a transform to a different user space. In order for
// the Pattern* that we return to be usable in aTarget's new user space we
// need the Pattern's mMatrix to be the transform from pattern space to
// aTarget's -new- user space. That transform is equivalent to the
// transform from pattern space to original user space (patternToUser),
// multiplied by the transform from original user space to device space,
// multiplied by the transform from device space to current user space.
Matrix deviceToCurrentUser = aTarget->GetTransform();
deviceToCurrentUser.Invert();
patternToUser = patternToUser * *aOriginalUserToDevice * deviceToCurrentUser;
}
patternToUser.NudgeToIntegers();
if (!mStops && if (!mStops &&
!mStopsList.IsEmpty()) { !mStopsList.IsEmpty()) {
mStops = aTarget->CreateGradientStops(mStopsList.Elements(), mStops = aTarget->CreateGradientStops(mStopsList.Elements(),
@ -135,18 +156,17 @@ gfxPattern::GetPattern(DrawTarget *aTarget, Matrix *aPatternTransform)
ToExtendMode(mExtend)); ToExtendMode(mExtend));
} }
Matrix* matrix = nullptr;
switch (mGfxPattern->GetType()) { switch (mGfxPattern->GetType()) {
case PatternType::SURFACE: case PatternType::SURFACE:
matrix = &mSurfacePattern.addr()->mMatrix; mSurfacePattern.addr()->mMatrix = patternToUser;
mSurfacePattern.addr()->mExtendMode = ToExtendMode(mExtend); mSurfacePattern.addr()->mExtendMode = ToExtendMode(mExtend);
break; break;
case PatternType::LINEAR_GRADIENT: case PatternType::LINEAR_GRADIENT:
matrix = &mLinearGradientPattern.addr()->mMatrix; mLinearGradientPattern.addr()->mMatrix = patternToUser;
mLinearGradientPattern.addr()->mStops = mStops; mLinearGradientPattern.addr()->mStops = mStops;
break; break;
case PatternType::RADIAL_GRADIENT: case PatternType::RADIAL_GRADIENT:
matrix = &mRadialGradientPattern.addr()->mMatrix; mRadialGradientPattern.addr()->mMatrix = patternToUser;
mRadialGradientPattern.addr()->mStops = mStops; mRadialGradientPattern.addr()->mStops = mStops;
break; break;
default: default:
@ -154,15 +174,6 @@ gfxPattern::GetPattern(DrawTarget *aTarget, Matrix *aPatternTransform)
break; break;
} }
if (matrix) {
*matrix = mTransform;
if (aPatternTransform) {
AdjustTransformForPattern(*matrix,
aTarget->GetTransform(),
aPatternTransform);
}
}
return mGfxPattern; return mGfxPattern;
} }
@ -233,29 +244,3 @@ gfxPattern::CairoStatus()
{ {
return CAIRO_STATUS_SUCCESS; return CAIRO_STATUS_SUCCESS;
} }
void
gfxPattern::AdjustTransformForPattern(Matrix &aPatternTransform,
const Matrix &aCurrentTransform,
const Matrix *aOriginalTransform)
{
aPatternTransform.Invert();
if (!aOriginalTransform) {
// User space is unchanged, so to get from pattern space to user space,
// just invert the cairo matrix.
aPatternTransform.NudgeToIntegers();
return;
}
// aPatternTransform now maps from pattern space to the user space defined
// by *aOriginalTransform.
Matrix mat = aCurrentTransform;
mat.Invert();
// mat maps from device space to current user space
// First, transform from pattern space to original user space. Then transform
// from original user space to device space. Then transform from
// device space to current user space.
aPatternTransform = aPatternTransform * *aOriginalTransform * mat;
aPatternTransform.NudgeToIntegers();
}

View File

@ -32,7 +32,7 @@ public:
gfxPattern(gfxFloat cx0, gfxFloat cy0, gfxFloat radius0, gfxPattern(gfxFloat cx0, gfxFloat cy0, gfxFloat radius0,
gfxFloat cx1, gfxFloat cy1, gfxFloat radius1); // radial gfxFloat cx1, gfxFloat cy1, gfxFloat radius1); // radial
gfxPattern(mozilla::gfx::SourceSurface *aSurface, gfxPattern(mozilla::gfx::SourceSurface *aSurface,
const mozilla::gfx::Matrix &aTransform); // Azure const mozilla::gfx::Matrix &aPatternToUserSpace);
void AddColorStop(gfxFloat offset, const gfxRGBA& c); void AddColorStop(gfxFloat offset, const gfxRGBA& c);
void SetColorStops(mozilla::gfx::GradientStops* aStops); void SetColorStops(mozilla::gfx::GradientStops* aStops);
@ -52,7 +52,7 @@ public:
* to the current transform. * to the current transform.
*/ */
mozilla::gfx::Pattern *GetPattern(mozilla::gfx::DrawTarget *aTarget, mozilla::gfx::Pattern *GetPattern(mozilla::gfx::DrawTarget *aTarget,
mozilla::gfx::Matrix *aPatternTransform = nullptr); mozilla::gfx::Matrix *aOriginalUserToDevice = nullptr);
bool IsOpaque(); bool IsOpaque();
enum GraphicsExtend { enum GraphicsExtend {
@ -97,21 +97,6 @@ private:
// Private destructor, to discourage deletion outside of Release(): // Private destructor, to discourage deletion outside of Release():
~gfxPattern(); ~gfxPattern();
/**
* aPatternTransform is the cairo pattern transform --- from user space at
* the time the pattern was set, to pattern space.
* aCurrentTransform is the DrawTarget's CTM --- from user space to device
* space.
* aOriginalTransform, if non-null, is the DrawTarget's TM when
* aPatternTransform was set --- user space to device space. If null, then
* the DrawTarget's CTM is the same as the TM when aPatternTransfrom was set.
* This function sets aPatternTransform to the Azure pattern transform ---
* from pattern space to current DrawTarget user space.
*/
void AdjustTransformForPattern(mozilla::gfx::Matrix &aPatternTransform,
const mozilla::gfx::Matrix &aCurrentTransform,
const mozilla::gfx::Matrix *aOriginalTransform);
union { union {
mozilla::AlignedStorage2<mozilla::gfx::ColorPattern> mColorPattern; mozilla::AlignedStorage2<mozilla::gfx::ColorPattern> mColorPattern;
mozilla::AlignedStorage2<mozilla::gfx::LinearGradientPattern> mLinearGradientPattern; mozilla::AlignedStorage2<mozilla::gfx::LinearGradientPattern> mLinearGradientPattern;
@ -122,7 +107,7 @@ private:
mozilla::gfx::Pattern *mGfxPattern; mozilla::gfx::Pattern *mGfxPattern;
mozilla::RefPtr<mozilla::gfx::SourceSurface> mSourceSurface; mozilla::RefPtr<mozilla::gfx::SourceSurface> mSourceSurface;
mozilla::gfx::Matrix mTransform; mozilla::gfx::Matrix mPatternToUserSpace;
mozilla::RefPtr<mozilla::gfx::GradientStops> mStops; mozilla::RefPtr<mozilla::gfx::GradientStops> mStops;
nsTArray<mozilla::gfx::GradientStop> mStopsList; nsTArray<mozilla::gfx::GradientStop> mStopsList;
GraphicsExtend mExtend; GraphicsExtend mExtend;