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:
Daniel Holbert 2010-09-08 13:40:39 -07:00
Родитель d6860f7116
Коммит f9a2dd705a
6 изменённых файлов: 106 добавлений и 12 удалений

Просмотреть файл

@ -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);