From 006e5cca66aaf6c72628d1556e3348495e929f14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Tue, 11 Feb 2020 20:56:20 +0000 Subject: [PATCH] Bug 1614198 - Use cbindgen instead of nsStyleImage. r=aosmond The trickier part is that we represent -moz-image-rect as a Rect() type instead of image with non-null clip-rect. So we need to add a bit of code to distinguish "image request types" from other types of images. But it's not too annoying, and we need to do the same for fancier images like image-set and such whenever we implement it, so seems nice to get rid of most explicit usages of nsStyleImage::GetType(). Differential Revision: https://phabricator.services.mozilla.com/D62164 --HG-- extra : moz-landing-system : lando --- image/ImgDrawResult.h | 4 +- layout/generic/nsCanvasFrame.cpp | 2 +- layout/generic/nsColumnSetFrame.cpp | 2 +- layout/generic/nsFloatManager.cpp | 10 +- layout/generic/nsFrame.cpp | 24 +- layout/generic/nsIFrame.h | 4 +- layout/generic/nsImageFrame.cpp | 6 +- layout/painting/nsCSSRendering.cpp | 29 +- layout/painting/nsCSSRendering.h | 2 +- layout/painting/nsCSSRenderingBorders.cpp | 5 +- layout/painting/nsDisplayList.cpp | 20 +- layout/painting/nsImageRenderer.cpp | 271 ++++++------- layout/painting/nsImageRenderer.h | 14 +- layout/style/GeckoBindings.cpp | 44 +- layout/style/GeckoBindings.h | 15 - layout/style/ServoBindings.toml | 1 + layout/style/ServoStyleConstsInlines.h | 42 ++ layout/style/nsComputedDOMStyle.cpp | 9 +- layout/style/nsComputedDOMStyle.h | 1 - layout/style/nsStyleStruct.cpp | 381 ++++++------------ layout/style/nsStyleStruct.h | 168 +------- layout/style/nsStyleStructInlines.h | 2 +- layout/svg/SVGObserverUtils.cpp | 28 +- servo/components/style/gecko/conversions.rs | 89 +--- .../components/style/properties/gecko.mako.rs | 45 +-- servo/ports/geckolib/cbindgen.toml | 55 ++- 26 files changed, 433 insertions(+), 840 deletions(-) diff --git a/image/ImgDrawResult.h b/image/ImgDrawResult.h index 169ceb51b35f..ca508d22aa66 100644 --- a/image/ImgDrawResult.h +++ b/image/ImgDrawResult.h @@ -26,8 +26,8 @@ namespace image { * SUCCESS_NOT_COMPLETE: The image was drawn successfully and completely, but * it hasn't notified about the sync-decode yet. This can only happen when * layout pokes at the internal image state beforehand via - * nsStyleImage::StartDecoding. This should probably go away eventually, - * somehow, see bug 1471583. + * StyleImage::StartDecoding. This should probably go away eventually, somehow, + * see bug 1471583. * * INCOMPLETE: We successfully drew a frame that was partially decoded. (Note * that successfully drawing a partially decoded frame may not actually draw any diff --git a/layout/generic/nsCanvasFrame.cpp b/layout/generic/nsCanvasFrame.cpp index da0d20ab7c81..e99c8c3251d5 100644 --- a/layout/generic/nsCanvasFrame.cpp +++ b/layout/generic/nsCanvasFrame.cpp @@ -519,7 +519,7 @@ void nsCanvasFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, // Create separate items for each background layer. const nsStyleImageLayers& layers = bg->StyleBackground()->mImage; NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT(i, layers) { - if (layers.mLayers[i].mImage.IsEmpty()) { + if (layers.mLayers[i].mImage.IsNone()) { continue; } if (layers.mLayers[i].mBlendMode != NS_STYLE_BLEND_NORMAL) { diff --git a/layout/generic/nsColumnSetFrame.cpp b/layout/generic/nsColumnSetFrame.cpp index fd1ebb33ac21..a4103f89dce9 100644 --- a/layout/generic/nsColumnSetFrame.cpp +++ b/layout/generic/nsColumnSetFrame.cpp @@ -237,7 +237,7 @@ void nsColumnSetFrame::CreateBorderRenderers( // Assert that we're not drawing a border-image here; if we were, we // couldn't ignore the ImgDrawResult that PaintBorderWithStyleBorder // returns. - MOZ_ASSERT(border.mBorderImageSource.GetType() == eStyleImageType_Null); + MOZ_ASSERT(border.mBorderImageSource.IsNone()); gfx::DrawTarget* dt = aCtx ? aCtx->GetDrawTarget() : nullptr; bool borderIsEmpty = false; diff --git a/layout/generic/nsFloatManager.cpp b/layout/generic/nsFloatManager.cpp index e4dd325bbdc2..945a2602705b 100644 --- a/layout/generic/nsFloatManager.cpp +++ b/layout/generic/nsFloatManager.cpp @@ -569,7 +569,7 @@ class nsFloatManager::ShapeInfo { WritingMode aWM, const nsSize& aContainerSize); - static UniquePtr CreateImageShape(const nsStyleImage& aShapeImage, + static UniquePtr CreateImageShape(const StyleImage& aShapeImage, float aShapeImageThreshold, nscoord aShapeMargin, nsIFrame* const aFrame, @@ -2665,7 +2665,7 @@ nsFloatManager::ShapeInfo::CreatePolygon(const StyleBasicShape& aBasicShape, } /* static */ UniquePtr -nsFloatManager::ShapeInfo::CreateImageShape(const nsStyleImage& aShapeImage, +nsFloatManager::ShapeInfo::CreateImageShape(const StyleImage& aShapeImage, float aShapeImageThreshold, nscoord aShapeMargin, nsIFrame* const aFrame, @@ -2682,10 +2682,8 @@ nsFloatManager::ShapeInfo::CreateImageShape(const nsStyleImage& aShapeImage, if (!imageRenderer.PrepareImage()) { // The image is not ready yet. Boost its loading priority since it will // affect layout. - if (aShapeImage.GetType() == eStyleImageType_Image) { - if (imgRequestProxy* req = aShapeImage.GetImageData()) { - req->BoostPriority(imgIRequest::CATEGORY_SIZE_QUERY); - } + if (imgRequestProxy* req = aShapeImage.GetImageRequest()) { + req->BoostPriority(imgIRequest::CATEGORY_SIZE_QUERY); } return nullptr; } diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index fc0c0123f9be..f03ce400f03e 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -923,8 +923,8 @@ static void CompareLayers( const nsStyleImageLayers* aSecondLayers, const std::function& aCallback) { NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT(i, (*aFirstLayers)) { - const nsStyleImage& image = aFirstLayers->mLayers[i].mImage; - if (image.GetType() != eStyleImageType_Image || !image.IsResolved()) { + const auto& image = aFirstLayers->mLayers[i].mImage; + if (!image.IsImageRequestType() || !image.IsResolved()) { continue; } @@ -932,8 +932,8 @@ static void CompareLayers( // be different with the corresponded one in aSecondLayers if (!aSecondLayers || i >= aSecondLayers->mImageCount || (!aSecondLayers->mLayers[i].mImage.IsResolved() || - !image.ImageDataEquals(aSecondLayers->mLayers[i].mImage))) { - if (imgRequestProxy* req = image.GetImageData()) { + image.GetImageRequest() != aSecondLayers->mLayers[i].mImage.GetImageRequest())) { + if (imgRequestProxy* req = image.GetImageRequest()) { aCallback(req); } } @@ -5523,12 +5523,8 @@ nsIFrame::ContentOffsets nsFrame::CalcContentOffsetsFromFramePoint( return OffsetsForSingleFrame(this, aPoint); } -bool nsIFrame::AssociateImage(const nsStyleImage& aImage) { - if (aImage.GetType() != eStyleImageType_Image) { - return false; - } - - imgRequestProxy* req = aImage.GetImageData(); +bool nsIFrame::AssociateImage(const StyleImage& aImage) { + imgRequestProxy* req = aImage.GetImageRequest(); if (!req) { return false; } @@ -5540,12 +5536,8 @@ bool nsIFrame::AssociateImage(const nsStyleImage& aImage) { return true; } -void nsIFrame::DisassociateImage(const nsStyleImage& aImage) { - if (aImage.GetType() != eStyleImageType_Image) { - return; - } - - imgRequestProxy* req = aImage.GetImageData(); +void nsIFrame::DisassociateImage(const StyleImage& aImage) { + imgRequestProxy* req = aImage.GetImageRequest(); if (!req) { return; } diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 04867925384c..0f1e8af52da4 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -2025,13 +2025,13 @@ class nsIFrame : public nsQueryFrame { * * Returns whether the image was in fact associated with the frame. */ - MOZ_MUST_USE bool AssociateImage(const nsStyleImage&); + MOZ_MUST_USE bool AssociateImage(const mozilla::StyleImage&); /** * This needs to be called if the above caller returned true, once the above * caller doesn't care about getting notified anymore. */ - void DisassociateImage(const nsStyleImage&); + void DisassociateImage(const mozilla::StyleImage&); enum class AllowCustomCursorImage { No, diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp index 58affbb7e937..e0ad35368059 100644 --- a/layout/generic/nsImageFrame.cpp +++ b/layout/generic/nsImageFrame.cpp @@ -1355,8 +1355,7 @@ ImgDrawResult nsImageFrame::DisplayAltFeedback(gfxContext& aRenderingContext, // Assert that we're not drawing a border-image here; if we were, we // couldn't ignore the ImgDrawResult that PaintBorderWithStyleBorder // returns. - MOZ_ASSERT(recessedBorder.mBorderImageSource.GetType() == - eStyleImageType_Null); + MOZ_ASSERT(recessedBorder.mBorderImageSource.IsNone()); Unused << nsCSSRendering::PaintBorderWithStyleBorder( PresContext(), aRenderingContext, this, inner, inner, recessedBorder, @@ -1538,8 +1537,7 @@ ImgDrawResult nsImageFrame::DisplayAltFeedbackWithoutLayer( // Assert that we're not drawing a border-image here; if we were, we // couldn't ignore the ImgDrawResult that PaintBorderWithStyleBorder // returns. - MOZ_ASSERT(recessedBorder.mBorderImageSource.GetType() == - eStyleImageType_Null); + MOZ_ASSERT(recessedBorder.mBorderImageSource.IsNone()); nsRect rect = nsRect(aPt, GetSize()); Unused << nsCSSRendering::CreateWebRenderCommandsForBorderWithStyleBorder( diff --git a/layout/painting/nsCSSRendering.cpp b/layout/painting/nsCSSRendering.cpp index 4ec222e47c50..8a4361529ec2 100644 --- a/layout/painting/nsCSSRendering.cpp +++ b/layout/painting/nsCSSRendering.cpp @@ -702,9 +702,9 @@ ImgDrawResult nsCSSRendering::CreateWebRenderCommandsForBorderWithStyleBorder( mozilla::layers::RenderRootStateManager* aManager, nsDisplayListBuilder* aDisplayListBuilder, const nsStyleBorder& aStyleBorder) { + auto& borderImage = aStyleBorder.mBorderImageSource; // First try to create commands for simple borders. - nsStyleImageType type = aStyleBorder.mBorderImageSource.GetType(); - if (type == eStyleImageType_Null) { + if (borderImage.IsNone()) { CreateWebRenderCommandsForNullBorder( aItem, aForFrame, aBorderArea, aBuilder, aResources, aSc, aStyleBorder); return ImgDrawResult::SUCCESS; @@ -712,7 +712,7 @@ ImgDrawResult nsCSSRendering::CreateWebRenderCommandsForBorderWithStyleBorder( // Next we try image and gradient borders. Gradients are not supported at // this very moment. - if (type != eStyleImageType_Image) { + if (!borderImage.IsImageRequestType()) { return ImgDrawResult::NOT_SUPPORTED; } @@ -845,7 +845,7 @@ ImgDrawResult nsCSSRendering::PaintBorderWithStyleBorder( } } - if (!aStyleBorder.mBorderImageSource.IsEmpty()) { + if (!aStyleBorder.mBorderImageSource.IsNone()) { ImgDrawResult result = ImgDrawResult::SUCCESS; uint32_t irFlags = 0; @@ -873,7 +873,7 @@ ImgDrawResult nsCSSRendering::PaintBorderWithStyleBorder( // If we had a border-image, but it wasn't loaded, then we should return // ImgDrawResult::NOT_READY; we'll want to try again if we do a paint with // sync decoding enabled. - if (aStyleBorder.mBorderImageSource.GetType() != eStyleImageType_Null) { + if (!aStyleBorder.mBorderImageSource.IsNone()) { result = ImgDrawResult::NOT_READY; } @@ -910,7 +910,7 @@ Maybe nsCSSRendering::CreateBorderRendererWithStyleBorder( const nsRect& aDirtyRect, const nsRect& aBorderArea, const nsStyleBorder& aStyleBorder, ComputedStyle* aStyle, bool* aOutBorderIsEmpty, Sides aSkipSides) { - if (aStyleBorder.mBorderImageSource.GetType() != eStyleImageType_Null) { + if (!aStyleBorder.mBorderImageSource.IsNone()) { return Nothing(); } return CreateNullBorderRendererWithStyleBorder( @@ -1881,15 +1881,15 @@ bool nsCSSRendering::CanBuildWebRenderDisplayItemsForStyleImageLayer( } } - // We only support painting gradients and image for a single style image layer - const nsStyleImage* styleImage = - &aBackgroundStyle->mImage.mLayers[aLayer].mImage; - if (styleImage->GetType() == eStyleImageType_Image) { - if (styleImage->GetCropRect()) { + // We only support painting gradients and image for a single style image + // layer, and we don't support crop-rects. + const auto& styleImage = aBackgroundStyle->mImage.mLayers[aLayer].mImage; + if (styleImage.IsImageRequestType()) { + if (styleImage.IsRect()) { return false; } - imgRequestProxy* requestProxy = styleImage->GetImageData(); + imgRequestProxy* requestProxy = styleImage.GetImageRequest(); if (!requestProxy) { return false; } @@ -1909,7 +1909,7 @@ bool nsCSSRendering::CanBuildWebRenderDisplayItemsForStyleImageLayer( return true; } - if (styleImage->GetType() == eStyleImageType_Gradient) { + if (styleImage.IsGradient()) { return true; } @@ -1966,8 +1966,9 @@ static bool IsOpaqueBorderEdge(const nsStyleBorder& aBorder, // because we may not even have the image loaded at this point, and // even if we did, checking whether the relevant tile is fully // opaque would be too much work. - if (aBorder.mBorderImageSource.GetType() != eStyleImageType_Null) + if (!aBorder.mBorderImageSource.IsNone()) { return false; + } StyleColor color = aBorder.BorderColorFor(aSide); // We don't know the foreground color here, so if it's being used diff --git a/layout/painting/nsCSSRendering.h b/layout/painting/nsCSSRendering.h index 85393e96d2f0..020f57d30e73 100644 --- a/layout/painting/nsCSSRendering.h +++ b/layout/painting/nsCSSRendering.h @@ -62,7 +62,7 @@ struct nsBackgroundLayerState { /** * @param aFlags some combination of nsCSSRendering::PAINTBG_* flags */ - nsBackgroundLayerState(nsIFrame* aForFrame, const nsStyleImage* aImage, + nsBackgroundLayerState(nsIFrame* aForFrame, const mozilla::StyleImage* aImage, uint32_t aFlags) : mImageRenderer(aForFrame, aImage, aFlags) {} diff --git a/layout/painting/nsCSSRenderingBorders.cpp b/layout/painting/nsCSSRenderingBorders.cpp index 3b37ec764916..4ac2d676099f 100644 --- a/layout/painting/nsCSSRenderingBorders.cpp +++ b/layout/painting/nsCSSRenderingBorders.cpp @@ -3609,7 +3609,8 @@ ImgDrawResult nsCSSBorderImageRenderer::CreateWebRenderCommands( ImgDrawResult drawResult = ImgDrawResult::SUCCESS; switch (mImageRenderer.GetType()) { - case eStyleImageType_Image: { + case StyleImage::Tag::Rect: + case StyleImage::Tag::Url: { RefPtr img = mImageRenderer.GetImage(); if (!img || img->GetType() == imgIContainer::TYPE_VECTOR) { // Vector images will redraw each segment of the border up to 8 times. @@ -3693,7 +3694,7 @@ ImgDrawResult nsCSSBorderImageRenderer::CreateWebRenderCommands( aBuilder.PushBorderImage(dest, clip, !aItem->BackfaceIsHidden(), params); break; } - case eStyleImageType_Gradient: { + case StyleImage::Tag::Gradient: { const StyleGradient& gradient = *mImageRenderer.GetGradientData(); nsCSSGradientRenderer renderer = nsCSSGradientRenderer::Create( aForFrame->PresContext(), aForFrame->Style(), gradient, mImageSize); diff --git a/layout/painting/nsDisplayList.cpp b/layout/painting/nsDisplayList.cpp index dc9e27d7287a..47a2cdb7ca5c 100644 --- a/layout/painting/nsDisplayList.cpp +++ b/layout/painting/nsDisplayList.cpp @@ -3914,7 +3914,7 @@ nsDisplayBackgroundImage::GetInitData(nsDisplayListBuilder* aBuilder, layer.mAttachment == StyleImageLayerAttachment::Fixed && !isTransformedFixed; - bool shouldFixToViewport = shouldTreatAsFixed && !layer.mImage.IsEmpty(); + bool shouldFixToViewport = shouldTreatAsFixed && !layer.mImage.IsNone(); bool isRasterImage = state.mImageRenderer.IsRasterImage(); nsCOMPtr image; if (isRasterImage) { @@ -4204,7 +4204,7 @@ bool nsDisplayBackgroundImage::AppendBackgroundItemsToTop( // Passing bg == nullptr in this macro will result in one iteration with // i = 0. NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT(i, bg->mImage) { - if (bg->mImage.mLayers[i].mImage.IsEmpty()) { + if (bg->mImage.mLayers[i].mImage.IsNone()) { continue; } @@ -4410,12 +4410,10 @@ nsDisplayBackgroundImage::ShouldCreateOwnLayer(nsDisplayListBuilder* aBuilder, if (StaticPrefs::layout_animated_image_layers_enabled() && mBackgroundStyle) { const nsStyleImageLayers::Layer& layer = mBackgroundStyle->StyleBackground()->mImage.mLayers[mLayer]; - const nsStyleImage* image = &layer.mImage; - if (image->GetType() == eStyleImageType_Image) { - imgIRequest* imgreq = image->GetImageData(); + const auto* image = &layer.mImage; + if (auto* request = image->GetImageRequest()) { nsCOMPtr image; - if (imgreq && NS_SUCCEEDED(imgreq->GetImage(getter_AddRefs(image))) && - image) { + if (NS_SUCCEEDED(request->GetImage(getter_AddRefs(image))) && image) { bool animated = false; if (NS_SUCCEEDED(image->GetAnimated(&animated)) && animated) { return WHENEVER_POSSIBLE; @@ -4734,9 +4732,9 @@ void nsDisplayBackgroundImage::ComputeInvalidationRegion( return; } if (aBuilder->ShouldSyncDecodeImages()) { - const nsStyleImage& image = + const auto& image = mBackgroundStyle->StyleBackground()->mImage.mLayers[mLayer].mImage; - if (image.GetType() == eStyleImageType_Image && + if (image.IsImageRequestType() && geometry->ShouldInvalidateToSyncDecodeImages()) { aInvalidRegion->Or(*aInvalidRegion, bounds); } @@ -9884,8 +9882,8 @@ void nsDisplayMasksAndClipPaths::ComputeInvalidationRegion( geometry->ShouldInvalidateToSyncDecodeImages()) { const nsStyleSVGReset* svgReset = mFrame->StyleSVGReset(); NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT(i, svgReset->mMask) { - const nsStyleImage& image = svgReset->mMask.mLayers[i].mImage; - if (image.GetType() == eStyleImageType_Image) { + const auto& image = svgReset->mMask.mLayers[i].mImage; + if (image.IsImageRequestType()) { aInvalidRegion->Or(*aInvalidRegion, bounds); break; } diff --git a/layout/painting/nsImageRenderer.cpp b/layout/painting/nsImageRenderer.cpp index 25dd4713494a..a58a544ec474 100644 --- a/layout/painting/nsImageRenderer.cpp +++ b/layout/painting/nsImageRenderer.cpp @@ -46,10 +46,10 @@ nsSize CSSSizeOrRatio::ComputeConcreteSize() const { } nsImageRenderer::nsImageRenderer(nsIFrame* aForFrame, - const nsStyleImage* aImage, uint32_t aFlags) + const StyleImage* aImage, uint32_t aFlags) : mForFrame(aForFrame), mImage(aImage), - mType(aImage->GetType()), + mType(aImage->tag), mImageContainer(nullptr), mGradientData(nullptr), mPaintServerFrame(nullptr), @@ -59,17 +59,13 @@ nsImageRenderer::nsImageRenderer(nsIFrame* aForFrame, mExtendMode(ExtendMode::CLAMP), mMaskOp(StyleMaskMode::MatchSource) {} -static bool ShouldTreatAsCompleteDueToSyncDecode(const nsStyleImage* aImage, +static bool ShouldTreatAsCompleteDueToSyncDecode(const StyleImage* aImage, uint32_t aFlags) { if (!(aFlags & nsImageRenderer::FLAG_SYNC_DECODE_IMAGES)) { return false; } - if (aImage->GetType() != eStyleImageType_Image) { - return false; - } - - imgRequestProxy* req = aImage->GetImageData(); + imgRequestProxy* req = aImage->GetImageRequest(); if (!req) { return false; } @@ -97,10 +93,10 @@ static bool ShouldTreatAsCompleteDueToSyncDecode(const nsStyleImage* aImage, } bool nsImageRenderer::PrepareImage() { - if (mImage->IsEmpty() || - (mType == eStyleImageType_Image && !mImage->GetImageData())) { - // mImage->GetImageData() could be null here if the nsStyleImage refused - // to load a same-document URL. + if (mImage->IsNone() || + (mImage->IsImageRequestType() && !mImage->GetImageRequest())) { + // mImage->GetImageRequest() could be null here if the StyleImage refused + // to load a same-document URL, or the url was invalid, for example. mPrepareResult = ImgDrawResult::BAD_IMAGE; return false; } @@ -111,10 +107,10 @@ bool nsImageRenderer::PrepareImage() { // Boost the loading priority since we know we want to draw the image. if ((mFlags & nsImageRenderer::FLAG_PAINTING_TO_WINDOW) && - mType == eStyleImageType_Image) { - MOZ_ASSERT(mImage->GetImageData(), + mImage->IsImageRequestType()) { + MOZ_ASSERT(mImage->GetImageRequest(), "must have image data, since we checked above"); - mImage->GetImageData()->BoostPriority(imgIRequest::CATEGORY_DISPLAY); + mImage->GetImageRequest()->BoostPriority(imgIRequest::CATEGORY_DISPLAY); } // Check again to see if we finished. @@ -128,75 +124,65 @@ bool nsImageRenderer::PrepareImage() { } } - switch (mType) { - case eStyleImageType_Image: { - MOZ_ASSERT(mImage->GetImageData(), - "must have image data, since we checked above"); - nsCOMPtr srcImage; - DebugOnly rv = - mImage->GetImageData()->GetImage(getter_AddRefs(srcImage)); + if (mImage->IsImageRequestType()) { + MOZ_ASSERT(mImage->GetImageRequest(), + "must have image data, since we checked above"); + nsCOMPtr srcImage; + DebugOnly rv = + mImage->GetImageRequest()->GetImage(getter_AddRefs(srcImage)); MOZ_ASSERT(NS_SUCCEEDED(rv) && srcImage, "If GetImage() is failing, mImage->IsComplete() " "should have returned false"); - if (!mImage->GetCropRect()) { + if (!mImage->IsRect()) { + mImageContainer.swap(srcImage); + } else { + auto croprect = mImage->ComputeActualCropRect(); + if (!croprect || croprect->mRect.IsEmpty()) { + // The cropped image has zero size + mPrepareResult = ImgDrawResult::BAD_IMAGE; + return false; + } + if (croprect->mIsEntireImage) { + // The cropped image is identical to the source image mImageContainer.swap(srcImage); } else { - nsIntRect actualCropRect; - bool isEntireImage; - bool success = - mImage->ComputeActualCropRect(actualCropRect, &isEntireImage); - if (!success || actualCropRect.IsEmpty()) { - // The cropped image has zero size - mPrepareResult = ImgDrawResult::BAD_IMAGE; - return false; - } - if (isEntireImage) { - // The cropped image is identical to the source image - mImageContainer.swap(srcImage); - } else { - nsCOMPtr subImage = - ImageOps::Clip(srcImage, actualCropRect, Nothing()); - mImageContainer.swap(subImage); - } + nsCOMPtr subImage = + ImageOps::Clip(srcImage, croprect->mRect, Nothing()); + mImageContainer.swap(subImage); } - mPrepareResult = ImgDrawResult::SUCCESS; - break; } - case eStyleImageType_Gradient: - mGradientData = &mImage->GetGradient(); - mPrepareResult = ImgDrawResult::SUCCESS; - break; - case eStyleImageType_Element: { - dom::Element* paintElement = // may be null - SVGObserverUtils::GetAndObserveBackgroundImage( - mForFrame->FirstContinuation(), mImage->GetElementId()); - // If the referenced element is an , , or