mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-03 10:33:33 +00:00
Bug 1073888 - Stop setting state on the gfxContext under SVGTextFrame::SetupCairoState, and restructure the code to make it easier to understand. r=heycam
This commit is contained in:
parent
e45fecdbb6
commit
a13699436c
@ -3671,10 +3671,16 @@ SVGTextFrame::PaintSVG(nsRenderingContext* aContext,
|
||||
gfxTextContextPaint *outerContextPaint =
|
||||
(gfxTextContextPaint*)aContext->GetDrawTarget()->GetUserData(&gfxTextContextPaint::sUserDataKey);
|
||||
|
||||
nsAutoPtr<gfxTextContextPaint> contextPaint;
|
||||
SVGTextContextPaint contextPaint;
|
||||
DrawMode drawMode =
|
||||
SetupCairoState(gfx, frame, outerContextPaint,
|
||||
getter_Transfers(contextPaint));
|
||||
SetupContextPaint(gfx->CurrentMatrix(), frame, outerContextPaint,
|
||||
&contextPaint);
|
||||
|
||||
if (int(drawMode) & int(DrawMode::GLYPH_STROKE)) {
|
||||
// This may change the gfxContext's transform (for non-scaling stroke),
|
||||
// in which case this needs to happen before we call SetMatrix() below.
|
||||
nsSVGUtils::SetupCairoStrokeGeometry(frame, gfx, outerContextPaint);
|
||||
}
|
||||
|
||||
// Set up the transform for painting the text frame for the substring
|
||||
// indicated by the run.
|
||||
@ -3691,10 +3697,10 @@ SVGTextFrame::PaintSVG(nsRenderingContext* aContext,
|
||||
matrixForPaintServers,
|
||||
paintSVGGlyphs);
|
||||
frame->PaintText(aContext, nsPoint(), frameRect, item,
|
||||
contextPaint, &callbacks);
|
||||
&contextPaint, &callbacks);
|
||||
} else {
|
||||
frame->PaintText(aContext, nsPoint(), frameRect, item,
|
||||
contextPaint, nullptr);
|
||||
&contextPaint, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5566,109 +5572,102 @@ SVGTextFrame::TransformFrameRectFromTextChild(const nsRect& aRect,
|
||||
return result - framePosition;
|
||||
}
|
||||
|
||||
DrawMode
|
||||
SVGTextFrame::SetupCairoState(gfxContext* aContext,
|
||||
nsIFrame* aFrame,
|
||||
gfxTextContextPaint* aOuterContextPaint,
|
||||
gfxTextContextPaint** aThisContextPaint)
|
||||
{
|
||||
DrawMode toDraw = DrawMode(0);
|
||||
SVGTextContextPaint *thisContextPaint = new SVGTextContextPaint();
|
||||
|
||||
if (SetupCairoStroke(aContext, aFrame, aOuterContextPaint, thisContextPaint)) {
|
||||
toDraw = DrawMode(int(toDraw) | int(DrawMode::GLYPH_STROKE));
|
||||
}
|
||||
|
||||
if (SetupCairoFill(aContext, aFrame, aOuterContextPaint, thisContextPaint)) {
|
||||
toDraw = DrawMode(int(toDraw) | int(DrawMode::GLYPH_FILL));
|
||||
}
|
||||
|
||||
*aThisContextPaint = thisContextPaint;
|
||||
|
||||
return toDraw;
|
||||
}
|
||||
|
||||
bool
|
||||
SVGTextFrame::SetupCairoStroke(gfxContext* aContext,
|
||||
nsIFrame* aFrame,
|
||||
gfxTextContextPaint* aOuterContextPaint,
|
||||
SVGTextContextPaint* aThisContextPaint)
|
||||
{
|
||||
const nsStyleSVG *style = aFrame->StyleSVG();
|
||||
if (style->mStroke.mType == eStyleSVGPaintType_None) {
|
||||
aThisContextPaint->SetStrokeOpacity(0.0f);
|
||||
return false;
|
||||
}
|
||||
|
||||
nsSVGUtils::SetupCairoStrokeGeometry(aFrame, aContext, aOuterContextPaint);
|
||||
float opacity = nsSVGUtils::GetOpacity(style->mStrokeOpacitySource,
|
||||
style->mStrokeOpacity,
|
||||
aOuterContextPaint);
|
||||
|
||||
SetupInheritablePaint(aContext, aFrame, opacity, aOuterContextPaint,
|
||||
aThisContextPaint->mStrokePaint, &nsStyleSVG::mStroke,
|
||||
nsSVGEffects::StrokeProperty());
|
||||
|
||||
aThisContextPaint->SetStrokeOpacity(opacity);
|
||||
|
||||
return opacity != 0.0f;
|
||||
}
|
||||
|
||||
bool
|
||||
SVGTextFrame::SetupCairoFill(gfxContext* aContext,
|
||||
nsIFrame* aFrame,
|
||||
gfxTextContextPaint* aOuterContextPaint,
|
||||
SVGTextContextPaint* aThisContextPaint)
|
||||
{
|
||||
const nsStyleSVG *style = aFrame->StyleSVG();
|
||||
if (style->mFill.mType == eStyleSVGPaintType_None) {
|
||||
aThisContextPaint->SetFillOpacity(0.0f);
|
||||
return false;
|
||||
}
|
||||
|
||||
float opacity = nsSVGUtils::GetOpacity(style->mFillOpacitySource,
|
||||
style->mFillOpacity,
|
||||
aOuterContextPaint);
|
||||
|
||||
SetupInheritablePaint(aContext, aFrame, opacity, aOuterContextPaint,
|
||||
aThisContextPaint->mFillPaint, &nsStyleSVG::mFill,
|
||||
nsSVGEffects::FillProperty());
|
||||
|
||||
aThisContextPaint->SetFillOpacity(opacity);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
SVGTextFrame::SetupInheritablePaint(gfxContext* aContext,
|
||||
nsIFrame* aFrame,
|
||||
float& aOpacity,
|
||||
gfxTextContextPaint* aOuterContextPaint,
|
||||
SVGTextContextPaint::Paint& aTargetPaint,
|
||||
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
|
||||
const FramePropertyDescriptor* aProperty)
|
||||
/**
|
||||
* Stores in |aTargetPaint| information on how to reconstruct the current
|
||||
* fill or stroke pattern. Will also set the paint opacity to transparent if
|
||||
* the paint is set to "none".
|
||||
* @param aOuterContextPaint pattern information from the outer text context
|
||||
* @param aTargetPaint where to store the current pattern information
|
||||
* @param aFillOrStroke member pointer to the paint we are setting up
|
||||
* @param aProperty the frame property descriptor of the fill or stroke paint
|
||||
* server frame
|
||||
*/
|
||||
static void
|
||||
SetupInheritablePaint(const gfxMatrix& aContextMatrix,
|
||||
nsIFrame* aFrame,
|
||||
float& aOpacity,
|
||||
gfxTextContextPaint* aOuterContextPaint,
|
||||
SVGTextContextPaint::Paint& aTargetPaint,
|
||||
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
|
||||
const FramePropertyDescriptor* aProperty)
|
||||
{
|
||||
const nsStyleSVG *style = aFrame->StyleSVG();
|
||||
nsSVGPaintServerFrame *ps =
|
||||
nsSVGEffects::GetPaintServer(aFrame, &(style->*aFillOrStroke), aProperty);
|
||||
|
||||
if (ps && ps->SetupPaintServer(aContext, aFrame, aFillOrStroke, aOpacity)) {
|
||||
aTargetPaint.SetPaintServer(aFrame, aContext->CurrentMatrix(), ps);
|
||||
} else if (nsSVGUtils::SetupContextPaint(aContext, aOuterContextPaint,
|
||||
style->*aFillOrStroke,
|
||||
aOpacity)) {
|
||||
aTargetPaint.SetContextPaint(aOuterContextPaint, (style->*aFillOrStroke).mType);
|
||||
} else {
|
||||
nscolor color = nsSVGUtils::GetFallbackOrPaintColor(aContext,
|
||||
aFrame->StyleContext(),
|
||||
aFillOrStroke);
|
||||
aTargetPaint.SetColor(color);
|
||||
|
||||
if (ps) {
|
||||
nsRefPtr<gfxPattern> 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 * aOpacity));
|
||||
aContext->SetPattern(pattern);
|
||||
ps->GetPaintServerPattern(aFrame, aContextMatrix, aFillOrStroke, aOpacity);
|
||||
if (pattern) {
|
||||
aTargetPaint.SetPaintServer(aFrame, aContextMatrix, ps);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (aOuterContextPaint) {
|
||||
nsRefPtr<gfxPattern> pattern;
|
||||
switch ((style->*aFillOrStroke).mType) {
|
||||
case eStyleSVGPaintType_ContextFill:
|
||||
pattern = aOuterContextPaint->GetFillPattern(aOpacity, aContextMatrix);
|
||||
break;
|
||||
case eStyleSVGPaintType_ContextStroke:
|
||||
pattern = aOuterContextPaint->GetStrokePattern(aOpacity, aContextMatrix);
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
if (pattern) {
|
||||
aTargetPaint.SetContextPaint(aOuterContextPaint, (style->*aFillOrStroke).mType);
|
||||
return;
|
||||
}
|
||||
}
|
||||
nscolor color =
|
||||
nsSVGUtils::GetFallbackOrPaintColor(aFrame->StyleContext(), aFillOrStroke);
|
||||
aTargetPaint.SetColor(color);
|
||||
}
|
||||
|
||||
DrawMode
|
||||
SVGTextFrame::SetupContextPaint(const gfxMatrix& aContextMatrix,
|
||||
nsIFrame* aFrame,
|
||||
gfxTextContextPaint* aOuterContextPaint,
|
||||
SVGTextContextPaint* aThisContextPaint)
|
||||
{
|
||||
DrawMode toDraw = DrawMode(0);
|
||||
|
||||
const nsStyleSVG *style = aFrame->StyleSVG();
|
||||
|
||||
// fill:
|
||||
if (style->mFill.mType == eStyleSVGPaintType_None) {
|
||||
aThisContextPaint->SetFillOpacity(0.0f);
|
||||
} else {
|
||||
float opacity = nsSVGUtils::GetOpacity(style->mFillOpacitySource,
|
||||
style->mFillOpacity,
|
||||
aOuterContextPaint);
|
||||
|
||||
SetupInheritablePaint(aContextMatrix, aFrame, opacity, aOuterContextPaint,
|
||||
aThisContextPaint->mFillPaint, &nsStyleSVG::mFill,
|
||||
nsSVGEffects::FillProperty());
|
||||
|
||||
aThisContextPaint->SetFillOpacity(opacity);
|
||||
|
||||
toDraw = DrawMode(int(toDraw) | int(DrawMode::GLYPH_FILL));
|
||||
}
|
||||
|
||||
// stroke:
|
||||
if (style->mStroke.mType == eStyleSVGPaintType_None) {
|
||||
aThisContextPaint->SetStrokeOpacity(0.0f);
|
||||
} else {
|
||||
float opacity = nsSVGUtils::GetOpacity(style->mStrokeOpacitySource,
|
||||
style->mStrokeOpacity,
|
||||
aOuterContextPaint);
|
||||
|
||||
SetupInheritablePaint(aContextMatrix, aFrame, opacity, aOuterContextPaint,
|
||||
aThisContextPaint->mStrokePaint, &nsStyleSVG::mStroke,
|
||||
nsSVGEffects::StrokeProperty());
|
||||
|
||||
aThisContextPaint->SetStrokeOpacity(opacity);
|
||||
|
||||
toDraw = DrawMode(int(toDraw) | int(DrawMode::GLYPH_STROKE));
|
||||
}
|
||||
|
||||
return toDraw;
|
||||
}
|
||||
|
@ -594,46 +594,10 @@ private:
|
||||
gfxFloat GetOffsetScale(nsIFrame* aTextPathFrame);
|
||||
gfxFloat GetStartOffset(nsIFrame* aTextPathFrame);
|
||||
|
||||
DrawMode SetupCairoState(gfxContext* aContext,
|
||||
nsIFrame* aFrame,
|
||||
gfxTextContextPaint* aOuterContextPaint,
|
||||
gfxTextContextPaint** aThisContextPaint);
|
||||
|
||||
/**
|
||||
* Sets up the stroke style for |aFrame| in |aContext| and stores stroke
|
||||
* pattern information in |aThisContextPaint|.
|
||||
*/
|
||||
bool SetupCairoStroke(gfxContext* aContext,
|
||||
nsIFrame* aFrame,
|
||||
gfxTextContextPaint* aOuterContextPaint,
|
||||
SVGTextContextPaint* aThisContextPaint);
|
||||
|
||||
/**
|
||||
* Sets up the fill style for |aFrame| in |aContext| and stores fill pattern
|
||||
* information in |aThisContextPaint|.
|
||||
*/
|
||||
bool SetupCairoFill(gfxContext* aContext,
|
||||
nsIFrame* aFrame,
|
||||
gfxTextContextPaint* aOuterContextPaint,
|
||||
SVGTextContextPaint* aThisContextPaint);
|
||||
|
||||
/**
|
||||
* Stores in |aTargetPaint| information on how to reconstruct the current
|
||||
* fill or stroke pattern. Will also set the paint opacity to transparent if
|
||||
* the paint is set to "none".
|
||||
* @param aOuterContextPaint pattern information from the outer text context
|
||||
* @param aTargetPaint where to store the current pattern information
|
||||
* @param aFillOrStroke member pointer to the paint we are setting up
|
||||
* @param aProperty the frame property descriptor of the fill or stroke paint
|
||||
* server frame
|
||||
*/
|
||||
void SetupInheritablePaint(gfxContext* aContext,
|
||||
DrawMode SetupContextPaint(const gfxMatrix& aContextMatrix,
|
||||
nsIFrame* aFrame,
|
||||
float& aOpacity,
|
||||
gfxTextContextPaint* aOuterContextPaint,
|
||||
SVGTextContextPaint::Paint& aTargetPaint,
|
||||
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
|
||||
const FramePropertyDescriptor* aProperty);
|
||||
SVGTextContextPaint* aThisContextPaint);
|
||||
|
||||
/**
|
||||
* The MutationObserver we have registered for the <text> element subtree.
|
||||
|
@ -1204,7 +1204,7 @@ nsSVGUtils::PathExtentsToMaxStrokeExtents(const gfxRect& aPathExtents,
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/* static */ nscolor
|
||||
nsSVGUtils::GetFallbackOrPaintColor(gfxContext *aContext, nsStyleContext *aStyleContext,
|
||||
nsSVGUtils::GetFallbackOrPaintColor(nsStyleContext *aStyleContext,
|
||||
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke)
|
||||
{
|
||||
const nsStyleSVGPaint &paint = aStyleContext->StyleSVG()->*aFillOrStroke;
|
||||
@ -1238,8 +1238,8 @@ SetupFallbackOrPaintColor(gfxContext *aContext, nsStyleContext *aStyleContext,
|
||||
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
|
||||
float aOpacity)
|
||||
{
|
||||
nscolor color = nsSVGUtils::GetFallbackOrPaintColor(
|
||||
aContext, aStyleContext, aFillOrStroke);
|
||||
nscolor color =
|
||||
nsSVGUtils::GetFallbackOrPaintColor(aStyleContext, aFillOrStroke);
|
||||
|
||||
aContext->SetColor(gfxRGBA(NS_GET_R(color)/255.0,
|
||||
NS_GET_G(color)/255.0,
|
||||
|
@ -503,8 +503,7 @@ public:
|
||||
std::min(double(INT32_MAX), aVal)));
|
||||
}
|
||||
|
||||
static nscolor GetFallbackOrPaintColor(gfxContext *aContext,
|
||||
nsStyleContext *aStyleContext,
|
||||
static nscolor GetFallbackOrPaintColor(nsStyleContext *aStyleContext,
|
||||
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke);
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user