VectorImage::Draw(gfxContext* aContext, const nsIntSize& aSize, const ImageRegion& aRegion, uint32_t aWhichFrame, Filter aFilter, const Maybe<SVGImageContext>& aSVGContext, uint32_t aFlags) { if (aWhichFrame > FRAME_MAX_VALUE) { return DrawResult::BAD_ARGS; } if (!aContext) { return DrawResult::BAD_ARGS; } if (mError) { return DrawResult::BAD_IMAGE; } if (!mIsFullyLoaded) { return DrawResult::NOT_READY; } if (mIsDrawing) { NS_WARNING("Refusing to make re-entrant call to VectorImage::Draw"); return DrawResult::TEMPORARY_ERROR; } if (mAnimationConsumers == 0 && mProgressTracker) { mProgressTracker->OnUnlockedDraw(); } AutoRestore<bool> autoRestoreIsDrawing(mIsDrawing); mIsDrawing = true; Maybe<SVGImageContext> svgContext; // If FLAG_FORCE_PRESERVEASPECTRATIO_NONE bit is set, that mean we should // overwrite SVG preserveAspectRatio attibute of this image with none, and // always stretch this image to viewport non-uniformly. // And we can do this only if the caller pass in the the SVG viewport, via // aSVGContext. if ((aFlags & FLAG_FORCE_PRESERVEASPECTRATIO_NONE) && aSVGContext.isSome()) { Maybe<SVGPreserveAspectRatio> aspectRatio = Some(SVGPreserveAspectRatio(SVG_PRESERVEASPECTRATIO_NONE, SVG_MEETORSLICE_UNKNOWN)); svgContext = Some(SVGImageContext(aSVGContext->GetViewportSize(), aspectRatio)); } else { svgContext = aSVGContext; } float animTime = (aWhichFrame == FRAME_FIRST) ? 0.0f : mSVGDocumentWrapper->GetCurrentTime(); AutoSVGRenderingState autoSVGState(svgContext, animTime, mSVGDocumentWrapper->GetRootSVGElem()); SVGDrawingParameters params(aContext, aSize, aRegion, aFilter, svgContext, animTime, aFlags); if (aFlags & FLAG_BYPASS_SURFACE_CACHE) { CreateSurfaceAndShow(params); return DrawResult::SUCCESS; } LookupResult result = SurfaceCache::Lookup(ImageKey(this), VectorSurfaceKey(params.size, params.svgContext, params.animationTime)); // Draw. if (result) { RefPtr<SourceSurface> surface = result.DrawableRef()->GetSurface(); if (surface) { RefPtr<gfxDrawable> svgDrawable = new gfxSurfaceDrawable(surface, result.DrawableRef()->GetSize()); Show(svgDrawable, params); return DrawResult::SUCCESS; } // We lost our surface due to some catastrophic event. RecoverFromLossOfSurfaces(); } CreateSurfaceAndShow(params); return DrawResult::SUCCESS; }
VectorImage::Draw(gfxContext* aContext, const nsIntSize& aSize, const ImageRegion& aRegion, uint32_t aWhichFrame, GraphicsFilter aFilter, const Maybe<SVGImageContext>& aSVGContext, uint32_t aFlags) { if (aWhichFrame > FRAME_MAX_VALUE) { return DrawResult::BAD_ARGS; } if (!aContext) { return DrawResult::BAD_ARGS; } if (mError) { return DrawResult::BAD_IMAGE; } if (!mIsFullyLoaded) { return DrawResult::NOT_READY; } if (mIsDrawing) { NS_WARNING("Refusing to make re-entrant call to VectorImage::Draw"); return DrawResult::TEMPORARY_ERROR; } if (mAnimationConsumers == 0 && mProgressTracker) { mProgressTracker->OnUnlockedDraw(); } AutoRestore<bool> autoRestoreIsDrawing(mIsDrawing); mIsDrawing = true; float animTime = (aWhichFrame == FRAME_FIRST) ? 0.0f : mSVGDocumentWrapper->GetCurrentTime(); AutoSVGRenderingState autoSVGState(aSVGContext, animTime, mSVGDocumentWrapper->GetRootSVGElem()); // Pack up the drawing parameters. SVGDrawingParameters params(aContext, aSize, aRegion, aFilter, aSVGContext, animTime, aFlags); if (aFlags & FLAG_BYPASS_SURFACE_CACHE) { CreateSurfaceAndShow(params); return DrawResult::SUCCESS; } DrawableFrameRef frameRef = SurfaceCache::Lookup(ImageKey(this), VectorSurfaceKey(params.size, params.svgContext, params.animationTime)); // Draw. if (frameRef) { RefPtr<SourceSurface> surface = frameRef->GetSurface(); if (surface) { nsRefPtr<gfxDrawable> svgDrawable = new gfxSurfaceDrawable(surface, frameRef->GetSize()); Show(svgDrawable, params); return DrawResult::SUCCESS; } // We lost our surface due to some catastrophic event. RecoverFromLossOfSurfaces(); } CreateSurfaceAndShow(params); return DrawResult::SUCCESS; }
VectorImage::Draw(gfxContext* aContext, const nsIntSize& aSize, const ImageRegion& aRegion, uint32_t aWhichFrame, SamplingFilter aSamplingFilter, const Maybe<SVGImageContext>& aSVGContext, uint32_t aFlags) { if (aWhichFrame > FRAME_MAX_VALUE) { return DrawResult::BAD_ARGS; } if (!aContext) { return DrawResult::BAD_ARGS; } if (mError) { return DrawResult::BAD_IMAGE; } if (!mIsFullyLoaded) { return DrawResult::NOT_READY; } if (mIsDrawing) { NS_WARNING("Refusing to make re-entrant call to VectorImage::Draw"); return DrawResult::TEMPORARY_ERROR; } if (mAnimationConsumers == 0 && mProgressTracker) { mProgressTracker->OnUnlockedDraw(); } AutoRestore<bool> autoRestoreIsDrawing(mIsDrawing); mIsDrawing = true; Maybe<SVGImageContext> svgContext; // If FLAG_FORCE_PRESERVEASPECTRATIO_NONE bit is set, that mean we should // overwrite SVG preserveAspectRatio attibute of this image with none, and // always stretch this image to viewport non-uniformly. // And we can do this only if the caller pass in the the SVG viewport, via // aSVGContext. if ((aFlags & FLAG_FORCE_PRESERVEASPECTRATIO_NONE) && aSVGContext.isSome()) { Maybe<SVGPreserveAspectRatio> aspectRatio = Some(SVGPreserveAspectRatio(SVG_PRESERVEASPECTRATIO_NONE, SVG_MEETORSLICE_UNKNOWN)); svgContext = Some(SVGImageContext(aSVGContext->GetViewportSize(), aspectRatio)); } else { svgContext = aSVGContext; } float animTime = (aWhichFrame == FRAME_FIRST) ? 0.0f : mSVGDocumentWrapper->GetCurrentTime(); AutoSVGRenderingState autoSVGState(svgContext, animTime, mSVGDocumentWrapper->GetRootSVGElem()); SVGDrawingParameters params(aContext, aSize, aRegion, aSamplingFilter, svgContext, animTime, aFlags); // If we have an prerasterized version of this image that matches the // drawing parameters, use that. RefPtr<gfxDrawable> svgDrawable = LookupCachedSurface(params); if (svgDrawable) { Show(svgDrawable, params); return DrawResult::SUCCESS; } // We didn't get a hit in the surface cache, so we'll need to rerasterize. CreateSurfaceAndShow(params); return DrawResult::SUCCESS; }
VectorImage::Draw(gfxContext* aContext, const nsIntSize& aSize, const ImageRegion& aRegion, uint32_t aWhichFrame, SamplingFilter aSamplingFilter, const Maybe<SVGImageContext>& aSVGContext, uint32_t aFlags, float aOpacity) { if (aWhichFrame > FRAME_MAX_VALUE) { return DrawResult::BAD_ARGS; } if (!aContext) { return DrawResult::BAD_ARGS; } if (mError) { return DrawResult::BAD_IMAGE; } if (!mIsFullyLoaded) { return DrawResult::NOT_READY; } if (mAnimationConsumers == 0) { SendOnUnlockedDraw(aFlags); } MOZ_ASSERT(!(aFlags & FLAG_FORCE_PRESERVEASPECTRATIO_NONE) || (aSVGContext && aSVGContext->GetViewportSize()), "Viewport size is required when using " "FLAG_FORCE_PRESERVEASPECTRATIO_NONE"); bool overridePAR = (aFlags & FLAG_FORCE_PRESERVEASPECTRATIO_NONE) && aSVGContext; bool haveContextPaint = aSVGContext && aSVGContext->GetContextPaint(); bool blockContextPaint = false; if (haveContextPaint) { nsCOMPtr<nsIURI> imageURI = mURI->ToIURI(); blockContextPaint = !SVGContextPaint::IsAllowedForImageFromURI(imageURI); } Maybe<SVGImageContext> newSVGContext; if (overridePAR || blockContextPaint) { // The key that we create for the image surface cache must match the way // that the image will be painted, so we need to initialize a new matching // SVGImageContext here in order to generate the correct key. newSVGContext = aSVGContext; // copy if (overridePAR) { // The SVGImageContext must take account of the preserveAspectRatio // overide: MOZ_ASSERT(!aSVGContext->GetPreserveAspectRatio(), "FLAG_FORCE_PRESERVEASPECTRATIO_NONE is not expected if a " "preserveAspectRatio override is supplied"); Maybe<SVGPreserveAspectRatio> aspectRatio = Some(SVGPreserveAspectRatio(SVG_PRESERVEASPECTRATIO_NONE, SVG_MEETORSLICE_UNKNOWN)); newSVGContext->SetPreserveAspectRatio(aspectRatio); } if (blockContextPaint) { // The SVGImageContext must not include context paint if the image is // not allowed to use it: newSVGContext->ClearContextPaint(); } } float animTime = (aWhichFrame == FRAME_FIRST) ? 0.0f : mSVGDocumentWrapper->GetCurrentTime(); SVGDrawingParameters params(aContext, aSize, aRegion, aSamplingFilter, newSVGContext ? newSVGContext : aSVGContext, animTime, aFlags, aOpacity); // If we have an prerasterized version of this image that matches the // drawing parameters, use that. RefPtr<gfxDrawable> svgDrawable = LookupCachedSurface(params); if (svgDrawable) { Show(svgDrawable, params); return DrawResult::SUCCESS; } // else, we need to paint the image: if (mIsDrawing) { NS_WARNING("Refusing to make re-entrant call to VectorImage::Draw"); return DrawResult::TEMPORARY_ERROR; } AutoRestore<bool> autoRestoreIsDrawing(mIsDrawing); mIsDrawing = true; // Apply any 'preserveAspectRatio' override (if specified) to the root // element: AutoPreserveAspectRatioOverride autoPAR(newSVGContext ? newSVGContext : aSVGContext, mSVGDocumentWrapper->GetRootSVGElem()); // Set the animation time: AutoSVGTimeSetRestore autoSVGTime(mSVGDocumentWrapper->GetRootSVGElem(), animTime); // Set context paint (if specified) on the document: Maybe<AutoSetRestoreSVGContextPaint> autoContextPaint; if (haveContextPaint && !blockContextPaint) { autoContextPaint.emplace(aSVGContext->GetContextPaint(), mSVGDocumentWrapper->GetDocument()); } // We didn't get a hit in the surface cache, so we'll need to rerasterize. CreateSurfaceAndShow(params, aContext->GetDrawTarget()->GetBackendType()); return DrawResult::SUCCESS; }