mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
Bug 1073012 , part 2 - Replace nsSVGUtils::SetupCairoStrokePaint with a helper that returns a gfxPattern. r=longsonr
This commit is contained in:
parent
071a7f8dad
commit
7c2f3f1ed0
@ -375,9 +375,13 @@ nsFilterInstance::BuildSourcePaint(SourceInfo *aSource,
|
||||
gfx->SetPattern(fillPattern);
|
||||
gfx->Fill();
|
||||
}
|
||||
} else if (aSource == &mStrokePaint &&
|
||||
nsSVGUtils::SetupCairoStrokePaint(mTargetFrame, gfx)) {
|
||||
gfx->Fill();
|
||||
} else if (aSource == &mStrokePaint) {
|
||||
nsRefPtr<gfxPattern> strokePattern =
|
||||
nsSVGUtils::MakeStrokePatternFor(mTargetFrame, gfx);
|
||||
if (strokePattern) {
|
||||
gfx->SetPattern(strokePattern);
|
||||
gfx->Fill(); // yes, filling a primitive subregion with _stroke_ paint
|
||||
}
|
||||
}
|
||||
gfx->Restore();
|
||||
}
|
||||
|
@ -503,7 +503,6 @@ nsSVGPathGeometryFrame::GetBBoxContribution(const Matrix &aToBBoxUserspace,
|
||||
// though, because if pathExtents is empty, its position will not have
|
||||
// been set. Happily we can use tmpCtx->GetUserStrokeExtent() to find
|
||||
// the center point of the extents even though it gets the extents wrong.
|
||||
nsSVGUtils::SetupCairoStrokeBBoxGeometry(this, tmpCtx);
|
||||
pathExtents.MoveTo(tmpCtx->GetUserStrokeExtent().Center());
|
||||
pathExtents.SizeTo(0, 0);
|
||||
}
|
||||
|
@ -1233,20 +1233,6 @@ nsSVGUtils::GetFallbackOrPaintColor(nsStyleContext *aStyleContext,
|
||||
return color;
|
||||
}
|
||||
|
||||
static void
|
||||
SetupFallbackOrPaintColor(gfxContext *aContext, nsStyleContext *aStyleContext,
|
||||
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
|
||||
float aOpacity)
|
||||
{
|
||||
nscolor color =
|
||||
nsSVGUtils::GetFallbackOrPaintColor(aStyleContext, aFillOrStroke);
|
||||
|
||||
aContext->SetColor(gfxRGBA(NS_GET_R(color)/255.0,
|
||||
NS_GET_G(color)/255.0,
|
||||
NS_GET_B(color)/255.0,
|
||||
NS_GET_A(color)/255.0 * aOpacity));
|
||||
}
|
||||
|
||||
static float
|
||||
MaybeOptimizeOpacity(nsIFrame *aFrame, float aFillOrStrokeOpacity)
|
||||
{
|
||||
@ -1257,38 +1243,6 @@ MaybeOptimizeOpacity(nsIFrame *aFrame, float aFillOrStrokeOpacity)
|
||||
return aFillOrStrokeOpacity;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
nsSVGUtils::SetupContextPaint(gfxContext *aContext,
|
||||
gfxTextContextPaint *aContextPaint,
|
||||
const nsStyleSVGPaint &aPaint,
|
||||
float aOpacity)
|
||||
{
|
||||
nsRefPtr<gfxPattern> pattern;
|
||||
|
||||
if (!aContextPaint) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (aPaint.mType) {
|
||||
case eStyleSVGPaintType_ContextFill:
|
||||
pattern = aContextPaint->GetFillPattern(aOpacity, aContext->CurrentMatrix());
|
||||
break;
|
||||
case eStyleSVGPaintType_ContextStroke:
|
||||
pattern = aContextPaint->GetStrokePattern(aOpacity, aContext->CurrentMatrix());
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!pattern) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aContext->SetPattern(pattern);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<gfxPattern>
|
||||
nsSVGUtils::MakeFillPatternFor(nsIFrame *aFrame,
|
||||
gfxContext* aContext,
|
||||
@ -1336,7 +1290,7 @@ nsSVGUtils::MakeFillPatternFor(nsIFrame *aFrame,
|
||||
// On failure, use the fallback colour in case we have an
|
||||
// objectBoundingBox where the width or height of the object is zero.
|
||||
// See http://www.w3.org/TR/SVG11/coords.html#ObjectBoundingBox
|
||||
nscolor color = GetFallbackOrPaintColor(aContext, aFrame->StyleContext(),
|
||||
nscolor color = GetFallbackOrPaintColor(aFrame->StyleContext(),
|
||||
&nsStyleSVG::mFill);
|
||||
pattern = new gfxPattern(gfxRGBA(NS_GET_R(color)/255.0,
|
||||
NS_GET_G(color)/255.0,
|
||||
@ -1345,35 +1299,60 @@ nsSVGUtils::MakeFillPatternFor(nsIFrame *aFrame,
|
||||
return pattern.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
nsSVGUtils::SetupCairoStrokePaint(nsIFrame *aFrame, gfxContext* aContext,
|
||||
gfxTextContextPaint *aContextPaint)
|
||||
/* static */ already_AddRefed<gfxPattern>
|
||||
nsSVGUtils::MakeStrokePatternFor(nsIFrame *aFrame,
|
||||
gfxContext* aContext,
|
||||
gfxTextContextPaint *aContextPaint)
|
||||
{
|
||||
const nsStyleSVG* style = aFrame->StyleSVG();
|
||||
if (style->mStroke.mType == eStyleSVGPaintType_None)
|
||||
return false;
|
||||
if (style->mStroke.mType == eStyleSVGPaintType_None) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
float opacity = MaybeOptimizeOpacity(aFrame,
|
||||
GetOpacity(style->mStrokeOpacitySource,
|
||||
style->mStrokeOpacity,
|
||||
aContextPaint));
|
||||
nsRefPtr<gfxPattern> pattern;
|
||||
|
||||
nsSVGPaintServerFrame *ps =
|
||||
nsSVGEffects::GetPaintServer(aFrame, &style->mStroke, nsSVGEffects::StrokeProperty());
|
||||
if (ps && ps->SetupPaintServer(aContext, aFrame, &nsStyleSVG::mStroke, opacity))
|
||||
return true;
|
||||
nsSVGEffects::GetPaintServer(aFrame, &style->mStroke,
|
||||
nsSVGEffects::StrokeProperty());
|
||||
if (ps) {
|
||||
pattern = ps->GetPaintServerPattern(aFrame, aContext->CurrentMatrix(),
|
||||
&nsStyleSVG::mStroke, opacity);
|
||||
if (pattern) {
|
||||
pattern->CacheColorStops(aContext->GetDrawTarget());
|
||||
return pattern.forget();
|
||||
}
|
||||
}
|
||||
|
||||
if (SetupContextPaint(aContext, aContextPaint, style->mStroke, opacity)) {
|
||||
return true;
|
||||
if (aContextPaint) {
|
||||
switch (style->mStroke.mType) {
|
||||
case eStyleSVGPaintType_ContextFill:
|
||||
pattern = aContextPaint->GetFillPattern(opacity, aContext->CurrentMatrix());
|
||||
break;
|
||||
case eStyleSVGPaintType_ContextStroke:
|
||||
pattern = aContextPaint->GetStrokePattern(opacity, aContext->CurrentMatrix());
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
if (pattern) {
|
||||
return pattern.forget();
|
||||
}
|
||||
}
|
||||
|
||||
// On failure, use the fallback colour in case we have an
|
||||
// objectBoundingBox where the width or height of the object is zero.
|
||||
// See http://www.w3.org/TR/SVG11/coords.html#ObjectBoundingBox
|
||||
SetupFallbackOrPaintColor(aContext, aFrame->StyleContext(),
|
||||
&nsStyleSVG::mStroke, opacity);
|
||||
|
||||
return true;
|
||||
nscolor color = GetFallbackOrPaintColor(aFrame->StyleContext(),
|
||||
&nsStyleSVG::mStroke);
|
||||
pattern = new gfxPattern(gfxRGBA(NS_GET_R(color)/255.0,
|
||||
NS_GET_G(color)/255.0,
|
||||
NS_GET_B(color)/255.0,
|
||||
NS_GET_A(color)/255.0 * opacity));
|
||||
return pattern.forget();
|
||||
}
|
||||
|
||||
/* static */ float
|
||||
@ -1431,51 +1410,6 @@ nsSVGUtils::GetStrokeWidth(nsIFrame* aFrame, gfxTextContextPaint *aContextPaint)
|
||||
return SVGContentUtils::CoordToFloat(ctx, style->mStrokeWidth);
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGUtils::SetupCairoStrokeBBoxGeometry(nsIFrame* aFrame,
|
||||
gfxContext *aContext,
|
||||
gfxTextContextPaint *aContextPaint)
|
||||
{
|
||||
float width = GetStrokeWidth(aFrame, aContextPaint);
|
||||
if (width <= 0)
|
||||
return;
|
||||
aContext->SetLineWidth(width);
|
||||
|
||||
// Apply any stroke-specific transform
|
||||
gfxMatrix strokeTransform = GetStrokeTransform(aFrame);
|
||||
if (!strokeTransform.IsIdentity()) {
|
||||
aContext->Multiply(strokeTransform);
|
||||
}
|
||||
|
||||
const nsStyleSVG* style = aFrame->StyleSVG();
|
||||
|
||||
switch (style->mStrokeLinecap) {
|
||||
case NS_STYLE_STROKE_LINECAP_BUTT:
|
||||
aContext->SetLineCap(gfxContext::LINE_CAP_BUTT);
|
||||
break;
|
||||
case NS_STYLE_STROKE_LINECAP_ROUND:
|
||||
aContext->SetLineCap(gfxContext::LINE_CAP_ROUND);
|
||||
break;
|
||||
case NS_STYLE_STROKE_LINECAP_SQUARE:
|
||||
aContext->SetLineCap(gfxContext::LINE_CAP_SQUARE);
|
||||
break;
|
||||
}
|
||||
|
||||
aContext->SetMiterLimit(style->mStrokeMiterlimit);
|
||||
|
||||
switch (style->mStrokeLinejoin) {
|
||||
case NS_STYLE_STROKE_LINEJOIN_MITER:
|
||||
aContext->SetLineJoin(gfxContext::LINE_JOIN_MITER);
|
||||
break;
|
||||
case NS_STYLE_STROKE_LINEJOIN_ROUND:
|
||||
aContext->SetLineJoin(gfxContext::LINE_JOIN_ROUND);
|
||||
break;
|
||||
case NS_STYLE_STROKE_LINEJOIN_BEVEL:
|
||||
aContext->SetLineJoin(gfxContext::LINE_JOIN_BEVEL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
GetStrokeDashData(nsIFrame* aFrame,
|
||||
FallibleTArray<gfxFloat>& aDashes,
|
||||
@ -1538,10 +1472,48 @@ GetStrokeDashData(nsIFrame* aFrame,
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGUtils::SetupCairoStrokeGeometry(nsIFrame* aFrame, gfxContext* aContext,
|
||||
nsSVGUtils::SetupCairoStrokeGeometry(nsIFrame* aFrame,
|
||||
gfxContext *aContext,
|
||||
gfxTextContextPaint *aContextPaint)
|
||||
{
|
||||
SetupCairoStrokeBBoxGeometry(aFrame, aContext, aContextPaint);
|
||||
float width = GetStrokeWidth(aFrame, aContextPaint);
|
||||
if (width <= 0)
|
||||
return;
|
||||
aContext->SetLineWidth(width);
|
||||
|
||||
// Apply any stroke-specific transform
|
||||
gfxMatrix strokeTransform = GetStrokeTransform(aFrame);
|
||||
if (!strokeTransform.IsIdentity()) {
|
||||
aContext->Multiply(strokeTransform);
|
||||
}
|
||||
|
||||
const nsStyleSVG* style = aFrame->StyleSVG();
|
||||
|
||||
switch (style->mStrokeLinecap) {
|
||||
case NS_STYLE_STROKE_LINECAP_BUTT:
|
||||
aContext->SetLineCap(gfxContext::LINE_CAP_BUTT);
|
||||
break;
|
||||
case NS_STYLE_STROKE_LINECAP_ROUND:
|
||||
aContext->SetLineCap(gfxContext::LINE_CAP_ROUND);
|
||||
break;
|
||||
case NS_STYLE_STROKE_LINECAP_SQUARE:
|
||||
aContext->SetLineCap(gfxContext::LINE_CAP_SQUARE);
|
||||
break;
|
||||
}
|
||||
|
||||
aContext->SetMiterLimit(style->mStrokeMiterlimit);
|
||||
|
||||
switch (style->mStrokeLinejoin) {
|
||||
case NS_STYLE_STROKE_LINEJOIN_MITER:
|
||||
aContext->SetLineJoin(gfxContext::LINE_JOIN_MITER);
|
||||
break;
|
||||
case NS_STYLE_STROKE_LINEJOIN_ROUND:
|
||||
aContext->SetLineJoin(gfxContext::LINE_JOIN_ROUND);
|
||||
break;
|
||||
case NS_STYLE_STROKE_LINEJOIN_BEVEL:
|
||||
aContext->SetLineJoin(gfxContext::LINE_JOIN_BEVEL);
|
||||
break;
|
||||
}
|
||||
|
||||
AutoFallibleTArray<gfxFloat, 10> dashes;
|
||||
gfxFloat dashOffset;
|
||||
@ -1618,7 +1590,13 @@ nsSVGUtils::SetupCairoStroke(nsIFrame* aFrame, gfxContext* aContext,
|
||||
}
|
||||
SetupCairoStrokeGeometry(aFrame, aContext, aContextPaint);
|
||||
|
||||
return SetupCairoStrokePaint(aFrame, aContext, aContextPaint);
|
||||
nsRefPtr<gfxPattern> pattern =
|
||||
MakeStrokePatternFor(aFrame, aContext, aContextPaint);
|
||||
if (pattern) {
|
||||
aContext->SetPattern(pattern);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -506,25 +506,15 @@ public:
|
||||
static nscolor GetFallbackOrPaintColor(nsStyleContext *aStyleContext,
|
||||
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke);
|
||||
|
||||
/**
|
||||
* Set up cairo context with an object pattern
|
||||
*/
|
||||
static bool SetupContextPaint(gfxContext *aContext,
|
||||
gfxTextContextPaint *aContextPaint,
|
||||
const nsStyleSVGPaint& aPaint,
|
||||
float aOpacity);
|
||||
|
||||
static already_AddRefed<gfxPattern>
|
||||
MakeFillPatternFor(nsIFrame *aFrame,
|
||||
gfxContext* aContext,
|
||||
gfxTextContextPaint *aContextPaint = nullptr);
|
||||
|
||||
/**
|
||||
* Sets the current paint on the specified gfxContent to be the SVG 'stroke'
|
||||
* for the given frame.
|
||||
*/
|
||||
static bool SetupCairoStrokePaint(nsIFrame* aFrame, gfxContext* aContext,
|
||||
gfxTextContextPaint *aContextPaint = nullptr);
|
||||
static already_AddRefed<gfxPattern>
|
||||
MakeStrokePatternFor(nsIFrame* aFrame,
|
||||
gfxContext* aContext,
|
||||
gfxTextContextPaint *aContextPaint = nullptr);
|
||||
|
||||
static float GetOpacity(nsStyleSVGOpacitySource aOpacityType,
|
||||
const float& aOpacity,
|
||||
@ -539,13 +529,6 @@ public:
|
||||
static float GetStrokeWidth(nsIFrame* aFrame,
|
||||
gfxTextContextPaint *aContextPaint = nullptr);
|
||||
|
||||
/*
|
||||
* Set up a cairo context for measuring the bounding box of a stroked path.
|
||||
*/
|
||||
static void SetupCairoStrokeBBoxGeometry(nsIFrame* aFrame,
|
||||
gfxContext *aContext,
|
||||
gfxTextContextPaint *aContextPaint = nullptr);
|
||||
|
||||
/*
|
||||
* Set up a cairo context for a stroked path (including any dashing that
|
||||
* applies).
|
||||
|
Loading…
Reference in New Issue
Block a user