diff --git a/gfx/thebes/gfxFont.h b/gfx/thebes/gfxFont.h index d28f1f331e7..252678d0638 100644 --- a/gfx/thebes/gfxFont.h +++ b/gfx/thebes/gfxFont.h @@ -1406,6 +1406,16 @@ public: return mFontEntry->HasGraphiteTables(); } + // Whether this is a font that may be doing full-color rendering, + // and therefore needs us to use a mask for text-shadow even when + // we're not actually blurring. + bool AlwaysNeedsMaskForShadow() { + return mFontEntry->TryGetColorGlyphs() || + mFontEntry->TryGetSVGData(this) || + mFontEntry->HasFontTable(TRUETYPE_TAG('C','B','D','T')) || + mFontEntry->HasFontTable(TRUETYPE_TAG('s','b','i','x')); + } + // whether a feature is supported by the font (limited to a small set // of features for which some form of fallback needs to be implemented) bool SupportsFeature(int32_t aScript, uint32_t aFeatureTag); diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp index 6321c23cf80..497741f16f5 100644 --- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -5543,7 +5543,8 @@ nsTextFrame::PaintOneShadow(uint32_t aOffset, uint32_t aLength, const gfxPoint& aFramePt, const gfxPoint& aTextBaselinePt, gfxContext* aCtx, const nscolor& aForegroundColor, const nsCharClipDisplayItem::ClipEdges& aClipEdges, - nscoord aLeftSideOffset, gfxRect& aBoundingBox) + nscoord aLeftSideOffset, gfxRect& aBoundingBox, + uint32_t aBlurFlags) { PROFILER_LABEL("nsTextFrame", "PaintOneShadow", js::ProfileEntry::Category::GRAPHICS); @@ -5564,7 +5565,8 @@ nsTextFrame::PaintOneShadow(uint32_t aOffset, uint32_t aLength, nsContextBoxBlur contextBoxBlur; gfxContext* shadowContext = contextBoxBlur.Init(shadowRect, 0, blurRadius, PresContext()->AppUnitsPerDevPixel(), - aCtx, aDirtyRect, nullptr); + aCtx, aDirtyRect, nullptr, + aBlurFlags); if (!shadowContext) return; @@ -6076,13 +6078,28 @@ nsTextFrame::PaintShadows(nsCSSShadowArray* aShadow, shadowMetrics.mAdvanceWidth, shadowMetrics.mAscent + shadowMetrics.mDescent); shadowMetrics.mBoundingBox.UnionRect(shadowMetrics.mBoundingBox, decorationRect); + + // If the textrun uses any color or SVG fonts, we need to force use of a mask + // for shadow rendering even if blur radius is zero. + uint32_t blurFlags = 0; + uint32_t numGlyphRuns; + const gfxTextRun::GlyphRun* run = mTextRun->GetGlyphRuns(&numGlyphRuns); + while (numGlyphRuns-- > 0) { + if (run->mFont->AlwaysNeedsMaskForShadow()) { + blurFlags = nsContextBoxBlur::FORCE_MASK; + break; + } + run++; + } + for (uint32_t i = aShadow->Length(); i > 0; --i) { PaintOneShadow(aOffset, aLength, aShadow->ShadowAt(i - 1), &aProvider, aDirtyRect, aFramePt, aTextBaselinePt, aCtx, aForegroundColor, aClipEdges, aLeftEdgeOffset, - shadowMetrics.mBoundingBox); + shadowMetrics.mBoundingBox, + blurFlags); } } diff --git a/layout/generic/nsTextFrame.h b/layout/generic/nsTextFrame.h index fa6ef6ea87c..7a085b7caf4 100644 --- a/layout/generic/nsTextFrame.h +++ b/layout/generic/nsTextFrame.h @@ -582,7 +582,8 @@ protected: const nscolor& aForegroundColor, const nsCharClipDisplayItem::ClipEdges& aClipEdges, nscoord aLeftSideOffset, - gfxRect& aBoundingBox); + gfxRect& aBoundingBox, + uint32_t aBlurFlags); void PaintShadows(nsCSSShadowArray* aShadow, uint32_t aOffset, uint32_t aLength,