зеркало из https://github.com/mozilla/gecko-dev.git
Bug 276431 Patch 10: Make imgContainer::Draw take image-viewport-size, and improve nsLayoutUtils drawing wrappers. r=roc r=joe a=blocking
This commit is contained in:
Родитель
d6860f7116
Коммит
f9a2dd705a
|
@ -3714,11 +3714,18 @@ ImageRenderer::ComputeSize(const nsSize& aDefault)
|
|||
case eStyleImageType_Image:
|
||||
{
|
||||
nsIntSize imageIntSize;
|
||||
mImageContainer->GetWidth(&imageIntSize.width);
|
||||
mImageContainer->GetHeight(&imageIntSize.height);
|
||||
PRBool gotHeight, gotWidth;
|
||||
nsLayoutUtils::ComputeSizeForDrawing(mImageContainer, imageIntSize,
|
||||
gotWidth, gotHeight);
|
||||
|
||||
mSize.width = gotWidth ?
|
||||
nsPresContext::CSSPixelsToAppUnits(imageIntSize.width) :
|
||||
aDefault.width;
|
||||
|
||||
mSize.height = gotHeight ?
|
||||
nsPresContext::CSSPixelsToAppUnits(imageIntSize.height) :
|
||||
aDefault.height;
|
||||
|
||||
mSize.width = nsPresContext::CSSPixelsToAppUnits(imageIntSize.width);
|
||||
mSize.height = nsPresContext::CSSPixelsToAppUnits(imageIntSize.height);
|
||||
break;
|
||||
}
|
||||
case eStyleImageType_Gradient:
|
||||
|
|
|
@ -3043,7 +3043,8 @@ DrawImageInternal(nsIRenderingContext* aRenderingContext,
|
|||
}
|
||||
|
||||
aImage->Draw(ctx, aGraphicsFilter, drawingParams.mUserSpaceToImageSpace,
|
||||
drawingParams.mFillRect, drawingParams.mSubimage, aImageFlags);
|
||||
drawingParams.mFillRect, drawingParams.mSubimage, aImageSize,
|
||||
aImageFlags);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -3134,8 +3135,13 @@ nsLayoutUtils::DrawSingleImage(nsIRenderingContext* aRenderingContext,
|
|||
const nsRect* aSourceArea)
|
||||
{
|
||||
nsIntSize imageSize;
|
||||
aImage->GetWidth(&imageSize.width);
|
||||
aImage->GetHeight(&imageSize.height);
|
||||
if (aImage->GetType() == imgIContainer::TYPE_VECTOR) {
|
||||
imageSize.width = nsPresContext::AppUnitsToIntCSSPixels(aDest.width);
|
||||
imageSize.height = nsPresContext::AppUnitsToIntCSSPixels(aDest.height);
|
||||
} else {
|
||||
aImage->GetWidth(&imageSize.width);
|
||||
aImage->GetHeight(&imageSize.height);
|
||||
}
|
||||
NS_ENSURE_TRUE(imageSize.width > 0 && imageSize.height > 0, NS_ERROR_FAILURE);
|
||||
|
||||
nsRect source;
|
||||
|
@ -3158,6 +3164,49 @@ nsLayoutUtils::DrawSingleImage(nsIRenderingContext* aRenderingContext,
|
|||
fill.TopLeft(), aDirty, imageSize, aImageFlags);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsLayoutUtils::ComputeSizeForDrawing(imgIContainer *aImage,
|
||||
nsIntSize& aImageSize, /*outparam*/
|
||||
PRBool& aGotWidth, /*outparam*/
|
||||
PRBool& aGotHeight /*outparam*/)
|
||||
{
|
||||
aGotWidth = NS_SUCCEEDED(aImage->GetWidth(&aImageSize.width));
|
||||
aGotHeight = NS_SUCCEEDED(aImage->GetHeight(&aImageSize.height));
|
||||
|
||||
if ((aGotWidth && aGotHeight) || // Trivial success!
|
||||
(!aGotWidth && !aGotHeight)) { // Trivial failure!
|
||||
return;
|
||||
}
|
||||
|
||||
// If we get here, we succeeded at querying *either* the width *or* the
|
||||
// height, but not both.
|
||||
NS_ASSERTION(aImage->GetType() == imgIContainer::TYPE_VECTOR,
|
||||
"GetWidth and GetHeight should only fail for vector images");
|
||||
|
||||
nsIFrame* rootFrame = aImage->GetRootLayoutFrame();
|
||||
NS_ASSERTION(rootFrame,
|
||||
"We should have a VectorImage, which should have a rootFrame");
|
||||
|
||||
// This falls back on failure, if we somehow end up without a rootFrame.
|
||||
nsSize ratio = rootFrame ? rootFrame->GetIntrinsicRatio() : nsSize(0,0);
|
||||
if (!aGotWidth) { // Have height, missing width
|
||||
if (ratio.height != 0) { // don't divide by zero
|
||||
aImageSize.width = NSToCoordRound(aImageSize.height *
|
||||
float(ratio.width) /
|
||||
float(ratio.height));
|
||||
aGotWidth = PR_TRUE;
|
||||
}
|
||||
} else { // Have width, missing height
|
||||
if (ratio.width != 0) { // don't divide by zero
|
||||
aImageSize.height = NSToCoordRound(aImageSize.width *
|
||||
float(ratio.height) /
|
||||
float(ratio.width));
|
||||
aGotHeight = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* static */ nsresult
|
||||
nsLayoutUtils::DrawImage(nsIRenderingContext* aRenderingContext,
|
||||
imgIContainer* aImage,
|
||||
|
@ -3169,9 +3218,16 @@ nsLayoutUtils::DrawImage(nsIRenderingContext* aRenderingContext,
|
|||
PRUint32 aImageFlags)
|
||||
{
|
||||
nsIntSize imageSize;
|
||||
aImage->GetWidth(&imageSize.width);
|
||||
aImage->GetHeight(&imageSize.height);
|
||||
NS_ENSURE_TRUE(imageSize.width > 0 && imageSize.height > 0, NS_ERROR_FAILURE);
|
||||
PRBool gotHeight, gotWidth;
|
||||
ComputeSizeForDrawing(aImage, imageSize, gotWidth, gotHeight);
|
||||
|
||||
// fallback size based on aFill.
|
||||
if (!gotWidth) {
|
||||
imageSize.width = nsPresContext::AppUnitsToIntCSSPixels(aFill.width);
|
||||
}
|
||||
if (!gotHeight) {
|
||||
imageSize.height = nsPresContext::AppUnitsToIntCSSPixels(aFill.height);
|
||||
}
|
||||
|
||||
return DrawImageInternal(aRenderingContext, aImage, aGraphicsFilter,
|
||||
aDest, aFill, aAnchor, aDirty,
|
||||
|
|
|
@ -1016,6 +1016,25 @@ public:
|
|||
PRUint32 aImageFlags,
|
||||
const nsRect* aSourceArea = nsnull);
|
||||
|
||||
/**
|
||||
* Given an imgIContainer, this method attempts to obtain an intrinsic
|
||||
* px-valued height & width for it. If the imgIContainer has a non-pixel
|
||||
* value for either height or width, this method tries to generate a pixel
|
||||
* value for that dimension using the intrinsic ratio (if available).
|
||||
*
|
||||
* This method will always set aGotWidth and aGotHeight to indicate whether
|
||||
* we were able to successfully obtain (or compute) a value for each
|
||||
* dimension.
|
||||
*
|
||||
* NOTE: This method is similar to ComputeSizeWithIntrinsicDimensions. The
|
||||
* difference is that this one is simpler and is suited to places where we
|
||||
* have less information about the frame tree.
|
||||
*/
|
||||
static void ComputeSizeForDrawing(imgIContainer* aImage,
|
||||
nsIntSize& aImageSize,
|
||||
PRBool& aGotWidth,
|
||||
PRBool& aGotHeight);
|
||||
|
||||
/**
|
||||
* Given a source area of an image (in appunits) and a destination area
|
||||
* that we want to map that source area too, computes the area that
|
||||
|
|
|
@ -52,6 +52,7 @@ interface imgIDecoderObserver;
|
|||
#include "gfxPattern.h"
|
||||
#include "gfxASurface.h"
|
||||
#include "nsRect.h"
|
||||
#include "nsSize.h"
|
||||
#include "limits.h"
|
||||
|
||||
class nsIFrame;
|
||||
|
@ -76,6 +77,7 @@ native gfxImageFormat(gfxASurface::gfxImageFormat);
|
|||
[ref] native gfxRect(gfxRect);
|
||||
native gfxGraphicsFilter(gfxPattern::GraphicsFilter);
|
||||
[ref] native nsIntRect(nsIntRect);
|
||||
[ref] native nsIntSize(nsIntSize);
|
||||
[ptr] native nsIFrame(nsIFrame);
|
||||
|
||||
/**
|
||||
|
@ -86,7 +88,7 @@ native gfxGraphicsFilter(gfxPattern::GraphicsFilter);
|
|||
*
|
||||
* Internally, imgIContainer also manages animation of images.
|
||||
*/
|
||||
[scriptable, uuid(8bb94fa2-f57a-482c-bef8-e0b0424b0b3c)]
|
||||
[scriptable, uuid(239dfa70-2285-4d63-99cd-e9b7ff9555c7)]
|
||||
interface imgIContainer : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -205,6 +207,13 @@ interface imgIContainer : nsISupports
|
|||
* automatically tiled as necessary.
|
||||
* @param aSubimage The area of the image, in pixels, that we are allowed to
|
||||
* sample from.
|
||||
* @param aViewportSize
|
||||
* The size (in CSS pixels) of the viewport that would be available
|
||||
* for the full image to occupy, if we were drawing the full image.
|
||||
* (Note that we might not actually be drawing the full image -- we
|
||||
* might be restricted by aSubimage -- but we still need the full
|
||||
* image's viewport-size in order for SVG images with the "viewBox"
|
||||
* attribute to position their content correctly.)
|
||||
* @param aFlags Flags of the FLAG_* variety
|
||||
*/
|
||||
[noscript] void draw(in gfxContext aContext,
|
||||
|
@ -212,6 +221,7 @@ interface imgIContainer : nsISupports
|
|||
[const] in gfxMatrix aUserSpaceToImageSpace,
|
||||
[const] in gfxRect aFill,
|
||||
[const] in nsIntRect aSubimage,
|
||||
[const] in nsIntSize aViewportSize,
|
||||
in PRUint32 aFlags);
|
||||
|
||||
/**
|
||||
|
|
|
@ -2425,6 +2425,7 @@ RasterImage::SyncDecode()
|
|||
* [const] in gfxMatrix aUserSpaceToImageSpace,
|
||||
* [const] in gfxRect aFill,
|
||||
* [const] in nsIntRect aSubimage,
|
||||
* [const] in nsIntSize aViewportSize,
|
||||
* in PRUint32 aFlags); */
|
||||
NS_IMETHODIMP
|
||||
RasterImage::Draw(gfxContext *aContext,
|
||||
|
@ -2432,6 +2433,7 @@ RasterImage::Draw(gfxContext *aContext,
|
|||
const gfxMatrix &aUserSpaceToImageSpace,
|
||||
const gfxRect &aFill,
|
||||
const nsIntRect &aSubimage,
|
||||
const nsIntSize& /*aViewportSize - ignored*/,
|
||||
PRUint32 aFlags)
|
||||
{
|
||||
if (mError)
|
||||
|
|
|
@ -628,7 +628,7 @@ 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,
|
||||
imgIContainer::FLAG_SYNC_DECODE);
|
||||
destSize, imgIContainer::FLAG_SYNC_DECODE);
|
||||
return NS_OK;
|
||||
} else {
|
||||
return aCanvas->RenderContextsExternal(ctx, gfxPattern::FILTER_GOOD);
|
||||
|
|
Загрузка…
Ссылка в новой задаче