зеркало из https://github.com/mozilla/gecko-dev.git
Convert imgContainerGIF to use nsCOMArray instead of nsSupportsArray. Bug 224621, r=darin, sr=tor.
This commit is contained in:
Родитель
5252fca867
Коммит
602eb22f1c
|
@ -32,6 +32,7 @@ FORCE_STATIC_LIB = 1
|
|||
MODULE_NAME = nsGIFModule2
|
||||
|
||||
REQUIRES = xpcom \
|
||||
string \
|
||||
gfx \
|
||||
imglib2 \
|
||||
$(NULL)
|
||||
|
|
|
@ -55,9 +55,6 @@ imgContainerGIF::~imgContainerGIF()
|
|||
{
|
||||
if (mTimer)
|
||||
mTimer->Cancel();
|
||||
|
||||
/* destructor code */
|
||||
mFrames.Clear();
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
|
@ -106,14 +103,19 @@ NS_IMETHODIMP imgContainerGIF::GetHeight(nscoord *aHeight)
|
|||
/* readonly attribute gfxIImageFrame currentFrame; */
|
||||
NS_IMETHODIMP imgContainerGIF::GetCurrentFrame(gfxIImageFrame * *aCurrentFrame)
|
||||
{
|
||||
return inlinedGetCurrentFrame(aCurrentFrame);
|
||||
if (!(*aCurrentFrame = inlinedGetCurrentFrame()))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
NS_ADDREF(*aCurrentFrame);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
/* readonly attribute unsigned long numFrames; */
|
||||
NS_IMETHODIMP imgContainerGIF::GetNumFrames(PRUint32 *aNumFrames)
|
||||
{
|
||||
return mFrames.Count(aNumFrames);
|
||||
*aNumFrames = mFrames.Count();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
|
@ -121,7 +123,11 @@ NS_IMETHODIMP imgContainerGIF::GetNumFrames(PRUint32 *aNumFrames)
|
|||
NS_IMETHODIMP imgContainerGIF::GetFrameAt(PRUint32 index,
|
||||
gfxIImageFrame **_retval)
|
||||
{
|
||||
return inlinedGetFrameAt(index, _retval);
|
||||
if (!(*_retval = mFrames[index]))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
NS_ADDREF(*_retval);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
|
@ -132,7 +138,7 @@ NS_IMETHODIMP imgContainerGIF::AppendFrame(gfxIImageFrame *item)
|
|||
if (!item)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
PRUint32 numFrames = inlinedGetNumFrames();
|
||||
PRInt32 numFrames = mFrames.Count();
|
||||
if (numFrames == 0) {
|
||||
// First Frame
|
||||
// If we dispose of the first frame by clearing it, then the
|
||||
|
@ -152,7 +158,7 @@ NS_IMETHODIMP imgContainerGIF::AppendFrame(gfxIImageFrame *item)
|
|||
mFirstFrameRefreshArea.UnionRect(mFirstFrameRefreshArea, itemRect);
|
||||
}
|
||||
|
||||
mFrames.AppendElement(NS_STATIC_CAST(nsISupports*, item));
|
||||
mFrames.AppendObject(item);
|
||||
|
||||
// If this is our second frame, start the animation.
|
||||
// Must be called after AppendElement because StartAnimation checks for > 1
|
||||
|
@ -188,19 +194,16 @@ NS_IMETHODIMP imgContainerGIF::DecodingComplete(void)
|
|||
mDoneDecoding = PR_TRUE;
|
||||
// If there's only 1 frame, optimize it.
|
||||
// Optimizing animated gifs is not supported
|
||||
PRUint32 numFrames = inlinedGetNumFrames();
|
||||
if (numFrames == 1) {
|
||||
nsCOMPtr<gfxIImageFrame> currentFrame;
|
||||
inlinedGetFrameAt(0, getter_AddRefs(currentFrame));
|
||||
currentFrame->SetMutable(PR_FALSE);
|
||||
}
|
||||
if (mFrames.Count() == 1)
|
||||
mFrames[0]->SetMutable(PR_FALSE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void clear (); */
|
||||
NS_IMETHODIMP imgContainerGIF::Clear()
|
||||
{
|
||||
return mFrames.Clear();
|
||||
mFrames.Clear();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
|
@ -243,12 +246,9 @@ NS_IMETHODIMP imgContainerGIF::StartAnimation()
|
|||
if (mAnimationMode == kDontAnimMode || mAnimating || mTimer)
|
||||
return NS_OK;
|
||||
|
||||
PRUint32 numFrames = inlinedGetNumFrames();
|
||||
if (numFrames > 1) {
|
||||
if (mFrames.Count() > 1) {
|
||||
PRInt32 timeout;
|
||||
nsCOMPtr<gfxIImageFrame> currentFrame;
|
||||
|
||||
inlinedGetCurrentFrame(getter_AddRefs(currentFrame));
|
||||
gfxIImageFrame *currentFrame = inlinedGetCurrentFrame();
|
||||
if (currentFrame) {
|
||||
currentFrame->GetTimeout(&timeout);
|
||||
if (timeout <= 0) // -1 means display this frame forever
|
||||
|
@ -304,11 +304,8 @@ NS_IMETHODIMP imgContainerGIF::ResetAnimation()
|
|||
mCurrentAnimationFrameIndex = 0;
|
||||
// Update display
|
||||
nsCOMPtr<imgIContainerObserver> observer(do_QueryReferent(mObserver));
|
||||
if (observer) {
|
||||
nsCOMPtr<gfxIImageFrame> firstFrame;
|
||||
inlinedGetFrameAt(0, getter_AddRefs(firstFrame));
|
||||
observer->FrameChanged(this, firstFrame, &mFirstFrameRefreshArea);
|
||||
}
|
||||
if (observer)
|
||||
observer->FrameChanged(this, mFrames[0], &mFirstFrameRefreshArea);
|
||||
|
||||
if (oldAnimating)
|
||||
return StartAnimation();
|
||||
|
@ -353,11 +350,11 @@ NS_IMETHODIMP imgContainerGIF::Notify(nsITimer *timer)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
PRInt32 numFrames = inlinedGetNumFrames();
|
||||
PRInt32 numFrames = mFrames.Count();
|
||||
if (!numFrames)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<gfxIImageFrame> nextFrame;
|
||||
gfxIImageFrame *nextFrame = nsnull;
|
||||
PRInt32 previousFrameIndex = mCurrentAnimationFrameIndex;
|
||||
PRInt32 nextFrameIndex = mCurrentAnimationFrameIndex + 1;
|
||||
PRInt32 timeout = 0;
|
||||
|
@ -384,8 +381,7 @@ NS_IMETHODIMP imgContainerGIF::Notify(nsITimer *timer)
|
|||
mLoopCount--;
|
||||
}
|
||||
|
||||
if (NS_FAILED(inlinedGetFrameAt(nextFrameIndex,
|
||||
getter_AddRefs(nextFrame)))) {
|
||||
if (!(nextFrame = mFrames[nextFrameIndex])) {
|
||||
// something wrong with the next frame, skip it
|
||||
mCurrentAnimationFrameIndex = nextFrameIndex;
|
||||
mTimer->SetDelay(100);
|
||||
|
@ -403,8 +399,7 @@ NS_IMETHODIMP imgContainerGIF::Notify(nsITimer *timer)
|
|||
// that hasn't been decoded yet, go back to the last frame decoded
|
||||
NS_WARNING("imgContainerGIF::Notify() Frame is passed decoded frame");
|
||||
nextFrameIndex = mCurrentDecodingFrameIndex;
|
||||
if (NS_FAILED(inlinedGetFrameAt(nextFrameIndex,
|
||||
getter_AddRefs(nextFrame)))) {
|
||||
if (!(nextFrame = mFrames[nextFrameIndex])) {
|
||||
// something wrong with the next frame, skip it
|
||||
mCurrentAnimationFrameIndex = nextFrameIndex;
|
||||
mTimer->SetDelay(100);
|
||||
|
@ -419,20 +414,19 @@ NS_IMETHODIMP imgContainerGIF::Notify(nsITimer *timer)
|
|||
StopAnimation();
|
||||
|
||||
nsRect dirtyRect;
|
||||
nsCOMPtr<gfxIImageFrame> frameToUse;
|
||||
gfxIImageFrame *frameToUse = nsnull;
|
||||
|
||||
if (nextFrameIndex == 0) {
|
||||
frameToUse = nextFrame;
|
||||
dirtyRect = mFirstFrameRefreshArea;
|
||||
} else {
|
||||
nsCOMPtr<gfxIImageFrame> prevFrame;
|
||||
if (NS_FAILED(inlinedGetFrameAt(previousFrameIndex,
|
||||
getter_AddRefs(prevFrame))))
|
||||
gfxIImageFrame *prevFrame = mFrames[previousFrameIndex];
|
||||
if (!prevFrame)
|
||||
return NS_OK;
|
||||
|
||||
// Change frame and announce it
|
||||
if (NS_FAILED(DoComposite(getter_AddRefs(frameToUse), &dirtyRect,
|
||||
prevFrame, nextFrame, nextFrameIndex))) {
|
||||
if (NS_FAILED(DoComposite(&frameToUse, &dirtyRect, prevFrame,
|
||||
nextFrame, nextFrameIndex))) {
|
||||
// something went wrong, move on to next
|
||||
NS_WARNING("imgContainerGIF: Composing Frame Failed\n");
|
||||
mCurrentAnimationFrameIndex = nextFrameIndex;
|
||||
|
@ -449,11 +443,11 @@ NS_IMETHODIMP imgContainerGIF::Notify(nsITimer *timer)
|
|||
//******************************************************************************
|
||||
// DoComposite gets called when the timer for animation get fired and we have to
|
||||
// update the composited frame of the animation.
|
||||
NS_IMETHODIMP imgContainerGIF::DoComposite(gfxIImageFrame** aFrameToUse,
|
||||
nsRect* aDirtyRect,
|
||||
gfxIImageFrame* aPrevFrame,
|
||||
gfxIImageFrame* aNextFrame,
|
||||
PRInt32 aNextFrameIndex)
|
||||
nsresult imgContainerGIF::DoComposite(gfxIImageFrame** aFrameToUse,
|
||||
nsRect* aDirtyRect,
|
||||
gfxIImageFrame* aPrevFrame,
|
||||
gfxIImageFrame* aNextFrame,
|
||||
PRInt32 aNextFrameIndex)
|
||||
{
|
||||
NS_ASSERTION(aDirtyRect, "imgContainerGIF::DoComposite aDirtyRect is null");
|
||||
NS_ASSERTION(aPrevFrame, "imgContainerGIF::DoComposite aPrevFrame is null");
|
||||
|
@ -472,7 +466,6 @@ NS_IMETHODIMP imgContainerGIF::DoComposite(gfxIImageFrame** aFrameToUse,
|
|||
if (prevFrameDisposalMethod == DISPOSE_CLEAR_ALL) {
|
||||
aDirtyRect->SetRect(0, 0, mSize.width, mSize.height);
|
||||
*aFrameToUse = aNextFrame;
|
||||
NS_ADDREF(*aFrameToUse);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -487,7 +480,6 @@ NS_IMETHODIMP imgContainerGIF::DoComposite(gfxIImageFrame** aFrameToUse,
|
|||
if (isFullPrevFrame && prevFrameDisposalMethod == DISPOSE_CLEAR) {
|
||||
aDirtyRect->SetRect(0, 0, mSize.width, mSize.height);
|
||||
*aFrameToUse = aNextFrame;
|
||||
NS_ADDREF(*aFrameToUse);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -511,7 +503,6 @@ NS_IMETHODIMP imgContainerGIF::DoComposite(gfxIImageFrame** aFrameToUse,
|
|||
|
||||
aDirtyRect->SetRect(0, 0, mSize.width, mSize.height);
|
||||
*aFrameToUse = aNextFrame;
|
||||
NS_ADDREF(*aFrameToUse);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -547,7 +538,6 @@ NS_IMETHODIMP imgContainerGIF::DoComposite(gfxIImageFrame** aFrameToUse,
|
|||
// since it's still sitting in mCompositingFrame)
|
||||
if (mLastCompositedFrameIndex == aNextFrameIndex) {
|
||||
*aFrameToUse = mCompositingFrame;
|
||||
NS_ADDREF(*aFrameToUse);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -670,14 +660,12 @@ NS_IMETHODIMP imgContainerGIF::DoComposite(gfxIImageFrame** aFrameToUse,
|
|||
aPrevFrame->SetFrameDisposalMethod(DISPOSE_CLEAR_ALL);
|
||||
mLastCompositedFrameIndex = -1;
|
||||
*aFrameToUse = aNextFrame;
|
||||
NS_ADDREF(*aFrameToUse);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
mLastCompositedFrameIndex = aNextFrameIndex;
|
||||
*aFrameToUse = mCompositingFrame;
|
||||
NS_ADDREF(*aFrameToUse);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
#include "imgIContainerObserver.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "nsSupportsArray.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsITimer.h"
|
||||
#include "imgIDecoderObserver.h"
|
||||
|
@ -130,27 +130,11 @@ private:
|
|||
DISPOSE_RESTORE_PREVIOUS = 3 //!< Restore the previous (composited) frame
|
||||
};
|
||||
|
||||
inline PRUint32 inlinedGetNumFrames() {
|
||||
PRUint32 nframes;
|
||||
mFrames.Count(&nframes);
|
||||
return nframes;
|
||||
}
|
||||
inline gfxIImageFrame* inlinedGetCurrentFrame() {
|
||||
if (mLastCompositedFrameIndex == mCurrentAnimationFrameIndex)
|
||||
return mCompositingFrame;
|
||||
|
||||
inline nsresult inlinedGetFrameAt(PRUint32 index, gfxIImageFrame **_retval) {
|
||||
// callers DO try to go past the end
|
||||
nsISupports *_elem = mFrames.ElementAt(index);
|
||||
if (!_elem) return NS_ERROR_FAILURE;
|
||||
*_retval = NS_STATIC_CAST(gfxIImageFrame*, _elem);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
inline nsresult inlinedGetCurrentFrame(gfxIImageFrame **_retval) {
|
||||
if (mLastCompositedFrameIndex == mCurrentAnimationFrameIndex) {
|
||||
*_retval = mCompositingFrame;
|
||||
NS_ADDREF(*_retval);
|
||||
return NS_OK;
|
||||
}
|
||||
return inlinedGetFrameAt(mCurrentAnimationFrameIndex, _retval);
|
||||
return mFrames[mCurrentAnimationFrameIndex];
|
||||
}
|
||||
|
||||
/** Function for doing the frame compositing of animations
|
||||
|
@ -162,10 +146,10 @@ private:
|
|||
* @param aNextFrame Frame we need to incorperate/display
|
||||
* @param aNextFrameIndex Position of aNextFrame in mFrames list
|
||||
*/
|
||||
NS_IMETHODIMP DoComposite(gfxIImageFrame** aFrameToUse, nsRect* aDirtyRect,
|
||||
gfxIImageFrame* aPrevFrame,
|
||||
gfxIImageFrame* aNextFrame,
|
||||
PRInt32 aNextFrameIndex);
|
||||
nsresult DoComposite(gfxIImageFrame** aFrameToUse, nsRect* aDirtyRect,
|
||||
gfxIImageFrame* aPrevFrame,
|
||||
gfxIImageFrame* aNextFrame,
|
||||
PRInt32 aNextFrameIndex);
|
||||
|
||||
/**
|
||||
* Combine aOverlayFrame's mask into aCompositingFrame's mask.
|
||||
|
@ -221,33 +205,33 @@ private:
|
|||
|
||||
|
||||
//! imgIContainerObserver; used for telling observers that the frame changed
|
||||
nsWeakPtr mObserver;
|
||||
nsWeakPtr mObserver;
|
||||
//! All the <gfxIImageFrame>s of the GIF
|
||||
nsSupportsArray mFrames;
|
||||
nsCOMArray<gfxIImageFrame> mFrames;
|
||||
|
||||
//! Size of GIF (not necessarily the frame)
|
||||
nsSize mSize;
|
||||
nsSize mSize;
|
||||
//! Area of the first frame that needs to be redrawn on subsequent loops
|
||||
nsRect mFirstFrameRefreshArea;
|
||||
nsRect mFirstFrameRefreshArea;
|
||||
|
||||
PRInt32 mCurrentDecodingFrameIndex; // 0 to numFrames-1
|
||||
PRInt32 mCurrentAnimationFrameIndex; // 0 to numFrames-1
|
||||
PRInt32 mCurrentDecodingFrameIndex; // 0 to numFrames-1
|
||||
PRInt32 mCurrentAnimationFrameIndex; // 0 to numFrames-1
|
||||
//! Track the last composited frame for Optimizations (See DoComposite code)
|
||||
PRInt32 mLastCompositedFrameIndex;
|
||||
PRInt32 mLastCompositedFrameIndex;
|
||||
//! Whether we can assume there will be no more frames
|
||||
//! (and thus loop the animation)
|
||||
PRBool mDoneDecoding;
|
||||
PRBool mDoneDecoding;
|
||||
|
||||
|
||||
//! Are we currently animating the GIF?
|
||||
PRBool mAnimating;
|
||||
PRBool mAnimating;
|
||||
//! See imgIContainer for mode constants
|
||||
PRUint16 mAnimationMode;
|
||||
PRUint16 mAnimationMode;
|
||||
//! # loops remaining before animation stops (-1 no stop)
|
||||
PRInt32 mLoopCount;
|
||||
PRInt32 mLoopCount;
|
||||
|
||||
//! Timer to animate multiframed images
|
||||
nsCOMPtr<nsITimer> mTimer;
|
||||
nsCOMPtr<nsITimer> mTimer;
|
||||
|
||||
/** For managing blending of frames
|
||||
*
|
||||
|
@ -257,7 +241,7 @@ private:
|
|||
* mLastCompositedFrameIndex to -1. Code assume that if
|
||||
* mLastCompositedFrameIndex >= 0 then mCompositingFrame exists.
|
||||
*/
|
||||
nsCOMPtr<gfxIImageFrame> mCompositingFrame;
|
||||
nsCOMPtr<gfxIImageFrame> mCompositingFrame;
|
||||
|
||||
/** the previous composited frame, for DISPOSE_RESTORE_PREVIOUS
|
||||
*
|
||||
|
@ -265,7 +249,7 @@ private:
|
|||
* stored in cases where the GIF specifies it wants the last frame back
|
||||
* when it's done with the current frame.
|
||||
*/
|
||||
nsCOMPtr<gfxIImageFrame> mCompositingPrevFrame;
|
||||
nsCOMPtr<gfxIImageFrame> mCompositingPrevFrame;
|
||||
};
|
||||
|
||||
#endif /* __imgContainerGIF_h__ */
|
||||
|
|
Загрузка…
Ссылка в новой задаче