Bug 928879 - Move SVGTextContextPaint to nsSVGTextFrame2.h/.cpp. r=heycam

This commit is contained in:
Jonathan Watt 2013-10-21 13:54:28 +02:00
parent 15c3ae590e
commit f93ec99ddd
4 changed files with 150 additions and 147 deletions

View File

@ -1074,83 +1074,6 @@ nsSVGGlyphFrame::SetupContextPaint(gfxContext *aContext,
return true;
}
//----------------------------------------------------------------------
// SVGTextContextPaint methods:
already_AddRefed<gfxPattern>
mozilla::SVGTextContextPaint::GetFillPattern(float aOpacity,
const gfxMatrix& aCTM)
{
return mFillPaint.GetPattern(aOpacity, &nsStyleSVG::mFill, aCTM);
}
already_AddRefed<gfxPattern>
mozilla::SVGTextContextPaint::GetStrokePattern(float aOpacity,
const gfxMatrix& aCTM)
{
return mStrokePaint.GetPattern(aOpacity, &nsStyleSVG::mStroke, aCTM);
}
already_AddRefed<gfxPattern>
mozilla::SVGTextContextPaint::Paint::GetPattern(float aOpacity,
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
const gfxMatrix& aCTM)
{
nsRefPtr<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(gfxRGBA(0.0f, 0.0f, 0.0f, 0.0f));
mPatternMatrix = gfxMatrix();
break;
case eStyleSVGPaintType_Color:
pattern = new gfxPattern(gfxRGBA(NS_GET_R(mPaintDefinition.mColor) / 255.0,
NS_GET_G(mPaintDefinition.mColor) / 255.0,
NS_GET_B(mPaintDefinition.mColor) / 255.0,
NS_GET_A(mPaintDefinition.mColor) / 255.0 * aOpacity));
mPatternMatrix = gfxMatrix();
break;
case eStyleSVGPaintType_Server:
pattern = mPaintDefinition.mPaintServerFrame->GetPaintServerPattern(mFrame,
mContextMatrix,
aFillOrStroke,
aOpacity);
{
// m maps original-user-space to pattern space
gfxMatrix m = pattern->GetMatrix();
gfxMatrix deviceToOriginalUserSpace = mContextMatrix;
deviceToOriginalUserSpace.Invert();
// 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(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(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();
}
//----------------------------------------------------------------------
// Internal methods

View File

@ -11,6 +11,7 @@
#include "nsISVGChildFrame.h"
#include "nsISVGGlyphFragmentNode.h"
#include "nsSVGGeometryFrame.h"
#include "nsSVGTextFrame2.h" // for SVGTextContextPaint
#include "nsSVGUtils.h"
#include "nsTextFragment.h"
#include "nsIContent.h"
@ -28,77 +29,10 @@ class gfxTextContextPaint;
struct CharacterPosition;
namespace mozilla {
namespace dom {
class SVGIRect;
}
// Slightly horrible callback for deferring application of opacity
struct SVGTextContextPaint : public gfxTextContextPaint {
already_AddRefed<gfxPattern> GetFillPattern(float aOpacity,
const gfxMatrix& aCTM) MOZ_OVERRIDE;
already_AddRefed<gfxPattern> GetStrokePattern(float aOpacity,
const gfxMatrix& aCTM) MOZ_OVERRIDE;
void SetFillOpacity(float aOpacity) { mFillOpacity = aOpacity; }
float GetFillOpacity() MOZ_OVERRIDE { return mFillOpacity; }
void SetStrokeOpacity(float aOpacity) { mStrokeOpacity = aOpacity; }
float GetStrokeOpacity() MOZ_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(gfxTextContextPaint *aContextPaint,
nsStyleSVGPaintType aPaintType) {
NS_ASSERTION(aPaintType == eStyleSVGPaintType_ContextFill ||
aPaintType == eStyleSVGPaintType_ContextStroke,
"Invalid context paint type");
mPaintType = aPaintType;
mPaintDefinition.mContextPaint = aContextPaint;
}
union {
nsSVGPaintServerFrame *mPaintServerFrame;
gfxTextContextPaint *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(float aOpacity,
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
const gfxMatrix& aCTM);
};
Paint mFillPaint;
Paint mStrokePaint;
float mFillOpacity;
float mStrokeOpacity;
};
} // namespace mozilla
}
using namespace mozilla;

View File

@ -2969,8 +2969,86 @@ SVGTextDrawPathCallbacks::StrokeGeometry()
}
}
//----------------------------------------------------------------------
// SVGTextContextPaint methods:
already_AddRefed<gfxPattern>
SVGTextContextPaint::GetFillPattern(float aOpacity,
const gfxMatrix& aCTM)
{
return mFillPaint.GetPattern(aOpacity, &nsStyleSVG::mFill, aCTM);
}
already_AddRefed<gfxPattern>
SVGTextContextPaint::GetStrokePattern(float aOpacity,
const gfxMatrix& aCTM)
{
return mStrokePaint.GetPattern(aOpacity, &nsStyleSVG::mStroke, aCTM);
}
already_AddRefed<gfxPattern>
SVGTextContextPaint::Paint::GetPattern(float aOpacity,
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
const gfxMatrix& aCTM)
{
nsRefPtr<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(gfxRGBA(0.0f, 0.0f, 0.0f, 0.0f));
mPatternMatrix = gfxMatrix();
break;
case eStyleSVGPaintType_Color:
pattern = new gfxPattern(gfxRGBA(NS_GET_R(mPaintDefinition.mColor) / 255.0,
NS_GET_G(mPaintDefinition.mColor) / 255.0,
NS_GET_B(mPaintDefinition.mColor) / 255.0,
NS_GET_A(mPaintDefinition.mColor) / 255.0 * aOpacity));
mPatternMatrix = gfxMatrix();
break;
case eStyleSVGPaintType_Server:
pattern = mPaintDefinition.mPaintServerFrame->GetPaintServerPattern(mFrame,
mContextMatrix,
aFillOrStroke,
aOpacity);
{
// m maps original-user-space to pattern space
gfxMatrix m = pattern->GetMatrix();
gfxMatrix deviceToOriginalUserSpace = mContextMatrix;
deviceToOriginalUserSpace.Invert();
// 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(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(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
// ============================================================================
// nsSVGTextFrame2

View File

@ -10,8 +10,9 @@
#include "gfxMatrix.h"
#include "gfxRect.h"
#include "gfxSVGGlyphs.h"
#include "nsIContent.h"
#include "nsStubMutationObserver.h"
#include "nsSVGGlyphFrame.h" // for SVGTextContextPaint
#include "nsSVGPaintServerFrame.h"
#include "nsSVGTextContainerFrame.h"
class nsDisplaySVGText;
@ -135,7 +136,72 @@ private:
nsSVGTextFrame2* mFrame;
};
}
// Slightly horrible callback for deferring application of opacity
struct SVGTextContextPaint : public gfxTextContextPaint {
already_AddRefed<gfxPattern> GetFillPattern(float aOpacity,
const gfxMatrix& aCTM) MOZ_OVERRIDE;
already_AddRefed<gfxPattern> GetStrokePattern(float aOpacity,
const gfxMatrix& aCTM) MOZ_OVERRIDE;
void SetFillOpacity(float aOpacity) { mFillOpacity = aOpacity; }
float GetFillOpacity() MOZ_OVERRIDE { return mFillOpacity; }
void SetStrokeOpacity(float aOpacity) { mStrokeOpacity = aOpacity; }
float GetStrokeOpacity() MOZ_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(gfxTextContextPaint *aContextPaint,
nsStyleSVGPaintType aPaintType) {
NS_ASSERTION(aPaintType == eStyleSVGPaintType_ContextFill ||
aPaintType == eStyleSVGPaintType_ContextStroke,
"Invalid context paint type");
mPaintType = aPaintType;
mPaintDefinition.mContextPaint = aContextPaint;
}
union {
nsSVGPaintServerFrame *mPaintServerFrame;
gfxTextContextPaint *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(float aOpacity,
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
const gfxMatrix& aCTM);
};
Paint mFillPaint;
Paint mStrokePaint;
float mFillOpacity;
float mStrokeOpacity;
};
} // namespace mozilla
/**
* Frame class for SVG <text> elements, used when the
@ -185,6 +251,8 @@ class nsSVGTextFrame2 : public nsSVGTextFrame2Base
friend class MutationObserver;
friend class nsDisplaySVGText;
typedef mozilla::SVGTextContextPaint SVGTextContextPaint;
protected:
nsSVGTextFrame2(nsStyleContext* aContext)
: nsSVGTextFrame2Base(aContext),