Bug 1764354 - Propagate color-scheme preference to SVG images on chrome documents. r=aosmond

This allows favicons to respect the user theme even when it doesn't
match the content theme.

Differential Revision: https://phabricator.services.mozilla.com/D143639
This commit is contained in:
Emilio Cobos Álvarez 2022-04-17 20:38:01 +00:00
parent c74815dce0
commit 20b8aec4d5
25 changed files with 170 additions and 66 deletions

View File

@ -205,6 +205,7 @@
#include "mozilla/dom/PromiseNativeHandler.h"
#include "mozilla/dom/ResizeObserverController.h"
#include "mozilla/dom/SVGElement.h"
#include "mozilla/dom/SVGDocument.h"
#include "mozilla/dom/SVGSVGElement.h"
#include "mozilla/dom/SVGUseElement.h"
#include "mozilla/dom/ScriptLoader.h"

View File

@ -10,11 +10,14 @@
#include "mozilla/AutoRestore.h"
#include "mozilla/SVGContextPaint.h"
#include "mozilla/dom/SVGSVGElement.h"
#include "nsPresContext.h"
#include "SVGDrawingParameters.h"
#include "SVGDocumentWrapper.h"
#include "mozilla/dom/DocumentInlines.h"
#include "mozilla/dom/SVGDocument.h"
#include "mozilla/dom/BrowsingContextBinding.h"
namespace mozilla {
namespace image {
namespace mozilla::image {
class MOZ_STACK_CLASS AutoRestoreSVGState final {
public:
@ -28,17 +31,27 @@ class MOZ_STACK_CLASS AutoRestoreSVGState final {
float aAnimationTime,
SVGDocumentWrapper* aSVGDocumentWrapper,
bool aContextPaint)
: mIsDrawing(aSVGDocumentWrapper->mIsDrawing)
: mIsDrawing(aSVGDocumentWrapper->mIsDrawing),
// Apply any 'preserveAspectRatio' override (if specified) to the root
// element:
,
mPAR(aSVGContext, aSVGDocumentWrapper->GetRootSVGElem())
mPAR(aSVGContext, aSVGDocumentWrapper->GetRootSVGElem()),
// Set the animation time:
,
mTime(aSVGDocumentWrapper->GetRootSVGElem(), aAnimationTime) {
MOZ_ASSERT(!mIsDrawing.SavedValue());
MOZ_ASSERT(aSVGDocumentWrapper->GetDocument());
if (auto* pc = aSVGDocumentWrapper->GetDocument()->GetPresContext()) {
pc->SetColorSchemeOverride([&] {
if (aSVGContext && aSVGContext->GetColorScheme()) {
auto scheme = *aSVGContext->GetColorScheme();
return scheme == ColorScheme::Light
? dom::PrefersColorSchemeOverride::Light
: dom::PrefersColorSchemeOverride::Dark;
}
return dom::PrefersColorSchemeOverride::None;
}());
}
aSVGDocumentWrapper->mIsDrawing = true;
// Set context paint (if specified) on the document:
@ -56,7 +69,6 @@ class MOZ_STACK_CLASS AutoRestoreSVGState final {
Maybe<AutoSetRestoreSVGContextPaint> mContextPaint;
};
} // namespace image
} // namespace mozilla
} // namespace mozilla::image
#endif // mozilla_image_AutoRestoreSVGState_h

View File

@ -450,6 +450,11 @@ class imgMemoryReporter final : public nsIMemoryReporter {
LossyAppendUTF16toASCII(aspect, surfacePathPrefix);
surfacePathPrefix.AppendLiteral(") ");
}
if (auto scheme = context.GetColorScheme()) {
surfacePathPrefix.AppendLiteral("colorScheme=");
surfacePathPrefix.AppendInt(int32_t(*scheme));
surfacePathPrefix.AppendLiteral(" ");
}
if (context.GetContextPaint()) {
const SVGEmbeddingContextPaint* paint = context.GetContextPaint();
surfacePathPrefix.AppendLiteral("contextPaint=(");

View File

@ -6706,7 +6706,8 @@ ImgDrawResult nsLayoutUtils::DrawImage(
const nsRect& aFill, const nsPoint& aAnchor, const nsRect& aDirty,
uint32_t aImageFlags, float aOpacity) {
Maybe<SVGImageContext> svgContext;
SVGImageContext::MaybeStoreContextPaint(svgContext, aComputedStyle, aImage);
SVGImageContext::MaybeStoreContextPaint(svgContext, *aPresContext,
*aComputedStyle, aImage);
return DrawImageInternal(aContext, aPresContext, aImage, aSamplingFilter,
aDest, aFill, aAnchor, aDirty, svgContext,

View File

@ -887,6 +887,22 @@ Maybe<ColorScheme> nsPresContext::GetOverriddenOrEmbedderColorScheme() const {
return Nothing();
}
void nsPresContext::SetColorSchemeOverride(
PrefersColorSchemeOverride aOverride) {
auto oldScheme = mDocument->PreferredColorScheme();
mOverriddenOrEmbedderColorScheme = aOverride;
if (mDocument->PreferredColorScheme() != oldScheme) {
// We need to restyle because not only media queries have changed, system
// colors may as well via the prefers-color-scheme meta tag / effective
// color-scheme property value.
MediaFeatureValuesChanged({RestyleHint::RecascadeSubtree(), nsChangeHint(0),
MediaFeatureChangeReason::SystemMetricsChange},
MediaFeatureChangePropagation::JustThisDocument);
}
}
void nsPresContext::RecomputeBrowsingContextDependentData() {
MOZ_ASSERT(mDocument);
dom::Document* doc = mDocument;
@ -905,9 +921,8 @@ void nsPresContext::RecomputeBrowsingContextDependentData() {
SetTextZoom(browsingContext->TextZoom());
SetOverrideDPPX(browsingContext->OverrideDPPX());
auto oldScheme = mDocument->PreferredColorScheme();
auto* top = browsingContext->Top();
mOverriddenOrEmbedderColorScheme = [&] {
SetColorSchemeOverride([&] {
auto overriden = top->PrefersColorSchemeOverride();
if (overriden != PrefersColorSchemeOverride::None) {
return overriden;
@ -919,16 +934,7 @@ void nsPresContext::RecomputeBrowsingContextDependentData() {
}
}
return PrefersColorSchemeOverride::None;
}();
if (mDocument->PreferredColorScheme() != oldScheme) {
// We need to restyle because not only media queries have changed, system
// colors may as well via the prefers-color-scheme meta tag / effective
// color-scheme property value.
MediaFeatureValuesChanged({RestyleHint::RecascadeSubtree(), nsChangeHint(0),
MediaFeatureChangeReason::SystemMetricsChange},
MediaFeatureChangePropagation::JustThisDocument);
}
}());
if (doc == mDocument) {
// Medium doesn't apply to resource documents, etc.

View File

@ -592,6 +592,11 @@ class nsPresContext : public nsISupports, public mozilla::SupportsWeakPtr {
*/
void RecomputeBrowsingContextDependentData();
/**
* Sets the effective color scheme override, and invalidate stuff as needed.
*/
void SetColorSchemeOverride(mozilla::dom::PrefersColorSchemeOverride);
mozilla::CSSCoord GetAutoQualityMinFontSize() const {
return DevPixelsToFloatCSSPixels(mAutoQualityMinFontSizePixelsPref);
}

View File

@ -0,0 +1,6 @@
<svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<style>
:root { color: purple }
</style>
<rect fill="currentColor" width="32" height="32"/>
</svg>

After

Width:  |  Height:  |  Size: 193 B

View File

@ -0,0 +1,6 @@
<svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<style>
:root { color: blue }
</style>
<rect fill="currentColor" width="32" height="32"/>
</svg>

After

Width:  |  Height:  |  Size: 191 B

View File

@ -0,0 +1,7 @@
<!doctype html>
<div style="color-scheme: light">
<img src="prefers-color-scheme-light.svg">
</div>
<div style="color-scheme: dark">
<img src="prefers-color-scheme-dark.svg">
</div>

View File

@ -0,0 +1,7 @@
<!doctype html>
<div style="color-scheme: light">
<img src="prefers-color-scheme.svg">
</div>
<div style="color-scheme: dark">
<img src="prefers-color-scheme.svg">
</div>

View File

@ -0,0 +1,9 @@
<svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<style>
:root { color: blue }
@media (prefers-color-scheme: dark) {
:root { color: purple }
}
</style>
<rect fill="currentColor" width="32" height="32"/>
</svg>

After

Width:  |  Height:  |  Size: 269 B

View File

@ -2,3 +2,5 @@ defaults pref(layout.css.color-scheme.enabled,true)
!= color-scheme-basic.html color-scheme-basic-notref.html
!= color-scheme-themed-button.html color-scheme-themed-button-notref.html
== chrome://reftest/content/color-scheme/prefers-color-scheme-svg-image.html chrome://reftest/content/color-scheme/prefers-color-scheme-svg-image-ref.html

View File

@ -10,6 +10,8 @@
// Keep others in (case-insensitive) order:
#include "gfxUtils.h"
#include "mozilla/Preferences.h"
#include "mozilla/LookAndFeel.h"
#include "mozilla/dom/Document.h"
#include "nsIFrame.h"
#include "nsPresContext.h"
#include "nsStyleStruct.h"
@ -20,23 +22,33 @@ namespace mozilla {
void SVGImageContext::MaybeStoreContextPaint(Maybe<SVGImageContext>& aContext,
nsIFrame* aFromFrame,
imgIContainer* aImgContainer) {
return MaybeStoreContextPaint(aContext, aFromFrame->Style(), aImgContainer);
return MaybeStoreContextPaint(aContext, *aFromFrame->PresContext(),
*aFromFrame->Style(), aImgContainer);
}
/* static */
void SVGImageContext::MaybeStoreContextPaint(
Maybe<SVGImageContext>& aContext, const ComputedStyle* aFromComputedStyle,
imgIContainer* aImgContainer) {
const nsStyleSVG* style = aFromComputedStyle->StyleSVG();
if (!style->ExposesContextProperties()) {
// Content must have '-moz-context-properties' set to the names of the
// properties it wants to expose to images it links to.
void SVGImageContext::MaybeStoreContextPaint(Maybe<SVGImageContext>& aContext,
const nsPresContext& aPresContext,
const ComputedStyle& aStyle,
imgIContainer* aImgContainer) {
if (aImgContainer->GetType() != imgIContainer::TYPE_VECTOR) {
// Avoid this overhead for raster images.
return;
}
if (aImgContainer->GetType() != imgIContainer::TYPE_VECTOR) {
// Avoid this overhead for raster images.
if (aPresContext.Document()->IsDocumentURISchemeChrome()) {
if (!aContext) {
aContext.emplace();
}
auto scheme = LookAndFeel::ColorSchemeForStyle(
*aPresContext.Document(), aStyle.StyleUI()->mColorScheme.bits);
aContext->SetColorScheme(Some(scheme));
}
const nsStyleSVG* style = aStyle.StyleSVG();
if (!style->ExposesContextProperties()) {
// Content must have '-moz-context-properties' set to the names of the
// properties it wants to expose to images it links to.
return;
}
@ -47,14 +59,12 @@ void SVGImageContext::MaybeStoreContextPaint(
if ((style->mMozContextProperties.bits & StyleContextPropertyBits::FILL) &&
style->mFill.kind.IsColor()) {
haveContextPaint = true;
contextPaint->SetFill(
style->mFill.kind.AsColor().CalcColor(*aFromComputedStyle));
contextPaint->SetFill(style->mFill.kind.AsColor().CalcColor(aStyle));
}
if ((style->mMozContextProperties.bits & StyleContextPropertyBits::STROKE) &&
style->mStroke.kind.IsColor()) {
haveContextPaint = true;
contextPaint->SetStroke(
style->mStroke.kind.AsColor().CalcColor(*aFromComputedStyle));
contextPaint->SetStroke(style->mStroke.kind.AsColor().CalcColor(aStyle));
}
if (style->mMozContextProperties.bits &
StyleContextPropertyBits::FILL_OPACITY) {

View File

@ -16,11 +16,12 @@ class nsIFrame;
namespace mozilla {
enum class ColorScheme : uint8_t;
class ComputedStyle;
// SVG image-specific rendering context. For imgIContainer::Draw.
// Used to pass information such as
// - viewport information from CSS, and
// - viewport and color-scheme information from CSS, and
// - overridden attributes from an SVG <image> element
// to the image's internal SVG document when it's drawn.
class SVGImageContext {
@ -45,17 +46,19 @@ class SVGImageContext {
*/
explicit SVGImageContext(
const Maybe<CSSIntSize>& aViewportSize,
const Maybe<SVGPreserveAspectRatio>& aPreserveAspectRatio = Nothing())
const Maybe<SVGPreserveAspectRatio>& aPreserveAspectRatio = Nothing(),
const Maybe<ColorScheme>& aColorScheme = Nothing())
: mViewportSize(aViewportSize),
mPreserveAspectRatio(aPreserveAspectRatio) {}
mPreserveAspectRatio(aPreserveAspectRatio),
mColorScheme(aColorScheme) {}
static void MaybeStoreContextPaint(Maybe<SVGImageContext>& aContext,
nsIFrame* aFromFrame,
imgIContainer* aImgContainer);
static void MaybeStoreContextPaint(Maybe<SVGImageContext>& aContext,
const ComputedStyle* aFromComputedStyle,
imgIContainer* aImgContainer);
const nsPresContext&, const ComputedStyle&,
imgIContainer*);
const Maybe<CSSIntSize>& GetViewportSize() const { return mViewportSize; }
@ -63,6 +66,12 @@ class SVGImageContext {
mViewportSize = aSize;
}
const Maybe<ColorScheme>& GetColorScheme() const { return mColorScheme; }
void SetColorScheme(const Maybe<ColorScheme>& aScheme) {
mColorScheme = aScheme;
}
const Maybe<SVGPreserveAspectRatio>& GetPreserveAspectRatio() const {
return mPreserveAspectRatio;
}
@ -86,7 +95,8 @@ class SVGImageContext {
*mContextPaint == *aOther.mContextPaint);
return contextPaintIsEqual && mViewportSize == aOther.mViewportSize &&
mPreserveAspectRatio == aOther.mPreserveAspectRatio;
mPreserveAspectRatio == aOther.mPreserveAspectRatio &&
mColorScheme == aOther.mColorScheme;
}
bool operator!=(const SVGImageContext& aOther) const {
@ -99,7 +109,8 @@ class SVGImageContext {
hash = HashGeneric(hash, mContextPaint->Hash());
}
return HashGeneric(hash, mViewportSize.map(HashSize).valueOr(0),
mPreserveAspectRatio.map(HashPAR).valueOr(0));
mPreserveAspectRatio.map(HashPAR).valueOr(0),
mColorScheme.map(HashColorScheme).valueOr(0));
}
private:
@ -109,11 +120,15 @@ class SVGImageContext {
static PLDHashNumber HashPAR(const SVGPreserveAspectRatio& aPAR) {
return aPAR.Hash();
}
static PLDHashNumber HashColorScheme(ColorScheme aScheme) {
return HashGeneric(uint8_t(aScheme));
}
// NOTE: When adding new member-vars, remember to update Hash() & operator==.
RefPtr<SVGEmbeddingContextPaint> mContextPaint;
Maybe<CSSIntSize> mViewportSize;
Maybe<SVGPreserveAspectRatio> mPreserveAspectRatio;
Maybe<ColorScheme> mColorScheme;
};
} // namespace mozilla

View File

@ -12,6 +12,7 @@ reftest.jar:
content/forms/placeholder (../../reftests/forms/placeholder/*)
content/forms/textbox (../../reftests/forms/textbox/*)
content/image-region (../../reftests/image-region/*)
content/color-scheme (../../reftests/color-scheme/*)
content/invalidation (../../reftests/invalidation/*)
content/native-theme (../../reftests/native-theme/*)
content/reftest-sanity (../../reftests/reftest-sanity/*)

View File

@ -3219,8 +3219,8 @@ ImgDrawResult nsTreeBodyFrame::PaintTwisty(
// Apply context paint if applicable
Maybe<SVGImageContext> svgContext;
SVGImageContext::MaybeStoreContextPaint(svgContext, twistyContext,
image);
SVGImageContext::MaybeStoreContextPaint(svgContext, *aPresContext,
*twistyContext, image);
// Paint the image.
result &= nsLayoutUtils::DrawSingleUnscaledImage(
@ -3593,7 +3593,8 @@ ImgDrawResult nsTreeBodyFrame::PaintCheckbox(int32_t aRowIndex,
// Apply context paint if applicable
Maybe<SVGImageContext> svgContext;
SVGImageContext::MaybeStoreContextPaint(svgContext, checkboxContext, image);
SVGImageContext::MaybeStoreContextPaint(svgContext, *aPresContext,
*checkboxContext, image);
// Paint the image.
result &= nsLayoutUtils::DrawSingleUnscaledImage(
aRenderingContext, aPresContext, image, SamplingFilter::POINT, pt,

View File

@ -11,6 +11,7 @@
#include "nsRect.h"
class imgIContainer;
class nsPresContext;
namespace mozilla {
class ComputedStyle;
@ -24,6 +25,7 @@ class ComputedStyle;
// Returns an autoreleased NSImage.
+ (NSImage*)iconImageFromImageContainer:(imgIContainer*)aImage
withSize:(NSSize)aSize
presContext:(const nsPresContext*)aPresContext
computedStyle:(const mozilla::ComputedStyle*)aComputedStyle
subrect:(const nsIntRect&)aSubRect
scaleFactor:(CGFloat)aScaleFactor;

View File

@ -22,6 +22,7 @@
// Returns an autoreleased NSImage.
+ (NSImage*)iconImageFromImageContainer:(imgIContainer*)aImage
withSize:(NSSize)aSize
presContext:(const nsPresContext*)aPresContext
computedStyle:(const mozilla::ComputedStyle*)aComputedStyle
subrect:(const nsIntRect&)aSubRect
scaleFactor:(CGFloat)aScaleFactor {
@ -30,11 +31,12 @@
nsresult rv;
if (aScaleFactor != 0.0f) {
rv = nsCocoaUtils::CreateNSImageFromImageContainer(aImage, imgIContainer::FRAME_CURRENT,
aComputedStyle, &retainedImage, aScaleFactor,
&isEntirelyBlack);
aPresContext, aComputedStyle, &retainedImage,
aScaleFactor, &isEntirelyBlack);
} else {
rv = nsCocoaUtils::CreateDualRepresentationNSImageFromImageContainer(
aImage, imgIContainer::FRAME_CURRENT, aComputedStyle, &retainedImage, &isEntirelyBlack);
aImage, imgIContainer::FRAME_CURRENT, aPresContext, aComputedStyle, &retainedImage,
&isEntirelyBlack);
}
NSImage* image = [retainedImage autorelease];

View File

@ -509,9 +509,9 @@ OSXNotificationCenter::OnImageReady(nsISupports* aUserData, imgIRequest* aReques
}
NSImage* cocoaImage = nil;
// TODO: Pass ComputedStyle here to support context paint properties
// TODO: Pass pres context / ComputedStyle here to support context paint properties
nsCocoaUtils::CreateDualRepresentationNSImageFromImageContainer(image, imgIContainer::FRAME_FIRST,
nullptr, &cocoaImage);
nullptr, nullptr, &cocoaImage);
(osxni->mPendingNotification).contentImage = cocoaImage;
[cocoaImage release];
ShowPendingNotification(osxni);

View File

@ -266,6 +266,7 @@ class nsCocoaUtils {
@return NS_OK if the conversion worked, NS_ERROR_FAILURE otherwise
*/
static nsresult CreateNSImageFromImageContainer(imgIContainer* aImage, uint32_t aWhichFrame,
const nsPresContext* aPresContext,
const mozilla::ComputedStyle* aComputedStyle,
NSImage** aResult, CGFloat scaleFactor,
bool* aIsEntirelyBlack = nullptr);
@ -284,8 +285,9 @@ class nsCocoaUtils {
@return NS_OK if the conversion worked, NS_ERROR_FAILURE otherwise
*/
static nsresult CreateDualRepresentationNSImageFromImageContainer(
imgIContainer* aImage, uint32_t aWhichFrame, const mozilla::ComputedStyle* aComputedStyle,
NSImage** aResult, bool* aIsEntirelyBlack = nullptr);
imgIContainer* aImage, uint32_t aWhichFrame, const nsPresContext* aPresContext,
const mozilla::ComputedStyle* aComputedStyle, NSImage** aResult,
bool* aIsEntirelyBlack = nullptr);
/**
* Returns nsAString for aSrc.

View File

@ -44,10 +44,8 @@ using namespace mozilla;
using namespace mozilla::widget;
using mozilla::dom::Promise;
using mozilla::gfx::BackendType;
using mozilla::gfx::DataSourceSurface;
using mozilla::gfx::DrawTarget;
using mozilla::gfx::Factory;
using mozilla::gfx::SamplingFilter;
using mozilla::gfx::IntPoint;
using mozilla::gfx::IntRect;
@ -55,7 +53,6 @@ using mozilla::gfx::IntSize;
using mozilla::gfx::SurfaceFormat;
using mozilla::gfx::SourceSurface;
using mozilla::image::ImageRegion;
using std::ceil;
LazyLogModule gCocoaUtilsLog("nsCocoaUtils");
#undef LOG
@ -389,6 +386,7 @@ nsresult nsCocoaUtils::CreateNSImageFromCGImage(CGImageRef aInputImage, NSImage*
}
nsresult nsCocoaUtils::CreateNSImageFromImageContainer(imgIContainer* aImage, uint32_t aWhichFrame,
const nsPresContext* aPresContext,
const ComputedStyle* aComputedStyle,
NSImage** aResult, CGFloat scaleFactor,
bool* aIsEntirelyBlack) {
@ -412,8 +410,8 @@ nsresult nsCocoaUtils::CreateNSImageFromImageContainer(imgIContainer* aImage, ui
MOZ_ASSERT(context);
Maybe<SVGImageContext> svgContext;
if (aComputedStyle) {
SVGImageContext::MaybeStoreContextPaint(svgContext, aComputedStyle, aImage);
if (aPresContext && aComputedStyle) {
SVGImageContext::MaybeStoreContextPaint(svgContext, *aPresContext, *aComputedStyle, aImage);
}
mozilla::image::ImgDrawResult res =
aImage->Draw(context, scaledSize, ImageRegion::Create(scaledSize), aWhichFrame,
@ -451,8 +449,8 @@ nsresult nsCocoaUtils::CreateNSImageFromImageContainer(imgIContainer* aImage, ui
}
nsresult nsCocoaUtils::CreateDualRepresentationNSImageFromImageContainer(
imgIContainer* aImage, uint32_t aWhichFrame, const ComputedStyle* aComputedStyle,
NSImage** aResult, bool* aIsEntirelyBlack) {
imgIContainer* aImage, uint32_t aWhichFrame, const nsPresContext* aPresContext,
const ComputedStyle* aComputedStyle, NSImage** aResult, bool* aIsEntirelyBlack) {
int32_t width = 0, height = 0;
aImage->GetWidth(&width);
aImage->GetHeight(&height);
@ -461,8 +459,8 @@ nsresult nsCocoaUtils::CreateDualRepresentationNSImageFromImageContainer(
[*aResult setSize:size];
NSImage* newRepresentation = nil;
nsresult rv = nsCocoaUtils::CreateNSImageFromImageContainer(
aImage, aWhichFrame, aComputedStyle, &newRepresentation, 1.0f, aIsEntirelyBlack);
nsresult rv = CreateNSImageFromImageContainer(aImage, aWhichFrame, aPresContext, aComputedStyle,
&newRepresentation, 1.0f, aIsEntirelyBlack);
if (NS_FAILED(rv) || !newRepresentation) {
return NS_ERROR_FAILURE;
}
@ -472,8 +470,8 @@ nsresult nsCocoaUtils::CreateDualRepresentationNSImageFromImageContainer(
[newRepresentation release];
newRepresentation = nil;
rv = nsCocoaUtils::CreateNSImageFromImageContainer(aImage, aWhichFrame, aComputedStyle,
&newRepresentation, 2.0f, aIsEntirelyBlack);
rv = CreateNSImageFromImageContainer(aImage, aWhichFrame, aPresContext, aComputedStyle,
&newRepresentation, 2.0f, aIsEntirelyBlack);
if (NS_FAILED(rv) || !newRepresentation) {
return NS_ERROR_FAILURE;
}

View File

@ -262,7 +262,7 @@ static constexpr nsCursor kCustomCursor = eCursorCount;
NSImage* cursorImage;
nsresult rv = nsCocoaUtils::CreateNSImageFromImageContainer(
aCursor.mContainer, imgIContainer::FRAME_FIRST, nullptr, &cursorImage, scaleFactor);
aCursor.mContainer, imgIContainer::FRAME_FIRST, nullptr, nullptr, &cursorImage, scaleFactor);
if (NS_FAILED(rv) || !cursorImage) {
return NS_ERROR_FAILURE;
}

View File

@ -20,6 +20,7 @@ class nsIContent;
class nsIPrincipal;
class imgRequestProxy;
class nsMenuParentX;
class nsPresContext;
namespace mozilla {
class ComputedStyle;
@ -58,10 +59,10 @@ class nsMenuItemIconX final : public mozilla::widget::IconLoader::Listener {
// GetIconURI returns null if the item should not have any icon.
already_AddRefed<nsIURI> GetIconURI(nsIContent* aContent);
nsCOMPtr<nsIContent> mContent; // always non-null
Listener* mListener; // [weak]
nsIntRect mImageRegionRect;
RefPtr<mozilla::ComputedStyle> mComputedStyle;
RefPtr<nsPresContext> mPresContext;
NSImage* mIconImage = nil; // [strong]
RefPtr<mozilla::widget::IconLoader> mIconLoader;
};

View File

@ -23,6 +23,7 @@
#include "MOZIconHelper.h"
#include "mozilla/dom/Document.h"
#include "mozilla/dom/DocumentInlines.h"
#include "nsCocoaUtils.h"
#include "nsComputedDOMStyle.h"
#include "nsContentUtils.h"
@ -150,6 +151,7 @@ already_AddRefed<nsIURI> nsMenuItemIconX::GetIconURI(nsIContent* aContent) {
mImageRegionRect = r.ToNearestPixels(mozilla::AppUnitsPerCSSPixel());
}
mComputedStyle = std::move(sc);
mPresContext = document->GetPresContext();
return iconURI.forget();
}
@ -168,10 +170,12 @@ nsresult nsMenuItemIconX::OnComplete(imgIContainer* aImage) {
mIconImage = [[MOZIconHelper iconImageFromImageContainer:aImage
withSize:NSMakeSize(kIconSize, kIconSize)
presContext:mPresContext
computedStyle:mComputedStyle
subrect:mImageRegionRect
scaleFactor:0.0f] retain];
mComputedStyle = nullptr;
mPresContext = nullptr;
if (mListener) {
mListener->IconUpdated();

View File

@ -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(kIconHeight, kIconHeight)
presContext:nullptr
computedStyle:nullptr
subrect:mImageRegionRect
scaleFactor:kHiDPIScalingFactor];