зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1351440
- Part 2. Encapsulate DrawResult and imgIContainer::FLAG_* into imgDrawingParams, and pass it to PaintSVG. r=jwatt
The DrawResult return was not in fact anything to do with the success or failure of that method, but was actually passing out a very specific piece of information about the success or failure of any imagelib drawing that may not have occurred under the various PaintSVG calls. The signature of PaintSVG is changed from DrawResult PaintSVG(...., uint32 flags); to void PaintSVG(...., imgDrawingParams& aPackage); imgDrawingParams wraps DrawResult and imgIContainer::FLAG_* as a pack, pass through PaintSVG to imagelib draw calls under beneath. MozReview-Commit-ID: IOq2evUAOQF --HG-- extra : rebase_source : 66c9a9e391c2f9e142575f42fd47b37334ec5752 extra : source : 97a08873177c0f18edffdb1b5589c77843a50553
This commit is contained in:
Родитель
fedf7f24d9
Коммит
eaa4406688
|
@ -2227,11 +2227,10 @@ gfxFont::RenderSVGGlyph(gfxContext *aContext, gfxPoint aPoint,
|
|||
|
||||
aContextPaint->InitStrokeGeometry(aContext, devUnitsPerSVGUnit);
|
||||
|
||||
bool rv = GetFontEntry()->RenderSVGGlyph(aContext, aGlyphId,
|
||||
aContextPaint);
|
||||
GetFontEntry()->RenderSVGGlyph(aContext, aGlyphId, aContextPaint);
|
||||
aContext->Restore();
|
||||
aContext->NewPath();
|
||||
return rv;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -348,12 +348,12 @@ gfxFontEntry::GetSVGGlyphExtents(DrawTarget* aDrawTarget, uint32_t aGlyphId,
|
|||
return mSVGGlyphs->GetGlyphExtents(aGlyphId, svgToAppSpace, aResult);
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
gfxFontEntry::RenderSVGGlyph(gfxContext *aContext, uint32_t aGlyphId,
|
||||
SVGContextPaint* aContextPaint)
|
||||
{
|
||||
NS_ASSERTION(mSVGInitialized, "SVG data has not yet been loaded. TryGetSVGData() first.");
|
||||
return mSVGGlyphs->RenderGlyph(aContext, aGlyphId, aContextPaint);
|
||||
mSVGGlyphs->RenderGlyph(aContext, aGlyphId, aContextPaint);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -189,7 +189,7 @@ public:
|
|||
bool HasSVGGlyph(uint32_t aGlyphId);
|
||||
bool GetSVGGlyphExtents(DrawTarget* aDrawTarget, uint32_t aGlyphId,
|
||||
gfxRect *aResult);
|
||||
bool RenderSVGGlyph(gfxContext *aContext, uint32_t aGlyphId,
|
||||
void RenderSVGGlyph(gfxContext *aContext, uint32_t aGlyphId,
|
||||
mozilla::SVGContextPaint* aContextPaint);
|
||||
// Call this when glyph geometry or rendering has changed
|
||||
// (e.g. animated SVG glyphs)
|
||||
|
|
|
@ -212,18 +212,18 @@ gfxSVGGlyphsDocument::FindGlyphElements(Element *aElem)
|
|||
* @param aGlyphId The glyph id
|
||||
* @return true iff rendering succeeded
|
||||
*/
|
||||
bool
|
||||
void
|
||||
gfxSVGGlyphs::RenderGlyph(gfxContext *aContext, uint32_t aGlyphId,
|
||||
SVGContextPaint* aContextPaint)
|
||||
{
|
||||
gfxContextAutoSaveRestore aContextRestorer(aContext);
|
||||
|
||||
Element *glyph = mGlyphIdMap.Get(aGlyphId);
|
||||
NS_ASSERTION(glyph, "No glyph element. Should check with HasSVGGlyph() first!");
|
||||
MOZ_ASSERT(glyph, "No glyph element. Should check with HasSVGGlyph() first!");
|
||||
|
||||
AutoSetRestoreSVGContextPaint autoSetRestore(aContextPaint, glyph->OwnerDoc());
|
||||
|
||||
return nsSVGUtils::PaintSVGGlyph(glyph, aContext);
|
||||
nsSVGUtils::PaintSVGGlyph(glyph, aContext);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -120,7 +120,7 @@ public:
|
|||
* @param aContextPaint Information on text context paints.
|
||||
* See |SVGContextPaint|.
|
||||
*/
|
||||
bool RenderGlyph(gfxContext *aContext, uint32_t aGlyphId,
|
||||
void RenderGlyph(gfxContext *aContext, uint32_t aGlyphId,
|
||||
mozilla::SVGContextPaint* aContextPaint);
|
||||
|
||||
/**
|
||||
|
|
|
@ -8734,9 +8734,9 @@ nsDisplayFilter::PaintAsLayer(nsDisplayListBuilder* aBuilder,
|
|||
borderArea, aBuilder,
|
||||
aManager,
|
||||
mHandleOpacity, flags);
|
||||
|
||||
image::DrawResult result = nsSVGIntegrationUtils::PaintFilter(params);
|
||||
nsDisplayFilterGeometry::UpdateDrawResult(this, result);
|
||||
imgDrawingParams imgParams(flags);
|
||||
nsSVGIntegrationUtils::PaintFilter(params, imgParams);
|
||||
nsDisplayFilterGeometry::UpdateDrawResult(this, imgParams.result);
|
||||
}
|
||||
|
||||
#ifdef MOZ_DUMP_PAINTING
|
||||
|
|
|
@ -1614,6 +1614,7 @@ public:
|
|||
typedef mozilla::layers::WebRenderParentCommand WebRenderParentCommand;
|
||||
typedef mozilla::layers::WebRenderDisplayItemLayer WebRenderDisplayItemLayer;
|
||||
typedef mozilla::LayerState LayerState;
|
||||
typedef mozilla::image::imgDrawingParams imgDrawingParams;
|
||||
typedef class mozilla::gfx::DrawTarget DrawTarget;
|
||||
|
||||
// This is never instantiated directly (it has pure virtual methods), so no
|
||||
|
|
|
@ -58,6 +58,8 @@ NS_QUERYFRAME_TAIL_INHERITING(nsFrame)
|
|||
// Display list item:
|
||||
|
||||
class nsDisplaySVGGeometry : public nsDisplayItem {
|
||||
typedef mozilla::image::imgDrawingParams imgDrawingParams;
|
||||
|
||||
public:
|
||||
nsDisplaySVGGeometry(nsDisplayListBuilder* aBuilder,
|
||||
SVGGeometryFrame* aFrame)
|
||||
|
@ -122,16 +124,14 @@ nsDisplaySVGGeometry::Paint(nsDisplayListBuilder* aBuilder,
|
|||
|
||||
gfxMatrix tm = nsSVGUtils::GetCSSPxToDevPxMatrix(mFrame) *
|
||||
gfxMatrix::Translation(devPixelOffset);
|
||||
imgDrawingParams imgParams(aBuilder->ShouldSyncDecodeImages()
|
||||
? imgIContainer::FLAG_SYNC_DECODE
|
||||
: imgIContainer::FLAG_SYNC_DECODE_IF_FAST);
|
||||
|
||||
uint32_t flag = aBuilder->ShouldSyncDecodeImages()
|
||||
? imgIContainer::FLAG_SYNC_DECODE
|
||||
: imgIContainer::FLAG_SYNC_DECODE_IF_FAST;
|
||||
static_cast<SVGGeometryFrame*>(mFrame)->PaintSVG(*aCtx->ThebesContext(),
|
||||
tm, imgParams);
|
||||
|
||||
DrawResult result =
|
||||
static_cast<SVGGeometryFrame*>(mFrame)->PaintSVG(*aCtx->ThebesContext(),
|
||||
tm, nullptr, flag);
|
||||
|
||||
nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result);
|
||||
nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, imgParams.result);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -277,48 +277,45 @@ SVGGeometryFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
|||
//----------------------------------------------------------------------
|
||||
// nsSVGDisplayableFrame methods
|
||||
|
||||
DrawResult
|
||||
void
|
||||
SVGGeometryFrame::PaintSVG(gfxContext& aContext,
|
||||
const gfxMatrix& aTransform,
|
||||
const nsIntRect* aDirtyRect,
|
||||
uint32_t aFlags)
|
||||
imgDrawingParams& aImgParams,
|
||||
const nsIntRect* aDirtyRect)
|
||||
{
|
||||
if (!StyleVisibility()->IsVisible())
|
||||
return DrawResult::SUCCESS;
|
||||
return;
|
||||
|
||||
// Matrix to the geometry's user space:
|
||||
gfxMatrix newMatrix =
|
||||
aContext.CurrentMatrix().PreMultiply(aTransform).NudgeToIntegers();
|
||||
if (newMatrix.IsSingular()) {
|
||||
return DrawResult::SUCCESS;
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t paintOrder = StyleSVG()->mPaintOrder;
|
||||
DrawResult result = DrawResult::SUCCESS;
|
||||
|
||||
if (paintOrder == NS_STYLE_PAINT_ORDER_NORMAL) {
|
||||
result = Render(&aContext, eRenderFill | eRenderStroke, newMatrix, aFlags);
|
||||
result &= PaintMarkers(aContext, aTransform, aFlags);
|
||||
Render(&aContext, eRenderFill | eRenderStroke, newMatrix, aImgParams);
|
||||
PaintMarkers(aContext, aTransform, aImgParams);
|
||||
} else {
|
||||
while (paintOrder) {
|
||||
uint32_t component =
|
||||
paintOrder & ((1 << NS_STYLE_PAINT_ORDER_BITWIDTH) - 1);
|
||||
switch (component) {
|
||||
case NS_STYLE_PAINT_ORDER_FILL:
|
||||
result &= Render(&aContext, eRenderFill, newMatrix, aFlags);
|
||||
Render(&aContext, eRenderFill, newMatrix, aImgParams);
|
||||
break;
|
||||
case NS_STYLE_PAINT_ORDER_STROKE:
|
||||
result &= Render(&aContext, eRenderStroke, newMatrix, aFlags);
|
||||
Render(&aContext, eRenderStroke, newMatrix, aImgParams);
|
||||
break;
|
||||
case NS_STYLE_PAINT_ORDER_MARKERS:
|
||||
result &= PaintMarkers(aContext, aTransform, aFlags);
|
||||
PaintMarkers(aContext, aTransform, aImgParams);
|
||||
break;
|
||||
}
|
||||
paintOrder >>= NS_STYLE_PAINT_ORDER_BITWIDTH;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
|
@ -752,11 +749,11 @@ SVGGeometryFrame::MarkerProperties::GetMarkerEndFrame()
|
|||
mMarkerEnd->GetReferencedFrame(LayoutFrameType::SVGMarker, nullptr));
|
||||
}
|
||||
|
||||
DrawResult
|
||||
void
|
||||
SVGGeometryFrame::Render(gfxContext* aContext,
|
||||
uint32_t aRenderComponents,
|
||||
const gfxMatrix& aNewTransform,
|
||||
uint32_t aFlags)
|
||||
imgDrawingParams& aImgParams)
|
||||
{
|
||||
MOZ_ASSERT(!aNewTransform.IsSingular());
|
||||
|
||||
|
@ -789,7 +786,7 @@ SVGGeometryFrame::Render(gfxContext* aContext,
|
|||
drawTarget->Fill(path, white,
|
||||
DrawOptions(1.0f, CompositionOp::OP_OVER, aaMode));
|
||||
}
|
||||
return DrawResult::SUCCESS;
|
||||
return;
|
||||
}
|
||||
|
||||
SVGGeometryElement::SimplePath simplePath;
|
||||
|
@ -799,17 +796,16 @@ SVGGeometryFrame::Render(gfxContext* aContext,
|
|||
if (!simplePath.IsPath()) {
|
||||
path = element->GetOrBuildPath(*drawTarget, fillRule);
|
||||
if (!path) {
|
||||
return DrawResult::SUCCESS;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SVGContextPaint* contextPaint = SVGContextPaint::GetContextPaint(mContent);
|
||||
DrawResult result = DrawResult::SUCCESS;
|
||||
|
||||
if (aRenderComponents & eRenderFill) {
|
||||
GeneralPattern fillPattern;
|
||||
result = nsSVGUtils::MakeFillPatternFor(this, aContext, &fillPattern,
|
||||
contextPaint, aFlags);
|
||||
nsSVGUtils::MakeFillPatternFor(this, aContext, &fillPattern, aImgParams,
|
||||
contextPaint);
|
||||
|
||||
if (fillPattern.GetPattern()) {
|
||||
DrawOptions drawOptions(1.0f, CompositionOp::OP_OVER, aaMode);
|
||||
|
@ -831,7 +827,7 @@ SVGGeometryFrame::Render(gfxContext* aContext,
|
|||
if (!path) {
|
||||
path = element->GetOrBuildPath(*drawTarget, fillRule);
|
||||
if (!path) {
|
||||
return DrawResult::SUCCESS;
|
||||
return;
|
||||
}
|
||||
simplePath.Reset();
|
||||
}
|
||||
|
@ -846,9 +842,8 @@ SVGGeometryFrame::Render(gfxContext* aContext,
|
|||
path = builder->Finish();
|
||||
}
|
||||
GeneralPattern strokePattern;
|
||||
result &=
|
||||
nsSVGUtils::MakeStrokePatternFor(this, aContext, &strokePattern,
|
||||
contextPaint, aFlags);
|
||||
nsSVGUtils::MakeStrokePatternFor(this, aContext, &strokePattern,
|
||||
aImgParams, contextPaint);
|
||||
|
||||
if (strokePattern.GetPattern()) {
|
||||
SVGContentUtils::AutoStrokeOptions strokeOptions;
|
||||
|
@ -857,7 +852,7 @@ SVGGeometryFrame::Render(gfxContext* aContext,
|
|||
StyleContext(), contextPaint);
|
||||
// GetStrokeOptions may set the line width to zero as an optimization
|
||||
if (strokeOptions.mLineWidth <= 0) {
|
||||
return DrawResult::SUCCESS;
|
||||
return;
|
||||
}
|
||||
DrawOptions drawOptions(1.0f, CompositionOp::OP_OVER, aaMode);
|
||||
if (simplePath.IsRect()) {
|
||||
|
@ -871,17 +866,14 @@ SVGGeometryFrame::Render(gfxContext* aContext,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
DrawResult
|
||||
void
|
||||
SVGGeometryFrame::PaintMarkers(gfxContext& aContext,
|
||||
const gfxMatrix& aTransform,
|
||||
uint32_t aFlags)
|
||||
imgDrawingParams& aImgParams)
|
||||
{
|
||||
SVGContextPaint* contextPaint = SVGContextPaint::GetContextPaint(mContent);
|
||||
DrawResult result = DrawResult::SUCCESS;
|
||||
if (static_cast<SVGGeometryElement*>(mContent)->IsMarkable()) {
|
||||
MarkerProperties properties = GetMarkerProperties(this);
|
||||
|
||||
|
@ -907,15 +899,13 @@ SVGGeometryFrame::PaintMarkers(gfxContext& aContext,
|
|||
nsSVGMark& mark = marks[i];
|
||||
nsSVGMarkerFrame* frame = markerFrames[mark.type];
|
||||
if (frame) {
|
||||
result &= frame->PaintMark(aContext, aTransform, this, &mark,
|
||||
strokeWidth, aFlags);
|
||||
frame->PaintMark(aContext, aTransform, this, &mark, strokeWidth,
|
||||
aImgParams);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
|
|
|
@ -98,10 +98,10 @@ public:
|
|||
gfxMatrix GetCanvasTM();
|
||||
protected:
|
||||
// nsSVGDisplayableFrame interface:
|
||||
virtual DrawResult PaintSVG(gfxContext& aContext,
|
||||
const gfxMatrix& aTransform,
|
||||
const nsIntRect* aDirtyRect = nullptr,
|
||||
uint32_t aFlags = 0) override;
|
||||
virtual void PaintSVG(gfxContext& aContext,
|
||||
const gfxMatrix& aTransform,
|
||||
imgDrawingParams& aImgParams,
|
||||
const nsIntRect* aDirtyRect = nullptr) override;
|
||||
virtual nsIFrame* GetFrameForPoint(const gfxPoint& aPoint) override;
|
||||
virtual void ReflowSVG() override;
|
||||
virtual void NotifySVGChanged(uint32_t aFlags) override;
|
||||
|
@ -118,15 +118,15 @@ protected:
|
|||
virtual uint16_t GetHitTestFlags();
|
||||
private:
|
||||
enum { eRenderFill = 1, eRenderStroke = 2 };
|
||||
DrawResult Render(gfxContext* aContext, uint32_t aRenderComponents,
|
||||
const gfxMatrix& aTransform, uint32_t aFlags);
|
||||
void Render(gfxContext* aContext, uint32_t aRenderComponents,
|
||||
const gfxMatrix& aTransform, imgDrawingParams& aImgParams);
|
||||
|
||||
/**
|
||||
* @param aMatrix The transform that must be multiplied onto aContext to
|
||||
* establish this frame's SVG user space.
|
||||
*/
|
||||
DrawResult PaintMarkers(gfxContext& aContext, const gfxMatrix& aMatrix,
|
||||
uint32_t aFlags);
|
||||
void PaintMarkers(gfxContext& aContext, const gfxMatrix& aMatrix,
|
||||
imgDrawingParams& aImgParams);
|
||||
|
||||
struct MarkerProperties {
|
||||
nsSVGMarkerProperty* mMarkerStart;
|
||||
|
|
|
@ -2733,6 +2733,8 @@ public:
|
|||
*/
|
||||
class SVGTextDrawPathCallbacks : public nsTextFrame::DrawPathCallbacks
|
||||
{
|
||||
typedef mozilla::image::imgDrawingParams imgDrawingParams;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructs an SVGTextDrawPathCallbacks.
|
||||
|
@ -2783,7 +2785,8 @@ private:
|
|||
* Sets the gfxContext paint to the appropriate color or pattern
|
||||
* for filling text geometry.
|
||||
*/
|
||||
void MakeFillPattern(GeneralPattern* aOutPattern);
|
||||
void MakeFillPattern(GeneralPattern* aOutPattern,
|
||||
imgDrawingParams& aImgParams);
|
||||
|
||||
/**
|
||||
* Fills and strokes a piece of text geometry, using group opacity
|
||||
|
@ -2828,7 +2831,9 @@ SVGTextDrawPathCallbacks::NotifySelectionBackgroundNeedsFill(
|
|||
mColor = aColor; // currently needed by MakeFillPattern
|
||||
|
||||
GeneralPattern fillPattern;
|
||||
MakeFillPattern(&fillPattern);
|
||||
// XXX cku Bug 1362417 we should pass imgDrawingParams from nsTextFrame.
|
||||
imgDrawingParams imgParams;
|
||||
MakeFillPattern(&fillPattern, imgParams);
|
||||
if (fillPattern.GetPattern()) {
|
||||
DrawOptions drawOptions(aColor == NS_40PERCENT_FOREGROUND_COLOR ? 0.4 : 1.0);
|
||||
aDrawTarget.FillRect(aBackgroundRect, fillPattern, drawOptions);
|
||||
|
@ -2925,11 +2930,12 @@ SVGTextDrawPathCallbacks::HandleTextGeometry()
|
|||
}
|
||||
|
||||
void
|
||||
SVGTextDrawPathCallbacks::MakeFillPattern(GeneralPattern* aOutPattern)
|
||||
SVGTextDrawPathCallbacks::MakeFillPattern(GeneralPattern* aOutPattern,
|
||||
imgDrawingParams& aImgParams)
|
||||
{
|
||||
if (mColor == NS_SAME_AS_FOREGROUND_COLOR ||
|
||||
mColor == NS_40PERCENT_FOREGROUND_COLOR) {
|
||||
Unused << nsSVGUtils::MakeFillPatternFor(mFrame, gfx, aOutPattern);
|
||||
nsSVGUtils::MakeFillPatternFor(mFrame, gfx, aOutPattern, aImgParams);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2978,7 +2984,9 @@ void
|
|||
SVGTextDrawPathCallbacks::FillGeometry()
|
||||
{
|
||||
GeneralPattern fillPattern;
|
||||
MakeFillPattern(&fillPattern);
|
||||
// XXX cku Bug 1362417 we should pass imgDrawingParams from nsTextFrame.
|
||||
imgDrawingParams imgParams;
|
||||
MakeFillPattern(&fillPattern, imgParams);
|
||||
if (fillPattern.GetPattern()) {
|
||||
RefPtr<Path> path = gfx->GetPath();
|
||||
FillRule fillRule = nsSVGUtils::ToFillRule(IsClipPathChild() ?
|
||||
|
@ -3000,8 +3008,10 @@ SVGTextDrawPathCallbacks::StrokeGeometry()
|
|||
mColor == NS_40PERCENT_FOREGROUND_COLOR) {
|
||||
if (nsSVGUtils::HasStroke(mFrame, /*aContextPaint*/ nullptr)) {
|
||||
GeneralPattern strokePattern;
|
||||
Unused << nsSVGUtils::MakeStrokePatternFor(mFrame, gfx, &strokePattern,
|
||||
/*aContextPaint*/ nullptr);
|
||||
// XXX cku Bug 1362417 we should pass imgDrawingParams from nsTextFrame.
|
||||
imgDrawingParams imgParams;
|
||||
nsSVGUtils::MakeStrokePatternFor(mFrame, gfx, &strokePattern, imgParams,
|
||||
/*aContextPaint*/ nullptr);
|
||||
if (strokePattern.GetPattern()) {
|
||||
if (!mFrame->GetParent()->GetContent()->IsSVGElement()) {
|
||||
// The cast that follows would be unsafe
|
||||
|
@ -3121,8 +3131,11 @@ nsDisplaySVGText::Paint(nsDisplayListBuilder* aBuilder,
|
|||
|
||||
gfxContext* ctx = aCtx->ThebesContext();
|
||||
ctx->Save();
|
||||
DrawResult result = static_cast<SVGTextFrame*>(mFrame)->PaintSVG(*ctx, tm);
|
||||
nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result);
|
||||
imgDrawingParams imgParams(aBuilder->ShouldSyncDecodeImages()
|
||||
? imgIContainer::FLAG_SYNC_DECODE
|
||||
: imgIContainer::FLAG_SYNC_DECODE_IF_FAST);
|
||||
static_cast<SVGTextFrame*>(mFrame)->PaintSVG(*ctx, tm, imgParams);
|
||||
nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, imgParams.result);
|
||||
ctx->Restore();
|
||||
}
|
||||
|
||||
|
@ -3553,17 +3566,17 @@ ShouldPaintCaret(const TextRenderedRun& aThisRun, nsCaret* aCaret)
|
|||
return false;
|
||||
}
|
||||
|
||||
DrawResult
|
||||
void
|
||||
SVGTextFrame::PaintSVG(gfxContext& aContext,
|
||||
const gfxMatrix& aTransform,
|
||||
const nsIntRect *aDirtyRect,
|
||||
uint32_t aFlags)
|
||||
imgDrawingParams& aImgParams,
|
||||
const nsIntRect *aDirtyRect)
|
||||
{
|
||||
DrawTarget& aDrawTarget = *aContext.GetDrawTarget();
|
||||
|
||||
nsIFrame* kid = PrincipalChildList().FirstChild();
|
||||
if (!kid)
|
||||
return DrawResult::SUCCESS;
|
||||
if (!kid) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsPresContext* presContext = PresContext();
|
||||
|
||||
|
@ -3576,7 +3589,7 @@ SVGTextFrame::PaintSVG(gfxContext& aContext,
|
|||
// dirty.
|
||||
if (presContext->PresShell()->InDrawWindowNotFlushing() &&
|
||||
NS_SUBTREE_DIRTY(this)) {
|
||||
return DrawResult::SUCCESS;
|
||||
return;
|
||||
}
|
||||
// Text frames inside <clipPath>, <mask>, etc. will never have had
|
||||
// ReflowSVG called on them, so call UpdateGlyphPositioning to do this now.
|
||||
|
@ -3585,12 +3598,12 @@ SVGTextFrame::PaintSVG(gfxContext& aContext,
|
|||
// If we are asked to paint before reflow has recomputed mPositions etc.
|
||||
// directly via PaintSVG, rather than via a display list, then we need
|
||||
// to bail out here too.
|
||||
return DrawResult::SUCCESS;
|
||||
return;
|
||||
}
|
||||
|
||||
if (aTransform.IsSingular()) {
|
||||
NS_WARNING("Can't render text element!");
|
||||
return DrawResult::SUCCESS;
|
||||
return;
|
||||
}
|
||||
|
||||
gfxMatrix matrixForPaintServers = aTransform * initialMatrix;
|
||||
|
@ -3612,7 +3625,7 @@ SVGTextFrame::PaintSVG(gfxContext& aContext,
|
|||
nsRect canvasRect = nsLayoutUtils::RoundGfxRectToAppRect(
|
||||
GetCanvasTM().TransformBounds(frameRect), 1);
|
||||
if (!canvasRect.Intersects(dirtyRect)) {
|
||||
return DrawResult::SUCCESS;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3641,7 +3654,6 @@ SVGTextFrame::PaintSVG(gfxContext& aContext,
|
|||
SVGContextPaint::GetContextPaint(mContent);
|
||||
|
||||
nsRenderingContext rendCtx(&aContext);
|
||||
DrawResult finalResult = DrawResult::SUCCESS;
|
||||
while (run.mFrame) {
|
||||
nsTextFrame* frame = run.mFrame;
|
||||
|
||||
|
@ -3659,7 +3671,7 @@ SVGTextFrame::PaintSVG(gfxContext& aContext,
|
|||
Tie(result, drawMode) = contextPaint->Init(&aDrawTarget,
|
||||
aContext.CurrentMatrix(),
|
||||
frame, outerContextPaint);
|
||||
finalResult &= result;
|
||||
aImgParams.result &= 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.
|
||||
|
@ -3700,8 +3712,6 @@ SVGTextFrame::PaintSVG(gfxContext& aContext,
|
|||
|
||||
run = it.Next();
|
||||
}
|
||||
|
||||
return finalResult;
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
|
|
|
@ -247,10 +247,10 @@ public:
|
|||
|
||||
// nsSVGDisplayableFrame interface:
|
||||
virtual void NotifySVGChanged(uint32_t aFlags) override;
|
||||
virtual DrawResult PaintSVG(gfxContext& aContext,
|
||||
const gfxMatrix& aTransform,
|
||||
const nsIntRect* aDirtyRect = nullptr,
|
||||
uint32_t aFlags = 0) override;
|
||||
virtual void PaintSVG(gfxContext& aContext,
|
||||
const gfxMatrix& aTransform,
|
||||
imgDrawingParams& aImgParams,
|
||||
const nsIntRect* aDirtyRect = nullptr) override;
|
||||
virtual nsIFrame* GetFrameForPoint(const gfxPoint& aPoint) override;
|
||||
virtual void ReflowSVG() override;
|
||||
virtual SVGBBox GetBBoxContribution(const Matrix& aToBBoxUserspace,
|
||||
|
|
|
@ -59,12 +59,13 @@ UserSpaceMetricsForFrame(nsIFrame* aFrame)
|
|||
return MakeUnique<NonSVGFrameUserSpaceMetrics>(aFrame);
|
||||
}
|
||||
|
||||
DrawResult
|
||||
void
|
||||
nsFilterInstance::PaintFilteredFrame(nsIFrame *aFilteredFrame,
|
||||
DrawTarget* aDrawTarget,
|
||||
const gfxMatrix& aTransform,
|
||||
nsSVGFilterPaintCallback *aPaintCallback,
|
||||
const nsRegion *aDirtyArea)
|
||||
const nsRegion *aDirtyArea,
|
||||
imgDrawingParams& aImgParams)
|
||||
{
|
||||
auto& filterChain = aFilteredFrame->StyleEffects()->mFilters;
|
||||
UniquePtr<UserSpaceMetrics> metrics = UserSpaceMetricsForFrame(aFilteredFrame);
|
||||
|
@ -74,11 +75,9 @@ nsFilterInstance::PaintFilteredFrame(nsIFrame *aFilteredFrame,
|
|||
*metrics, filterChain, /* InputIsTainted */ true,
|
||||
aPaintCallback, aTransform, aDirtyArea, nullptr,
|
||||
nullptr, nullptr);
|
||||
if (!instance.IsInitialized()) {
|
||||
return DrawResult::BAD_IMAGE;
|
||||
if (instance.IsInitialized()) {
|
||||
instance.Render(aDrawTarget, aImgParams);
|
||||
}
|
||||
|
||||
return instance.Render(aDrawTarget);
|
||||
}
|
||||
|
||||
nsRegion
|
||||
|
@ -373,20 +372,21 @@ nsFilterInstance::ComputeNeededBoxes()
|
|||
UpdateNeededBounds(strokePaintNeededRegion, mStrokePaint.mNeededBounds);
|
||||
}
|
||||
|
||||
DrawResult
|
||||
nsFilterInstance::BuildSourcePaint(SourceInfo *aSource)
|
||||
void
|
||||
nsFilterInstance::BuildSourcePaint(SourceInfo *aSource,
|
||||
imgDrawingParams& aImgParams)
|
||||
{
|
||||
MOZ_ASSERT(mTargetFrame);
|
||||
nsIntRect neededRect = aSource->mNeededBounds;
|
||||
if (neededRect.IsEmpty()) {
|
||||
return DrawResult::SUCCESS;
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<DrawTarget> offscreenDT =
|
||||
gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(
|
||||
neededRect.Size(), SurfaceFormat::B8G8R8A8);
|
||||
if (!offscreenDT || !offscreenDT->IsValid()) {
|
||||
return DrawResult::TEMPORARY_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<gfxContext> ctx = gfxContext::CreateOrNull(offscreenDT);
|
||||
|
@ -396,11 +396,10 @@ nsFilterInstance::BuildSourcePaint(SourceInfo *aSource)
|
|||
ctx->SetMatrix(mPaintTransform *
|
||||
gfxMatrix::Translation(-neededRect.TopLeft()));
|
||||
GeneralPattern pattern;
|
||||
DrawResult result = DrawResult::SUCCESS;
|
||||
if (aSource == &mFillPaint) {
|
||||
result = nsSVGUtils::MakeFillPatternFor(mTargetFrame, ctx, &pattern);
|
||||
nsSVGUtils::MakeFillPatternFor(mTargetFrame, ctx, &pattern, aImgParams);
|
||||
} else if (aSource == &mStrokePaint) {
|
||||
result = nsSVGUtils::MakeStrokePatternFor(mTargetFrame, ctx, &pattern);
|
||||
nsSVGUtils::MakeStrokePatternFor(mTargetFrame, ctx, &pattern, aImgParams);
|
||||
}
|
||||
|
||||
if (pattern.GetPattern()) {
|
||||
|
@ -410,52 +409,42 @@ nsFilterInstance::BuildSourcePaint(SourceInfo *aSource)
|
|||
|
||||
aSource->mSourceSurface = offscreenDT->Snapshot();
|
||||
aSource->mSurfaceRect = neededRect;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
DrawResult
|
||||
nsFilterInstance::BuildSourcePaints()
|
||||
void
|
||||
nsFilterInstance::BuildSourcePaints(imgDrawingParams& aImgParams)
|
||||
{
|
||||
if (!mFillPaint.mNeededBounds.IsEmpty()) {
|
||||
DrawResult result = BuildSourcePaint(&mFillPaint);
|
||||
if (result != DrawResult::SUCCESS) {
|
||||
return result;
|
||||
}
|
||||
BuildSourcePaint(&mFillPaint, aImgParams);
|
||||
}
|
||||
|
||||
if (!mStrokePaint.mNeededBounds.IsEmpty()) {
|
||||
DrawResult result = BuildSourcePaint(&mStrokePaint);
|
||||
if (result != DrawResult::SUCCESS) {
|
||||
return result;
|
||||
}
|
||||
BuildSourcePaint(&mStrokePaint, aImgParams);
|
||||
}
|
||||
|
||||
return DrawResult::SUCCESS;
|
||||
}
|
||||
|
||||
DrawResult
|
||||
nsFilterInstance::BuildSourceImage()
|
||||
void
|
||||
nsFilterInstance::BuildSourceImage(imgDrawingParams& aImgParams)
|
||||
{
|
||||
MOZ_ASSERT(mTargetFrame);
|
||||
|
||||
nsIntRect neededRect = mSourceGraphic.mNeededBounds;
|
||||
if (neededRect.IsEmpty()) {
|
||||
return DrawResult::SUCCESS;
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<DrawTarget> offscreenDT =
|
||||
gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(
|
||||
neededRect.Size(), SurfaceFormat::B8G8R8A8);
|
||||
if (!offscreenDT || !offscreenDT->IsValid()) {
|
||||
return DrawResult::TEMPORARY_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
gfxRect r = FilterSpaceToUserSpace(ThebesRect(neededRect));
|
||||
r.RoundOut();
|
||||
nsIntRect dirty;
|
||||
if (!gfxUtils::GfxRectToIntRect(r, &dirty)){
|
||||
return DrawResult::SUCCESS;
|
||||
return;
|
||||
}
|
||||
|
||||
// SVG graphics paint to device space, so we need to set an initial device
|
||||
|
@ -477,29 +466,26 @@ nsFilterInstance::BuildSourceImage()
|
|||
ctx->SetMatrix(devPxToCssPxTM * mPaintTransform *
|
||||
gfxMatrix::Translation(-neededRect.TopLeft()));
|
||||
|
||||
DrawResult result =
|
||||
mPaintCallback->Paint(*ctx, mTargetFrame, mPaintTransform, &dirty);
|
||||
mPaintCallback->Paint(*ctx, mTargetFrame, mPaintTransform, &dirty, aImgParams);
|
||||
|
||||
mSourceGraphic.mSourceSurface = offscreenDT->Snapshot();
|
||||
mSourceGraphic.mSurfaceRect = neededRect;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
DrawResult
|
||||
nsFilterInstance::Render(DrawTarget* aDrawTarget)
|
||||
void
|
||||
nsFilterInstance::Render(DrawTarget* aDrawTarget, imgDrawingParams& aImgParams)
|
||||
{
|
||||
MOZ_ASSERT(mTargetFrame, "Need a frame for rendering");
|
||||
|
||||
if (mPrimitiveDescriptions.IsEmpty()) {
|
||||
// An filter without any primitive. Treat it as success and paint nothing.
|
||||
return DrawResult::SUCCESS;
|
||||
return;
|
||||
}
|
||||
|
||||
nsIntRect filterRect =
|
||||
mPostFilterDirtyRegion.GetBounds().Intersect(OutputFilterSpaceBounds());
|
||||
if (filterRect.IsEmpty() || mPaintTransform.IsSingular()) {
|
||||
return DrawResult::SUCCESS;
|
||||
return;
|
||||
}
|
||||
|
||||
AutoRestoreTransform autoRestoreTransform(aDrawTarget);
|
||||
|
@ -509,14 +495,8 @@ nsFilterInstance::Render(DrawTarget* aDrawTarget)
|
|||
|
||||
ComputeNeededBoxes();
|
||||
|
||||
DrawResult result = BuildSourceImage();
|
||||
if (result != DrawResult::SUCCESS){
|
||||
return result;
|
||||
}
|
||||
result = BuildSourcePaints();
|
||||
if (result != DrawResult::SUCCESS){
|
||||
return result;
|
||||
}
|
||||
BuildSourceImage(aImgParams);
|
||||
BuildSourcePaints(aImgParams);
|
||||
|
||||
FilterSupport::RenderFilterDescription(
|
||||
aDrawTarget, mFilterDescription, IntRectToRect(filterRect),
|
||||
|
@ -524,8 +504,6 @@ nsFilterInstance::Render(DrawTarget* aDrawTarget)
|
|||
mFillPaint.mSourceSurface, mFillPaint.mSurfaceRect,
|
||||
mStrokePaint.mSourceSurface, mStrokePaint.mSurfaceRect,
|
||||
mInputImages, Point(0, 0));
|
||||
|
||||
return DrawResult::SUCCESS;
|
||||
}
|
||||
|
||||
nsRegion
|
||||
|
|
|
@ -56,6 +56,7 @@ class nsFilterInstance
|
|||
typedef mozilla::gfx::FilterDescription FilterDescription;
|
||||
typedef mozilla::dom::UserSpaceMetrics UserSpaceMetrics;
|
||||
typedef mozilla::image::DrawResult DrawResult;
|
||||
typedef mozilla::image::imgDrawingParams imgDrawingParams;
|
||||
public:
|
||||
/**
|
||||
* Create a FilterDescription for the supplied filter. All coordinates in
|
||||
|
@ -83,11 +84,12 @@ public:
|
|||
* frame space (i.e. relative to its origin, the top-left corner of its
|
||||
* border box).
|
||||
*/
|
||||
static DrawResult PaintFilteredFrame(nsIFrame *aFilteredFrame,
|
||||
DrawTarget* aDrawTarget,
|
||||
const gfxMatrix& aTransform,
|
||||
nsSVGFilterPaintCallback *aPaintCallback,
|
||||
const nsRegion* aDirtyArea);
|
||||
static void PaintFilteredFrame(nsIFrame *aFilteredFrame,
|
||||
DrawTarget* aDrawTarget,
|
||||
const gfxMatrix& aTransform,
|
||||
nsSVGFilterPaintCallback *aPaintCallback,
|
||||
const nsRegion* aDirtyArea,
|
||||
imgDrawingParams& aImgParams);
|
||||
|
||||
/**
|
||||
* Returns the post-filter area that could be dirtied when the given
|
||||
|
@ -167,7 +169,7 @@ private:
|
|||
* by passing it as the aPostFilterDirtyRegion argument to the
|
||||
* nsFilterInstance constructor.
|
||||
*/
|
||||
DrawResult Render(DrawTarget* aDrawTarget);
|
||||
void Render(DrawTarget* aDrawTarget, imgDrawingParams& aImgParams);
|
||||
|
||||
const FilterDescription& ExtractDescriptionAndAdditionalImages(nsTArray<RefPtr<SourceSurface>>& aOutAdditionalImages)
|
||||
{
|
||||
|
@ -220,20 +222,20 @@ private:
|
|||
* Creates a SourceSurface for either the FillPaint or StrokePaint graph
|
||||
* nodes
|
||||
*/
|
||||
DrawResult BuildSourcePaint(SourceInfo *aPrimitive);
|
||||
void BuildSourcePaint(SourceInfo *aPrimitive, imgDrawingParams& aImgParams);
|
||||
|
||||
/**
|
||||
* Creates a SourceSurface for either the FillPaint and StrokePaint graph
|
||||
* nodes, fills its contents and assigns it to mFillPaint.mSourceSurface and
|
||||
* mStrokePaint.mSourceSurface respectively.
|
||||
*/
|
||||
DrawResult BuildSourcePaints();
|
||||
void BuildSourcePaints(imgDrawingParams& aImgParams);
|
||||
|
||||
/**
|
||||
* Creates the SourceSurface for the SourceGraphic graph node, paints its
|
||||
* contents, and assigns it to mSourceGraphic.mSourceSurface.
|
||||
*/
|
||||
DrawResult BuildSourceImage();
|
||||
void BuildSourceImage(imgDrawingParams& aImgParams);
|
||||
|
||||
/**
|
||||
* Build the list of FilterPrimitiveDescriptions that describes the filter's
|
||||
|
|
|
@ -172,7 +172,7 @@ nsSVGClipPathFrame::PaintClipMask(gfxContext& aMaskContext,
|
|||
// Paint our children into the mask:
|
||||
for (nsIFrame* kid = mFrames.FirstChild(); kid;
|
||||
kid = kid->GetNextSibling()) {
|
||||
result &= PaintFrameIntoMask(kid, aClippedFrame, aMaskContext, aMatrix);
|
||||
PaintFrameIntoMask(kid, aClippedFrame, aMaskContext, aMatrix);
|
||||
}
|
||||
|
||||
if (maskUsage.shouldGenerateClipMaskLayer) {
|
||||
|
@ -193,7 +193,7 @@ nsSVGClipPathFrame::PaintClipMask(gfxContext& aMaskContext,
|
|||
return result;
|
||||
}
|
||||
|
||||
DrawResult
|
||||
void
|
||||
nsSVGClipPathFrame::PaintFrameIntoMask(nsIFrame *aFrame,
|
||||
nsIFrame* aClippedFrame,
|
||||
gfxContext& aTarget,
|
||||
|
@ -201,7 +201,7 @@ nsSVGClipPathFrame::PaintFrameIntoMask(nsIFrame *aFrame,
|
|||
{
|
||||
nsSVGDisplayableFrame* frame = do_QueryFrame(aFrame);
|
||||
if (!frame) {
|
||||
return DrawResult::SUCCESS;
|
||||
return;
|
||||
}
|
||||
|
||||
// The CTM of each frame referencing us can be different.
|
||||
|
@ -211,7 +211,7 @@ nsSVGClipPathFrame::PaintFrameIntoMask(nsIFrame *aFrame,
|
|||
nsSVGEffects::EffectProperties effectProperties =
|
||||
nsSVGEffects::GetEffectProperties(aFrame);
|
||||
if (effectProperties.HasInvalidClipPath()) {
|
||||
return DrawResult::SUCCESS;
|
||||
return;
|
||||
}
|
||||
nsSVGClipPathFrame *clipPathThatClipsChild =
|
||||
effectProperties.GetClipPathFrame();
|
||||
|
@ -242,18 +242,20 @@ nsSVGClipPathFrame::PaintFrameIntoMask(nsIFrame *aFrame,
|
|||
PrependLocalTransformsTo(mMatrixForChildren, eUserSpaceToParent);
|
||||
}
|
||||
|
||||
// clipPath does not result in any image rendering, so we just use a dummy
|
||||
// imgDrawingParams instead of requiring our caller to pass one.
|
||||
image::imgDrawingParams imgParams;
|
||||
|
||||
// Our children have NS_STATE_SVG_CLIPPATH_CHILD set on them, and
|
||||
// SVGGeometryFrame::Render checks for that state bit and paints
|
||||
// only the geometry (opaque black) if set.
|
||||
result &= frame->PaintSVG(aTarget, toChildsUserSpace);
|
||||
frame->PaintSVG(aTarget, toChildsUserSpace, imgParams);
|
||||
|
||||
if (maskUsage.shouldGenerateClipMaskLayer) {
|
||||
aTarget.PopGroupAndBlend();
|
||||
} else if (maskUsage.shouldApplyClipPath) {
|
||||
aTarget.PopClip();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
mozilla::Pair<DrawResult, RefPtr<SourceSurface>>
|
||||
|
|
|
@ -150,8 +150,8 @@ private:
|
|||
already_AddRefed<DrawTarget> CreateClipMask(gfxContext& aReferenceContext,
|
||||
mozilla::gfx::IntPoint& aOffset);
|
||||
|
||||
DrawResult PaintFrameIntoMask(nsIFrame *aFrame, nsIFrame* aClippedFrame,
|
||||
gfxContext& aTarget, const gfxMatrix& aMatrix);
|
||||
void PaintFrameIntoMask(nsIFrame *aFrame, nsIFrame* aClippedFrame,
|
||||
gfxContext& aTarget, const gfxMatrix& aMatrix);
|
||||
|
||||
// Set, during a GetClipMask() call, to the transform that still needs to be
|
||||
// concatenated to the transform of the DrawTarget that was passed to
|
||||
|
|
|
@ -252,11 +252,11 @@ nsSVGDisplayContainerFrame::IsSVGTransformed(gfx::Matrix *aOwnTransform,
|
|||
//----------------------------------------------------------------------
|
||||
// nsSVGDisplayableFrame methods
|
||||
|
||||
DrawResult
|
||||
void
|
||||
nsSVGDisplayContainerFrame::PaintSVG(gfxContext& aContext,
|
||||
const gfxMatrix& aTransform,
|
||||
const nsIntRect *aDirtyRect,
|
||||
uint32_t aFlags)
|
||||
imgDrawingParams& aImgParams,
|
||||
const nsIntRect *aDirtyRect)
|
||||
{
|
||||
NS_ASSERTION(!NS_SVGDisplayListPaintingEnabled() ||
|
||||
(mState & NS_FRAME_IS_NONDISPLAY) ||
|
||||
|
@ -265,7 +265,7 @@ nsSVGDisplayContainerFrame::PaintSVG(gfxContext& aContext,
|
|||
"SVG should take this code path");
|
||||
|
||||
if (StyleEffects()->mOpacity == 0.0) {
|
||||
return DrawResult::SUCCESS;
|
||||
return;
|
||||
}
|
||||
|
||||
gfxMatrix matrix = aTransform;
|
||||
|
@ -273,11 +273,10 @@ nsSVGDisplayContainerFrame::PaintSVG(gfxContext& aContext,
|
|||
matrix = static_cast<const nsSVGElement*>(GetContent())->
|
||||
PrependLocalTransformsTo(matrix, eChildToUserSpace);
|
||||
if (matrix.IsSingular()) {
|
||||
return DrawResult::SUCCESS;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DrawResult result = DrawResult::SUCCESS;
|
||||
for (nsIFrame* kid = mFrames.FirstChild(); kid;
|
||||
kid = kid->GetNextSibling()) {
|
||||
gfxMatrix m = matrix;
|
||||
|
@ -294,14 +293,8 @@ nsSVGDisplayContainerFrame::PaintSVG(gfxContext& aContext,
|
|||
continue;
|
||||
}
|
||||
}
|
||||
result = nsSVGUtils::PaintFrameWithEffects(kid, aContext, m, aDirtyRect,
|
||||
aFlags);
|
||||
if (result != DrawResult::SUCCESS) {
|
||||
return result;
|
||||
}
|
||||
nsSVGUtils::PaintFrameWithEffects(kid, aContext, m, aImgParams, aDirtyRect);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
|
|
|
@ -141,10 +141,10 @@ public:
|
|||
Matrix *aFromParentTransform = nullptr) const override;
|
||||
|
||||
// nsSVGDisplayableFrame interface:
|
||||
virtual DrawResult PaintSVG(gfxContext& aContext,
|
||||
const gfxMatrix& aTransform,
|
||||
const nsIntRect *aDirtyRect = nullptr,
|
||||
uint32_t aFlags = 0) override;
|
||||
virtual void PaintSVG(gfxContext& aContext,
|
||||
const gfxMatrix& aTransform,
|
||||
imgDrawingParams& aImgParams,
|
||||
const nsIntRect* aDirtyRect = nullptr) override;
|
||||
virtual nsIFrame* GetFrameForPoint(const gfxPoint& aPoint) override;
|
||||
virtual void ReflowSVG() override;
|
||||
virtual void NotifySVGChanged(uint32_t aFlags) override;
|
||||
|
|
|
@ -52,6 +52,7 @@ public:
|
|||
typedef mozilla::SVGLengthList SVGLengthList;
|
||||
typedef mozilla::SVGUserUnitList SVGUserUnitList;
|
||||
typedef mozilla::image::DrawResult DrawResult;
|
||||
typedef mozilla::image::imgDrawingParams imgDrawingParams;
|
||||
|
||||
NS_DECL_QUERYFRAME_TARGET(nsSVGDisplayableFrame)
|
||||
|
||||
|
@ -79,15 +80,16 @@ public:
|
|||
* very expensive for certain DrawTarget backends so it is best to minimize
|
||||
* the number of transform changes.
|
||||
*
|
||||
* @param aImgParams imagelib parameters that may be used when painting
|
||||
* feImage.
|
||||
*
|
||||
* @param aDirtyRect The area being redrawn, in frame offset pixel
|
||||
* coordinates.
|
||||
*
|
||||
* @param aFlags Image flags of the imgIContainer::FLAG_* variety.
|
||||
*/
|
||||
virtual DrawResult PaintSVG(gfxContext& aContext,
|
||||
const gfxMatrix& aTransform,
|
||||
const nsIntRect* aDirtyRect = nullptr,
|
||||
uint32_t aFlags = 0) = 0;
|
||||
virtual void PaintSVG(gfxContext& aContext,
|
||||
const gfxMatrix& aTransform,
|
||||
imgDrawingParams& aImgParams,
|
||||
const nsIntRect* aDirtyRect = nullptr) = 0;
|
||||
|
||||
/**
|
||||
* Returns the frame that should handle pointer events at aPoint. aPoint is
|
||||
|
|
|
@ -13,7 +13,7 @@ class gfxContext;
|
|||
|
||||
class nsSVGFilterPaintCallback {
|
||||
public:
|
||||
typedef mozilla::image::DrawResult DrawResult;
|
||||
typedef mozilla::image::imgDrawingParams imgDrawingParams;
|
||||
|
||||
/**
|
||||
* Paint the frame contents.
|
||||
|
@ -27,9 +27,9 @@ public:
|
|||
* @param aTransformRoot the outermost frame whose transform should be taken
|
||||
* into account when painting an SVG glyph
|
||||
*/
|
||||
virtual DrawResult Paint(gfxContext& aContext, nsIFrame *aTarget,
|
||||
const gfxMatrix& aTransform,
|
||||
const nsIntRect *aDirtyRect) = 0;
|
||||
virtual void Paint(gfxContext& aContext, nsIFrame *aTarget,
|
||||
const gfxMatrix& aTransform, const nsIntRect *aDirtyRect,
|
||||
imgDrawingParams& aImgParams) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -196,27 +196,29 @@ nsSVGForeignObjectFrame::IsSVGTransformed(Matrix *aOwnTransform,
|
|||
return foundTransform;
|
||||
}
|
||||
|
||||
DrawResult
|
||||
void
|
||||
nsSVGForeignObjectFrame::PaintSVG(gfxContext& aContext,
|
||||
const gfxMatrix& aTransform,
|
||||
const nsIntRect* aDirtyRect,
|
||||
uint32_t aFlags)
|
||||
imgDrawingParams& aImgParams,
|
||||
const nsIntRect* aDirtyRect)
|
||||
{
|
||||
NS_ASSERTION(!NS_SVGDisplayListPaintingEnabled() ||
|
||||
(mState & NS_FRAME_IS_NONDISPLAY),
|
||||
"If display lists are enabled, only painting of non-display "
|
||||
"SVG should take this code path");
|
||||
|
||||
if (IsDisabled())
|
||||
return DrawResult::SUCCESS;
|
||||
if (IsDisabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsIFrame* kid = PrincipalChildList().FirstChild();
|
||||
if (!kid)
|
||||
return DrawResult::SUCCESS;
|
||||
if (!kid) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aTransform.IsSingular()) {
|
||||
NS_WARNING("Can't render foreignObject element!");
|
||||
return DrawResult::SUCCESS;
|
||||
return;
|
||||
}
|
||||
|
||||
nsRect kidDirtyRect = kid->GetVisualOverflowRect();
|
||||
|
@ -244,7 +246,7 @@ nsSVGForeignObjectFrame::PaintSVG(gfxContext& aContext,
|
|||
// int32_t appUnitsPerDevPx = PresContext()->AppUnitsPerDevPixel();
|
||||
// mRect.ToOutsidePixels(appUnitsPerDevPx).Intersects(*aDirtyRect)
|
||||
if (kidDirtyRect.IsEmpty())
|
||||
return DrawResult::SUCCESS;
|
||||
return;
|
||||
}
|
||||
|
||||
aContext.Save();
|
||||
|
@ -274,15 +276,16 @@ nsSVGForeignObjectFrame::PaintSVG(gfxContext& aContext,
|
|||
if (SVGAutoRenderState::IsPaintingToWindow(aContext.GetDrawTarget())) {
|
||||
flags |= PaintFrameFlags::PAINT_TO_WINDOW;
|
||||
}
|
||||
if (aImgParams.imageFlags & imgIContainer::FLAG_SYNC_DECODE) {
|
||||
flags |= PaintFrameFlags::PAINT_SYNC_DECODE_IMAGES;
|
||||
}
|
||||
nsRenderingContext rendCtx(&aContext);
|
||||
nsresult rv = nsLayoutUtils::PaintFrame(&rendCtx, kid, nsRegion(kidDirtyRect),
|
||||
NS_RGBA(0,0,0,0),
|
||||
nsDisplayListBuilderMode::PAINTING,
|
||||
flags);
|
||||
Unused << nsLayoutUtils::PaintFrame(&rendCtx, kid, nsRegion(kidDirtyRect),
|
||||
NS_RGBA(0,0,0,0),
|
||||
nsDisplayListBuilderMode::PAINTING,
|
||||
flags);
|
||||
|
||||
aContext.Restore();
|
||||
|
||||
return NS_FAILED(rv) ? DrawResult::BAD_ARGS : DrawResult::SUCCESS;
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
|
|
|
@ -67,10 +67,10 @@ public:
|
|||
#endif
|
||||
|
||||
// nsSVGDisplayableFrame interface:
|
||||
virtual DrawResult PaintSVG(gfxContext& aContext,
|
||||
const gfxMatrix& aTransform,
|
||||
const nsIntRect* aDirtyRect = nullptr,
|
||||
uint32_t aFlags = 0) override;
|
||||
virtual void PaintSVG(gfxContext& aContext,
|
||||
const gfxMatrix& aTransform,
|
||||
imgDrawingParams& aImgParams,
|
||||
const nsIntRect* aDirtyRect = nullptr) override;
|
||||
virtual nsIFrame* GetFrameForPoint(const gfxPoint& aPoint) override;
|
||||
virtual void ReflowSVG() override;
|
||||
virtual void NotifySVGChanged(uint32_t aFlags) override;
|
||||
|
|
|
@ -68,10 +68,10 @@ public:
|
|||
NS_DECL_FRAMEARENA_HELPERS
|
||||
|
||||
// nsSVGDisplayableFrame interface:
|
||||
virtual DrawResult PaintSVG(gfxContext& aContext,
|
||||
const gfxMatrix& aTransform,
|
||||
const nsIntRect* aDirtyRect = nullptr,
|
||||
uint32_t aFlags = 0) override;
|
||||
virtual void PaintSVG(gfxContext& aContext,
|
||||
const gfxMatrix& aTransform,
|
||||
imgDrawingParams& aImgParams,
|
||||
const nsIntRect* aDirtyRect = nullptr) override;
|
||||
virtual nsIFrame* GetFrameForPoint(const gfxPoint& aPoint) override;
|
||||
virtual void ReflowSVG() override;
|
||||
|
||||
|
@ -331,14 +331,15 @@ nsSVGImageFrame::TransformContextForPainting(gfxContext* aGfxContext,
|
|||
|
||||
//----------------------------------------------------------------------
|
||||
// nsSVGDisplayableFrame methods:
|
||||
DrawResult
|
||||
void
|
||||
nsSVGImageFrame::PaintSVG(gfxContext& aContext,
|
||||
const gfxMatrix& aTransform,
|
||||
const nsIntRect *aDirtyRect,
|
||||
uint32_t aFlags)
|
||||
imgDrawingParams& aImgParams,
|
||||
const nsIntRect *aDirtyRect)
|
||||
{
|
||||
if (!StyleVisibility()->IsVisible())
|
||||
return DrawResult::SUCCESS;
|
||||
if (!StyleVisibility()->IsVisible()) {
|
||||
return;
|
||||
}
|
||||
|
||||
float x, y, width, height;
|
||||
SVGImageElement *imgElem = static_cast<SVGImageElement*>(mContent);
|
||||
|
@ -357,7 +358,6 @@ nsSVGImageFrame::PaintSVG(gfxContext& aContext,
|
|||
currentRequest->GetImage(getter_AddRefs(mImageContainer));
|
||||
}
|
||||
|
||||
DrawResult result = DrawResult::SUCCESS;
|
||||
if (mImageContainer) {
|
||||
gfxContextAutoSaveRestore autoRestorer(&aContext);
|
||||
|
||||
|
@ -368,7 +368,7 @@ nsSVGImageFrame::PaintSVG(gfxContext& aContext,
|
|||
}
|
||||
|
||||
if (!TransformContextForPainting(&aContext, aTransform)) {
|
||||
return DrawResult::SUCCESS;
|
||||
return ;
|
||||
}
|
||||
|
||||
// fill-opacity doesn't affect <image>, so if we're allowed to
|
||||
|
@ -418,7 +418,7 @@ nsSVGImageFrame::PaintSVG(gfxContext& aContext,
|
|||
// Note: Can't use DrawSingleUnscaledImage for the TYPE_VECTOR case.
|
||||
// That method needs our image to have a fixed native width & height,
|
||||
// and that's not always true for TYPE_VECTOR images.
|
||||
result = nsLayoutUtils::DrawSingleImage(
|
||||
aImgParams.result &= nsLayoutUtils::DrawSingleImage(
|
||||
aContext,
|
||||
PresContext(),
|
||||
mImageContainer,
|
||||
|
@ -426,16 +426,16 @@ nsSVGImageFrame::PaintSVG(gfxContext& aContext,
|
|||
destRect,
|
||||
aDirtyRect ? dirtyRect : destRect,
|
||||
context,
|
||||
aFlags);
|
||||
aImgParams.imageFlags);
|
||||
} else { // mImageContainer->GetType() == TYPE_RASTER
|
||||
result = nsLayoutUtils::DrawSingleUnscaledImage(
|
||||
aImgParams.result &= nsLayoutUtils::DrawSingleUnscaledImage(
|
||||
aContext,
|
||||
PresContext(),
|
||||
mImageContainer,
|
||||
nsLayoutUtils::GetSamplingFilterForFrame(this),
|
||||
nsPoint(0, 0),
|
||||
aDirtyRect ? &dirtyRect : nullptr,
|
||||
aFlags);
|
||||
aImgParams.imageFlags);
|
||||
}
|
||||
|
||||
if (opacity != 1.0f || StyleEffects()->mMixBlendMode != NS_STYLE_BLEND_NORMAL) {
|
||||
|
@ -443,8 +443,6 @@ nsSVGImageFrame::PaintSVG(gfxContext& aContext,
|
|||
}
|
||||
// gfxContextAutoSaveRestore goes out of scope & cleans up our gfxContext
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
|
|
|
@ -52,11 +52,11 @@ nsSVGInnerSVGFrame::Init(nsIContent* aContent,
|
|||
//----------------------------------------------------------------------
|
||||
// nsSVGDisplayableFrame methods
|
||||
|
||||
DrawResult
|
||||
void
|
||||
nsSVGInnerSVGFrame::PaintSVG(gfxContext& aContext,
|
||||
const gfxMatrix& aTransform,
|
||||
const nsIntRect *aDirtyRect,
|
||||
uint32_t aFlags)
|
||||
imgDrawingParams& aImgParams,
|
||||
const nsIntRect *aDirtyRect)
|
||||
{
|
||||
NS_ASSERTION(!NS_SVGDisplayListPaintingEnabled() ||
|
||||
(mState & NS_FRAME_IS_NONDISPLAY),
|
||||
|
@ -71,7 +71,7 @@ nsSVGInnerSVGFrame::PaintSVG(gfxContext& aContext,
|
|||
GetAnimatedLengthValues(&x, &y, &width, &height, nullptr);
|
||||
|
||||
if (width <= 0 || height <= 0) {
|
||||
return DrawResult::SUCCESS;
|
||||
return;
|
||||
}
|
||||
|
||||
autoSR.SetContext(&aContext);
|
||||
|
@ -80,7 +80,8 @@ nsSVGInnerSVGFrame::PaintSVG(gfxContext& aContext,
|
|||
nsSVGUtils::SetClipRect(&aContext, aTransform, clipRect);
|
||||
}
|
||||
|
||||
return nsSVGDisplayContainerFrame::PaintSVG(aContext, aTransform, aDirtyRect, aFlags);
|
||||
nsSVGDisplayContainerFrame::PaintSVG(aContext, aTransform, aImgParams,
|
||||
aDirtyRect);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -49,10 +49,10 @@ public:
|
|||
int32_t aModType) override;
|
||||
|
||||
// nsSVGDisplayableFrame interface:
|
||||
virtual DrawResult PaintSVG(gfxContext& aContext,
|
||||
const gfxMatrix& aTransform,
|
||||
const nsIntRect *aDirtyRect = nullptr,
|
||||
uint32_t aFlags = 0) override;
|
||||
virtual void PaintSVG(gfxContext& aContext,
|
||||
const gfxMatrix& aTransform,
|
||||
imgDrawingParams& aImgParams,
|
||||
const nsIntRect* aDirtyRect = nullptr) override;
|
||||
virtual void ReflowSVG() override;
|
||||
virtual void NotifySVGChanged(uint32_t aFlags) override;
|
||||
SVGBBox GetBBoxContribution(const Matrix &aToBBoxUserspace,
|
||||
|
|
|
@ -384,9 +384,10 @@ public:
|
|||
: mBuilder(aBuilder), mLayerManager(aManager),
|
||||
mUserSpaceToFrameSpaceOffset(aUserSpaceToFrameSpaceOffset) {}
|
||||
|
||||
virtual DrawResult Paint(gfxContext& aContext, nsIFrame *aTarget,
|
||||
const gfxMatrix& aTransform,
|
||||
const nsIntRect* aDirtyRect) override
|
||||
virtual void Paint(gfxContext& aContext, nsIFrame *aTarget,
|
||||
const gfxMatrix& aTransform,
|
||||
const nsIntRect* aDirtyRect,
|
||||
imgDrawingParams& aImgParams) override
|
||||
{
|
||||
BasicLayerManager* basic = mLayerManager->AsBasicLayerManager();
|
||||
RefPtr<gfxContext> oldCtx = basic->GetTarget();
|
||||
|
@ -397,7 +398,6 @@ public:
|
|||
|
||||
mLayerManager->EndTransaction(FrameLayerBuilder::DrawPaintedLayer, mBuilder);
|
||||
basic->SetTarget(oldCtx);
|
||||
return DrawResult::SUCCESS;
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -1058,8 +1058,9 @@ nsSVGIntegrationUtils::PaintMaskAndClipPath(const PaintFramesParams& aParams)
|
|||
return result;
|
||||
}
|
||||
|
||||
DrawResult
|
||||
nsSVGIntegrationUtils::PaintFilter(const PaintFramesParams& aParams)
|
||||
void
|
||||
nsSVGIntegrationUtils::PaintFilter(const PaintFramesParams& aParams,
|
||||
imgDrawingParams& aImgParams)
|
||||
{
|
||||
MOZ_ASSERT(!aParams.builder->IsForGenerateGlyphMask(),
|
||||
"Filter effect is discarded while generating glyph mask.");
|
||||
|
@ -1068,12 +1069,12 @@ nsSVGIntegrationUtils::PaintFilter(const PaintFramesParams& aParams)
|
|||
|
||||
nsIFrame* frame = aParams.frame;
|
||||
if (!ValidateSVGFrame(frame)) {
|
||||
return DrawResult::SUCCESS;
|
||||
return;
|
||||
}
|
||||
|
||||
float opacity = nsSVGUtils::ComputeOpacity(frame, aParams.handleOpacity);
|
||||
if (opacity == 0.0f) {
|
||||
return DrawResult::SUCCESS;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Properties are added lazily and may have been removed by a restyle,
|
||||
|
@ -1084,7 +1085,7 @@ nsSVGIntegrationUtils::PaintFilter(const PaintFramesParams& aParams)
|
|||
nsSVGEffects::GetEffectProperties(firstFrame);
|
||||
|
||||
if (effectProperties.HasInvalidFilter()) {
|
||||
return DrawResult::NOT_READY;
|
||||
return;
|
||||
}
|
||||
|
||||
gfxContext& context = aParams.ctx;
|
||||
|
@ -1112,15 +1113,13 @@ nsSVGIntegrationUtils::PaintFilter(const PaintFramesParams& aParams)
|
|||
|
||||
gfxMatrix tm =
|
||||
scaleMatrix * nsSVGUtils::GetCSSPxToDevPxMatrix(frame);
|
||||
DrawResult result =
|
||||
nsFilterInstance::PaintFilteredFrame(frame, context.GetDrawTarget(),
|
||||
tm, &callback, &dirtyRegion);
|
||||
nsFilterInstance::PaintFilteredFrame(frame, context.GetDrawTarget(),
|
||||
tm, &callback, &dirtyRegion,
|
||||
aImgParams);
|
||||
|
||||
if (opacity != 1.0f) {
|
||||
context.PopGroupAndBlend();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
class PaintFrameCallback : public gfxDrawingCallback {
|
||||
|
|
|
@ -41,6 +41,7 @@ class nsSVGIntegrationUtils final
|
|||
typedef mozilla::gfx::DrawTarget DrawTarget;
|
||||
typedef mozilla::gfx::IntRect IntRect;
|
||||
typedef mozilla::image::DrawResult DrawResult;
|
||||
typedef mozilla::image::imgDrawingParams imgDrawingParams;
|
||||
|
||||
public:
|
||||
/**
|
||||
|
@ -152,8 +153,7 @@ public:
|
|||
bool aHandleOpacity, uint32_t aFlags)
|
||||
: ctx(aCtx), frame(aFrame), dirtyRect(aDirtyRect),
|
||||
borderArea(aBorderArea), builder(aBuilder),
|
||||
layerManager(aLayerManager), handleOpacity(aHandleOpacity),
|
||||
flags(aFlags)
|
||||
layerManager(aLayerManager), handleOpacity(aHandleOpacity)
|
||||
{ }
|
||||
};
|
||||
|
||||
|
@ -179,8 +179,8 @@ public:
|
|||
/**
|
||||
* Paint non-SVG frame with filter and opacity effect.
|
||||
*/
|
||||
static DrawResult
|
||||
PaintFilter(const PaintFramesParams& aParams);
|
||||
static void
|
||||
PaintFilter(const PaintFramesParams& aParams, imgDrawingParams& aImgParams);
|
||||
|
||||
/**
|
||||
* @param aRenderingContext the target rendering context in which the paint
|
||||
|
|
|
@ -96,32 +96,32 @@ GetAnonymousChildFrame(nsIFrame* aFrame)
|
|||
return kid;
|
||||
}
|
||||
|
||||
DrawResult
|
||||
void
|
||||
nsSVGMarkerFrame::PaintMark(gfxContext& aContext,
|
||||
const gfxMatrix& aToMarkedFrameUserSpace,
|
||||
SVGGeometryFrame *aMarkedFrame,
|
||||
nsSVGMark *aMark, float aStrokeWidth,
|
||||
uint32_t aFlags)
|
||||
imgDrawingParams& aImgParams)
|
||||
{
|
||||
// If the flag is set when we get here, it means this marker frame
|
||||
// has already been used painting the current mark, and the document
|
||||
// has a marker reference loop.
|
||||
if (mInUse) {
|
||||
return DrawResult::SUCCESS;
|
||||
return;
|
||||
}
|
||||
|
||||
AutoMarkerReferencer markerRef(this, aMarkedFrame);
|
||||
|
||||
SVGMarkerElement *marker = static_cast<SVGMarkerElement*>(mContent);
|
||||
if (!marker->HasValidDimensions()) {
|
||||
return DrawResult::SUCCESS;
|
||||
return;
|
||||
}
|
||||
|
||||
const nsSVGViewBoxRect viewBox = marker->GetViewBoxRect();
|
||||
|
||||
if (viewBox.width <= 0.0f || viewBox.height <= 0.0f) {
|
||||
// We must disable rendering if the viewBox width or height are zero.
|
||||
return DrawResult::SUCCESS;
|
||||
return;
|
||||
}
|
||||
|
||||
mStrokeWidth = aStrokeWidth;
|
||||
|
@ -151,13 +151,10 @@ nsSVGMarkerFrame::PaintMark(gfxContext& aContext,
|
|||
nsSVGDisplayableFrame* SVGFrame = do_QueryFrame(kid);
|
||||
// The CTM of each frame referencing us may be different.
|
||||
SVGFrame->NotifySVGChanged(nsSVGDisplayableFrame::TRANSFORM_CHANGED);
|
||||
DrawResult result = nsSVGUtils::PaintFrameWithEffects(kid, aContext, markTM,
|
||||
nullptr, aFlags);
|
||||
nsSVGUtils::PaintFrameWithEffects(kid, aContext, markTM, aImgParams);
|
||||
|
||||
if (StyleDisplay()->IsScrollableOverflow())
|
||||
aContext.Restore();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
SVGBBox
|
||||
|
|
|
@ -28,6 +28,8 @@ struct nsSVGMark;
|
|||
|
||||
class nsSVGMarkerFrame final : public nsSVGContainerFrame
|
||||
{
|
||||
typedef mozilla::image::imgDrawingParams imgDrawingParams;
|
||||
|
||||
friend class nsSVGMarkerAnonChildFrame;
|
||||
friend nsContainerFrame*
|
||||
NS_NewSVGMarkerFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
|
||||
|
@ -75,12 +77,12 @@ public:
|
|||
}
|
||||
|
||||
// nsSVGMarkerFrame methods:
|
||||
DrawResult PaintMark(gfxContext& aContext,
|
||||
const gfxMatrix& aToMarkedFrameUserSpace,
|
||||
mozilla::SVGGeometryFrame *aMarkedFrame,
|
||||
nsSVGMark *aMark,
|
||||
float aStrokeWidth,
|
||||
uint32_t aFlags);
|
||||
void PaintMark(gfxContext& aContext,
|
||||
const gfxMatrix& aToMarkedFrameUserSpace,
|
||||
mozilla::SVGGeometryFrame *aMarkedFrame,
|
||||
nsSVGMark *aMark,
|
||||
float aStrokeWidth,
|
||||
imgDrawingParams& aImgParams);
|
||||
|
||||
SVGBBox GetMarkBBoxContribution(const Matrix &aToBBoxUserspace,
|
||||
uint32_t aFlags,
|
||||
|
|
|
@ -253,7 +253,7 @@ nsSVGMaskFrame::GetMaskForMaskedFrame(MaskParams& aParams)
|
|||
|
||||
mMatrixForChildren = GetMaskTransform(aParams.maskedFrame) *
|
||||
aParams.toUserSpace;
|
||||
DrawResult result = DrawResult::SUCCESS;
|
||||
imgDrawingParams imgParams(aParams.flags);
|
||||
|
||||
for (nsIFrame* kid = mFrames.FirstChild(); kid;
|
||||
kid = kid->GetNextSibling()) {
|
||||
|
@ -267,8 +267,7 @@ nsSVGMaskFrame::GetMaskForMaskedFrame(MaskParams& aParams)
|
|||
m = static_cast<nsSVGElement*>(kid->GetContent())->
|
||||
PrependLocalTransformsTo(m, eUserSpaceToParent);
|
||||
}
|
||||
result &= nsSVGUtils::PaintFrameWithEffects(kid, *tmpCtx, m, nullptr,
|
||||
aParams.flags);
|
||||
nsSVGUtils::PaintFrameWithEffects(kid, *tmpCtx, m, imgParams);
|
||||
}
|
||||
|
||||
RefPtr<SourceSurface> maskSnapshot = maskDT->Snapshot();
|
||||
|
@ -328,7 +327,7 @@ nsSVGMaskFrame::GetMaskForMaskedFrame(MaskParams& aParams)
|
|||
|
||||
*aParams.maskTransform = ToMatrix(maskSurfaceMatrix);
|
||||
RefPtr<SourceSurface> surface = destMaskSurface.forget();
|
||||
return MakePair(result, Move(surface));
|
||||
return MakePair(imgParams.result, Move(surface));
|
||||
}
|
||||
|
||||
gfxRect
|
||||
|
|
|
@ -40,6 +40,7 @@ class nsSVGMaskFrame final : public nsSVGContainerFrame
|
|||
typedef mozilla::gfx::Matrix Matrix;
|
||||
typedef mozilla::gfx::SourceSurface SourceSurface;
|
||||
typedef mozilla::image::DrawResult DrawResult;
|
||||
typedef mozilla::image::imgDrawingParams imgDrawingParams;
|
||||
|
||||
protected:
|
||||
explicit nsSVGMaskFrame(nsStyleContext* aContext)
|
||||
|
|
|
@ -625,17 +625,16 @@ nsDisplayOuterSVG::Paint(nsDisplayListBuilder* aBuilder,
|
|||
nsLayoutUtils::PointToGfxPoint(viewportRect.TopLeft(), appUnitsPerDevPixel);
|
||||
|
||||
aContext->ThebesContext()->Save();
|
||||
uint32_t flags = aBuilder->ShouldSyncDecodeImages()
|
||||
? imgIContainer::FLAG_SYNC_DECODE
|
||||
: imgIContainer::FLAG_SYNC_DECODE_IF_FAST;
|
||||
imgDrawingParams imgParams(aBuilder->ShouldSyncDecodeImages()
|
||||
? imgIContainer::FLAG_SYNC_DECODE
|
||||
: imgIContainer::FLAG_SYNC_DECODE_IF_FAST);
|
||||
// We include the offset of our frame and a scale from device pixels to user
|
||||
// units (i.e. CSS px) in the matrix that we pass to our children):
|
||||
gfxMatrix tm = nsSVGUtils::GetCSSPxToDevPxMatrix(mFrame) *
|
||||
gfxMatrix::Translation(devPixelOffset);
|
||||
DrawResult result =
|
||||
nsSVGUtils::PaintFrameWithEffects(mFrame, *aContext->ThebesContext(), tm,
|
||||
&contentAreaDirtyRect, flags);
|
||||
nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result);
|
||||
nsSVGUtils::PaintFrameWithEffects(mFrame, *aContext->ThebesContext(), tm,
|
||||
imgParams, &contentAreaDirtyRect);
|
||||
nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, imgParams.result);
|
||||
aContext->ThebesContext()->Restore();
|
||||
|
||||
#if defined(DEBUG) && defined(SVG_DEBUG_PAINT_TIMING)
|
||||
|
@ -863,18 +862,18 @@ nsSVGOuterSVGFrame::NotifyViewportOrTransformChanged(uint32_t aFlags)
|
|||
//----------------------------------------------------------------------
|
||||
// nsSVGDisplayableFrame methods:
|
||||
|
||||
DrawResult
|
||||
void
|
||||
nsSVGOuterSVGFrame::PaintSVG(gfxContext& aContext,
|
||||
const gfxMatrix& aTransform,
|
||||
const nsIntRect* aDirtyRect,
|
||||
uint32_t aFlags)
|
||||
imgDrawingParams& aImgParams,
|
||||
const nsIntRect* aDirtyRect)
|
||||
{
|
||||
NS_ASSERTION(PrincipalChildList().FirstChild()->IsSVGOuterSVGAnonChildFrame() &&
|
||||
!PrincipalChildList().FirstChild()->GetNextSibling(),
|
||||
"We should have a single, anonymous, child");
|
||||
nsSVGOuterSVGAnonChildFrame *anonKid =
|
||||
static_cast<nsSVGOuterSVGAnonChildFrame*>(PrincipalChildList().FirstChild());
|
||||
return anonKid->PaintSVG(aContext, aTransform, aDirtyRect, aFlags);
|
||||
anonKid->PaintSVG(aContext, aTransform, aImgParams, aDirtyRect);
|
||||
}
|
||||
|
||||
SVGBBox
|
||||
|
|
|
@ -21,6 +21,8 @@ class nsSVGForeignObjectFrame;
|
|||
class nsSVGOuterSVGFrame final : public nsSVGDisplayContainerFrame
|
||||
, public nsISVGSVGFrame
|
||||
{
|
||||
typedef mozilla::image::imgDrawingParams imgDrawingParams;
|
||||
|
||||
friend nsContainerFrame*
|
||||
NS_NewSVGOuterSVGFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
|
||||
protected:
|
||||
|
@ -106,10 +108,10 @@ public:
|
|||
virtual void NotifyViewportOrTransformChanged(uint32_t aFlags) override;
|
||||
|
||||
// nsSVGDisplayableFrame methods:
|
||||
virtual DrawResult PaintSVG(gfxContext& aContext,
|
||||
const gfxMatrix& aTransform,
|
||||
const nsIntRect* aDirtyRect = nullptr,
|
||||
uint32_t aFlags = 0) override;
|
||||
virtual void PaintSVG(gfxContext& aContext,
|
||||
const gfxMatrix& aTransform,
|
||||
imgDrawingParams& aImgParams,
|
||||
const nsIntRect* aDirtyRect = nullptr) override;
|
||||
virtual SVGBBox GetBBoxContribution(const Matrix &aToBBoxUserspace,
|
||||
uint32_t aFlags) override;
|
||||
|
||||
|
|
|
@ -66,6 +66,8 @@ protected:
|
|||
}
|
||||
|
||||
public:
|
||||
typedef mozilla::image::imgDrawingParams imgDrawingParams;
|
||||
|
||||
NS_DECL_ABSTRACT_FRAME(nsSVGPaintServerFrame)
|
||||
|
||||
/**
|
||||
|
|
|
@ -376,7 +376,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;
|
||||
imgDrawingParams imgParams(aFlags);
|
||||
if (!(patternWithChildren->GetStateBits() & NS_FRAME_DRAWING_AS_PAINTSERVER)) {
|
||||
AutoSetRestorePaintServerState paintServer(patternWithChildren);
|
||||
for (nsIFrame* kid = firstKid; kid;
|
||||
|
@ -392,8 +392,7 @@ nsSVGPatternFrame::PaintPattern(const DrawTarget* aDrawTarget,
|
|||
PrependLocalTransformsTo(tm, eUserSpaceToParent);
|
||||
}
|
||||
|
||||
result &= nsSVGUtils::PaintFrameWithEffects(kid, *ctx, tm, nullptr,
|
||||
aFlags);
|
||||
nsSVGUtils::PaintFrameWithEffects(kid, *ctx, tm, imgParams);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -406,7 +405,7 @@ nsSVGPatternFrame::PaintPattern(const DrawTarget* aDrawTarget,
|
|||
|
||||
// caller now owns the surface
|
||||
RefPtr<SourceSurface> surf = dt->Snapshot();
|
||||
return MakePair(result, Move(surf));
|
||||
return MakePair(imgParams.result, Move(surf));
|
||||
}
|
||||
|
||||
/* Will probably need something like this... */
|
||||
|
|
|
@ -43,10 +43,10 @@ public:
|
|||
const nsDisplayListSet& aLists) override;
|
||||
|
||||
// nsSVGDisplayableFrame interface:
|
||||
virtual DrawResult PaintSVG(gfxContext& aContext,
|
||||
const gfxMatrix& aTransform,
|
||||
const nsIntRect* aDirtyRect = nullptr,
|
||||
uint32_t aFlags = 0) override;
|
||||
virtual void PaintSVG(gfxContext& aContext,
|
||||
const gfxMatrix& aTransform,
|
||||
imgDrawingParams& aPackage,
|
||||
const nsIntRect* aDirtyRect = nullptr) override;
|
||||
nsIFrame* GetFrameForPoint(const gfxPoint& aPoint) override;
|
||||
virtual void ReflowSVG() override;
|
||||
virtual SVGBBox GetBBoxContribution(const Matrix &aToBBoxUserspace,
|
||||
|
@ -91,21 +91,21 @@ nsSVGSwitchFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
|||
}
|
||||
}
|
||||
|
||||
DrawResult
|
||||
void
|
||||
nsSVGSwitchFrame::PaintSVG(gfxContext& aContext,
|
||||
const gfxMatrix& aTransform,
|
||||
const nsIntRect* aDirtyRect,
|
||||
uint32_t aFlags)
|
||||
imgDrawingParams& aImgParams,
|
||||
const nsIntRect* aDirtyRect)
|
||||
{
|
||||
NS_ASSERTION(!NS_SVGDisplayListPaintingEnabled() ||
|
||||
(mState & NS_FRAME_IS_NONDISPLAY),
|
||||
"If display lists are enabled, only painting of non-display "
|
||||
"SVG should take this code path");
|
||||
|
||||
if (StyleEffects()->mOpacity == 0.0)
|
||||
return DrawResult::SUCCESS;
|
||||
if (StyleEffects()->mOpacity == 0.0){
|
||||
return;
|
||||
}
|
||||
|
||||
DrawResult result = DrawResult::SUCCESS;
|
||||
nsIFrame *kid = GetActiveChildFrame();
|
||||
if (kid) {
|
||||
gfxMatrix tm = aTransform;
|
||||
|
@ -113,9 +113,8 @@ nsSVGSwitchFrame::PaintSVG(gfxContext& aContext,
|
|||
tm = static_cast<nsSVGElement*>(kid->GetContent())->
|
||||
PrependLocalTransformsTo(tm, eUserSpaceToParent);
|
||||
}
|
||||
result = nsSVGUtils::PaintFrameWithEffects(kid, aContext, tm, aDirtyRect);
|
||||
nsSVGUtils::PaintFrameWithEffects(kid, aContext, tm, aImgParams, aDirtyRect);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -469,13 +469,10 @@ nsSVGUtils::NotifyChildrenOfSVGChange(nsIFrame *aFrame, uint32_t aFlags)
|
|||
class SVGPaintCallback : public nsSVGFilterPaintCallback
|
||||
{
|
||||
public:
|
||||
explicit SVGPaintCallback(uint32_t aFlags)
|
||||
: mFlags(aFlags)
|
||||
{ }
|
||||
|
||||
virtual DrawResult Paint(gfxContext& aContext, nsIFrame *aTarget,
|
||||
virtual void Paint(gfxContext& aContext, nsIFrame *aTarget,
|
||||
const gfxMatrix& aTransform,
|
||||
const nsIntRect* aDirtyRect) override
|
||||
const nsIntRect* aDirtyRect,
|
||||
imgDrawingParams& aImgParams) override
|
||||
{
|
||||
nsSVGDisplayableFrame* svgFrame = do_QueryFrame(aTarget);
|
||||
NS_ASSERTION(svgFrame, "Expected SVG frame here");
|
||||
|
@ -488,7 +485,7 @@ public:
|
|||
if (aDirtyRect) {
|
||||
gfxMatrix userToDeviceSpace = aTransform;
|
||||
if (userToDeviceSpace.IsSingular()) {
|
||||
return DrawResult::SUCCESS;
|
||||
return;
|
||||
}
|
||||
gfxRect dirtyBounds = userToDeviceSpace.TransformBounds(
|
||||
gfxRect(aDirtyRect->x, aDirtyRect->y, aDirtyRect->width, aDirtyRect->height));
|
||||
|
@ -498,13 +495,9 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
return svgFrame->PaintSVG(aContext,
|
||||
nsSVGUtils::GetCSSPxToDevPxMatrix(aTarget),
|
||||
dirtyRect, mFlags);
|
||||
svgFrame->PaintSVG(aContext, nsSVGUtils::GetCSSPxToDevPxMatrix(aTarget),
|
||||
aImgParams, dirtyRect);
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t mFlags;
|
||||
};
|
||||
|
||||
float
|
||||
|
@ -678,12 +671,12 @@ private:
|
|||
IntPoint mTargetOffset;
|
||||
};
|
||||
|
||||
DrawResult
|
||||
void
|
||||
nsSVGUtils::PaintFrameWithEffects(nsIFrame *aFrame,
|
||||
gfxContext& aContext,
|
||||
const gfxMatrix& aTransform,
|
||||
const nsIntRect *aDirtyRect,
|
||||
uint32_t aFlags)
|
||||
imgDrawingParams& aImgParams,
|
||||
const nsIntRect *aDirtyRect)
|
||||
{
|
||||
NS_ASSERTION(!NS_SVGDisplayListPaintingEnabled() ||
|
||||
(aFrame->GetStateBits() & NS_FRAME_IS_NONDISPLAY) ||
|
||||
|
@ -693,18 +686,18 @@ nsSVGUtils::PaintFrameWithEffects(nsIFrame *aFrame,
|
|||
|
||||
nsSVGDisplayableFrame* svgFrame = do_QueryFrame(aFrame);
|
||||
if (!svgFrame)
|
||||
return DrawResult::SUCCESS;
|
||||
return;
|
||||
|
||||
MaskUsage maskUsage;
|
||||
DetermineMaskUsage(aFrame, true, maskUsage);
|
||||
if (maskUsage.opacity == 0.0f) {
|
||||
return DrawResult::SUCCESS;
|
||||
return;
|
||||
}
|
||||
|
||||
const nsIContent* content = aFrame->GetContent();
|
||||
if (content->IsSVGElement() &&
|
||||
!static_cast<const nsSVGElement*>(content)->HasValidDimensions()) {
|
||||
return DrawResult::SUCCESS;
|
||||
return;
|
||||
}
|
||||
|
||||
if (aDirtyRect &&
|
||||
|
@ -728,7 +721,7 @@ nsSVGUtils::PaintFrameWithEffects(nsIFrame *aFrame,
|
|||
HasChildrenOnlyTransform(&childrenOnlyTM)) {
|
||||
// Undo the children-only transform:
|
||||
if (!childrenOnlyTM.Invert()) {
|
||||
return DrawResult::SUCCESS;
|
||||
return;
|
||||
}
|
||||
tm = ThebesMatrix(childrenOnlyTM) * tm;
|
||||
}
|
||||
|
@ -737,7 +730,7 @@ nsSVGUtils::PaintFrameWithEffects(nsIFrame *aFrame,
|
|||
tm, aFrame->PresContext()).
|
||||
ToOutsidePixels(appUnitsPerDevPx);
|
||||
if (!aDirtyRect->Intersects(bounds)) {
|
||||
return DrawResult::SUCCESS;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -763,7 +756,7 @@ nsSVGUtils::PaintFrameWithEffects(nsIFrame *aFrame,
|
|||
nsSVGEffects::GetEffectProperties(aFrame);
|
||||
if (effectProperties.HasInvalidEffects()) {
|
||||
// Some resource is invalid. We shouldn't paint anything.
|
||||
return DrawResult::SUCCESS;
|
||||
return;
|
||||
}
|
||||
|
||||
nsSVGClipPathFrame *clipPathFrame = effectProperties.GetClipPathFrame();
|
||||
|
@ -775,11 +768,9 @@ nsSVGUtils::PaintFrameWithEffects(nsIFrame *aFrame,
|
|||
? blender.CreateBlendTarget(aTransform) : &aContext;
|
||||
|
||||
if (!target) {
|
||||
return DrawResult::TEMPORARY_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
DrawResult result = DrawResult::SUCCESS;
|
||||
|
||||
/* Check if we need to do additional operations on this child's
|
||||
* rendering, which necessitates rendering into another surface. */
|
||||
bool shouldGenerateMask = (maskUsage.opacity != 1.0f ||
|
||||
|
@ -802,13 +793,14 @@ nsSVGUtils::PaintFrameWithEffects(nsIFrame *aFrame,
|
|||
aFrame->StyleSVGReset()->mMask.mLayers[0].mMaskMode;
|
||||
nsSVGMaskFrame::MaskParams params(&aContext, aFrame, aTransform,
|
||||
maskUsage.opacity, &maskTransform,
|
||||
maskMode, aFlags);
|
||||
Tie(result, maskSurface) = maskFrame->GetMaskForMaskedFrame(params);
|
||||
maskMode, aImgParams.imageFlags);
|
||||
Tie(aImgParams.result, maskSurface) =
|
||||
maskFrame->GetMaskForMaskedFrame(params);
|
||||
|
||||
if (!maskSurface) {
|
||||
// Either entire surface is clipped out, or gfx buffer allocation
|
||||
// failure in nsSVGMaskFrame::GetMaskForMaskedFrame.
|
||||
return result;
|
||||
return;
|
||||
}
|
||||
shouldPushMask = true;
|
||||
}
|
||||
|
@ -821,14 +813,14 @@ nsSVGUtils::PaintFrameWithEffects(nsIFrame *aFrame,
|
|||
clipPathFrame->GetClipMask(aContext, aFrame, aTransform,
|
||||
&clippedMaskTransform, maskSurface,
|
||||
maskTransform);
|
||||
result &= clipMaskResult;
|
||||
aImgParams.result &= clipMaskResult;
|
||||
if (clipMaskSurface) {
|
||||
maskSurface = clipMaskSurface;
|
||||
maskTransform = clippedMaskTransform;
|
||||
} else {
|
||||
// Either entire surface is clipped out, or gfx buffer allocation
|
||||
// failure in nsSVGClipPathFrame::GetClipMask.
|
||||
return result;
|
||||
return;
|
||||
}
|
||||
shouldPushMask = true;
|
||||
}
|
||||
|
@ -867,7 +859,7 @@ nsSVGUtils::PaintFrameWithEffects(nsIFrame *aFrame,
|
|||
// it in frame space.
|
||||
gfxMatrix userToDeviceSpace = aTransform;
|
||||
if (userToDeviceSpace.IsSingular()) {
|
||||
return DrawResult::SUCCESS;
|
||||
return;
|
||||
}
|
||||
gfxMatrix deviceToUserSpace = userToDeviceSpace;
|
||||
deviceToUserSpace.Invert();
|
||||
|
@ -881,13 +873,12 @@ nsSVGUtils::PaintFrameWithEffects(nsIFrame *aFrame,
|
|||
dirtyRegion = &tmpDirtyRegion;
|
||||
}
|
||||
|
||||
SVGPaintCallback paintCallback(aFlags);
|
||||
result =
|
||||
nsFilterInstance::PaintFilteredFrame(aFrame, target->GetDrawTarget(),
|
||||
aTransform, &paintCallback,
|
||||
dirtyRegion);
|
||||
SVGPaintCallback paintCallback;
|
||||
nsFilterInstance::PaintFilteredFrame(aFrame, target->GetDrawTarget(),
|
||||
aTransform, &paintCallback,
|
||||
dirtyRegion, aImgParams);
|
||||
} else {
|
||||
result = svgFrame->PaintSVG(*target, aTransform, aDirtyRect, aFlags);
|
||||
svgFrame->PaintSVG(*target, aTransform, aImgParams, aDirtyRect);
|
||||
}
|
||||
|
||||
if (maskUsage.shouldApplyClipPath || maskUsage.shouldApplyBasicShape) {
|
||||
|
@ -902,8 +893,6 @@ nsSVGUtils::PaintFrameWithEffects(nsIFrame *aFrame,
|
|||
MOZ_ASSERT(target != &aContext);
|
||||
blender.BlendToTarget();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1489,16 +1478,16 @@ nsSVGUtils::GetFallbackOrPaintColor(nsStyleContext *aStyleContext,
|
|||
return color;
|
||||
}
|
||||
|
||||
/* static */ DrawResult
|
||||
/* static */ void
|
||||
nsSVGUtils::MakeFillPatternFor(nsIFrame* aFrame,
|
||||
gfxContext* aContext,
|
||||
GeneralPattern* aOutPattern,
|
||||
SVGContextPaint* aContextPaint,
|
||||
uint32_t aFlags)
|
||||
imgDrawingParams& aImgParams,
|
||||
SVGContextPaint* aContextPaint)
|
||||
{
|
||||
const nsStyleSVG* style = aFrame->StyleSVG();
|
||||
if (style->mFill.Type() == eStyleSVGPaintType_None) {
|
||||
return DrawResult::SUCCESS;
|
||||
return;
|
||||
}
|
||||
|
||||
const float opacity = aFrame->StyleEffects()->mOpacity;
|
||||
|
@ -1518,17 +1507,17 @@ nsSVGUtils::MakeFillPatternFor(nsIFrame* aFrame,
|
|||
nsSVGPaintServerFrame *ps =
|
||||
nsSVGEffects::GetPaintServer(aFrame, &nsStyleSVG::mFill,
|
||||
nsSVGEffects::FillProperty());
|
||||
DrawResult result = DrawResult::SUCCESS;
|
||||
|
||||
if (ps) {
|
||||
RefPtr<gfxPattern> pattern;
|
||||
Tie(result, pattern) =
|
||||
Tie(aImgParams.result, pattern) =
|
||||
ps->GetPaintServerPattern(aFrame, dt, aContext->CurrentMatrix(),
|
||||
&nsStyleSVG::mFill, fillOpacity, nullptr,
|
||||
aFlags);
|
||||
aImgParams.imageFlags);
|
||||
if (pattern) {
|
||||
pattern->CacheColorStops(dt);
|
||||
aOutPattern->Init(*pattern->GetPattern(dt));
|
||||
return result;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1536,26 +1525,28 @@ nsSVGUtils::MakeFillPatternFor(nsIFrame* aFrame,
|
|||
RefPtr<gfxPattern> pattern;
|
||||
switch (style->mFill.Type()) {
|
||||
case eStyleSVGPaintType_ContextFill:
|
||||
Tie(result, pattern) =
|
||||
Tie(aImgParams.result, pattern) =
|
||||
aContextPaint->GetFillPattern(dt, fillOpacity,
|
||||
aContext->CurrentMatrix(), aFlags);
|
||||
aContext->CurrentMatrix(),
|
||||
aImgParams.imageFlags);
|
||||
break;
|
||||
case eStyleSVGPaintType_ContextStroke:
|
||||
Tie(result, pattern) =
|
||||
Tie(aImgParams.result, pattern) =
|
||||
aContextPaint->GetStrokePattern(dt, fillOpacity,
|
||||
aContext->CurrentMatrix(), aFlags);
|
||||
aContext->CurrentMatrix(),
|
||||
aImgParams.imageFlags);
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
if (pattern) {
|
||||
aOutPattern->Init(*pattern->GetPattern(dt));
|
||||
return result;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (style->mFill.GetFallbackType() == eStyleSVGFallbackType_None) {
|
||||
return DrawResult::SUCCESS;
|
||||
return;
|
||||
}
|
||||
|
||||
// On failure, use the fallback colour in case we have an
|
||||
|
@ -1565,20 +1556,18 @@ nsSVGUtils::MakeFillPatternFor(nsIFrame* aFrame,
|
|||
&nsStyleSVG::mFill)));
|
||||
color.a *= fillOpacity;
|
||||
aOutPattern->InitColorPattern(ToDeviceColor(color));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* static */ DrawResult
|
||||
/* static */ void
|
||||
nsSVGUtils::MakeStrokePatternFor(nsIFrame* aFrame,
|
||||
gfxContext* aContext,
|
||||
GeneralPattern* aOutPattern,
|
||||
SVGContextPaint* aContextPaint,
|
||||
uint32_t aFlags)
|
||||
imgDrawingParams& aImgParams,
|
||||
SVGContextPaint* aContextPaint)
|
||||
{
|
||||
const nsStyleSVG* style = aFrame->StyleSVG();
|
||||
if (style->mStroke.Type() == eStyleSVGPaintType_None) {
|
||||
return DrawResult::SUCCESS;
|
||||
return;
|
||||
}
|
||||
|
||||
const float opacity = aFrame->StyleEffects()->mOpacity;
|
||||
|
@ -1598,17 +1587,17 @@ nsSVGUtils::MakeStrokePatternFor(nsIFrame* aFrame,
|
|||
nsSVGPaintServerFrame *ps =
|
||||
nsSVGEffects::GetPaintServer(aFrame, &nsStyleSVG::mStroke,
|
||||
nsSVGEffects::StrokeProperty());
|
||||
DrawResult result = DrawResult::SUCCESS;
|
||||
|
||||
if (ps) {
|
||||
RefPtr<gfxPattern> pattern;
|
||||
Tie(result, pattern) =
|
||||
Tie(aImgParams.result, pattern) =
|
||||
ps->GetPaintServerPattern(aFrame, dt, aContext->CurrentMatrix(),
|
||||
&nsStyleSVG::mStroke, strokeOpacity, nullptr,
|
||||
aFlags);
|
||||
aImgParams.imageFlags);
|
||||
if (pattern) {
|
||||
pattern->CacheColorStops(dt);
|
||||
aOutPattern->Init(*pattern->GetPattern(dt));
|
||||
return result;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1616,26 +1605,28 @@ nsSVGUtils::MakeStrokePatternFor(nsIFrame* aFrame,
|
|||
RefPtr<gfxPattern> pattern;
|
||||
switch (style->mStroke.Type()) {
|
||||
case eStyleSVGPaintType_ContextFill:
|
||||
Tie(result, pattern) =
|
||||
Tie(aImgParams.result, pattern) =
|
||||
aContextPaint->GetFillPattern(dt, strokeOpacity,
|
||||
aContext->CurrentMatrix(), aFlags);
|
||||
aContext->CurrentMatrix(),
|
||||
aImgParams.imageFlags);
|
||||
break;
|
||||
case eStyleSVGPaintType_ContextStroke:
|
||||
Tie(result, pattern) =
|
||||
Tie(aImgParams.result, pattern) =
|
||||
aContextPaint->GetStrokePattern(dt, strokeOpacity,
|
||||
aContext->CurrentMatrix(), aFlags);
|
||||
aContext->CurrentMatrix(),
|
||||
aImgParams.imageFlags);
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
if (pattern) {
|
||||
aOutPattern->Init(*pattern->GetPattern(dt));
|
||||
return result;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (style->mStroke.GetFallbackType() == eStyleSVGFallbackType_None) {
|
||||
return DrawResult::SUCCESS;
|
||||
return;
|
||||
}
|
||||
|
||||
// On failure, use the fallback colour in case we have an
|
||||
|
@ -1645,8 +1636,6 @@ nsSVGUtils::MakeStrokePatternFor(nsIFrame* aFrame,
|
|||
&nsStyleSVG::mStroke)));
|
||||
color.a *= strokeOpacity;
|
||||
aOutPattern->InitColorPattern(ToDeviceColor(color));
|
||||
|
||||
return DrawResult::SUCCESS;
|
||||
}
|
||||
|
||||
/* static */ float
|
||||
|
@ -1876,13 +1865,13 @@ nsSVGUtils::GetGeometryHitTestFlags(nsIFrame* aFrame)
|
|||
return flags;
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
nsSVGUtils::PaintSVGGlyph(Element* aElement, gfxContext* aContext)
|
||||
{
|
||||
nsIFrame* frame = aElement->GetPrimaryFrame();
|
||||
nsSVGDisplayableFrame* svgFrame = do_QueryFrame(frame);
|
||||
if (!svgFrame) {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
gfxMatrix m;
|
||||
if (frame->GetContent()->IsSVGElement()) {
|
||||
|
@ -1891,8 +1880,11 @@ nsSVGUtils::PaintSVGGlyph(Element* aElement, gfxContext* aContext)
|
|||
m = static_cast<nsSVGElement*>(frame->GetContent())->
|
||||
PrependLocalTransformsTo(gfxMatrix(), eUserSpaceToParent);
|
||||
}
|
||||
DrawResult result = svgFrame->PaintSVG(*aContext, m);
|
||||
return (result == DrawResult::SUCCESS);
|
||||
|
||||
// SVG-in-OpenType is not allowed to paint exteral resources, so we can
|
||||
// just pass a dummy params into PatintSVG.
|
||||
imgDrawingParams dummy;
|
||||
svgFrame->PaintSVG(*aContext, m, dummy);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -193,6 +193,7 @@ public:
|
|||
typedef mozilla::SVGContextPaintImpl SVGContextPaintImpl;
|
||||
typedef mozilla::SVGGeometryFrame SVGGeometryFrame;
|
||||
typedef mozilla::image::DrawResult DrawResult;
|
||||
typedef mozilla::image::imgDrawingParams imgDrawingParams;
|
||||
|
||||
static void Init();
|
||||
|
||||
|
@ -290,11 +291,11 @@ public:
|
|||
|
||||
/* Paint SVG frame with SVG effects - aDirtyRect is the area being
|
||||
* redrawn, in device pixel coordinates relative to the outer svg */
|
||||
static DrawResult PaintFrameWithEffects(nsIFrame *aFrame,
|
||||
gfxContext& aContext,
|
||||
const gfxMatrix& aTransform,
|
||||
const nsIntRect *aDirtyRect = nullptr,
|
||||
uint32_t aFlags = 0);
|
||||
static void PaintFrameWithEffects(nsIFrame *aFrame,
|
||||
gfxContext& aContext,
|
||||
const gfxMatrix& aTransform,
|
||||
imgDrawingParams& aImgParams,
|
||||
const nsIntRect *aDirtyRect = nullptr);
|
||||
|
||||
/* Hit testing - check if point hits the clipPath of indicated
|
||||
* frame. Returns true if no clipPath set. */
|
||||
|
@ -510,18 +511,19 @@ public:
|
|||
static nscolor GetFallbackOrPaintColor(nsStyleContext *aStyleContext,
|
||||
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke);
|
||||
|
||||
static DrawResult MakeFillPatternFor(nsIFrame *aFrame,
|
||||
gfxContext* aContext,
|
||||
GeneralPattern* aOutPattern,
|
||||
SVGContextPaint* aContextPaint = nullptr,
|
||||
uint32_t aFlags = 0);
|
||||
static void
|
||||
MakeFillPatternFor(nsIFrame *aFrame,
|
||||
gfxContext* aContext,
|
||||
GeneralPattern* aOutPattern,
|
||||
imgDrawingParams& aImgParams,
|
||||
SVGContextPaint* aContextPaint = nullptr);
|
||||
|
||||
static DrawResult
|
||||
static void
|
||||
MakeStrokePatternFor(nsIFrame* aFrame,
|
||||
gfxContext* aContext,
|
||||
GeneralPattern* aOutPattern,
|
||||
SVGContextPaint* aContextPaint = nullptr,
|
||||
uint32_t aFlags = 0);
|
||||
imgDrawingParams& aImgParams,
|
||||
SVGContextPaint* aContextPaint = nullptr);
|
||||
|
||||
static float GetOpacity(nsStyleSVGOpacitySource aOpacityType,
|
||||
const float& aOpacity,
|
||||
|
@ -567,7 +569,7 @@ public:
|
|||
* @param aContext the thebes aContext to draw to
|
||||
* @return true if rendering succeeded
|
||||
*/
|
||||
static bool PaintSVGGlyph(Element* aElement, gfxContext* aContext);
|
||||
static void PaintSVGGlyph(Element* aElement, gfxContext* aContext);
|
||||
|
||||
/**
|
||||
* Get the extents of a SVG glyph.
|
||||
|
|
Загрузка…
Ссылка в новой задаче