Bug 1058040, part 3 - Move SVGTextContextPaint into SVGContextPaint.h/.cpp. r=dholbert

--HG--
extra : rebase_source : 716c7586dcf6cd7c55df2cd6d0df40287a1b1374
This commit is contained in:
Jonathan Watt 2016-07-25 13:27:00 +01:00
Родитель f323872778
Коммит a6f638eeec
4 изменённых файлов: 165 добавлений и 159 удалений

Просмотреть файл

@ -6,6 +6,9 @@
#include "gfxContext.h"
#include "nsIDocument.h"
#include "nsSVGPaintServerFrame.h"
using namespace mozilla::gfx;
namespace mozilla {
@ -21,6 +24,88 @@ SVGContextPaint::InitStrokeGeometry(gfxContext* aContext,
mDashOffset /= devUnitsPerSVGUnit;
}
already_AddRefed<gfxPattern>
SVGTextContextPaint::GetFillPattern(const DrawTarget* aDrawTarget,
float aOpacity,
const gfxMatrix& aCTM)
{
return mFillPaint.GetPattern(aDrawTarget, aOpacity, &nsStyleSVG::mFill, aCTM);
}
already_AddRefed<gfxPattern>
SVGTextContextPaint::GetStrokePattern(const DrawTarget* aDrawTarget,
float aOpacity,
const gfxMatrix& aCTM)
{
return mStrokePaint.GetPattern(aDrawTarget, aOpacity, &nsStyleSVG::mStroke, aCTM);
}
already_AddRefed<gfxPattern>
SVGTextContextPaint::Paint::GetPattern(const DrawTarget* aDrawTarget,
float aOpacity,
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
const gfxMatrix& aCTM)
{
RefPtr<gfxPattern> pattern;
if (mPatternCache.Get(aOpacity, getter_AddRefs(pattern))) {
// Set the pattern matrix just in case it was messed with by a previous
// caller. We should get the same matrix each time a pattern is constructed
// so this should be fine.
pattern->SetMatrix(aCTM * mPatternMatrix);
return pattern.forget();
}
switch (mPaintType) {
case eStyleSVGPaintType_None:
pattern = new gfxPattern(Color());
mPatternMatrix = gfxMatrix();
break;
case eStyleSVGPaintType_Color: {
Color color = Color::FromABGR(mPaintDefinition.mColor);
color.a *= aOpacity;
pattern = new gfxPattern(color);
mPatternMatrix = gfxMatrix();
break;
}
case eStyleSVGPaintType_Server:
pattern = mPaintDefinition.mPaintServerFrame->GetPaintServerPattern(mFrame,
aDrawTarget,
mContextMatrix,
aFillOrStroke,
aOpacity);
{
// m maps original-user-space to pattern space
gfxMatrix m = pattern->GetMatrix();
gfxMatrix deviceToOriginalUserSpace = mContextMatrix;
if (!deviceToOriginalUserSpace.Invert()) {
return nullptr;
}
// mPatternMatrix maps device space to pattern space via original user space
mPatternMatrix = deviceToOriginalUserSpace * m;
}
pattern->SetMatrix(aCTM * mPatternMatrix);
break;
case eStyleSVGPaintType_ContextFill:
pattern = mPaintDefinition.mContextPaint->GetFillPattern(aDrawTarget,
aOpacity, aCTM);
// Don't cache this. mContextPaint will have cached it anyway. If we
// cache it, we'll have to compute mPatternMatrix, which is annoying.
return pattern.forget();
case eStyleSVGPaintType_ContextStroke:
pattern = mPaintDefinition.mContextPaint->GetStrokePattern(aDrawTarget,
aOpacity, aCTM);
// Don't cache this. mContextPaint will have cached it anyway. If we
// cache it, we'll have to compute mPatternMatrix, which is annoying.
return pattern.forget();
default:
MOZ_ASSERT(false, "invalid paint type");
return nullptr;
}
mPatternCache.Put(aOpacity, pattern);
return pattern.forget();
}
AutoSetRestoreSVGContextPaint::AutoSetRestoreSVGContextPaint(
SVGContextPaint* aContextPaint,
nsIDocument* aSVGDocument)

Просмотреть файл

@ -11,10 +11,12 @@
#include "gfxTypes.h"
#include "mozilla/AlreadyAddRefed.h"
#include "mozilla/gfx/2D.h"
#include "nsStyleStruct.h"
#include "nsTArray.h"
class gfxContext;
class nsIDocument;
class nsSVGPaintServerFrame;
namespace mozilla {
@ -102,6 +104,83 @@ private:
void* mOuterContextPaint;
};
/**
* This class should be flattened into SVGContextPaint once we get rid of the
* other sub-class (SimpleTextContextPaint).
*/
struct SVGTextContextPaint : public SVGContextPaint
{
protected:
typedef mozilla::gfx::DrawTarget DrawTarget;
public:
already_AddRefed<gfxPattern> GetFillPattern(const DrawTarget* aDrawTarget,
float aOpacity,
const gfxMatrix& aCTM) override;
already_AddRefed<gfxPattern> GetStrokePattern(const DrawTarget* aDrawTarget,
float aOpacity,
const gfxMatrix& aCTM) override;
void SetFillOpacity(float aOpacity) { mFillOpacity = aOpacity; }
float GetFillOpacity() const override { return mFillOpacity; }
void SetStrokeOpacity(float aOpacity) { mStrokeOpacity = aOpacity; }
float GetStrokeOpacity() const override { return mStrokeOpacity; }
struct Paint {
Paint() : mPaintType(eStyleSVGPaintType_None) {}
void SetPaintServer(nsIFrame* aFrame,
const gfxMatrix& aContextMatrix,
nsSVGPaintServerFrame* aPaintServerFrame) {
mPaintType = eStyleSVGPaintType_Server;
mPaintDefinition.mPaintServerFrame = aPaintServerFrame;
mFrame = aFrame;
mContextMatrix = aContextMatrix;
}
void SetColor(const nscolor &aColor) {
mPaintType = eStyleSVGPaintType_Color;
mPaintDefinition.mColor = aColor;
}
void SetContextPaint(SVGContextPaint* aContextPaint,
nsStyleSVGPaintType aPaintType) {
NS_ASSERTION(aPaintType == eStyleSVGPaintType_ContextFill ||
aPaintType == eStyleSVGPaintType_ContextStroke,
"Invalid context paint type");
mPaintType = aPaintType;
mPaintDefinition.mContextPaint = aContextPaint;
}
union {
nsSVGPaintServerFrame* mPaintServerFrame;
SVGContextPaint* mContextPaint;
nscolor mColor;
} mPaintDefinition;
nsIFrame* mFrame;
// CTM defining the user space for the pattern we will use.
gfxMatrix mContextMatrix;
nsStyleSVGPaintType mPaintType;
// Device-space-to-pattern-space
gfxMatrix mPatternMatrix;
nsRefPtrHashtable<nsFloatHashKey, gfxPattern> mPatternCache;
already_AddRefed<gfxPattern> GetPattern(const DrawTarget* aDrawTarget,
float aOpacity,
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
const gfxMatrix& aCTM);
};
Paint mFillPaint;
Paint mStrokePaint;
float mFillOpacity;
float mStrokeOpacity;
};
} // namespace mozilla
#endif // MOZILLA_SVGCONTEXTPAINT_H_

Просмотреть файл

@ -3030,91 +3030,6 @@ SVGTextDrawPathCallbacks::StrokeGeometry()
}
}
//----------------------------------------------------------------------
// SVGTextContextPaint methods:
already_AddRefed<gfxPattern>
SVGTextContextPaint::GetFillPattern(const DrawTarget* aDrawTarget,
float aOpacity,
const gfxMatrix& aCTM)
{
return mFillPaint.GetPattern(aDrawTarget, aOpacity, &nsStyleSVG::mFill, aCTM);
}
already_AddRefed<gfxPattern>
SVGTextContextPaint::GetStrokePattern(const DrawTarget* aDrawTarget,
float aOpacity,
const gfxMatrix& aCTM)
{
return mStrokePaint.GetPattern(aDrawTarget, aOpacity, &nsStyleSVG::mStroke, aCTM);
}
already_AddRefed<gfxPattern>
SVGTextContextPaint::Paint::GetPattern(const DrawTarget* aDrawTarget,
float aOpacity,
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
const gfxMatrix& aCTM)
{
RefPtr<gfxPattern> pattern;
if (mPatternCache.Get(aOpacity, getter_AddRefs(pattern))) {
// Set the pattern matrix just in case it was messed with by a previous
// caller. We should get the same matrix each time a pattern is constructed
// so this should be fine.
pattern->SetMatrix(aCTM * mPatternMatrix);
return pattern.forget();
}
switch (mPaintType) {
case eStyleSVGPaintType_None:
pattern = new gfxPattern(Color());
mPatternMatrix = gfxMatrix();
break;
case eStyleSVGPaintType_Color: {
Color color = Color::FromABGR(mPaintDefinition.mColor);
color.a *= aOpacity;
pattern = new gfxPattern(color);
mPatternMatrix = gfxMatrix();
break;
}
case eStyleSVGPaintType_Server:
pattern = mPaintDefinition.mPaintServerFrame->GetPaintServerPattern(mFrame,
aDrawTarget,
mContextMatrix,
aFillOrStroke,
aOpacity);
{
// m maps original-user-space to pattern space
gfxMatrix m = pattern->GetMatrix();
gfxMatrix deviceToOriginalUserSpace = mContextMatrix;
if (!deviceToOriginalUserSpace.Invert()) {
return nullptr;
}
// mPatternMatrix maps device space to pattern space via original user space
mPatternMatrix = deviceToOriginalUserSpace * m;
}
pattern->SetMatrix(aCTM * mPatternMatrix);
break;
case eStyleSVGPaintType_ContextFill:
pattern = mPaintDefinition.mContextPaint->GetFillPattern(aDrawTarget,
aOpacity, aCTM);
// Don't cache this. mContextPaint will have cached it anyway. If we
// cache it, we'll have to compute mPatternMatrix, which is annoying.
return pattern.forget();
case eStyleSVGPaintType_ContextStroke:
pattern = mPaintDefinition.mContextPaint->GetStrokePattern(aDrawTarget,
aOpacity, aCTM);
// Don't cache this. mContextPaint will have cached it anyway. If we
// cache it, we'll have to compute mPatternMatrix, which is annoying.
return pattern.forget();
default:
MOZ_ASSERT(false, "invalid paint type");
return nullptr;
}
mPatternCache.Put(aOpacity, pattern);
return pattern.forget();
}
} // namespace mozilla

Просмотреть файл

@ -9,14 +9,13 @@
#include "mozilla/Attributes.h"
#include "mozilla/RefPtr.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/SVGContextPaint.h"
#include "gfxMatrix.h"
#include "gfxRect.h"
#include "gfxTextRun.h"
#include "nsAutoPtr.h"
#include "nsIContent.h" // for GetContent
#include "nsStubMutationObserver.h"
#include "nsSVGPaintServerFrame.h"
#include "nsSVGContainerFrame.h"
class gfxContext;
class nsDisplaySVGText;
@ -138,77 +137,6 @@ private:
SVGTextFrame* mFrame;
};
// Slightly horrible callback for deferring application of opacity
struct SVGTextContextPaint : public SVGContextPaint {
protected:
typedef mozilla::gfx::DrawTarget DrawTarget;
public:
already_AddRefed<gfxPattern> GetFillPattern(const DrawTarget* aDrawTarget,
float aOpacity,
const gfxMatrix& aCTM) override;
already_AddRefed<gfxPattern> GetStrokePattern(const DrawTarget* aDrawTarget,
float aOpacity,
const gfxMatrix& aCTM) override;
void SetFillOpacity(float aOpacity) { mFillOpacity = aOpacity; }
float GetFillOpacity() const override { return mFillOpacity; }
void SetStrokeOpacity(float aOpacity) { mStrokeOpacity = aOpacity; }
float GetStrokeOpacity() const override { return mStrokeOpacity; }
struct Paint {
Paint() : mPaintType(eStyleSVGPaintType_None) {}
void SetPaintServer(nsIFrame *aFrame, const gfxMatrix& aContextMatrix,
nsSVGPaintServerFrame *aPaintServerFrame) {
mPaintType = eStyleSVGPaintType_Server;
mPaintDefinition.mPaintServerFrame = aPaintServerFrame;
mFrame = aFrame;
mContextMatrix = aContextMatrix;
}
void SetColor(const nscolor &aColor) {
mPaintType = eStyleSVGPaintType_Color;
mPaintDefinition.mColor = aColor;
}
void SetContextPaint(SVGContextPaint* aContextPaint,
nsStyleSVGPaintType aPaintType) {
NS_ASSERTION(aPaintType == eStyleSVGPaintType_ContextFill ||
aPaintType == eStyleSVGPaintType_ContextStroke,
"Invalid context paint type");
mPaintType = aPaintType;
mPaintDefinition.mContextPaint = aContextPaint;
}
union {
nsSVGPaintServerFrame *mPaintServerFrame;
SVGContextPaint* mContextPaint;
nscolor mColor;
} mPaintDefinition;
nsIFrame *mFrame;
// CTM defining the user space for the pattern we will use.
gfxMatrix mContextMatrix;
nsStyleSVGPaintType mPaintType;
// Device-space-to-pattern-space
gfxMatrix mPatternMatrix;
nsRefPtrHashtable<nsFloatHashKey, gfxPattern> mPatternCache;
already_AddRefed<gfxPattern> GetPattern(const DrawTarget* aDrawTarget,
float aOpacity,
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
const gfxMatrix& aCTM);
};
Paint mFillPaint;
Paint mStrokePaint;
float mFillOpacity;
float mStrokeOpacity;
};
} // namespace mozilla
/**
@ -262,7 +190,6 @@ class SVGTextFrame final : public nsSVGDisplayContainerFrame
typedef mozilla::gfx::DrawTarget DrawTarget;
typedef mozilla::gfx::Path Path;
typedef mozilla::gfx::Point Point;
typedef mozilla::SVGTextContextPaint SVGTextContextPaint;
typedef mozilla::image::DrawResult DrawResult;
protected: