Bug 1345853 - Part 1. Pass DrawResult from nsSVGPatternFrame::PaintPattern back to nsDisplaySVGGeometry::Paint. r=mstange,tnikkel

I did many change in many files in this patch. But the goal is pretty simple: To
pass the return value of nsSVGPatternFrame::PaintPattern back to the caller
(nsDisplaySVGGeometry). My suggestion is to review this patch right from
nsSVGPatternFrame.cpp.

I made two mistakes in bug 1258510
1. We should not return directly at [1]. RemoveStateBits at l418 will be skip.
2. nsSVGPatternFrame::PaintPattern should return both SourceSurface and draw
result, so that we can update UpdateDrawResult in display item.

All the other changes are to
1. make sure the return value of nsSVGPatternFrame::PaintPattern goes back to
nsDisplaySVGGeometry::Paint correctly.
2. Since the return value of nsSVGPatternFrame::PaintPattern change, we need
modify all existed callers.

I also filed bug 1346124 for handle the returning value of PaintMarkers.

[1] https://hg.mozilla.org/mozilla-central/file/c0700bedb4f7/layout/svg/nsSVGPatternFrame.cpp#l415

MozReview-Commit-ID: Iq9RPQ6Omz0

--HG--
extra : rebase_source : ca7a35bb9f5e27880d5dc62e03feb91b6ac3435d
This commit is contained in:
cku 2017-03-21 10:12:23 +08:00
Родитель 2860ecd0e5
Коммит 148bb081ca
17 изменённых файлов: 242 добавлений и 175 удалений

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

@ -1623,10 +1623,16 @@ private:
Pattern *pat;
RefPtr<gfxPattern> fillPattern;
if (!mFontParams.contextPaint ||
!(fillPattern = mFontParams.contextPaint->GetFillPattern(
mRunParams.context->GetDrawTarget(),
mRunParams.context->CurrentMatrix()))) {
if (mFontParams.contextPaint) {
mozilla::image::DrawResult result = mozilla::image::DrawResult::SUCCESS;
Tie(result, fillPattern) =
mFontParams.contextPaint->GetFillPattern(
mRunParams.context->GetDrawTarget(),
mRunParams.context->CurrentMatrix());
// XXX cku Flush should return result to the caller?
Unused << result;
}
if (!fillPattern) {
if (state.pattern) {
pat = state.pattern->GetPattern(mRunParams.dt,
state.patternTransformChanged ?

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

@ -202,24 +202,26 @@ public:
mStrokeMatrix = SetupDeviceToPatternMatrix(aStrokePattern, aCTM);
}
already_AddRefed<gfxPattern> GetFillPattern(const DrawTarget* aDrawTarget,
float aOpacity,
const gfxMatrix& aCTM) {
mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
GetFillPattern(const DrawTarget* aDrawTarget,
float aOpacity,
const gfxMatrix& aCTM) {
if (mFillPattern) {
mFillPattern->SetMatrix(aCTM * mFillMatrix);
}
RefPtr<gfxPattern> fillPattern = mFillPattern;
return fillPattern.forget();
return MakePair(DrawResult::SUCCESS, Move(fillPattern));
}
already_AddRefed<gfxPattern> GetStrokePattern(const DrawTarget* aDrawTarget,
float aOpacity,
const gfxMatrix& aCTM) {
mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
GetStrokePattern(const DrawTarget* aDrawTarget,
float aOpacity,
const gfxMatrix& aCTM) {
if (mStrokePattern) {
mStrokePattern->SetMatrix(aCTM * mStrokeMatrix);
}
RefPtr<gfxPattern> strokePattern = mStrokePattern;
return strokePattern.forget();
return MakePair(DrawResult::SUCCESS, Move(strokePattern));
}
float GetFillOpacity() const {

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

@ -13,6 +13,7 @@
#include "nsSVGPaintServerFrame.h"
using namespace mozilla::gfx;
using namespace mozilla::image;
namespace mozilla {
@ -26,7 +27,7 @@ namespace mozilla {
* @param aProperty the frame property descriptor of the fill or stroke paint
* server frame
*/
static void
static DrawResult
SetupInheritablePaint(const DrawTarget* aDrawTarget,
const gfxMatrix& aContextMatrix,
nsIFrame* aFrame,
@ -40,40 +41,49 @@ SetupInheritablePaint(const DrawTarget* aDrawTarget,
nsSVGPaintServerFrame *ps =
nsSVGEffects::GetPaintServer(aFrame, aFillOrStroke, aProperty);
DrawResult result = DrawResult::SUCCESS;
if (ps) {
RefPtr<gfxPattern> pattern =
RefPtr<gfxPattern> pattern;
Tie(result, pattern) =
ps->GetPaintServerPattern(aFrame, aDrawTarget, aContextMatrix,
aFillOrStroke, aOpacity);
if (pattern) {
aTargetPaint.SetPaintServer(aFrame, aContextMatrix, ps);
return;
return result;
}
}
if (aOuterContextPaint) {
RefPtr<gfxPattern> pattern;
switch ((style->*aFillOrStroke).Type()) {
case eStyleSVGPaintType_ContextFill:
pattern = aOuterContextPaint->GetFillPattern(aDrawTarget, aOpacity,
aContextMatrix);
Tie(result, pattern) =
aOuterContextPaint->GetFillPattern(aDrawTarget, aOpacity,
aContextMatrix);
break;
case eStyleSVGPaintType_ContextStroke:
pattern = aOuterContextPaint->GetStrokePattern(aDrawTarget, aOpacity,
aContextMatrix);
Tie(result, pattern) =
aOuterContextPaint->GetStrokePattern(aDrawTarget, aOpacity,
aContextMatrix);
break;
default:
;
}
if (pattern) {
aTargetPaint.SetContextPaint(aOuterContextPaint, (style->*aFillOrStroke).Type());
return;
return result;
}
}
nscolor color =
nsSVGUtils::GetFallbackOrPaintColor(aFrame->StyleContext(), aFillOrStroke);
aTargetPaint.SetColor(color);
return result;
}
DrawMode
mozilla::Pair<DrawResult, DrawMode>
SVGContextPaintImpl::Init(const DrawTarget* aDrawTarget,
const gfxMatrix& aContextMatrix,
nsIFrame* aFrame,
@ -82,6 +92,7 @@ SVGContextPaintImpl::Init(const DrawTarget* aDrawTarget,
DrawMode toDraw = DrawMode(0);
const nsStyleSVG *style = aFrame->StyleSVG();
DrawResult result = DrawResult::SUCCESS;
// fill:
if (style->mFill.Type() == eStyleSVGPaintType_None) {
@ -91,10 +102,10 @@ SVGContextPaintImpl::Init(const DrawTarget* aDrawTarget,
style->mFillOpacity,
aOuterContextPaint);
SetupInheritablePaint(aDrawTarget, aContextMatrix, aFrame,
opacity, aOuterContextPaint,
mFillPaint, &nsStyleSVG::mFill,
nsSVGEffects::FillProperty());
result &= SetupInheritablePaint(aDrawTarget, aContextMatrix, aFrame,
opacity, aOuterContextPaint,
mFillPaint, &nsStyleSVG::mFill,
nsSVGEffects::FillProperty());
SetFillOpacity(opacity);
@ -109,17 +120,17 @@ SVGContextPaintImpl::Init(const DrawTarget* aDrawTarget,
style->mStrokeOpacity,
aOuterContextPaint);
SetupInheritablePaint(aDrawTarget, aContextMatrix, aFrame,
opacity, aOuterContextPaint,
mStrokePaint, &nsStyleSVG::mStroke,
nsSVGEffects::StrokeProperty());
result &= SetupInheritablePaint(aDrawTarget, aContextMatrix, aFrame,
opacity, aOuterContextPaint,
mStrokePaint, &nsStyleSVG::mStroke,
nsSVGEffects::StrokeProperty());
SetStrokeOpacity(opacity);
toDraw |= DrawMode::GLYPH_STROKE;
}
return toDraw;
return MakePair(result, toDraw);
}
void
@ -158,7 +169,7 @@ SVGContextPaint::GetContextPaint(nsIContent* aContent)
ownerDoc->GetProperty(nsGkAtoms::svgContextPaint));
}
already_AddRefed<gfxPattern>
mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
SVGContextPaintImpl::GetFillPattern(const DrawTarget* aDrawTarget,
float aOpacity,
const gfxMatrix& aCTM)
@ -166,7 +177,7 @@ SVGContextPaintImpl::GetFillPattern(const DrawTarget* aDrawTarget,
return mFillPaint.GetPattern(aDrawTarget, aOpacity, &nsStyleSVG::mFill, aCTM);
}
already_AddRefed<gfxPattern>
mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
SVGContextPaintImpl::GetStrokePattern(const DrawTarget* aDrawTarget,
float aOpacity,
const gfxMatrix& aCTM)
@ -174,7 +185,7 @@ SVGContextPaintImpl::GetStrokePattern(const DrawTarget* aDrawTarget,
return mStrokePaint.GetPattern(aDrawTarget, aOpacity, &nsStyleSVG::mStroke, aCTM);
}
already_AddRefed<gfxPattern>
mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
SVGContextPaintImpl::Paint::GetPattern(const DrawTarget* aDrawTarget,
float aOpacity,
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
@ -186,9 +197,10 @@ SVGContextPaintImpl::Paint::GetPattern(const DrawTarget* aDrawTarget,
// 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();
return MakePair(DrawResult::SUCCESS, Move(pattern));
}
DrawResult result = DrawResult::SUCCESS;
switch (mPaintType) {
case eStyleSVGPaintType_None:
pattern = new gfxPattern(Color());
@ -202,17 +214,18 @@ SVGContextPaintImpl::Paint::GetPattern(const DrawTarget* aDrawTarget,
break;
}
case eStyleSVGPaintType_Server:
pattern = mPaintDefinition.mPaintServerFrame->GetPaintServerPattern(mFrame,
aDrawTarget,
mContextMatrix,
aFillOrStroke,
aOpacity);
Tie(result, 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;
return MakePair(DrawResult::SUCCESS, RefPtr<gfxPattern>());
}
// mPatternMatrix maps device space to pattern space via original user space
mPatternMatrix = deviceToOriginalUserSpace * m;
@ -220,24 +233,26 @@ SVGContextPaintImpl::Paint::GetPattern(const DrawTarget* aDrawTarget,
pattern->SetMatrix(aCTM * mPatternMatrix);
break;
case eStyleSVGPaintType_ContextFill:
pattern = mPaintDefinition.mContextPaint->GetFillPattern(aDrawTarget,
Tie(result, 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();
return MakePair(result, Move(pattern));
case eStyleSVGPaintType_ContextStroke:
pattern = mPaintDefinition.mContextPaint->GetStrokePattern(aDrawTarget,
Tie(result, 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();
return MakePair(result, Move(pattern));
default:
MOZ_ASSERT(false, "invalid paint type");
return nullptr;
return MakePair(DrawResult::SUCCESS, RefPtr<gfxPattern>());
}
mPatternCache.Put(aOpacity, pattern);
return pattern.forget();
return MakePair(result, Move(pattern));
}
AutoSetRestoreSVGContextPaint::AutoSetRestoreSVGContextPaint(
@ -279,33 +294,35 @@ AutoSetRestoreSVGContextPaint::~AutoSetRestoreSVGContextPaint()
// SVGEmbeddingContextPaint
already_AddRefed<gfxPattern>
mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
SVGEmbeddingContextPaint::GetFillPattern(const DrawTarget* aDrawTarget,
float aFillOpacity,
const gfxMatrix& aCTM)
{
if (!mFill) {
return nullptr;
return MakePair(DrawResult::SUCCESS, RefPtr<gfxPattern>());
}
// The gfxPattern that we create below depends on aFillOpacity, and since
// different elements in the SVG image may pass in different values for
// fill opacities we don't try to cache the gfxPattern that we create.
Color fill = *mFill;
fill.a *= aFillOpacity;
return do_AddRef(new gfxPattern(fill));
RefPtr<gfxPattern> patern = new gfxPattern(fill);
return MakePair(DrawResult::SUCCESS, Move(patern));
}
already_AddRefed<gfxPattern>
mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
SVGEmbeddingContextPaint::GetStrokePattern(const DrawTarget* aDrawTarget,
float aStrokeOpacity,
const gfxMatrix& aCTM)
{
if (!mStroke) {
return nullptr;
return MakePair(DrawResult::SUCCESS, RefPtr<gfxPattern>());
}
Color stroke = *mStroke;
stroke.a *= aStrokeOpacity;
return do_AddRef(new gfxPattern(stroke));
RefPtr<gfxPattern> patern = new gfxPattern(stroke);
return MakePair(DrawResult::SUCCESS, Move(patern));
}
uint32_t

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

@ -17,6 +17,7 @@
#include "nsColor.h"
#include "nsStyleStruct.h"
#include "nsTArray.h"
#include "DrawResult.h"
class gfxContext;
class nsIDocument;
@ -53,26 +54,30 @@ protected:
SVGContextPaint() {}
public:
typedef image::DrawResult DrawResult;
MOZ_DECLARE_REFCOUNTED_TYPENAME(SVGContextPaint)
virtual ~SVGContextPaint() {}
virtual already_AddRefed<gfxPattern> GetFillPattern(const DrawTarget* aDrawTarget,
float aOpacity,
const gfxMatrix& aCTM) = 0;
virtual already_AddRefed<gfxPattern> GetStrokePattern(const DrawTarget* aDrawTarget,
float aOpacity,
const gfxMatrix& aCTM) = 0;
virtual mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
GetFillPattern(const DrawTarget* aDrawTarget,
float aOpacity,
const gfxMatrix& aCTM) = 0;
virtual mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
GetStrokePattern(const DrawTarget* aDrawTarget,
float aOpacity,
const gfxMatrix& aCTM) = 0;
virtual float GetFillOpacity() const = 0;
virtual float GetStrokeOpacity() const = 0;
already_AddRefed<gfxPattern> GetFillPattern(const DrawTarget* aDrawTarget,
const gfxMatrix& aCTM) {
mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
GetFillPattern(const DrawTarget* aDrawTarget, const gfxMatrix& aCTM) {
return GetFillPattern(aDrawTarget, GetFillOpacity(), aCTM);
}
already_AddRefed<gfxPattern> GetStrokePattern(const DrawTarget* aDrawTarget,
const gfxMatrix& aCTM) {
mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
GetStrokePattern(const DrawTarget* aDrawTarget, const gfxMatrix& aCTM) {
return GetStrokePattern(aDrawTarget, GetStrokeOpacity(), aCTM);
}
@ -138,18 +143,24 @@ struct SVGContextPaintImpl : public SVGContextPaint
{
protected:
typedef mozilla::gfx::DrawTarget DrawTarget;
public:
DrawMode Init(const DrawTarget* aDrawTarget,
const gfxMatrix& aContextMatrix,
nsIFrame* aFrame,
SVGContextPaint* aOuterContextPaint);
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;
public:
typedef mozilla::image::DrawResult DrawResult;
mozilla::Pair<DrawResult, DrawMode>
Init(const DrawTarget* aDrawTarget,
const gfxMatrix& aContextMatrix,
nsIFrame* aFrame,
SVGContextPaint* aOuterContextPaint);
mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
GetFillPattern(const DrawTarget* aDrawTarget,
float aOpacity,
const gfxMatrix& aCTM) override;
mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
GetStrokePattern(const DrawTarget* aDrawTarget,
float aOpacity,
const gfxMatrix& aCTM) override;
void SetFillOpacity(float aOpacity) { mFillOpacity = aOpacity; }
float GetFillOpacity() const override { return mFillOpacity; }
@ -199,10 +210,11 @@ public:
gfxMatrix mPatternMatrix;
nsRefPtrHashtable<nsFloatHashKey, gfxPattern> mPatternCache;
already_AddRefed<gfxPattern> GetPattern(const DrawTarget* aDrawTarget,
float aOpacity,
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
const gfxMatrix& aCTM);
mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
GetPattern(const DrawTarget* aDrawTarget,
float aOpacity,
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
const gfxMatrix& aCTM);
};
Paint mFillPaint;
@ -221,6 +233,7 @@ public:
class SVGEmbeddingContextPaint : public SVGContextPaint
{
typedef gfx::Color Color;
typedef mozilla::image::DrawResult DrawResult;
public:
SVGEmbeddingContextPaint() {}
@ -235,16 +248,16 @@ public:
/**
* Returns a pattern of type PatternType::COLOR, or else nullptr.
*/
already_AddRefed<gfxPattern> GetFillPattern(const DrawTarget* aDrawTarget,
float aFillOpacity,
const gfxMatrix& aCTM) override;
mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
GetFillPattern(const DrawTarget* aDrawTarget, float aFillOpacity,
const gfxMatrix& aCTM) override;
/**
* Returns a pattern of type PatternType::COLOR, or else nullptr.
*/
already_AddRefed<gfxPattern> GetStrokePattern(const DrawTarget* aDrawTarget,
float aStrokeOpacity,
const gfxMatrix& aCTM) override;
mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
GetStrokePattern(const DrawTarget* aDrawTarget, float aStrokeOpacity,
const gfxMatrix& aCTM) override;
float GetFillOpacity() const override {
// Always 1.0f since we don't currently allow 'context-fill-opacity'

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

@ -293,8 +293,10 @@ SVGGeometryFrame::PaintSVG(gfxContext& aContext,
}
uint32_t paintOrder = StyleSVG()->mPaintOrder;
DrawResult result = DrawResult::SUCCESS;
if (paintOrder == NS_STYLE_PAINT_ORDER_NORMAL) {
Render(&aContext, eRenderFill | eRenderStroke, newMatrix);
result = Render(&aContext, eRenderFill | eRenderStroke, newMatrix);
PaintMarkers(aContext, aTransform);
} else {
while (paintOrder) {
@ -302,10 +304,10 @@ SVGGeometryFrame::PaintSVG(gfxContext& aContext,
paintOrder & ((1 << NS_STYLE_PAINT_ORDER_BITWIDTH) - 1);
switch (component) {
case NS_STYLE_PAINT_ORDER_FILL:
Render(&aContext, eRenderFill, newMatrix);
result &= Render(&aContext, eRenderFill, newMatrix);
break;
case NS_STYLE_PAINT_ORDER_STROKE:
Render(&aContext, eRenderStroke, newMatrix);
result &= Render(&aContext, eRenderStroke, newMatrix);
break;
case NS_STYLE_PAINT_ORDER_MARKERS:
PaintMarkers(aContext, aTransform);
@ -315,7 +317,7 @@ SVGGeometryFrame::PaintSVG(gfxContext& aContext,
}
}
return DrawResult::SUCCESS;
return result;
}
nsIFrame*
@ -749,7 +751,7 @@ SVGGeometryFrame::MarkerProperties::GetMarkerEndFrame()
(mMarkerEnd->GetReferencedFrame(nsGkAtoms::svgMarkerFrame, nullptr));
}
void
DrawResult
SVGGeometryFrame::Render(gfxContext* aContext,
uint32_t aRenderComponents,
const gfxMatrix& aNewTransform)
@ -785,7 +787,7 @@ SVGGeometryFrame::Render(gfxContext* aContext,
drawTarget->Fill(path, white,
DrawOptions(1.0f, CompositionOp::OP_OVER, aaMode));
}
return;
return DrawResult::SUCCESS;
}
SVGGeometryElement::SimplePath simplePath;
@ -795,15 +797,18 @@ SVGGeometryFrame::Render(gfxContext* aContext,
if (!simplePath.IsPath()) {
path = element->GetOrBuildPath(*drawTarget, fillRule);
if (!path) {
return;
return DrawResult::SUCCESS;
}
}
SVGContextPaint* contextPaint = SVGContextPaint::GetContextPaint(mContent);
DrawResult result = DrawResult::SUCCESS;
if (aRenderComponents & eRenderFill) {
GeneralPattern fillPattern;
nsSVGUtils::MakeFillPatternFor(this, aContext, &fillPattern, contextPaint);
result = nsSVGUtils::MakeFillPatternFor(this, aContext, &fillPattern,
contextPaint);
if (fillPattern.GetPattern()) {
DrawOptions drawOptions(1.0f, CompositionOp::OP_OVER, aaMode);
if (simplePath.IsRect()) {
@ -824,7 +829,7 @@ SVGGeometryFrame::Render(gfxContext* aContext,
if (!path) {
path = element->GetOrBuildPath(*drawTarget, fillRule);
if (!path) {
return;
return DrawResult::SUCCESS;
}
simplePath.Reset();
}
@ -839,7 +844,10 @@ SVGGeometryFrame::Render(gfxContext* aContext,
path = builder->Finish();
}
GeneralPattern strokePattern;
nsSVGUtils::MakeStrokePatternFor(this, aContext, &strokePattern, contextPaint);
result &=
nsSVGUtils::MakeStrokePatternFor(this, aContext, &strokePattern,
contextPaint);
if (strokePattern.GetPattern()) {
SVGContentUtils::AutoStrokeOptions strokeOptions;
SVGContentUtils::GetStrokeOptions(&strokeOptions,
@ -847,7 +855,7 @@ SVGGeometryFrame::Render(gfxContext* aContext,
StyleContext(), contextPaint);
// GetStrokeOptions may set the line width to zero as an optimization
if (strokeOptions.mLineWidth <= 0) {
return;
return DrawResult::SUCCESS;
}
DrawOptions drawOptions(1.0f, CompositionOp::OP_OVER, aaMode);
if (simplePath.IsRect()) {
@ -861,6 +869,8 @@ SVGGeometryFrame::Render(gfxContext* aContext,
}
}
}
return result;
}
void

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

@ -120,8 +120,8 @@ protected:
virtual uint16_t GetHitTestFlags();
private:
enum { eRenderFill = 1, eRenderStroke = 2 };
void Render(gfxContext* aContext, uint32_t aRenderComponents,
const gfxMatrix& aTransform);
DrawResult Render(gfxContext* aContext, uint32_t aRenderComponents,
const gfxMatrix& aTransform);
/**
* @param aMatrix The transform that must be multiplied onto aContext to

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

@ -2929,7 +2929,7 @@ SVGTextDrawPathCallbacks::MakeFillPattern(GeneralPattern* aOutPattern)
{
if (mColor == NS_SAME_AS_FOREGROUND_COLOR ||
mColor == NS_40PERCENT_FOREGROUND_COLOR) {
nsSVGUtils::MakeFillPatternFor(mFrame, gfx, aOutPattern);
Unused << nsSVGUtils::MakeFillPatternFor(mFrame, gfx, aOutPattern);
return;
}
@ -3000,7 +3000,8 @@ SVGTextDrawPathCallbacks::StrokeGeometry()
mColor == NS_40PERCENT_FOREGROUND_COLOR) {
if (nsSVGUtils::HasStroke(mFrame, /*aContextPaint*/ nullptr)) {
GeneralPattern strokePattern;
nsSVGUtils::MakeStrokePatternFor(mFrame, gfx, &strokePattern, /*aContextPaint*/ nullptr);
Unused << nsSVGUtils::MakeStrokePatternFor(mFrame, gfx, &strokePattern,
/*aContextPaint*/ nullptr);
if (strokePattern.GetPattern()) {
if (!mFrame->GetParent()->GetContent()->IsSVGElement()) {
// The cast that follows would be unsafe
@ -3645,7 +3646,7 @@ SVGTextFrame::PaintSVG(gfxContext& aContext,
SVGContextPaint::GetContextPaint(mContent);
nsRenderingContext rendCtx(&aContext);
DrawResult finalResult = DrawResult::SUCCESS;
while (run.mFrame) {
nsTextFrame* frame = run.mFrame;
@ -3658,10 +3659,12 @@ SVGTextFrame::PaintSVG(gfxContext& aContext,
aContext.SetMatrix(initialMatrix);
RefPtr<SVGContextPaintImpl> contextPaint = new SVGContextPaintImpl();
DrawMode drawMode = contextPaint->Init(&aDrawTarget,
aContext.CurrentMatrix(),
frame, outerContextPaint);
DrawMode drawMode;
DrawResult result = DrawResult::SUCCESS;
Tie(result, drawMode) = contextPaint->Init(&aDrawTarget,
aContext.CurrentMatrix(),
frame, outerContextPaint);
finalResult &= result;
if (drawMode & 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.
@ -3703,7 +3706,7 @@ SVGTextFrame::PaintSVG(gfxContext& aContext,
run = it.Next();
}
return DrawResult::SUCCESS;
return finalResult;
}
nsIFrame*

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

@ -396,10 +396,11 @@ nsFilterInstance::BuildSourcePaint(SourceInfo *aSource)
ctx->SetMatrix(mPaintTransform *
gfxMatrix::Translation(-neededRect.TopLeft()));
GeneralPattern pattern;
DrawResult result = DrawResult::SUCCESS;
if (aSource == &mFillPaint) {
nsSVGUtils::MakeFillPatternFor(mTargetFrame, ctx, &pattern);
result = nsSVGUtils::MakeFillPatternFor(mTargetFrame, ctx, &pattern);
} else if (aSource == &mStrokePaint) {
nsSVGUtils::MakeStrokePatternFor(mTargetFrame, ctx, &pattern);
result = nsSVGUtils::MakeStrokePatternFor(mTargetFrame, ctx, &pattern);
}
if (pattern.GetPattern()) {
@ -410,7 +411,7 @@ nsFilterInstance::BuildSourcePaint(SourceInfo *aSource)
aSource->mSourceSurface = offscreenDT->Snapshot();
aSource->mSurfaceRect = neededRect;
return DrawResult::SUCCESS;
return result;
}
DrawResult

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

@ -223,7 +223,7 @@ static void GetStopInformation(nsIFrame* aStopFrame,
*aStopOpacity = aStopFrame->StyleSVGReset()->mStopOpacity;
}
already_AddRefed<gfxPattern>
mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
nsSVGGradientFrame::GetPaintServerPattern(nsIFrame* aSource,
const DrawTarget* aDrawTarget,
const gfxMatrix& aContextMatrix,
@ -251,7 +251,7 @@ nsSVGGradientFrame::GetPaintServerPattern(nsIFrame* aSource,
// the corresponding fill or stroke had "none" specified.
if (nStops == 0) {
RefPtr<gfxPattern> pattern = new gfxPattern(Color());
return pattern.forget();
return MakePair(DrawResult::SUCCESS, Move(pattern));
}
if (nStops == 1 || GradientVectorLengthIsZero()) {
@ -263,7 +263,7 @@ nsSVGGradientFrame::GetPaintServerPattern(nsIFrame* aSource,
Color stopColor2 = Color::FromABGR(stopColor);
stopColor2.a *= stopOpacity * aGraphicOpacity;
RefPtr<gfxPattern> pattern = new gfxPattern(stopColor2);
return pattern.forget();
return MakePair(DrawResult::SUCCESS, Move(pattern));
}
// Get the transform list (if there is one). We do this after the returns
@ -272,7 +272,7 @@ nsSVGGradientFrame::GetPaintServerPattern(nsIFrame* aSource,
gfxMatrix patternMatrix = GetGradientTransform(aSource, aOverrideBounds);
if (patternMatrix.IsSingular()) {
return nullptr;
return MakePair(DrawResult::BAD_ARGS, RefPtr<gfxPattern>());
}
// revert any vector effect transform so that the gradient appears unchanged
@ -284,12 +284,13 @@ nsSVGGradientFrame::GetPaintServerPattern(nsIFrame* aSource,
}
if (!patternMatrix.Invert()) {
return nullptr;
return MakePair(DrawResult::BAD_ARGS, RefPtr<gfxPattern>());
}
RefPtr<gfxPattern> gradient = CreateGradient();
if (!gradient)
return nullptr;
if (!gradient) {
return MakePair(DrawResult::TEMPORARY_ERROR, RefPtr<gfxPattern>());
}
uint16_t aSpread = GetSpreadMethod();
if (aSpread == SVG_SPREADMETHOD_PAD)
@ -320,7 +321,7 @@ nsSVGGradientFrame::GetPaintServerPattern(nsIFrame* aSource,
gradient->AddColorStop(offset, stopColor2);
}
return gradient.forget();
return MakePair(DrawResult::SUCCESS, Move(gradient));
}
// Private (helper) methods

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

@ -46,7 +46,7 @@ public:
NS_DECL_ABSTRACT_FRAME(nsSVGGradientFrame)
// nsSVGPaintServerFrame methods:
virtual already_AddRefed<gfxPattern>
virtual mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
GetPaintServerPattern(nsIFrame* aSource,
const DrawTarget* aDrawTarget,
const gfxMatrix& aContextMatrix,

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

@ -925,7 +925,6 @@ nsSVGIntegrationUtils::PaintMaskAndClipPath(const PaintFramesParams& aParams)
result &= paintResult.result;
maskSurface = paintResult.maskSurface;
if (maskSurface) {
MOZ_ASSERT(paintResult.result == DrawResult::SUCCESS);
shouldPushMask = true;
maskTransform = paintResult.maskTransform;
opacityApplied = paintResult.opacityApplied;
@ -1232,10 +1231,12 @@ nsSVGIntegrationUtils::DrawableFromPaintServer(nsIFrame* aFrame,
gfxRect overrideBounds(0, 0,
aPaintServerSize.width, aPaintServerSize.height);
overrideBounds.ScaleInverse(aFrame->PresContext()->AppUnitsPerDevPixel());
RefPtr<gfxPattern> pattern =
server->GetPaintServerPattern(aTarget, aDrawTarget,
aContextMatrix, &nsStyleSVG::mFill, 1.0,
&overrideBounds);
DrawResult result = DrawResult::SUCCESS;
RefPtr<gfxPattern> pattern;
Tie(result, pattern) =
server->GetPaintServerPattern(aTarget, aDrawTarget,
aContextMatrix, &nsStyleSVG::mFill, 1.0,
&overrideBounds);
if (!pattern)
return nullptr;

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

@ -253,7 +253,7 @@ nsSVGMaskFrame::GetMaskForMaskedFrame(MaskParams& aParams)
mMatrixForChildren = GetMaskTransform(aParams.maskedFrame) *
aParams.toUserSpace;
DrawResult result;
DrawResult result = DrawResult::SUCCESS;
for (nsIFrame* kid = mFrames.FirstChild(); kid;
kid = kid->GetNextSibling()) {
@ -267,10 +267,7 @@ nsSVGMaskFrame::GetMaskForMaskedFrame(MaskParams& aParams)
m = static_cast<nsSVGElement*>(kid->GetContent())->
PrependLocalTransformsTo(m, eUserSpaceToParent);
}
result = nsSVGUtils::PaintFrameWithEffects(kid, *tmpCtx, m);
if (result != DrawResult::SUCCESS) {
return MakePair(result, RefPtr<SourceSurface>());
}
result &= nsSVGUtils::PaintFrameWithEffects(kid, *tmpCtx, m);
}
RefPtr<SourceSurface> maskSnapshot = maskDT->Snapshot();
@ -329,7 +326,7 @@ nsSVGMaskFrame::GetMaskForMaskedFrame(MaskParams& aParams)
*aParams.maskTransform = ToMatrix(maskSurfaceMatrix);
RefPtr<SourceSurface> surface = destMaskSurface.forget();
return MakePair(DrawResult::SUCCESS, Move(surface));
return MakePair(result, Move(surface));
}
gfxRect

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

@ -56,6 +56,7 @@ class nsSVGPaintServerFrame : public nsSVGContainerFrame
{
protected:
typedef mozilla::gfx::DrawTarget DrawTarget;
typedef mozilla::image::DrawResult DrawResult;
explicit nsSVGPaintServerFrame(nsStyleContext* aContext)
: nsSVGContainerFrame(aContext)
@ -74,7 +75,7 @@ public:
* that surfaces of the correct size can be created. (SVG gradients are
* vector based, so it's not used there.)
*/
virtual already_AddRefed<gfxPattern>
virtual mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
GetPaintServerPattern(nsIFrame *aSource,
const DrawTarget* aDrawTarget,
const gfxMatrix& aContextMatrix,

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

@ -211,7 +211,7 @@ GetTargetGeometry(gfxRect *aBBox,
return NS_OK;
}
already_AddRefed<SourceSurface>
mozilla::Pair<DrawResult, RefPtr<SourceSurface>>
nsSVGPatternFrame::PaintPattern(const DrawTarget* aDrawTarget,
Matrix* patternMatrix,
const Matrix &aContextMatrix,
@ -234,7 +234,8 @@ nsSVGPatternFrame::PaintPattern(const DrawTarget* aDrawTarget,
nsSVGPatternFrame* patternWithChildren = GetPatternWithChildren();
if (!patternWithChildren) {
return nullptr; // Either no kids or a bad reference
// Either no kids or a bad reference
return MakePair(DrawResult::SUCCESS, RefPtr<SourceSurface>());
}
nsIFrame* firstKid = patternWithChildren->mFrames.FirstChild();
@ -273,7 +274,7 @@ nsSVGPatternFrame::PaintPattern(const DrawTarget* aDrawTarget,
aSource,
aContextMatrix,
aOverrideBounds))) {
return nullptr;
return MakePair(DrawResult::SUCCESS, RefPtr<SourceSurface>());
}
// Construct the CTM that we will provide to our children when we
@ -281,7 +282,7 @@ nsSVGPatternFrame::PaintPattern(const DrawTarget* aDrawTarget,
gfxMatrix ctm = ConstructCTM(viewBox, patternContentUnits, patternUnits,
callerBBox, aContextMatrix, aSource);
if (ctm.IsSingular()) {
return nullptr;
return MakePair(DrawResult::BAD_ARGS, RefPtr<SourceSurface>());
}
if (patternWithChildren->mCTM) {
@ -295,7 +296,7 @@ nsSVGPatternFrame::PaintPattern(const DrawTarget* aDrawTarget,
// box for the pattern tile.
gfxRect bbox = GetPatternRect(patternUnits, callerBBox, aContextMatrix, aSource);
if (bbox.Width() <= 0.0 || bbox.Height() <= 0.0) {
return nullptr;
return MakePair(DrawResult::SUCCESS, RefPtr<SourceSurface>());
}
// Get the pattern transform
@ -308,7 +309,7 @@ nsSVGPatternFrame::PaintPattern(const DrawTarget* aDrawTarget,
patternTransform *= ToMatrix(userToOuterSVG);
if (patternTransform.IsSingular()) {
NS_WARNING("Singular matrix painting non-scaling-stroke");
return nullptr;
return MakePair(DrawResult::BAD_ARGS, RefPtr<SourceSurface>());
}
}
}
@ -318,7 +319,7 @@ nsSVGPatternFrame::PaintPattern(const DrawTarget* aDrawTarget,
*patternMatrix = GetPatternMatrix(patternUnits, patternTransform,
bbox, callerBBox, aContextMatrix);
if (patternMatrix->IsSingular()) {
return nullptr;
return MakePair(DrawResult::BAD_ARGS, RefPtr<SourceSurface>());
}
// Now that we have all of the necessary geometries, we can
@ -332,7 +333,7 @@ nsSVGPatternFrame::PaintPattern(const DrawTarget* aDrawTarget,
// 0 disables rendering, < 0 is an error
if (surfaceSize.width <= 0 || surfaceSize.height <= 0) {
return nullptr;
return MakePair(DrawResult::SUCCESS, RefPtr<SourceSurface>());
}
gfxFloat patternWidth = bbox.Width();
@ -356,7 +357,7 @@ nsSVGPatternFrame::PaintPattern(const DrawTarget* aDrawTarget,
RefPtr<DrawTarget> dt =
aDrawTarget->CreateSimilarDrawTarget(surfaceSize, SurfaceFormat::B8G8R8A8);
if (!dt || !dt->IsValid()) {
return nullptr;
return MakePair(DrawResult::TEMPORARY_ERROR, RefPtr<SourceSurface>());
}
dt->ClearRect(Rect(0, 0, surfaceSize.width, surfaceSize.height));
@ -379,6 +380,7 @@ nsSVGPatternFrame::PaintPattern(const DrawTarget* aDrawTarget,
// Delay checking NS_FRAME_DRAWING_AS_PAINTSERVER bit until here so we can
// give back a clear surface if there's a loop
DrawResult result = DrawResult::SUCCESS;
if (!(patternWithChildren->GetStateBits() & NS_FRAME_DRAWING_AS_PAINTSERVER)) {
AutoSetRestorePaintServerState paintServer(patternWithChildren);
for (nsIFrame* kid = firstKid; kid;
@ -393,10 +395,8 @@ nsSVGPatternFrame::PaintPattern(const DrawTarget* aDrawTarget,
tm = static_cast<nsSVGElement*>(kid->GetContent())->
PrependLocalTransformsTo(tm, eUserSpaceToParent);
}
DrawResult result = nsSVGUtils::PaintFrameWithEffects(kid, *ctx, tm);
if (result != DrawResult::SUCCESS) {
return nullptr;
}
result &= nsSVGUtils::PaintFrameWithEffects(kid, *ctx, tm);
}
}
@ -408,7 +408,8 @@ nsSVGPatternFrame::PaintPattern(const DrawTarget* aDrawTarget,
}
// caller now owns the surface
return dt->Snapshot();
RefPtr<SourceSurface> surf = dt->Snapshot();
return MakePair(result, Move(surf));
}
/* Will probably need something like this... */
@ -721,8 +722,7 @@ nsSVGPatternFrame::ConstructCTM(const nsSVGViewBox& aViewBox,
//----------------------------------------------------------------------
// nsSVGPaintServerFrame methods:
already_AddRefed<gfxPattern>
mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
nsSVGPatternFrame::GetPaintServerPattern(nsIFrame *aSource,
const DrawTarget* aDrawTarget,
const gfxMatrix& aContextMatrix,
@ -732,26 +732,29 @@ nsSVGPatternFrame::GetPaintServerPattern(nsIFrame *aSource,
{
if (aGraphicOpacity == 0.0f) {
RefPtr<gfxPattern> pattern = new gfxPattern(Color());
return pattern.forget();
return MakePair(DrawResult::SUCCESS, Move(pattern));
}
// Paint it!
Matrix pMatrix;
RefPtr<SourceSurface> surface =
RefPtr<SourceSurface> surface;
DrawResult result = DrawResult::SUCCESS;
Tie(result, surface) =
PaintPattern(aDrawTarget, &pMatrix, ToMatrix(aContextMatrix), aSource,
aFillOrStroke, aGraphicOpacity, aOverrideBounds);
if (!surface) {
return nullptr;
return MakePair(result, RefPtr<gfxPattern>());
}
RefPtr<gfxPattern> pattern = new gfxPattern(surface, pMatrix);
if (!pattern)
return nullptr;
if (!pattern) {
return MakePair(DrawResult::TEMPORARY_ERROR, RefPtr<gfxPattern>());
}
pattern->SetExtend(ExtendMode::REPEAT);
return pattern.forget();
return MakePair(result, Move(pattern));
}
// -------------------------------------------------------------------------

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

@ -40,7 +40,7 @@ public:
explicit nsSVGPatternFrame(nsStyleContext* aContext);
// nsSVGPaintServerFrame methods:
virtual already_AddRefed<gfxPattern>
virtual mozilla::Pair<DrawResult, RefPtr<gfxPattern>>
GetPaintServerPattern(nsIFrame *aSource,
const DrawTarget* aDrawTarget,
const gfxMatrix& aContextMatrix,
@ -106,7 +106,7 @@ protected:
return GetLengthValue(aIndex, mContent);
}
already_AddRefed<SourceSurface>
mozilla::Pair<DrawResult, RefPtr<SourceSurface>>
PaintPattern(const DrawTarget* aDrawTarget,
Matrix *patternMatrix,
const Matrix &aContextMatrix,

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

@ -1479,7 +1479,7 @@ nsSVGUtils::GetFallbackOrPaintColor(nsStyleContext *aStyleContext,
return color;
}
/* static */ void
/* static */ DrawResult
nsSVGUtils::MakeFillPatternFor(nsIFrame* aFrame,
gfxContext* aContext,
GeneralPattern* aOutPattern,
@ -1487,7 +1487,7 @@ nsSVGUtils::MakeFillPatternFor(nsIFrame* aFrame,
{
const nsStyleSVG* style = aFrame->StyleSVG();
if (style->mFill.Type() == eStyleSVGPaintType_None) {
return;
return DrawResult::SUCCESS;
}
const float opacity = aFrame->StyleEffects()->mOpacity;
@ -1507,14 +1507,16 @@ nsSVGUtils::MakeFillPatternFor(nsIFrame* aFrame,
nsSVGPaintServerFrame *ps =
nsSVGEffects::GetPaintServer(aFrame, &nsStyleSVG::mFill,
nsSVGEffects::FillProperty());
DrawResult result = DrawResult::SUCCESS;
if (ps) {
RefPtr<gfxPattern> pattern =
RefPtr<gfxPattern> pattern;
Tie(result, pattern) =
ps->GetPaintServerPattern(aFrame, dt, aContext->CurrentMatrix(),
&nsStyleSVG::mFill, fillOpacity);
if (pattern) {
pattern->CacheColorStops(dt);
aOutPattern->Init(*pattern->GetPattern(dt));
return;
return result;
}
}
@ -1522,19 +1524,21 @@ nsSVGUtils::MakeFillPatternFor(nsIFrame* aFrame,
RefPtr<gfxPattern> pattern;
switch (style->mFill.Type()) {
case eStyleSVGPaintType_ContextFill:
pattern = aContextPaint->GetFillPattern(dt, fillOpacity,
aContext->CurrentMatrix());
Tie(result, pattern) =
aContextPaint->GetFillPattern(dt, fillOpacity,
aContext->CurrentMatrix());
break;
case eStyleSVGPaintType_ContextStroke:
pattern = aContextPaint->GetStrokePattern(dt, fillOpacity,
aContext->CurrentMatrix());
Tie(result, pattern) =
aContextPaint->GetStrokePattern(dt, fillOpacity,
aContext->CurrentMatrix());
break;
default:
;
}
if (pattern) {
aOutPattern->Init(*pattern->GetPattern(dt));
return;
return result;
}
}
@ -1545,9 +1549,11 @@ nsSVGUtils::MakeFillPatternFor(nsIFrame* aFrame,
&nsStyleSVG::mFill)));
color.a *= fillOpacity;
aOutPattern->InitColorPattern(ToDeviceColor(color));
return result;
}
/* static */ void
/* static */ DrawResult
nsSVGUtils::MakeStrokePatternFor(nsIFrame* aFrame,
gfxContext* aContext,
GeneralPattern* aOutPattern,
@ -1555,7 +1561,7 @@ nsSVGUtils::MakeStrokePatternFor(nsIFrame* aFrame,
{
const nsStyleSVG* style = aFrame->StyleSVG();
if (style->mStroke.Type() == eStyleSVGPaintType_None) {
return;
return DrawResult::SUCCESS;
}
const float opacity = aFrame->StyleEffects()->mOpacity;
@ -1575,14 +1581,16 @@ nsSVGUtils::MakeStrokePatternFor(nsIFrame* aFrame,
nsSVGPaintServerFrame *ps =
nsSVGEffects::GetPaintServer(aFrame, &nsStyleSVG::mStroke,
nsSVGEffects::StrokeProperty());
DrawResult result = DrawResult::SUCCESS;
if (ps) {
RefPtr<gfxPattern> pattern =
RefPtr<gfxPattern> pattern;
Tie(result, pattern) =
ps->GetPaintServerPattern(aFrame, dt, aContext->CurrentMatrix(),
&nsStyleSVG::mStroke, strokeOpacity);
if (pattern) {
pattern->CacheColorStops(dt);
aOutPattern->Init(*pattern->GetPattern(dt));
return;
return result;
}
}
@ -1590,19 +1598,21 @@ nsSVGUtils::MakeStrokePatternFor(nsIFrame* aFrame,
RefPtr<gfxPattern> pattern;
switch (style->mStroke.Type()) {
case eStyleSVGPaintType_ContextFill:
pattern = aContextPaint->GetFillPattern(dt, strokeOpacity,
aContext->CurrentMatrix());
Tie(result, pattern) =
aContextPaint->GetFillPattern(dt, strokeOpacity,
aContext->CurrentMatrix());
break;
case eStyleSVGPaintType_ContextStroke:
pattern = aContextPaint->GetStrokePattern(dt, strokeOpacity,
aContext->CurrentMatrix());
Tie(result, pattern) =
aContextPaint->GetStrokePattern(dt, strokeOpacity,
aContext->CurrentMatrix());
break;
default:
;
}
if (pattern) {
aOutPattern->Init(*pattern->GetPattern(dt));
return;
return result;
}
}
@ -1613,6 +1623,8 @@ nsSVGUtils::MakeStrokePatternFor(nsIFrame* aFrame,
&nsStyleSVG::mStroke)));
color.a *= strokeOpacity;
aOutPattern->InitColorPattern(ToDeviceColor(color));
return DrawResult::SUCCESS;
}
/* static */ float

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

@ -509,12 +509,12 @@ public:
static nscolor GetFallbackOrPaintColor(nsStyleContext *aStyleContext,
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke);
static void MakeFillPatternFor(nsIFrame *aFrame,
gfxContext* aContext,
GeneralPattern* aOutPattern,
SVGContextPaint* aContextPaint = nullptr);
static DrawResult MakeFillPatternFor(nsIFrame *aFrame,
gfxContext* aContext,
GeneralPattern* aOutPattern,
SVGContextPaint* aContextPaint = nullptr);
static void
static DrawResult
MakeStrokePatternFor(nsIFrame* aFrame,
gfxContext* aContext,
GeneralPattern* aOutPattern,