Bug 843895 (Part 1) - Add an aWhichFrame parameter to imgIContainer::Draw. r=joe

This commit is contained in:
Seth Fowler 2013-03-10 18:43:37 -07:00
parent 2f67cab8ff
commit ed3494d327
8 changed files with 50 additions and 11 deletions

View File

@ -398,6 +398,7 @@ class NS_STACK_CLASS AutoSVGRenderingState
{
public:
AutoSVGRenderingState(const SVGImageContext* aSVGContext,
float aFrameTime,
dom::SVGSVGElement* aRootElem
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: mHaveOverrides(!!aSVGContext)
@ -412,10 +413,14 @@ public:
mRootElem->SetImageOverridePreserveAspectRatio(
aSVGContext->GetPreserveAspectRatio());
}
mOriginalTime = mRootElem->GetCurrentTime();
mRootElem->SetCurrentTime(aFrameTime); // Does nothing if there's no change.
}
~AutoSVGRenderingState()
{
mRootElem->SetCurrentTime(mOriginalTime);
if (mHaveOverrides) {
mRootElem->ClearImageOverridePreserveAspectRatio();
}
@ -423,6 +428,7 @@ public:
private:
const bool mHaveOverrides;
float mOriginalTime;
const nsRefPtr<dom::SVGSVGElement> mRootElem;
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
};

View File

@ -192,7 +192,7 @@ interface imgIContainer : nsISupports
in uint32_t aFlags);
/**
* Draw the current frame on to the context specified.
* Draw a frame onto the context specified.
*
* @param aContext The Thebes context to draw the image to.
* @param aFilter The filter to be used if we're scaling the image.
@ -214,6 +214,7 @@ interface imgIContainer : nsISupports
* @param aSVGContext If non-null, SVG-related rendering context such as
* overridden attributes on the image document's root <svg>
* node. Ignored for raster images.
* @param aWhichFrame Frame specifier of the FRAME_* variety.
* @param aFlags Flags of the FLAG_* variety
*/
[noscript] void draw(in gfxContext aContext,
@ -223,6 +224,7 @@ interface imgIContainer : nsISupports
[const] in nsIntRect aSubimage,
[const] in nsIntSize aViewportSize,
[const] in SVGImageContext aSVGContext,
in uint32_t aWhichFrame,
in uint32_t aFlags);
/*

View File

@ -3061,6 +3061,7 @@ RasterImage::DrawWithPreDownscaleIfNeeded(imgFrame *aFrame,
* [const] in nsIntRect aSubimage,
* [const] in nsIntSize aViewportSize,
* [const] in SVGImageContext aSVGContext,
* in uint32_t aWhichFrame,
* in uint32_t aFlags); */
NS_IMETHODIMP
RasterImage::Draw(gfxContext *aContext,
@ -3070,8 +3071,12 @@ RasterImage::Draw(gfxContext *aContext,
const nsIntRect &aSubimage,
const nsIntSize& /*aViewportSize - ignored*/,
const SVGImageContext* /*aSVGContext - ignored*/,
uint32_t aWhichFrame,
uint32_t aFlags)
{
if (aWhichFrame > FRAME_MAX_VALUE)
return NS_ERROR_INVALID_ARG;
if (mError)
return NS_ERROR_FAILURE;
@ -3130,7 +3135,9 @@ RasterImage::Draw(gfxContext *aContext,
NS_ENSURE_SUCCESS(rv, rv);
}
imgFrame *frame = GetCurrentDrawableImgFrame();
uint32_t frameIndex = aWhichFrame == FRAME_FIRST ? 0
: GetCurrentImgFrameIndex();
imgFrame *frame = GetDrawableImgFrame(frameIndex);
if (!frame) {
return NS_OK; // Getting the frame (above) touches the image and kicks off decoding
}

View File

@ -203,6 +203,22 @@ SVGDocumentWrapper::ResetAnimation()
svgElem->SetCurrentTime(0.0f);
}
float
SVGDocumentWrapper::GetCurrentTime()
{
SVGSVGElement* svgElem = GetRootSVGElem();
return svgElem ? svgElem->GetCurrentTime()
: 0.0f;
}
void
SVGDocumentWrapper::SetCurrentTime(float aTime)
{
SVGSVGElement* svgElem = GetRootSVGElem();
if (svgElem && svgElem->GetCurrentTime() != aTime) {
svgElem->SetCurrentTime(aTime);
}
}
/** nsIStreamListener methods **/

View File

@ -135,6 +135,8 @@ public:
void StartAnimation();
void StopAnimation();
void ResetAnimation();
float GetCurrentTime();
void SetCurrentTime(float aTime);
/**
* Force a layout flush of the underlying SVG document.

View File

@ -560,9 +560,7 @@ VectorImage::GetFrame(uint32_t aWhichFrame,
gfxASurface** _retval)
{
NS_ENSURE_ARG_POINTER(_retval);
// XXXdholbert NOTE: Currently assuming FRAME_CURRENT for simplicity.
// Could handle FRAME_FIRST by saving helper-doc current time, seeking
// to time 0, rendering, and then seeking to saved time.
if (aWhichFrame > FRAME_MAX_VALUE)
return NS_ERROR_INVALID_ARG;
@ -603,11 +601,10 @@ VectorImage::GetFrame(uint32_t aWhichFrame,
gfxRect(gfxPoint(0,0), gfxIntSize(imageIntSize.width,
imageIntSize.height)),
nsIntRect(nsIntPoint(0,0), imageIntSize),
imageIntSize, nullptr, aFlags);
if (NS_SUCCEEDED(rv)) {
*_retval = surface.forget().get();
}
imageIntSize, nullptr, aWhichFrame, aFlags);
NS_ENSURE_SUCCESS(rv, rv);
*_retval = surface.forget().get();
return rv;
}
@ -677,6 +674,7 @@ VectorImage::ExtractFrame(uint32_t aWhichFrame,
* [const] in nsIntRect aSubimage,
* [const] in nsIntSize aViewportSize,
* [const] in SVGImageContext aSVGContext,
* in uint32_t aWhichFrame,
* in uint32_t aFlags); */
NS_IMETHODIMP
VectorImage::Draw(gfxContext* aContext,
@ -686,8 +684,12 @@ VectorImage::Draw(gfxContext* aContext,
const nsIntRect& aSubimage,
const nsIntSize& aViewportSize,
const SVGImageContext* aSVGContext,
uint32_t aWhichFrame,
uint32_t aFlags)
{
if (aWhichFrame > FRAME_MAX_VALUE)
return NS_ERROR_INVALID_ARG;
NS_ENSURE_ARG_POINTER(aContext);
if (mError || !mIsFullyLoaded)
return NS_ERROR_FAILURE;
@ -699,7 +701,10 @@ VectorImage::Draw(gfxContext* aContext,
AutoRestore<bool> autoRestoreIsDrawing(mIsDrawing);
mIsDrawing = true;
float time = aWhichFrame == FRAME_FIRST ? 0.0f
: mSVGDocumentWrapper->GetCurrentTime();
AutoSVGRenderingState autoSVGState(aSVGContext,
time,
mSVGDocumentWrapper->GetRootSVGElem());
mSVGDocumentWrapper->UpdateViewportBounds(aViewportSize);
mSVGDocumentWrapper->FlushImageTransformInvalidation();

View File

@ -4005,7 +4005,7 @@ DrawImageInternal(nsRenderingContext* aRenderingContext,
aImage->Draw(ctx, aGraphicsFilter, drawingParams.mUserSpaceToImageSpace,
drawingParams.mFillRect, drawingParams.mSubimage, aImageSize,
aSVGContext, aImageFlags);
aSVGContext, imgIContainer::FRAME_CURRENT, aImageFlags);
return NS_OK;
}

View File

@ -639,7 +639,8 @@ nsBaseDragService::DrawDragForImage(nsPresContext* aPresContext,
gfxMatrix().Scale(srcSize.width/outRect.Width(), srcSize.height/outRect.Height());
nsIntRect imgSize(0, 0, srcSize.width, srcSize.height);
imgContainer->Draw(ctx, gfxPattern::FILTER_GOOD, scale, outRect, imgSize,
destSize, nullptr, imgIContainer::FLAG_SYNC_DECODE);
destSize, nullptr, imgIContainer::FRAME_CURRENT,
imgIContainer::FLAG_SYNC_DECODE);
return NS_OK;
} else {
return aCanvas->RenderContextsExternal(ctx, gfxPattern::FILTER_GOOD);