зеркало из https://github.com/mozilla/pjs.git
Bug 391295 - "APNG blending mode APNG_BLEND_OP_SOURCE not implemented" [p=asmith15@littlesvr.ca (Andrew Smith) r=stuart a1.9=damons]
This commit is contained in:
Родитель
28afec6ce7
Коммит
3bff19fe58
|
@ -57,7 +57,7 @@ native nsRectRef(nsIntRect &);
|
|||
* @author Stuart Parmenter <pavlov@netscape.com>
|
||||
* @version 0.1
|
||||
*/
|
||||
[scriptable, uuid(2502c898-73bd-4da5-8fae-21cf7a492f64)]
|
||||
[scriptable, uuid(7292afa2-3b94-424d-97d5-51ce2f04c0fe)]
|
||||
interface gfxIImageFrame : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -156,4 +156,8 @@ interface gfxIImageFrame : nsISupports
|
|||
* moment
|
||||
*/
|
||||
attribute long frameDisposalMethod;
|
||||
|
||||
/* PNG specific methods */
|
||||
|
||||
attribute long blendMethod;
|
||||
};
|
||||
|
|
|
@ -46,7 +46,8 @@ gfxImageFrame::gfxImageFrame() :
|
|||
mInitialized(PR_FALSE),
|
||||
mMutable(PR_TRUE),
|
||||
mTimeout(100),
|
||||
mDisposalMethod(0)
|
||||
mDisposalMethod(0), /* imgIContainer::kDisposeNotSpecified */
|
||||
mBlendMethod(1) /* imgIContainer::kBlendOver */
|
||||
{
|
||||
/* member initializers and constructor code */
|
||||
}
|
||||
|
@ -343,6 +344,24 @@ NS_IMETHODIMP gfxImageFrame::SetFrameDisposalMethod(PRInt32 aFrameDisposalMethod
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
/* attribute long blendMethod; */
|
||||
NS_IMETHODIMP gfxImageFrame::GetBlendMethod(PRInt32 *aBlendMethod)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
*aBlendMethod = mBlendMethod;
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP gfxImageFrame::SetBlendMethod(PRInt32 aBlendMethod)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
mBlendMethod = (PRInt8)aBlendMethod;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP gfxImageFrame::GetInterface(const nsIID & aIID, void * *result)
|
||||
{
|
||||
if (!mInitialized)
|
||||
|
|
|
@ -80,4 +80,5 @@ private:
|
|||
PRInt32 mTimeout; // -1 means display forever
|
||||
nsIntPoint mOffset;
|
||||
PRInt32 mDisposalMethod;
|
||||
PRInt8 mBlendMethod;
|
||||
};
|
||||
|
|
|
@ -136,13 +136,13 @@ void nsPNGDecoder::SetAnimFrameInfo()
|
|||
{
|
||||
png_uint_16 delay_num, delay_den; /* in seconds */
|
||||
png_byte dispose_op;
|
||||
png_byte blend_op;
|
||||
PRInt32 timeout; /* in milliseconds */
|
||||
|
||||
delay_num = png_get_next_frame_delay_num(mPNG, mInfo);
|
||||
delay_den = png_get_next_frame_delay_den(mPNG, mInfo);
|
||||
dispose_op = png_get_next_frame_dispose_op(mPNG, mInfo);
|
||||
|
||||
// XXX need to handle blend_op here!
|
||||
blend_op = png_get_next_frame_blend_op(mPNG, mInfo);
|
||||
|
||||
if (delay_num == 0) {
|
||||
timeout = 0; // gfxImageFrame::SetTimeout() will set to a minimum
|
||||
|
@ -163,6 +163,11 @@ void nsPNGDecoder::SetAnimFrameInfo()
|
|||
mFrame->SetFrameDisposalMethod(imgIContainer::kDisposeClear);
|
||||
else
|
||||
mFrame->SetFrameDisposalMethod(imgIContainer::kDisposeKeep);
|
||||
|
||||
if (blend_op == PNG_BLEND_OP_SOURCE)
|
||||
mFrame->SetBlendMethod(imgIContainer::kBlendSource);
|
||||
/*else // 'over' is the default for a gfxImageFrame
|
||||
mFrame->SetBlendMethod(imgIContainer::kBlendOver); */
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -68,6 +68,16 @@ interface imgIContainer : nsISupports
|
|||
const long kDisposeClear = 2; // Clear the frame's area, revealing bg
|
||||
const long kDisposeRestorePrevious = 3; // Restore the previous (composited) frame
|
||||
|
||||
/*
|
||||
* "Blend" method indicates how the current image is combined with the
|
||||
* previous image.
|
||||
*/
|
||||
const long kBlendSource = 0; // All color components of the frame, including alpha,
|
||||
// overwrite the current contents of the frame's
|
||||
// output buffer region
|
||||
const long kBlendOver = 1; // The frame should be composited onto the output buffer
|
||||
// based on its alpha, using a simple OVER operation
|
||||
|
||||
/**
|
||||
* Create a new \a aWidth x \a aHeight sized image container.
|
||||
*
|
||||
|
|
|
@ -943,7 +943,7 @@ nsresult imgContainer::DoComposite(gfxIImageFrame** aFrameToUse,
|
|||
}
|
||||
|
||||
// Check if the frame we are composing wants the previous image restored afer
|
||||
// it is done. Don't store it (again) if last frame wanted it's image restored
|
||||
// it is done. Don't store it (again) if last frame wanted its image restored
|
||||
// too
|
||||
if ((nextFrameDisposalMethod == imgIContainer::kDisposeRestorePrevious) &&
|
||||
(prevFrameDisposalMethod != imgIContainer::kDisposeRestorePrevious)) {
|
||||
|
@ -1089,7 +1089,19 @@ nsresult imgContainer::DrawFrameTo(gfxIImageFrame *aSrc,
|
|||
dstImg->GetSurface(getter_AddRefs(dstSurf));
|
||||
|
||||
gfxContext dst(dstSurf);
|
||||
|
||||
// first clear the surface if the blend flag says so
|
||||
PRInt32 blendMethod;
|
||||
aSrc->GetBlendMethod(&blendMethod);
|
||||
gfxContext::GraphicsOperator defaultOperator = dst.CurrentOperator();
|
||||
if (blendMethod == imgIContainer::kBlendSource) {
|
||||
dst.SetOperator(gfxContext::OPERATOR_CLEAR);
|
||||
dst.Rectangle(gfxRect(aDstRect.x, aDstRect.y, aDstRect.width, aDstRect.height));
|
||||
dst.Fill();
|
||||
}
|
||||
|
||||
dst.NewPath();
|
||||
dst.SetOperator(defaultOperator);
|
||||
// We don't use PixelSnappedRectangleAndSetPattern because if
|
||||
// these coords aren't already pixel aligned, we've lost
|
||||
// before we've even begun.
|
||||
|
|
Загрузка…
Ссылка в новой задаче