diff --git a/layout/base/moz.build b/layout/base/moz.build index bb4d3abb5081..bf2baa4f4d57 100644 --- a/layout/base/moz.build +++ b/layout/base/moz.build @@ -23,6 +23,7 @@ XPIDL_SOURCES += [ "nsILayoutHistoryState.idl", "nsIPreloadedStyleSheet.idl", "nsIStyleSheetService.idl", + "nsISVGPaintContext.idl", ] if CONFIG["MOZ_DEBUG"]: diff --git a/layout/base/nsISVGPaintContext.idl b/layout/base/nsISVGPaintContext.idl new file mode 100644 index 000000000000..e8572c954168 --- /dev/null +++ b/layout/base/nsISVGPaintContext.idl @@ -0,0 +1,35 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * 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 "nsISupports.idl" + +/* + * Used to set SVG context values when rendering SVG images outside of a DOM + * context. + */ + +[scriptable, uuid(43966236-3146-4518-ab39-f938795cd1a1)] +interface nsISVGPaintContext : nsISupports +{ + /** + * The fill color to use. Any CSS color value. + */ + readonly attribute ACString fillColor; + + /** + * The stroke color to use. Any CSS color value. + */ + readonly attribute ACString strokeColor; + + /** + * The fill opacity to use. + */ + readonly attribute float fillOpacity; + + /** + * The stroke opacity to use. + */ + readonly attribute float strokeOpacity; +}; diff --git a/layout/svg/SVGImageContext.cpp b/layout/svg/SVGImageContext.cpp index b256d3cf292e..c15a4f34f8c3 100644 --- a/layout/svg/SVGImageContext.cpp +++ b/layout/svg/SVGImageContext.cpp @@ -15,6 +15,8 @@ #include "nsIFrame.h" #include "nsPresContext.h" #include "nsStyleStruct.h" +#include "nsISVGPaintContext.h" +#include "mozilla/ServoCSSParser.h" namespace mozilla { @@ -85,4 +87,50 @@ void SVGImageContext::MaybeStoreContextPaint(SVGImageContext& aContext, } } +/* static */ +void SVGImageContext::MaybeStoreContextPaint(SVGImageContext& aContext, + nsISVGPaintContext* aPaintContext, + imgIContainer* aImgContainer) { + if (aImgContainer->GetType() != imgIContainer::TYPE_VECTOR || + !aPaintContext) { + // Avoid this overhead for raster images. + return; + } + + bool haveContextPaint = false; + auto contextPaint = MakeRefPtr(); + nsCString value; + float opacity; + + if (NS_SUCCEEDED(aPaintContext->GetStrokeColor(value)) && !value.IsEmpty()) { + nscolor color; + if (ServoCSSParser::ComputeColor(nullptr, NS_RGB(0, 0, 0), value, &color)) { + haveContextPaint = true; + contextPaint->SetStroke(color); + } + } + + if (NS_SUCCEEDED(aPaintContext->GetFillColor(value)) && !value.IsEmpty()) { + nscolor color; + if (ServoCSSParser::ComputeColor(nullptr, NS_RGB(0, 0, 0), value, &color)) { + haveContextPaint = true; + contextPaint->SetFill(color); + } + } + + if (NS_SUCCEEDED(aPaintContext->GetStrokeOpacity(&opacity))) { + haveContextPaint = true; + contextPaint->SetStrokeOpacity(opacity); + } + + if (NS_SUCCEEDED(aPaintContext->GetFillOpacity(&opacity))) { + haveContextPaint = true; + contextPaint->SetFillOpacity(opacity); + } + + if (haveContextPaint) { + aContext.mContextPaint = std::move(contextPaint); + } +} + } // namespace mozilla diff --git a/layout/svg/SVGImageContext.h b/layout/svg/SVGImageContext.h index e40e41d16b2b..55c29a71bb93 100644 --- a/layout/svg/SVGImageContext.h +++ b/layout/svg/SVGImageContext.h @@ -13,6 +13,7 @@ #include "Units.h" class nsIFrame; +class nsISVGPaintContext; namespace mozilla { @@ -60,6 +61,10 @@ class SVGImageContext { const nsPresContext&, const ComputedStyle&, imgIContainer*); + static void MaybeStoreContextPaint(SVGImageContext& aContext, + nsISVGPaintContext* aPaintContext, + imgIContainer* aImgContainer); + const Maybe& GetViewportSize() const { return mViewportSize; } void SetViewportSize(const Maybe& aSize) { diff --git a/widget/cocoa/MOZIconHelper.h b/widget/cocoa/MOZIconHelper.h index 4b66f13c0587..2c204ab67ef7 100644 --- a/widget/cocoa/MOZIconHelper.h +++ b/widget/cocoa/MOZIconHelper.h @@ -15,7 +15,8 @@ class nsPresContext; namespace mozilla { class ComputedStyle; -} +class SVGImageContext; +} // namespace mozilla @interface MOZIconHelper : NSObject @@ -25,9 +26,8 @@ class ComputedStyle; // Returns an autoreleased NSImage. + (NSImage*)iconImageFromImageContainer:(imgIContainer*)aImage withSize:(NSSize)aSize - presContext:(const nsPresContext*)aPresContext - computedStyle: - (const mozilla::ComputedStyle*)aComputedStyle + svgContext: + (const mozilla::SVGImageContext*)aSVGContext scaleFactor:(CGFloat)aScaleFactor; @end diff --git a/widget/cocoa/MOZIconHelper.mm b/widget/cocoa/MOZIconHelper.mm index f9c8f02406de..ada013f4c104 100644 --- a/widget/cocoa/MOZIconHelper.mm +++ b/widget/cocoa/MOZIconHelper.mm @@ -22,21 +22,20 @@ // Returns an autoreleased NSImage. + (NSImage*)iconImageFromImageContainer:(imgIContainer*)aImage withSize:(NSSize)aSize - presContext:(const nsPresContext*)aPresContext - computedStyle: - (const mozilla::ComputedStyle*)aComputedStyle + svgContext: + (const mozilla::SVGImageContext*)aSVGContext scaleFactor:(CGFloat)aScaleFactor { bool isEntirelyBlack = false; NSImage* retainedImage = nil; nsresult rv; if (aScaleFactor != 0.0f) { rv = nsCocoaUtils::CreateNSImageFromImageContainer( - aImage, imgIContainer::FRAME_CURRENT, aPresContext, aComputedStyle, - aSize, &retainedImage, aScaleFactor, &isEntirelyBlack); + aImage, imgIContainer::FRAME_CURRENT, aSVGContext, aSize, + &retainedImage, aScaleFactor, &isEntirelyBlack); } else { rv = nsCocoaUtils::CreateDualRepresentationNSImageFromImageContainer( - aImage, imgIContainer::FRAME_CURRENT, aPresContext, aComputedStyle, - aSize, &retainedImage, &isEntirelyBlack); + aImage, imgIContainer::FRAME_CURRENT, aSVGContext, aSize, + &retainedImage, &isEntirelyBlack); } NSImage* image = [retainedImage autorelease]; diff --git a/widget/cocoa/OSXNotificationCenter.mm b/widget/cocoa/OSXNotificationCenter.mm index f7d507a947d7..7905508aa329 100644 --- a/widget/cocoa/OSXNotificationCenter.mm +++ b/widget/cocoa/OSXNotificationCenter.mm @@ -547,7 +547,7 @@ OSXNotificationCenter::OnImageReady(nsISupports* aUserData, // properties. // TODO: Do we have a reasonable size to pass around here? nsCocoaUtils::CreateDualRepresentationNSImageFromImageContainer( - image, imgIContainer::FRAME_FIRST, nullptr, nullptr, NSMakeSize(0, 0), + image, imgIContainer::FRAME_FIRST, nullptr, NSMakeSize(0, 0), &cocoaImage); (osxni->mPendingNotification).contentImage = cocoaImage; [cocoaImage release]; diff --git a/widget/cocoa/nsCocoaUtils.h b/widget/cocoa/nsCocoaUtils.h index bc05575befae..ad64d61e8c70 100644 --- a/widget/cocoa/nsCocoaUtils.h +++ b/widget/cocoa/nsCocoaUtils.h @@ -286,8 +286,8 @@ class nsCocoaUtils { 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 aSVGContext the SVG context paint properties for the image. Can be + null. @param aResult the resulting NSImage @param scaleFactor the desired scale factor of the NSImage (2 for a retina display) @@ -298,18 +298,16 @@ class nsCocoaUtils { */ static nsresult CreateNSImageFromImageContainer( imgIContainer* aImage, uint32_t aWhichFrame, - const nsPresContext* aPresContext, - const mozilla::ComputedStyle* aComputedStyle, - const NSSize& aPreferredSize, NSImage** aResult, CGFloat scaleFactor, - bool* aIsEntirelyBlack = nullptr); + const mozilla::SVGImageContext* aSVGContext, const NSSize& aPreferredSize, + NSImage** aResult, CGFloat scaleFactor, bool* aIsEntirelyBlack = nullptr); /** Creates a Cocoa NSImage from a frame of an imgIContainer. The new NSImage will have both a regular and HiDPI representation. 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 aSVGContext the SVG context paint properties for the image. 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 @@ -318,10 +316,8 @@ class nsCocoaUtils { */ static nsresult CreateDualRepresentationNSImageFromImageContainer( imgIContainer* aImage, uint32_t aWhichFrame, - const nsPresContext* aPresContext, - const mozilla::ComputedStyle* aComputedStyle, - const NSSize& aPreferredSize, NSImage** aResult, - bool* aIsEntirelyBlack = nullptr); + const mozilla::SVGImageContext* aSVGContext, const NSSize& aPreferredSize, + NSImage** aResult, bool* aIsEntirelyBlack = nullptr); /** * Returns nsAString for aSrc. diff --git a/widget/cocoa/nsCocoaUtils.mm b/widget/cocoa/nsCocoaUtils.mm index 55891c48a53b..69c2a3ff7db4 100644 --- a/widget/cocoa/nsCocoaUtils.mm +++ b/widget/cocoa/nsCocoaUtils.mm @@ -506,9 +506,8 @@ nsresult nsCocoaUtils::CreateNSImageFromCGImage(CGImageRef aInputImage, nsresult nsCocoaUtils::CreateNSImageFromImageContainer( imgIContainer* aImage, uint32_t aWhichFrame, - const nsPresContext* aPresContext, const ComputedStyle* aComputedStyle, - const NSSize& aPreferredSize, NSImage** aResult, CGFloat scaleFactor, - bool* aIsEntirelyBlack) { + const SVGImageContext* aSVGContext, const NSSize& aPreferredSize, + NSImage** aResult, CGFloat scaleFactor, bool* aIsEntirelyBlack) { RefPtr surface; int32_t width = 0; int32_t height = 0; @@ -544,14 +543,15 @@ nsresult nsCocoaUtils::CreateNSImageFromImageContainer( gfxContext context(drawTarget); - SVGImageContext svgContext; - if (aPresContext && aComputedStyle) { - SVGImageContext::MaybeStoreContextPaint(svgContext, *aPresContext, - *aComputedStyle, aImage); + UniquePtr svgContext; + if (!aSVGContext) { + svgContext = MakeUnique(); + aSVGContext = svgContext.get(); } + mozilla::image::ImgDrawResult res = aImage->Draw(&context, scaledSize, ImageRegion::Create(scaledSize), - aWhichFrame, SamplingFilter::POINT, svgContext, + aWhichFrame, SamplingFilter::POINT, *aSVGContext, imgIContainer::FLAG_SYNC_DECODE, 1.0); if (res != mozilla::image::ImgDrawResult::SUCCESS) { @@ -589,12 +589,12 @@ nsresult nsCocoaUtils::CreateNSImageFromImageContainer( nsresult nsCocoaUtils::CreateDualRepresentationNSImageFromImageContainer( imgIContainer* aImage, uint32_t aWhichFrame, - const nsPresContext* aPresContext, const ComputedStyle* aComputedStyle, - const NSSize& aPreferredSize, NSImage** aResult, bool* aIsEntirelyBlack) { + const SVGImageContext* aSVGContext, const NSSize& aPreferredSize, + NSImage** aResult, bool* aIsEntirelyBlack) { NSImage* newRepresentation = nil; nsresult rv = CreateNSImageFromImageContainer( - aImage, aWhichFrame, aPresContext, aComputedStyle, aPreferredSize, - &newRepresentation, 1.0f, aIsEntirelyBlack); + aImage, aWhichFrame, aSVGContext, aPreferredSize, &newRepresentation, + 1.0f, aIsEntirelyBlack); if (NS_FAILED(rv) || !newRepresentation) { return NS_ERROR_FAILURE; } @@ -609,9 +609,9 @@ nsresult nsCocoaUtils::CreateDualRepresentationNSImageFromImageContainer( [newRepresentation release]; newRepresentation = nil; - rv = CreateNSImageFromImageContainer( - aImage, aWhichFrame, aPresContext, aComputedStyle, aPreferredSize, - &newRepresentation, 2.0f, aIsEntirelyBlack); + rv = CreateNSImageFromImageContainer(aImage, aWhichFrame, aSVGContext, + aPreferredSize, &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 11a37f59b788..5e4315e3c254 100644 --- a/widget/cocoa/nsCursorManager.mm +++ b/widget/cocoa/nsCursorManager.mm @@ -307,8 +307,8 @@ static constexpr nsCursor kCustomCursor = eCursorCount; const NSSize cocoaSize = NSMakeSize(size.width, size.height); NSImage* cursorImage; nsresult rv = nsCocoaUtils::CreateNSImageFromImageContainer( - aCursor.mContainer, imgIContainer::FRAME_FIRST, nullptr, nullptr, - cocoaSize, &cursorImage, scaleFactor); + aCursor.mContainer, imgIContainer::FRAME_FIRST, nullptr, cocoaSize, + &cursorImage, scaleFactor); if (NS_FAILED(rv) || !cursorImage) { return NS_ERROR_FAILURE; } diff --git a/widget/cocoa/nsMacDockSupport.h b/widget/cocoa/nsMacDockSupport.h index f3a12485b36d..7e0026f53882 100644 --- a/widget/cocoa/nsMacDockSupport.h +++ b/widget/cocoa/nsMacDockSupport.h @@ -24,12 +24,15 @@ class nsMacDockSupport : public nsIMacDockSupport, public nsITaskbarProgress { nsCOMPtr mDockMenu; nsString mBadgeText; + bool mHasBadgeImage; NSView* mDockTileWrapperView; + NSImageView* mDockBadgeView; MOZProgressDockOverlayView* mProgressDockOverlayView; nsTaskbarProgressState mProgressState; double mProgressFraction; + void BuildDockTile(); nsresult UpdateDockTile(); }; diff --git a/widget/cocoa/nsMacDockSupport.mm b/widget/cocoa/nsMacDockSupport.mm index 5e9da63e10c9..33b79275c8aa 100644 --- a/widget/cocoa/nsMacDockSupport.mm +++ b/widget/cocoa/nsMacDockSupport.mm @@ -13,6 +13,10 @@ #include "nsObjCExceptions.h" #include "nsNativeThemeColors.h" #include "nsString.h" +#include "imgLoader.h" +#include "MOZIconHelper.h" +#include "mozilla/SVGImageContext.h" +#include "nsISVGPaintContext.h" NS_IMPL_ISUPPORTS(nsMacDockSupport, nsIMacDockSupport, nsITaskbarProgress) @@ -71,7 +75,9 @@ NS_IMPL_ISUPPORTS(nsMacDockSupport, nsIMacDockSupport, nsITaskbarProgress) @end nsMacDockSupport::nsMacDockSupport() - : mDockTileWrapperView(nil), + : mHasBadgeImage(false), + mDockTileWrapperView(nil), + mDockBadgeView(nil), mProgressDockOverlayView(nil), mProgressState(STATE_NO_PROGRESS), mProgressFraction(0.0) {} @@ -81,6 +87,10 @@ nsMacDockSupport::~nsMacDockSupport() { [mDockTileWrapperView release]; mDockTileWrapperView = nil; } + if (mDockBadgeView) { + [mDockBadgeView release]; + mDockBadgeView = nil; + } if (mProgressDockOverlayView) { [mProgressDockOverlayView release]; mProgressDockOverlayView = nil; @@ -117,14 +127,18 @@ nsMacDockSupport::SetBadgeText(const nsAString& aBadgeText) { NSDockTile* tile = [[NSApplication sharedApplication] dockTile]; mBadgeText = aBadgeText; - if (aBadgeText.IsEmpty()) + if (aBadgeText.IsEmpty()) { [tile setBadgeLabel:nil]; - else + } else { + SetBadgeImage(nullptr, nullptr); + [tile setBadgeLabel:[NSString stringWithCharacters:reinterpret_cast( mBadgeText.get()) length:mBadgeText.Length()]]; + } + return NS_OK; NS_OBJC_END_TRY_BLOCK_RETURN(NS_ERROR_FAILURE); @@ -136,6 +150,45 @@ nsMacDockSupport::GetBadgeText(nsAString& aBadgeText) { return NS_OK; } +NS_IMETHODIMP +nsMacDockSupport::SetBadgeImage(imgIContainer* aImage, + nsISVGPaintContext* aPaintContext) { + if (!aImage) { + mHasBadgeImage = false; + if (mDockBadgeView) { + mDockBadgeView.image = nullptr; + } + + return UpdateDockTile(); + } + + if (!mBadgeText.IsEmpty()) { + mBadgeText.Truncate(); + NSDockTile* tile = [[NSApplication sharedApplication] dockTile]; + [tile setBadgeLabel:nil]; + } + + NS_OBJC_BEGIN_TRY_BLOCK_RETURN + + mHasBadgeImage = true; + BuildDockTile(); + + mozilla::SVGImageContext svgContext; + mozilla::SVGImageContext::MaybeStoreContextPaint(svgContext, aPaintContext, + aImage); + NSImage* image = + [MOZIconHelper iconImageFromImageContainer:aImage + withSize:NSMakeSize(256, 256) + svgContext:&svgContext + scaleFactor:0.0]; + image.resizingMode = NSImageResizingModeStretch; + mDockBadgeView.image = image; + + return UpdateDockTile(); + + NS_OBJC_END_TRY_BLOCK_RETURN(NS_ERROR_FAILURE) +} + NS_IMETHODIMP nsMacDockSupport::SetProgressState(nsTaskbarProgressState aState, uint64_t aCurrentValue, uint64_t aMaxValue) { @@ -158,46 +211,67 @@ nsMacDockSupport::SetProgressState(nsTaskbarProgressState aState, return UpdateDockTile(); } +void nsMacDockSupport::BuildDockTile() { + if (!mDockTileWrapperView) { + // Create the following NSView hierarchy: + // * mDockTileWrapperView (NSView) + // * imageView (NSImageView) <- has the application icon + // * mDockBadgeView (NSImageView) <- has the dock badge + // * mProgressDockOverlayView (MOZProgressDockOverlayView) <- draws the + // progress bar + + mDockTileWrapperView = + [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 32, 32)]; + mDockTileWrapperView.autoresizingMask = + NSViewWidthSizable | NSViewHeightSizable; + + NSImageView* imageView = + [[NSImageView alloc] initWithFrame:[mDockTileWrapperView bounds]]; + imageView.image = [NSImage imageNamed:@"NSApplicationIcon"]; + imageView.imageScaling = NSImageScaleAxesIndependently; + imageView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable; + [mDockTileWrapperView addSubview:imageView]; + + mDockBadgeView = + [[NSImageView alloc] initWithFrame:NSMakeRect(19.5, 19.5, 12, 12)]; + mDockBadgeView.imageScaling = NSImageScaleProportionallyUpOrDown; + mDockBadgeView.autoresizingMask = NSViewMinXMargin | NSViewWidthSizable | + NSViewMaxXMargin | NSViewMinYMargin | + NSViewHeightSizable | NSViewMaxYMargin; + [mDockTileWrapperView addSubview:mDockBadgeView]; + + mProgressDockOverlayView = [[MOZProgressDockOverlayView alloc] + initWithFrame:NSMakeRect(1, 3, 30, 4)]; + mProgressDockOverlayView.autoresizingMask = + NSViewMinXMargin | NSViewWidthSizable | NSViewMaxXMargin | + NSViewMinYMargin | NSViewHeightSizable | NSViewMaxYMargin; + [mDockTileWrapperView addSubview:mProgressDockOverlayView]; + } +} + nsresult nsMacDockSupport::UpdateDockTile() { NS_OBJC_BEGIN_TRY_BLOCK_RETURN; - if (mProgressState == STATE_NORMAL || mProgressState == STATE_INDETERMINATE) { - if (!mDockTileWrapperView) { - // Create the following NSView hierarchy: - // * mDockTileWrapperView (NSView) - // * imageView (NSImageView) <- has the application icon - // * mProgressDockOverlayView (MOZProgressDockOverlayView) <- draws the - // progress bar + if (mProgressState == STATE_NORMAL || mProgressState == STATE_INDETERMINATE || + mHasBadgeImage) { + BuildDockTile(); - mDockTileWrapperView = - [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 32, 32)]; - mDockTileWrapperView.autoresizingMask = - NSViewWidthSizable | NSViewHeightSizable; - - NSImageView* imageView = - [[NSImageView alloc] initWithFrame:[mDockTileWrapperView bounds]]; - imageView.image = [NSImage imageNamed:@"NSApplicationIcon"]; - imageView.imageScaling = NSImageScaleAxesIndependently; - imageView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable; - [mDockTileWrapperView addSubview:imageView]; - - mProgressDockOverlayView = [[MOZProgressDockOverlayView alloc] - initWithFrame:NSMakeRect(1, 3, 30, 4)]; - mProgressDockOverlayView.autoresizingMask = - NSViewMinXMargin | NSViewWidthSizable | NSViewMaxXMargin | - NSViewMinYMargin | NSViewHeightSizable | NSViewMaxYMargin; - [mDockTileWrapperView addSubview:mProgressDockOverlayView]; - } if (NSApp.dockTile.contentView != mDockTileWrapperView) { NSApp.dockTile.contentView = mDockTileWrapperView; } + mDockBadgeView.hidden = !mHasBadgeImage; + if (mProgressState == STATE_NORMAL) { mProgressDockOverlayView.fractionValue = mProgressFraction; - } else { + mProgressDockOverlayView.hidden = false; + } else if (mProgressState == STATE_INDETERMINATE) { // Indeterminate states are rare. Just fill the entire progress bar in // that case. mProgressDockOverlayView.fractionValue = 1.0; + mProgressDockOverlayView.hidden = false; + } else { + mProgressDockOverlayView.hidden = true; } [NSApp.dockTile display]; } else if (NSApp.dockTile.contentView) { diff --git a/widget/cocoa/nsMenuItemIconX.mm b/widget/cocoa/nsMenuItemIconX.mm index 6749d787de09..c240408f8092 100644 --- a/widget/cocoa/nsMenuItemIconX.mm +++ b/widget/cocoa/nsMenuItemIconX.mm @@ -24,6 +24,7 @@ #include "MOZIconHelper.h" #include "mozilla/dom/Document.h" #include "mozilla/dom/DocumentInlines.h" +#include "mozilla/SVGImageContext.h" #include "nsCocoaUtils.h" #include "nsComputedDOMStyle.h" #include "nsContentUtils.h" @@ -152,11 +153,17 @@ nsresult nsMenuItemIconX::OnComplete(imgIContainer* aImage) { mIconImage = nil; } RefPtr pc = mPresContext.get(); + UniquePtr svgContext; + if (pc && mComputedStyle) { + svgContext = MakeUnique(); + SVGImageContext::MaybeStoreContextPaint(*svgContext, *pc, *mComputedStyle, + aImage); + } + mIconImage = [[MOZIconHelper iconImageFromImageContainer:aImage withSize:NSMakeSize(kIconSize, kIconSize) - presContext:pc - computedStyle:mComputedStyle + svgContext:svgContext.get() scaleFactor:0.0f] retain]; mComputedStyle = nullptr; mPresContext = nullptr; diff --git a/widget/cocoa/nsTouchBarInputIcon.mm b/widget/cocoa/nsTouchBarInputIcon.mm index 69e0c2aa0fc9..4c81b29cd891 100644 --- a/widget/cocoa/nsTouchBarInputIcon.mm +++ b/widget/cocoa/nsTouchBarInputIcon.mm @@ -127,8 +127,7 @@ nsresult nsTouchBarInputIcon::OnComplete(imgIContainer* aImage) { NSImage* image = [MOZIconHelper iconImageFromImageContainer:aImage withSize:NSMakeSize(kIconHeight, kIconHeight) - presContext:nullptr - computedStyle:nullptr + svgContext:nullptr scaleFactor:kHiDPIScalingFactor]; [mButton setImage:image]; [mShareScrubber setButtonImage:image]; diff --git a/widget/nsIMacDockSupport.idl b/widget/nsIMacDockSupport.idl index 6f0f1adbaeda..6b9179f56b0d 100644 --- a/widget/nsIMacDockSupport.idl +++ b/widget/nsIMacDockSupport.idl @@ -5,6 +5,8 @@ #include "nsISupports.idl" interface nsIStandaloneNativeMenu; +interface nsISVGPaintContext; +interface imgIContainer; /** * Allow applications to interface with the Mac OS X Dock. @@ -33,10 +35,17 @@ interface nsIMacDockSupport : nsISupports void activateApplication(in boolean aIgnoreOtherApplications); /** - * Text used to badge the dock tile. + * Text used to badge the dock tile. Setting this will remove any badge image. */ attribute AString badgeText; + /** + * An image to add to the dock icon as a badge. Setting this will remove any + * badgeText. If an SVG image is passed the given paint context is used to + * set the stroke and fill properties. + */ + void setBadgeImage(in imgIContainer aBadgeImage, [optional] in nsISVGPaintContext aPaintContext); + /** * True if this app is in the list of apps that are persisted to the macOS * Dock (as if the user selected "Keep in Dock").