Backed out 2 changesets (bug 1816628) for causing OS X mochitests-plain failures in test_bug1426594.html.

Backed out changeset e32deae0b0b4 (bug 1816628)
Backed out changeset 3ee753e740b9 (bug 1816628)
This commit is contained in:
Stanca Serban 2024-02-24 06:38:52 +02:00
parent 1c092fded6
commit 71b51917c2
14 changed files with 71 additions and 204 deletions

View file

@ -115,7 +115,7 @@ function runTest() {
const sin45 = Math.sin(Math.PI / 4);
isfuzzy(text1Bounds.left, 23, 1, "text1.getBoundingClientRect().left");
isfuzzy(text1Bounds.left, 24, 1, "text1.getBoundingClientRect().left");
is(text2Bounds.left, text1Bounds.left + 100, "text2.getBoundingClientRect().left");
is(text2Bounds.top, text1Bounds.top, "text2.getBoundingClientRect().top");
@ -194,9 +194,9 @@ function runTest() {
var text2aBounds = doc.getElementById("text2a").getBoundingClientRect();
isfuzzy(text1aBounds.left, 81, 1, "text1a.getBoundingClientRect().left");
isfuzzy(text1aBounds.left, 82, 1, "text1a.getBoundingClientRect().left");
is(text1aBounds.width, text1Bounds.width + 4, "text1a.getBoundingClientRect().width");
isfuzzy(text1bBounds.width, text1Bounds.width + 170, 1, "text1b.getBoundingClientRect().width");
is(text1bBounds.width, text1Bounds.width, "text1b.getBoundingClientRect().width");
isfuzzy(text1bBounds.height, 196, 5, "text1b.getBoundingClientRect().height");
is(text2aBounds.left, text1aBounds.left + 100 - 3, "text2a.getBoundingClientRect().left");

View file

@ -165,7 +165,8 @@ class nsDisplayTextOverflowMarker final : public nsPaintedDisplayItem {
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
bool* aSnap) const override {
*aSnap = false;
return nsLayoutUtils::GetTextShadowRectsUnion(mRect, mFrame);
nsRect shadowRect = nsLayoutUtils::GetTextShadowRectsUnion(mRect, mFrame);
return mRect.Union(shadowRect);
}
virtual nsRect GetComponentAlphaBounds(

View file

@ -226,7 +226,6 @@ struct nsTextFrame::DrawTextRunParams {
float textStrokeWidth = 0.0f;
bool drawSoftHyphen = false;
bool hasTextShadow = false;
bool paintingShadows = false;
DrawTextRunParams(gfxContext* aContext,
mozilla::gfx::PaletteCache& aPaletteCache)
: context(aContext), paletteCache(aPaletteCache) {}
@ -277,7 +276,6 @@ struct nsTextFrame::PaintShadowParams {
Point framePt;
Point textBaselinePt;
gfxContext* context;
DrawPathCallbacks* callbacks = nullptr;
nscolor foregroundColor = NS_RGBA(0, 0, 0, 0);
const ClipEdges* clipEdges = nullptr;
PropertyProvider* provider = nullptr;
@ -5376,8 +5374,9 @@ void nsTextFrame::UnionAdditionalOverflow(nsPresContext* aPresContext,
// Text-shadow overflows
if (aIncludeShadows) {
*aInkOverflowRect =
nsRect shadowRect =
nsLayoutUtils::GetTextShadowRectsUnion(*aInkOverflowRect, this);
aInkOverflowRect->UnionRect(*aInkOverflowRect, shadowRect);
}
// When this frame is not selected, the text-decoration area must be in
@ -5461,7 +5460,6 @@ struct nsTextFrame::PaintDecorationLineParams
gfxFloat baselineOffset = 0.0f;
DecorationType decorationType = DecorationType::Normal;
DrawPathCallbacks* callbacks = nullptr;
bool paintingShadows = false;
};
void nsTextFrame::PaintDecorationLine(
@ -5476,11 +5474,9 @@ void nsTextFrame::PaintDecorationLine(
if (aParams.callbacks) {
Rect path = nsCSSRendering::DecorationLineToPath(params);
if (aParams.decorationType == DecorationType::Normal) {
aParams.callbacks->PaintDecorationLine(path, aParams.paintingShadows,
params.color);
aParams.callbacks->PaintDecorationLine(path, params.color);
} else {
aParams.callbacks->PaintSelectionDecorationLine(
path, aParams.paintingShadows, params.color);
aParams.callbacks->PaintSelectionDecorationLine(path, params.color);
}
} else {
nsCSSRendering::PaintDecorationLine(this, *aParams.context->GetDrawTarget(),
@ -5942,7 +5938,6 @@ void nsTextFrame::PaintOneShadow(const PaintShadowParams& aParams,
gfxFloat advanceWidth;
nsTextPaintStyle textPaintStyle(this);
DrawTextParams params(shadowContext, PresContext()->FontPaletteCache());
params.paintingShadows = true;
params.advanceWidth = &advanceWidth;
params.dirtyRect = aParams.dirtyRect;
params.framePt = aParams.framePt + shadowGfxOffset;
@ -5950,10 +5945,9 @@ void nsTextFrame::PaintOneShadow(const PaintShadowParams& aParams,
params.textStyle = &textPaintStyle;
params.textColor =
aParams.context == shadowContext ? shadowColor : NS_RGB(0, 0, 0);
params.callbacks = aParams.callbacks;
params.clipEdges = aParams.clipEdges;
params.drawSoftHyphen = HasAnyStateBits(TEXT_HYPHEN_BREAK);
// Multi-color shadow is not allowed, so we use the same color as the text
// Multi-color shadow is not allowed, so we use the same color of the text
// color.
params.decorationOverrideColor = &params.textColor;
params.fontPalette = StyleFont()->GetFontPaletteAtom();
@ -6259,7 +6253,6 @@ bool nsTextFrame::PaintTextWithSelectionColors(
PaintShadowParams shadowParams(aParams);
shadowParams.provider = aParams.provider;
shadowParams.callbacks = aParams.callbacks;
shadowParams.clipEdges = &aClipEdges;
// Draw text
@ -6822,7 +6815,6 @@ void nsTextFrame::PaintText(const PaintTextParams& aParams,
shadowParams.textBaselinePt = textBaselinePt;
shadowParams.leftSideOffset = snappedStartEdge;
shadowParams.provider = &provider;
shadowParams.callbacks = aParams.callbacks;
shadowParams.foregroundColor = foregroundColor;
shadowParams.clipEdges = &clipEdges;
PaintShadows(textStyle->mTextShadow.AsSpan(), shadowParams);
@ -6862,8 +6854,7 @@ static void DrawTextRun(const gfxTextRun* aTextRun,
params.callbacks = aParams.callbacks;
params.hasTextShadow = aParams.hasTextShadow;
if (aParams.callbacks) {
aParams.callbacks->NotifyBeforeText(aParams.paintingShadows,
aParams.textColor);
aParams.callbacks->NotifyBeforeText(aParams.textColor);
params.drawMode = DrawMode::GLYPH_PATH;
aTextRun->Draw(aRange, aTextBaselinePt, params);
aParams.callbacks->NotifyAfterText();
@ -7004,7 +6995,6 @@ void nsTextFrame::DrawTextRunAndDecorations(
params.callbacks = aParams.callbacks;
params.glyphRange = aParams.glyphRange;
params.provider = aParams.provider;
params.paintingShadows = aParams.paintingShadows;
// pt is the physical point where the decoration is to be drawn,
// relative to the frame; one of its coordinates will be updated below.
params.pt = Point(x / app, y / app);

View file

@ -513,22 +513,20 @@ class nsTextFrame : public nsIFrame {
* Called before (for under/over-line) or after (for line-through) the text
* is drawn to have a text decoration line drawn.
*/
virtual void PaintDecorationLine(Rect aPath, bool aPaintingShadows,
nscolor aColor) {}
virtual void PaintDecorationLine(Rect aPath, nscolor aColor) {}
/**
* Called after selected text is drawn to have a decoration line drawn over
* the text. (All types of text decoration are drawn after the text when
* text is selected.)
*/
virtual void PaintSelectionDecorationLine(Rect aPath, bool aPaintingShadows,
nscolor aColor) {}
virtual void PaintSelectionDecorationLine(Rect aPath, nscolor aColor) {}
/**
* Called just before any paths have been emitted to the gfxContext
* for the glyphs of the frame's text.
*/
virtual void NotifyBeforeText(bool aPaintingShadows, nscolor aColor) {}
virtual void NotifyBeforeText(nscolor aColor) {}
/**
* Called just after all the paths have been emitted to the gfxContext

View file

@ -133,7 +133,7 @@ fuzzy(0-4,0-100) == textLength-3.svg textLength-3-ref.svg
== textLength-6.svg textLength-6-ref.svg
# text-shadow
== text-shadow.svg text-shadow-ref.svg
fuzzy(0-127,0-5) fuzzy-if(Android,0-127,0-12) == text-shadow.svg text-shadow-ref.svg
# vertical text
== vertical-01.svg vertical-01-ref.svg
@ -173,7 +173,7 @@ fuzzy(0-4,0-100) == textLength-3.svg textLength-3-ref.svg
== dynamic-dominant-baseline.svg dynamic-dominant-baseline-ref.svg
== dynamic-multiple-x.svg dynamic-multiple-x-ref.svg
fuzzy(0-1,0-200) == dynamic-non-scaling-stroke.svg dynamic-non-scaling-stroke-ref.svg #Bug 885316
== dynamic-text-shadow.svg text-shadow-ref.svg
fuzzy(0-127,0-5) fuzzy-if(Android,0-127,0-41) == dynamic-text-shadow.svg text-shadow-ref.svg
# text and masks
fuzzy-if(winWidget,0-50,0-224) == mask-applied.svg mask-applied-ref.svg

View file

@ -800,18 +800,18 @@ SVGBBox TextRenderedRun::GetRunUserSpaceRect(nsPresContext* aContext,
return r;
}
// Determine the amount of overflow around frame's mRect.
// Determine the amount of overflow above and below the frame's mRect.
//
// We need to call InkOverflowRectRelativeToSelf because this includes
// overflowing decorations, which the MeasureText call below does not.
// overflowing decorations, which the MeasureText call below does not. We
// assume here the decorations only overflow above and below the frame, never
// horizontally.
nsRect self = mFrame->InkOverflowRectRelativeToSelf();
nsRect rect = mFrame->GetRect();
bool vertical = IsVertical();
nsMargin inkOverflow(
vertical ? -self.x : -self.y,
vertical ? self.YMost() - rect.height : self.XMost() - rect.width,
vertical ? self.XMost() - rect.width : self.YMost() - rect.height,
vertical ? -self.y : -self.x);
nscoord above = vertical ? -self.x : -self.y;
nscoord below =
vertical ? self.XMost() - rect.width : self.YMost() - rect.height;
gfxSkipCharsIterator it = mFrame->EnsureTextRun(nsTextFrame::eInflated);
gfxSkipCharsIterator start = it;
@ -838,7 +838,8 @@ SVGBBox TextRenderedRun::GetRunUserSpaceRect(nsPresContext* aContext,
metrics.mBoundingBox.UnionRect(metrics.mBoundingBox, fontBox);
// Determine the rectangle that covers the rendered run's fill,
// taking into account the measured overflow due to decorations.
// taking into account the measured vertical overflow due to
// decorations.
nscoord baseline =
NSToCoordRoundWithClamp(metrics.mBoundingBox.y + metrics.mAscent);
gfxFloat x, width;
@ -853,10 +854,10 @@ SVGBBox TextRenderedRun::GetRunUserSpaceRect(nsPresContext* aContext,
x = metrics.mBoundingBox.x;
width = metrics.mBoundingBox.width;
}
nsRect fillInAppUnits(NSToCoordRoundWithClamp(x), baseline,
NSToCoordRoundWithClamp(width),
NSToCoordRoundWithClamp(metrics.mBoundingBox.height));
fillInAppUnits.Inflate(inkOverflow);
nsRect fillInAppUnits(
NSToCoordRoundWithClamp(x), baseline - above,
NSToCoordRoundWithClamp(width),
NSToCoordRoundWithClamp(metrics.mBoundingBox.height) + above + below);
if (textRun->IsVertical()) {
// Swap line-relative textMetrics dimensions to physical coordinates.
std::swap(fillInAppUnits.x, fillInAppUnits.y);
@ -2412,11 +2413,9 @@ class SVGTextDrawPathCallbacks final : public nsTextFrame::DrawPathCallbacks {
void NotifySelectionBackgroundNeedsFill(const Rect& aBackgroundRect,
nscolor aColor,
DrawTarget& aDrawTarget) override;
void PaintDecorationLine(Rect aPath, bool aPaintingShadows,
nscolor aColor) override;
void PaintSelectionDecorationLine(Rect aPath, bool aPaintingShadows,
nscolor aColor) override;
void NotifyBeforeText(bool aPaintingShadows, nscolor aColor) override;
void PaintDecorationLine(Rect aPath, nscolor aColor) override;
void PaintSelectionDecorationLine(Rect aPath, nscolor aColor) override;
void NotifyBeforeText(nscolor aColor) override;
void NotifyGlyphPathEmitted() override;
void NotifyAfterText() override;
@ -2455,12 +2454,6 @@ class SVGTextDrawPathCallbacks final : public nsTextFrame::DrawPathCallbacks {
*/
void StrokeGeometry();
/*
* Takes a colour and modifies it to account for opacity properties.
*/
void ApplyOpacity(sRGBColor& aColor, const StyleSVGPaint& aPaint,
const StyleSVGOpacity& aOpacity) const;
SVGTextFrame* const mSVGTextFrame;
gfxContext& mContext;
nsTextFrame* const mFrame;
@ -2474,11 +2467,6 @@ class SVGTextDrawPathCallbacks final : public nsTextFrame::DrawPathCallbacks {
* painting selections or IME decorations.
*/
nscolor mColor;
/**
* Whether we're painting text shadows.
*/
bool mPaintingShadows;
};
void SVGTextDrawPathCallbacks::NotifySelectionBackgroundNeedsFill(
@ -2499,10 +2487,8 @@ void SVGTextDrawPathCallbacks::NotifySelectionBackgroundNeedsFill(
}
}
void SVGTextDrawPathCallbacks::NotifyBeforeText(bool aPaintingShadows,
nscolor aColor) {
void SVGTextDrawPathCallbacks::NotifyBeforeText(nscolor aColor) {
mColor = aColor;
mPaintingShadows = aPaintingShadows;
SetupContext();
mContext.NewPath();
}
@ -2514,11 +2500,8 @@ void SVGTextDrawPathCallbacks::NotifyGlyphPathEmitted() {
void SVGTextDrawPathCallbacks::NotifyAfterText() { mContext.Restore(); }
void SVGTextDrawPathCallbacks::PaintDecorationLine(Rect aPath,
bool aPaintingShadows,
nscolor aColor) {
void SVGTextDrawPathCallbacks::PaintDecorationLine(Rect aPath, nscolor aColor) {
mColor = aColor;
mPaintingShadows = aPaintingShadows;
AntialiasMode aaMode =
SVGUtils::ToAntialiasMode(mFrame->StyleText()->mTextRendering);
@ -2531,15 +2514,14 @@ void SVGTextDrawPathCallbacks::PaintDecorationLine(Rect aPath,
mContext.Restore();
}
void SVGTextDrawPathCallbacks::PaintSelectionDecorationLine(
Rect aPath, bool aPaintingShadows, nscolor aColor) {
void SVGTextDrawPathCallbacks::PaintSelectionDecorationLine(Rect aPath,
nscolor aColor) {
if (IsClipPathChild()) {
// Don't paint selection decorations when in a clip path.
return;
}
mColor = aColor;
mPaintingShadows = aPaintingShadows;
mContext.Save();
mContext.NewPath();
@ -2579,17 +2561,6 @@ void SVGTextDrawPathCallbacks::HandleTextGeometry() {
}
}
void SVGTextDrawPathCallbacks::ApplyOpacity(
sRGBColor& aColor, const StyleSVGPaint& aPaint,
const StyleSVGOpacity& aOpacity) const {
if (aPaint.kind.tag == StyleSVGPaintKind::Tag::Color) {
aColor.a *=
sRGBColor::FromABGR(aPaint.kind.AsColor().CalcColor(*mFrame->Style()))
.a;
}
aColor.a *= SVGUtils::GetOpacity(aOpacity, /*aContextPaint*/ nullptr);
}
void SVGTextDrawPathCallbacks::MakeFillPattern(GeneralPattern* aOutPattern) {
if (mColor == NS_SAME_AS_FOREGROUND_COLOR ||
mColor == NS_40PERCENT_FOREGROUND_COLOR) {
@ -2601,12 +2572,7 @@ void SVGTextDrawPathCallbacks::MakeFillPattern(GeneralPattern* aOutPattern) {
return;
}
sRGBColor color(sRGBColor::FromABGR(mColor));
if (mPaintingShadows) {
ApplyOpacity(color, mFrame->StyleSVG()->mFill,
mFrame->StyleSVG()->mFillOpacity);
}
aOutPattern->InitColorPattern(ToDeviceColor(color));
aOutPattern->InitColorPattern(ToDeviceColor(mColor));
}
void SVGTextDrawPathCallbacks::FillAndStrokeGeometry() {
@ -2641,9 +2607,6 @@ void SVGTextDrawPathCallbacks::FillAndStrokeGeometry() {
}
void SVGTextDrawPathCallbacks::FillGeometry() {
if (mFrame->StyleSVG()->mFill.kind.IsNone()) {
return;
}
GeneralPattern fillPattern;
MakeFillPattern(&fillPattern);
if (fillPattern.GetPattern()) {
@ -2659,44 +2622,39 @@ void SVGTextDrawPathCallbacks::FillGeometry() {
void SVGTextDrawPathCallbacks::StrokeGeometry() {
// We don't paint the stroke when we are filling with a selection color.
if (!(mColor == NS_SAME_AS_FOREGROUND_COLOR ||
mColor == NS_40PERCENT_FOREGROUND_COLOR || mPaintingShadows)) {
return;
}
if (mColor == NS_SAME_AS_FOREGROUND_COLOR ||
mColor == NS_40PERCENT_FOREGROUND_COLOR) {
if (SVGUtils::HasStroke(mFrame, /*aContextPaint*/ nullptr)) {
GeneralPattern strokePattern;
SVGUtils::MakeStrokePatternFor(mFrame, &mContext, &strokePattern,
mImgParams, /*aContextPaint*/ nullptr);
if (strokePattern.GetPattern()) {
if (!mFrame->GetParent()->GetContent()->IsSVGElement()) {
// The cast that follows would be unsafe
MOZ_ASSERT(false, "Our nsTextFrame's parent's content should be SVG");
return;
}
SVGElement* svgOwner =
static_cast<SVGElement*>(mFrame->GetParent()->GetContent());
if (!SVGUtils::HasStroke(mFrame, /*aContextPaint*/ nullptr)) {
return;
}
// Apply any stroke-specific transform
gfxMatrix outerSVGToUser;
if (SVGUtils::GetNonScalingStrokeTransform(mFrame, &outerSVGToUser) &&
outerSVGToUser.Invert()) {
mContext.Multiply(outerSVGToUser);
}
GeneralPattern strokePattern;
if (mPaintingShadows) {
sRGBColor color(sRGBColor::FromABGR(mColor));
ApplyOpacity(color, mFrame->StyleSVG()->mStroke,
mFrame->StyleSVG()->mStrokeOpacity);
strokePattern.InitColorPattern(ToDeviceColor(color));
} else {
SVGUtils::MakeStrokePatternFor(mFrame, &mContext, &strokePattern,
mImgParams, /*aContextPaint*/ nullptr);
}
if (strokePattern.GetPattern()) {
SVGElement* svgOwner =
SVGElement::FromNode(mFrame->GetParent()->GetContent());
// Apply any stroke-specific transform
gfxMatrix outerSVGToUser;
if (SVGUtils::GetNonScalingStrokeTransform(mFrame, &outerSVGToUser) &&
outerSVGToUser.Invert()) {
mContext.Multiply(outerSVGToUser);
RefPtr<Path> path = mContext.GetPath();
SVGContentUtils::AutoStrokeOptions strokeOptions;
SVGContentUtils::GetStrokeOptions(&strokeOptions, svgOwner,
mFrame->Style(),
/*aContextPaint*/ nullptr);
DrawOptions drawOptions;
drawOptions.mAntialiasMode =
SVGUtils::ToAntialiasMode(mFrame->StyleText()->mTextRendering);
mContext.GetDrawTarget()->Stroke(path, strokePattern, strokeOptions);
}
}
RefPtr<Path> path = mContext.GetPath();
SVGContentUtils::AutoStrokeOptions strokeOptions;
SVGContentUtils::GetStrokeOptions(&strokeOptions, svgOwner, mFrame->Style(),
/*aContextPaint*/ nullptr);
DrawOptions drawOptions;
drawOptions.mAntialiasMode =
SVGUtils::ToAntialiasMode(mFrame->StyleText()->mTextRendering);
mContext.GetDrawTarget()->Stroke(path, strokePattern, strokeOptions);
}
}
@ -4953,20 +4911,11 @@ bool SVGTextFrame::ShouldRenderAsPath(nsTextFrame* aFrame,
const nsStyleSVG* style = aFrame->StyleSVG();
// Fill is a non-solid paint or is not opaque.
// Fill is a non-solid paint, has a non-default fill-rule or has
// non-1 opacity.
if (!(style->mFill.kind.IsNone() ||
(style->mFill.kind.IsColor() &&
SVGUtils::GetOpacity(style->mFillOpacity, /*aContextPaint*/ nullptr) ==
1.0f))) {
return true;
}
// If we're going to need to draw a non-opaque shadow.
// It's possible nsTextFrame will support non-opaque shadows in the future,
// in which case this test can be removed.
if (style->mFill.kind.IsColor() && aFrame->StyleText()->HasTextShadow() &&
NS_GET_A(style->mFill.kind.AsColor().CalcColor(*aFrame->Style())) !=
0xFF) {
(style->mFill.kind.IsColor() && style->mFillOpacity.IsOpacity() &&
style->mFillOpacity.AsOpacity() == 1))) {
return true;
}

View file

@ -1,8 +0,0 @@
<!doctype html>
<style>
svg { font: bold 64px Arial, sans-serif; fill: none; stroke-width: 4px; }
</style>
<svg width="240" height="80">
<text x="40" y="60" stroke="grey">Hello</text>
<text x="30" y="50" stroke="black">Hello</text>
</svg>

View file

@ -1,10 +0,0 @@
<!doctype html>
<title>CSS Test: 'text-shadow' respects 'fill="none"'</title>
<link rel="help" href="https://www.w3.org/TR/css-text-decor-3/#text-shadow-property">
<link rel="match" href="svg-fill-none-ref.html">
<style>
svg { font: bold 64px Arial, sans-serif; text-shadow: grey 10px 10px }
</style>
<svg width="240" height="80">
<text x="30" y="50" fill="none" stroke="black" stroke-width="4">Hello</text>
</svg>

View file

@ -1,7 +0,0 @@
<!doctype html>
<style>
svg { font: bold 64px Arial, sans-serif; text-shadow: grey 10px 10px }
</style>
<svg width="240" height="80">
<text x="30" y="50" fill-opacity="0.5" fill="#FFFF00">Hello</text>
</svg>

View file

@ -1,10 +0,0 @@
<!doctype html>
<title>CSS Test: 'text-shadow' respects non-opaque fill</title>
<link rel="help" href="https://www.w3.org/TR/css-text-decor-3/#text-shadow-property">
<link rel="match" href="svg-fill-opacity-ref.html">
<style>
svg { font: bold 64px Arial, sans-serif; text-shadow: grey 10px 10px }
</style>
<svg width="240" height="80">
<text x="30" y="50" fill="rgba(255, 255, 0, 0.5)">Hello</text>
</svg>

View file

@ -1,8 +0,0 @@
<!doctype html>
<style>
svg { font: bold 64px Arial, sans-serif; fill: none; stroke-width: 2px; stroke-dasharray:2, 2; }
</style>
<svg width="240" height="80">
<text x="40" y="60" stroke="grey">Hello</text>
<text x="30" y="50" stroke="black">Hello</text>
</svg>

View file

@ -1,10 +0,0 @@
<!doctype html>
<title>CSS Test: 'text-shadow' respects stroke-dasharray</title>
<link rel="help" href="https://www.w3.org/TR/css-text-decor-3/#text-shadow-property">
<link rel="match" href="svg-stroke-dasharray-ref.html">
<style>
svg { font: bold 64px Arial, sans-serif; text-shadow: grey 10px 10px }
</style>
<svg width="240" height="80">
<text x="30" y="50" fill="none" stroke="black" stroke-width="2" stroke-dasharray="2, 2">Hello</text>
</svg>

View file

@ -1,8 +0,0 @@
<!doctype html>
<style>
svg { font: bold 64px Arial, sans-serif; stroke: black; stroke-width: 4px; }
</style>
<svg width="240" height="80">
<text x="40" y="60" fill="grey" stroke="grey">Hello</text>
<text x="30" y="50">Hello</text>
</svg>

View file

@ -1,10 +0,0 @@
<!doctype html>
<title>CSS Test: 'text-shadow' respects stroke</title>
<link rel="help" href="https://www.w3.org/TR/css-text-decor-3/#text-shadow-property">
<link rel="match" href="svg-stroke-ref.html">
<style>
svg { font: bold 64px Arial, sans-serif; text-shadow: grey 10px 10px }
</style>
<svg width="240" height="80">
<text x="30" y="50" stroke="black" stroke-width="4">Hello</text>
</svg>