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:
cku 2017-05-05 17:19:43 +08:00
Родитель fedf7f24d9
Коммит eaa4406688
37 изменённых файлов: 359 добавлений и 387 удалений

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

@ -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.