зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
c74815dce0
Коммит
20b8aec4d5
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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=(");
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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>
|
После Ширина: | Высота: | Размер: 193 B |
|
@ -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>
|
После Ширина: | Высота: | Размер: 191 B |
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
После Ширина: | Высота: | Размер: 269 B |
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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/*)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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];
|
||||
|
|
Загрузка…
Ссылка в новой задаче