diff --git a/image/ClippedImage.cpp b/image/ClippedImage.cpp index 7ee260b4e0bd..87b5b81be41a 100644 --- a/image/ClippedImage.cpp +++ b/image/ClippedImage.cpp @@ -195,6 +195,17 @@ ClippedImage::GetHeight(int32_t* aHeight) { return NS_OK; } +NS_IMETHODIMP +ClippedImage::GetIntrinsicSize(ImageIntrinsicSize* aIntrinsicSize) { + if (!ShouldClip()) { + return InnerImage()->GetIntrinsicSize(aIntrinsicSize); + } + + aIntrinsicSize->mWidth = Some(mClip.Width()); + aIntrinsicSize->mHeight = Some(mClip.Height()); + return NS_OK; +} + NS_IMETHODIMP ClippedImage::GetIntrinsicSizeInAppUnits(nsSize* aSize) { if (!ShouldClip()) { diff --git a/image/ClippedImage.h b/image/ClippedImage.h index 91685f08e13b..95a95ceb578a 100644 --- a/image/ClippedImage.h +++ b/image/ClippedImage.h @@ -35,6 +35,7 @@ class ClippedImage : public ImageWrapper { NS_IMETHOD GetWidth(int32_t* aWidth) override; NS_IMETHOD GetHeight(int32_t* aHeight) override; + NS_IMETHOD GetIntrinsicSize(ImageIntrinsicSize* aIntrinsicSize) override; NS_IMETHOD GetIntrinsicSizeInAppUnits(nsSize* aSize) override; AspectRatio GetIntrinsicRatio() override; NS_IMETHOD_(already_AddRefed) diff --git a/image/DynamicImage.cpp b/image/DynamicImage.cpp index 4cfaba373916..dbcec0e0feca 100644 --- a/image/DynamicImage.cpp +++ b/image/DynamicImage.cpp @@ -97,6 +97,15 @@ nsresult DynamicImage::GetNativeSizes(nsTArray&) { size_t DynamicImage::GetNativeSizesLength() { return 0; } +NS_IMETHODIMP +DynamicImage::GetIntrinsicSize(ImageIntrinsicSize* aIntrinsicSize) { + IntSize intSize(mDrawable->Size()); + aIntrinsicSize->mWidth = Some(intSize.width); + aIntrinsicSize->mHeight = Some(intSize.height); + + return NS_OK; +} + NS_IMETHODIMP DynamicImage::GetIntrinsicSizeInAppUnits(nsSize* aSize) { // XXXdholbert This probably needs to be scaled; see bug 1965106. diff --git a/image/ImageWrapper.cpp b/image/ImageWrapper.cpp index 5b6909f54e14..1a4e7bd2f276 100644 --- a/image/ImageWrapper.cpp +++ b/image/ImageWrapper.cpp @@ -114,6 +114,11 @@ size_t ImageWrapper::GetNativeSizesLength() { return mInnerImage->GetNativeSizesLength(); } +NS_IMETHODIMP +ImageWrapper::GetIntrinsicSize(ImageIntrinsicSize* aIntrinsicSize) { + return mInnerImage->GetIntrinsicSize(aIntrinsicSize); +} + NS_IMETHODIMP ImageWrapper::GetIntrinsicSizeInAppUnits(nsSize* aSize) { return mInnerImage->GetIntrinsicSizeInAppUnits(aSize); diff --git a/image/RasterImage.cpp b/image/RasterImage.cpp index 04ecd06bcdae..2c1ec02abba0 100644 --- a/image/RasterImage.cpp +++ b/image/RasterImage.cpp @@ -207,6 +207,20 @@ RasterImage::GetHeight(int32_t* aHeight) { return NS_OK; } +//****************************************************************************** +NS_IMETHODIMP +RasterImage::GetIntrinsicSize(ImageIntrinsicSize* aIntrinsicSize) { + NS_ENSURE_ARG_POINTER(aIntrinsicSize); + + if (mError) { + return NS_ERROR_FAILURE; + } + + aIntrinsicSize->mWidth = Some(mSize.width); + aIntrinsicSize->mHeight = Some(mSize.height); + return NS_OK; +} + //****************************************************************************** void RasterImage::MediaFeatureValuesChangedAllDocuments( const mozilla::MediaFeatureChange& aChange) {} diff --git a/image/VectorImage.cpp b/image/VectorImage.cpp index cba2dd41c6ff..ca8303a5b455 100644 --- a/image/VectorImage.cpp +++ b/image/VectorImage.cpp @@ -447,6 +447,7 @@ static Maybe ClampedPxLengthOrNothing( // imgIContainer methods //****************************************************************************** + NS_IMETHODIMP VectorImage::GetWidth(int32_t* aWidth) { if (mError || !mIsFullyLoaded) { @@ -507,6 +508,25 @@ VectorImage::GetHeight(int32_t* aHeight) { return NS_OK; } +//****************************************************************************** +NS_IMETHODIMP +VectorImage::GetIntrinsicSize(ImageIntrinsicSize* aIntrinsicSize) { + if (mError || !mIsFullyLoaded) { + return NS_ERROR_FAILURE; + } + SVGSVGElement* rootElem = mSVGDocumentWrapper->GetRootSVGElem(); + if (MOZ_UNLIKELY(!rootElem)) { + return NS_ERROR_FAILURE; + } + + aIntrinsicSize->mWidth = + ClampedPxLengthOrNothing(rootElem->GetIntrinsicWidth()); + aIntrinsicSize->mHeight = + ClampedPxLengthOrNothing(rootElem->GetIntrinsicHeight()); + + return NS_OK; +} + //****************************************************************************** NS_IMETHODIMP VectorImage::GetIntrinsicSizeInAppUnits(nsSize* aSize) { diff --git a/image/imgIContainer.idl b/image/imgIContainer.idl index 43ff00771a91..e1fcd72ea72d 100644 --- a/image/imgIContainer.idl +++ b/image/imgIContainer.idl @@ -43,12 +43,34 @@ class ImageIntRegion; class WebRenderImageProvider; struct Orientation; struct Resolution; + +/** + * This represents an image's intrinsic size, in units of pixels (the same + * units as our 'width' and 'height' attributes). Both components are + * optional, because an image (particularly a vector image) may lack an + * intrinsic width and/or height. + * + * We use signed types for the components, but the values are expected to be + * nonnegative; any negative values should be considered an error. (Zero is + * valid, though.) + * + * Note that this is similar to a gfx::IntSize, except for the use of Maybe<> + * to reflect that the components are optional. This is also similar to + * nsIFrame.h's mozilla::IntrinsicSize class, with the difference being pixel + * units here vs. nscoord units there. + */ +struct ImageIntrinsicSize { + Maybe mWidth; + Maybe mHeight; +}; + } } %} native AspectRatio(mozilla::AspectRatio); +native ImageIntrinsicSize(mozilla::image::ImageIntrinsicSize); native ImgDrawResult(mozilla::image::ImgDrawResult); [ptr] native gfxContext(gfxContext); [ref] native gfxMatrix(gfxMatrix); @@ -98,6 +120,20 @@ interface imgIContainer : nsISupports */ readonly attribute int32_t height; + /** + * The intrinsic size of this image in pixels. The values and units here are + * the same as those that the 'width' and 'height' attributes (declared + * above) would return. + * + * If an image lacks an intrinsic width and/or height, then that component + * will be Nothing() in the returned value. (This is different from the + * 'width' and 'height' attributes; they treat this case as an error, for + * historical reasons, but we can handle it more elegantly here.) + * + * In case of any error, an exception will be thrown. + */ + [noscript] readonly attribute ImageIntrinsicSize intrinsicSize; + /** * The intrinsic size of this image in appunits. If the image has no intrinsic * size in a dimension, -1 will be returned for that dimension. In the case of