diff --git a/widget/cocoa/MOZIconHelper.h b/widget/cocoa/MOZIconHelper.h
index be26c6d11d6d..16f03573fc68 100644
--- a/widget/cocoa/MOZIconHelper.h
+++ b/widget/cocoa/MOZIconHelper.h
@@ -12,6 +12,10 @@
class imgIContainer;
+namespace mozilla {
+class ComputedStyle;
+}
+
@interface MOZIconHelper : NSObject
// Returns an autoreleased empty NSImage.
@@ -20,6 +24,7 @@ class imgIContainer;
// Returns an autoreleased NSImage.
+ (NSImage*)iconImageFromImageContainer:(imgIContainer*)aImage
withSize:(NSSize)aSize
+ computedStyle:(const mozilla::ComputedStyle*)aComputedStyle
subrect:(const nsIntRect&)aSubRect
scaleFactor:(CGFloat)aScaleFactor;
diff --git a/widget/cocoa/MOZIconHelper.mm b/widget/cocoa/MOZIconHelper.mm
index fce5f3bdb6c4..f8fad8e7a14f 100644
--- a/widget/cocoa/MOZIconHelper.mm
+++ b/widget/cocoa/MOZIconHelper.mm
@@ -22,17 +22,19 @@
// Returns an autoreleased NSImage.
+ (NSImage*)iconImageFromImageContainer:(imgIContainer*)aImage
withSize:(NSSize)aSize
+ computedStyle:(const mozilla::ComputedStyle*)aComputedStyle
subrect:(const nsIntRect&)aSubRect
scaleFactor:(CGFloat)aScaleFactor {
bool isEntirelyBlack = false;
NSImage* retainedImage = nil;
nsresult rv;
if (aScaleFactor != 0.0f) {
- rv = nsCocoaUtils::CreateNSImageFromImageContainer(
- aImage, imgIContainer::FRAME_CURRENT, &retainedImage, aScaleFactor, &isEntirelyBlack);
+ rv = nsCocoaUtils::CreateNSImageFromImageContainer(aImage, imgIContainer::FRAME_CURRENT,
+ aComputedStyle, &retainedImage, aScaleFactor,
+ &isEntirelyBlack);
} else {
rv = nsCocoaUtils::CreateDualRepresentationNSImageFromImageContainer(
- aImage, imgIContainer::FRAME_CURRENT, &retainedImage, &isEntirelyBlack);
+ aImage, imgIContainer::FRAME_CURRENT, aComputedStyle, &retainedImage, &isEntirelyBlack);
}
NSImage* image = [retainedImage autorelease];
diff --git a/widget/cocoa/OSXNotificationCenter.mm b/widget/cocoa/OSXNotificationCenter.mm
index 73e52f2603eb..bd19cfb23197 100644
--- a/widget/cocoa/OSXNotificationCenter.mm
+++ b/widget/cocoa/OSXNotificationCenter.mm
@@ -507,8 +507,9 @@ OSXNotificationCenter::OnImageReady(nsISupports* aUserData, imgIRequest* aReques
}
NSImage* cocoaImage = nil;
+ // TODO: Pass ComputedStyle here to support context paint properties
nsCocoaUtils::CreateDualRepresentationNSImageFromImageContainer(image, imgIContainer::FRAME_FIRST,
- &cocoaImage);
+ nullptr, &cocoaImage);
(osxni->mPendingNotification).contentImage = cocoaImage;
[cocoaImage release];
ShowPendingNotification(osxni);
diff --git a/widget/cocoa/nsCocoaUtils.h b/widget/cocoa/nsCocoaUtils.h
index f5794be998c1..4494bd473931 100644
--- a/widget/cocoa/nsCocoaUtils.h
+++ b/widget/cocoa/nsCocoaUtils.h
@@ -257,6 +257,8 @@ class nsCocoaUtils {
Combines the two methods above. The caller owns the NSImage
.
@param aImage the image to extract a frame from
@param aWhichFrame the frame to extract (see imgIContainer FRAME_*)
+ @param aComputedStyle the ComputedStyle of the element that the image is for, to support SVG
+ context paint properties, can be null
@param aResult the resulting NSImage
@param scaleFactor the desired scale factor of the NSImage (2 for a retina display)
@param aIsEntirelyBlack an outparam that, if non-null, will be set to a
@@ -265,6 +267,7 @@ class nsCocoaUtils {
@return NS_OK if the conversion worked, NS_ERROR_FAILURE otherwise
*/
static nsresult CreateNSImageFromImageContainer(imgIContainer* aImage, uint32_t aWhichFrame,
+ const mozilla::ComputedStyle* aComputedStyle,
NSImage** aResult, CGFloat scaleFactor,
bool* aIsEntirelyBlack = nullptr);
@@ -273,6 +276,8 @@ class nsCocoaUtils {
The caller owns the NSImage
.
@param aImage the image to extract a frame from
@param aWhichFrame the frame to extract (see imgIContainer FRAME_*)
+ @param aComputedStyle the ComputedStyle of the element that the image is for, to support SVG
+ context paint properties, can be null
@param aResult the resulting NSImage
@param aIsEntirelyBlack an outparam that, if non-null, will be set to a
bool that indicates whether the RGB values on all
@@ -280,8 +285,8 @@ class nsCocoaUtils {
@return NS_OK if the conversion worked, NS_ERROR_FAILURE otherwise
*/
static nsresult CreateDualRepresentationNSImageFromImageContainer(
- imgIContainer* aImage, uint32_t aWhichFrame, NSImage** aResult,
- bool* aIsEntirelyBlack = nullptr);
+ imgIContainer* aImage, uint32_t aWhichFrame, const mozilla::ComputedStyle* aComputedStyle,
+ NSImage** aResult, bool* aIsEntirelyBlack = nullptr);
/**
* Returns nsAString for aSrc.
diff --git a/widget/cocoa/nsCocoaUtils.mm b/widget/cocoa/nsCocoaUtils.mm
index 30634aabd905..f9e77301ba90 100644
--- a/widget/cocoa/nsCocoaUtils.mm
+++ b/widget/cocoa/nsCocoaUtils.mm
@@ -388,6 +388,7 @@ nsresult nsCocoaUtils::CreateNSImageFromCGImage(CGImageRef aInputImage, NSImage*
}
nsresult nsCocoaUtils::CreateNSImageFromImageContainer(imgIContainer* aImage, uint32_t aWhichFrame,
+ const ComputedStyle* aComputedStyle,
NSImage** aResult, CGFloat scaleFactor,
bool* aIsEntirelyBlack) {
RefPtr surface;
@@ -396,7 +397,7 @@ nsresult nsCocoaUtils::CreateNSImageFromImageContainer(imgIContainer* aImage, ui
aImage->GetHeight(&height);
// Render a vector image at the correct resolution on a retina display
- if (aImage->GetType() == imgIContainer::TYPE_VECTOR && scaleFactor != 1.0f) {
+ if (aImage->GetType() == imgIContainer::TYPE_VECTOR) {
IntSize scaledSize = IntSize::Ceil(width * scaleFactor, height * scaleFactor);
RefPtr drawTarget = gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(
@@ -409,9 +410,13 @@ nsresult nsCocoaUtils::CreateNSImageFromImageContainer(imgIContainer* aImage, ui
RefPtr context = gfxContext::CreateOrNull(drawTarget);
MOZ_ASSERT(context);
- mozilla::image::ImgDrawResult res = aImage->Draw(
- context, scaledSize, ImageRegion::Create(scaledSize), aWhichFrame, SamplingFilter::POINT,
- /* no SVGImageContext */ Nothing(), imgIContainer::FLAG_SYNC_DECODE, 1.0);
+ Maybe svgContext;
+ if (aComputedStyle) {
+ SVGImageContext::MaybeStoreContextPaint(svgContext, aComputedStyle, aImage);
+ }
+ mozilla::image::ImgDrawResult res =
+ aImage->Draw(context, scaledSize, ImageRegion::Create(scaledSize), aWhichFrame,
+ SamplingFilter::POINT, svgContext, imgIContainer::FLAG_SYNC_DECODE, 1.0);
if (res != mozilla::image::ImgDrawResult::SUCCESS) {
return NS_ERROR_FAILURE;
@@ -444,10 +449,9 @@ nsresult nsCocoaUtils::CreateNSImageFromImageContainer(imgIContainer* aImage, ui
return NS_OK;
}
-nsresult nsCocoaUtils::CreateDualRepresentationNSImageFromImageContainer(imgIContainer* aImage,
- uint32_t aWhichFrame,
- NSImage** aResult,
- bool* aIsEntirelyBlack) {
+nsresult nsCocoaUtils::CreateDualRepresentationNSImageFromImageContainer(
+ imgIContainer* aImage, uint32_t aWhichFrame, const ComputedStyle* aComputedStyle,
+ NSImage** aResult, bool* aIsEntirelyBlack) {
int32_t width = 0, height = 0;
aImage->GetWidth(&width);
aImage->GetHeight(&height);
@@ -457,7 +461,7 @@ nsresult nsCocoaUtils::CreateDualRepresentationNSImageFromImageContainer(imgICon
NSImage* newRepresentation = nil;
nsresult rv = nsCocoaUtils::CreateNSImageFromImageContainer(
- aImage, aWhichFrame, &newRepresentation, 1.0f, aIsEntirelyBlack);
+ aImage, aWhichFrame, aComputedStyle, &newRepresentation, 1.0f, aIsEntirelyBlack);
if (NS_FAILED(rv) || !newRepresentation) {
return NS_ERROR_FAILURE;
}
@@ -467,8 +471,8 @@ nsresult nsCocoaUtils::CreateDualRepresentationNSImageFromImageContainer(imgICon
[newRepresentation release];
newRepresentation = nil;
- rv = nsCocoaUtils::CreateNSImageFromImageContainer(aImage, aWhichFrame, &newRepresentation, 2.0f,
- aIsEntirelyBlack);
+ rv = nsCocoaUtils::CreateNSImageFromImageContainer(aImage, aWhichFrame, aComputedStyle,
+ &newRepresentation, 2.0f, aIsEntirelyBlack);
if (NS_FAILED(rv) || !newRepresentation) {
return NS_ERROR_FAILURE;
}
diff --git a/widget/cocoa/nsCursorManager.mm b/widget/cocoa/nsCursorManager.mm
index 558d7b3534f2..7b3251240774 100644
--- a/widget/cocoa/nsCursorManager.mm
+++ b/widget/cocoa/nsCursorManager.mm
@@ -265,7 +265,7 @@ static const nsCursor sCustomCursor = eCursorCount;
NSImage* cursorImage;
nsresult rv = nsCocoaUtils::CreateNSImageFromImageContainer(
- aCursorImage, imgIContainer::FRAME_FIRST, &cursorImage, scaleFactor);
+ aCursorImage, imgIContainer::FRAME_FIRST, nullptr, &cursorImage, scaleFactor);
if (NS_FAILED(rv) || !cursorImage) {
return NS_ERROR_FAILURE;
}
diff --git a/widget/cocoa/nsMenuItemIconX.h b/widget/cocoa/nsMenuItemIconX.h
index 050c0af3027d..dca07a8fd481 100644
--- a/widget/cocoa/nsMenuItemIconX.h
+++ b/widget/cocoa/nsMenuItemIconX.h
@@ -10,6 +10,8 @@
#ifndef nsMenuItemIconX_h_
#define nsMenuItemIconX_h_
+#import
+
#include "mozilla/widget/IconLoader.h"
class nsIconLoaderService;
@@ -19,7 +21,9 @@ class nsIPrincipal;
class imgRequestProxy;
class nsMenuParentX;
-#import
+namespace mozilla {
+class ComputedStyle;
+}
class nsMenuItemIconX final : public mozilla::widget::IconLoader::Listener {
public:
@@ -57,6 +61,7 @@ class nsMenuItemIconX final : public mozilla::widget::IconLoader::Listener {
nsCOMPtr mContent; // always non-null
Listener* mListener; // [weak]
nsIntRect mImageRegionRect;
+ RefPtr mComputedStyle;
NSImage* mIconImage = nil; // [strong]
RefPtr mIconLoader;
};
diff --git a/widget/cocoa/nsMenuItemIconX.mm b/widget/cocoa/nsMenuItemIconX.mm
index 9221ea49c945..ef61c4a018c7 100644
--- a/widget/cocoa/nsMenuItemIconX.mm
+++ b/widget/cocoa/nsMenuItemIconX.mm
@@ -149,6 +149,8 @@ already_AddRefed nsMenuItemIconX::GetIconURI(nsIContent* aContent) {
} else {
mImageRegionRect = r.ToNearestPixels(mozilla::AppUnitsPerCSSPixel());
}
+ mComputedStyle = std::move(sc);
+
return iconURI.forget();
}
@@ -166,8 +168,11 @@ nsresult nsMenuItemIconX::OnComplete(imgIContainer* aImage) {
mIconImage = [[MOZIconHelper iconImageFromImageContainer:aImage
withSize:NSMakeSize(kIconSize, kIconSize)
+ computedStyle:mComputedStyle
subrect:mImageRegionRect
scaleFactor:0.0f] retain];
+ mComputedStyle = nullptr;
+
if (mListener) {
mListener->IconUpdated();
}
diff --git a/widget/cocoa/nsTouchBarInputIcon.mm b/widget/cocoa/nsTouchBarInputIcon.mm
index 767d25bd964b..1d1b82dd0f09 100644
--- a/widget/cocoa/nsTouchBarInputIcon.mm
+++ b/widget/cocoa/nsTouchBarInputIcon.mm
@@ -119,6 +119,7 @@ nsresult nsTouchBarInputIcon::OnComplete(imgIContainer* aImage) {
// displays and we have no need for icons @1x.
NSImage* image = [MOZIconHelper iconImageFromImageContainer:aImage
withSize:NSMakeSize(kIconSize, kIconSize)
+ computedStyle:nullptr
subrect:mImageRegionRect
scaleFactor:kHiDPIScalingFactor];
[mButton setImage:image];