Bug 1034345 (Part 4) - Implement OptimalImageSizeForDest for other image types. r=tn

--HG--
extra : rebase_source : 3237d5ec3e196ec674d9ab0e67b65b867f458251
This commit is contained in:
Seth Fowler 2014-07-28 14:27:40 -07:00
Родитель f0f537417b
Коммит e40db04549
6 изменённых файлов: 80 добавлений и 0 удалений

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

@ -3,6 +3,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <cmath>
#include "gfxDrawable.h"
#include "gfxPlatform.h"
#include "gfxUtils.h"
@ -19,6 +21,7 @@ namespace mozilla {
using namespace gfx;
using layers::LayerManager;
using layers::ImageContainer;
using std::modf;
namespace image {
@ -424,6 +427,44 @@ ClippedImage::GetOrientation()
return InnerImage()->GetOrientation();
}
nsIntSize
ClippedImage::OptimalImageSizeForDest(const gfxSize& aDest, uint32_t aWhichFrame,
GraphicsFilter aFilter, uint32_t aFlags)
{
if (!ShouldClip()) {
return InnerImage()->OptimalImageSizeForDest(aDest, aWhichFrame, aFilter, aFlags);
}
int32_t imgWidth, imgHeight;
if (NS_SUCCEEDED(InnerImage()->GetWidth(&imgWidth)) &&
NS_SUCCEEDED(InnerImage()->GetHeight(&imgHeight))) {
// To avoid ugly sampling artifacts, ClippedImage needs the image size to
// be chosen such that the clipping region lies on pixel boundaries.
// First, we select a scale that's good for ClippedImage. An integer multiple
// of the size of the clipping region is always fine.
nsIntSize scale(ceil(aDest.width / mClip.width),
ceil(aDest.height / mClip.height));
// Determine the size we'd prefer to render the inner image at, and ask the
// inner image what size we should actually use.
gfxSize desiredSize(imgWidth * scale.width, imgHeight * scale.height);
nsIntSize innerDesiredSize =
InnerImage()->OptimalImageSizeForDest(desiredSize, aWhichFrame,
aFilter, aFlags);
// To get our final result, we take the inner image's desired size and
// determine how large the clipped region would be at that scale. (Again, we
// ensure an integer multiple of the size of the clipping region.)
nsIntSize finalScale(ceil(double(innerDesiredSize.width) / imgWidth),
ceil(double(innerDesiredSize.height) / imgHeight));
return mClip.Size() * finalScale;
} else {
MOZ_ASSERT(false, "If ShouldClip() led us to draw then we should never get here");
return InnerImage()->OptimalImageSizeForDest(aDest, aWhichFrame, aFilter, aFlags);
}
}
NS_IMETHODIMP_(nsIntRect)
ClippedImage::GetImageSpaceInvalidationRect(const nsIntRect& aRect)
{

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

@ -53,6 +53,10 @@ public:
NS_IMETHOD RequestDiscard() MOZ_OVERRIDE;
NS_IMETHOD_(Orientation) GetOrientation() MOZ_OVERRIDE;
NS_IMETHOD_(nsIntRect) GetImageSpaceInvalidationRect(const nsIntRect& aRect) MOZ_OVERRIDE;
nsIntSize OptimalImageSizeForDest(const gfxSize& aDest,
uint32_t aWhichFrame,
GraphicsFilter aFilter,
uint32_t aFlags) MOZ_OVERRIDE;
protected:
ClippedImage(Image* aImage, nsIntRect aClip);

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

@ -338,6 +338,13 @@ NS_IMETHODIMP_(void)
DynamicImage::SetAnimationStartTime(const mozilla::TimeStamp& aTime)
{ }
nsIntSize
DynamicImage::OptimalImageSizeForDest(const gfxSize& aDest, uint32_t aWhichFrame, GraphicsFilter aFilter, uint32_t aFlags)
{
gfxIntSize size(mDrawable->Size());
return nsIntSize(size.width, size.height);
}
NS_IMETHODIMP_(nsIntRect)
DynamicImage::GetImageSpaceInvalidationRect(const nsIntRect& aRect)
{

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

@ -318,6 +318,13 @@ ImageWrapper::SetAnimationStartTime(const TimeStamp& aTime)
mInnerImage->SetAnimationStartTime(aTime);
}
nsIntSize
ImageWrapper::OptimalImageSizeForDest(const gfxSize& aDest, uint32_t aWhichFrame,
GraphicsFilter aFilter, uint32_t aFlags)
{
return mInnerImage->OptimalImageSizeForDest(aDest, aWhichFrame, aFilter, aFlags);
}
NS_IMETHODIMP_(nsIntRect)
ImageWrapper::GetImageSpaceInvalidationRect(const nsIntRect& aRect)
{

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

@ -251,6 +251,23 @@ OrientedImage::Draw(gfxContext* aContext,
aWhichFrame, aFlags);
}
nsIntSize
OrientedImage::OptimalImageSizeForDest(const gfxSize& aDest, uint32_t aWhichFrame,
GraphicsFilter aFilter, uint32_t aFlags)
{
if (!mOrientation.SwapsWidthAndHeight()) {
return InnerImage()->OptimalImageSizeForDest(aDest, aWhichFrame, aFilter, aFlags);
}
// Swap the size for the calculation, then swap it back for the caller.
gfxSize destSize(aDest.height, aDest.width);
nsIntSize innerImageSize(InnerImage()->OptimalImageSizeForDest(destSize,
aWhichFrame,
aFilter,
aFlags));
return nsIntSize(innerImageSize.height, innerImageSize.width);
}
NS_IMETHODIMP_(nsIntRect)
OrientedImage::GetImageSpaceInvalidationRect(const nsIntRect& aRect)
{

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

@ -48,6 +48,10 @@ public:
uint32_t aWhichFrame,
uint32_t aFlags) MOZ_OVERRIDE;
NS_IMETHOD_(nsIntRect) GetImageSpaceInvalidationRect(const nsIntRect& aRect) MOZ_OVERRIDE;
nsIntSize OptimalImageSizeForDest(const gfxSize& aDest,
uint32_t aWhichFrame,
GraphicsFilter aFilter,
uint32_t aFlags) MOZ_OVERRIDE;
protected:
OrientedImage(Image* aImage, Orientation aOrientation)