Bug 139322

Summary: Setting the "vector-effect" attribute in the SVG <text> tag to "non-scaling-stroke" has no effect
Product: WebKit Reporter: Said Abou-Hallawa <sabouhallawa>
Component: SVGAssignee: Nikolas Zimmermann <zimmermann>
Status: RESOLVED FIXED    
Severity: Normal CC: karlcow, maggotfish, mario, tgym.candycorn+bugzilla, tombigel, webkit-bug-importer, zimmermann
Priority: P2 Keywords: BrowserCompat, InRadar
Version: 528+ (Nightly build)   
Hardware: Unspecified   
OS: Unspecified   
Bug Depends on: 258120    
Bug Blocks:    
Attachments:
Description Flags
Safari-Rendering
none
FireFox-Rendering none

Description Said Abou-Hallawa 2014-12-05 16:20:06 PST
Open the following svg in WebKit:

<svg xmlns="http://www.w3.org/2000/svg">
  <g id="g" style="font: 16px sans-serif; text-rendering: geometricPrecision" transform="scale(2)">
    <text x="50" y="50" stroke="blue" stroke-width="3">hello there</text>
  </g>
  <g id="g" style="font: 16px sans-serif; text-rendering: geometricPrecision" transform="translate(0, 100) scale(2)">
    <text x="50" y="50" stroke="blue" stroke-width="3" vector-effect="non-scaling-stroke">hello there</text>
  </g>
  <g id="g" style="font: 32px sans-serif; text-rendering: geometricPrecision" transform="translate(0, 200)">
    <text x="100" y="100" stroke="blue" stroke-width="3" >hello there</text>
  </g>
</svg>

Result: The stroke of the text in the first and the second lines are scaled up.
Expected: 
- Only the first line should have the stroke width scaled up. 
- The second line is scaled using transform="translate(0, 100) scale(2)" but the attribute vector-effect="non-scaling-stroke" is added to the <text> tag. So the stroke width should not scale up.
- The third line is scaled manually: the font size (in the <g> tag), the x and the y (in the <text> tag) are doubled.
Comment 1 Said Abou-Hallawa 2014-12-05 16:23:33 PST
Created attachment 242674 [details]
Safari-Rendering
Comment 2 Said Abou-Hallawa 2014-12-05 16:23:57 PST
Created attachment 242675 [details]
FireFox-Rendering
Comment 3 Radar WebKit Bug Importer 2014-12-05 16:24:52 PST
<rdar://problem/19163695>
Comment 4 Brad Bice 2019-05-09 10:40:16 PDT
This is still happening in Safari Version 12.1 (14607.1.40.1.4).

CSS rules applied to SVG or SVG element children also have no effect.
Comment 5 Julius Tarng 2021-08-31 06:56:31 PDT
Still experiencing this bug in latest Safari. Any known workarounds or updates on status?
Comment 6 Yehonatan Daniv 2022-08-31 07:16:05 PDT
Still experiencing this today: https://twitter.com/bigel/status/1564977943872520197?s=20&t=SVNrk_3Vvggd42pDvMNblg
Comment 7 Tom Bigelajzen 2022-08-31 07:22:11 PDT
FYI This was fixed in Chromium on 2015
https://bugs.chromium.org/p/chromium/issues/detail?id=475203
Comment 8 Nikolas Zimmermann 2023-06-14 10:42:07 PDT
I have been working on a fix on this. While testing I found out another Chrome/Blink specific issue: 'text-rendering: geometricPrecision' breaks 'vector-effect: non-scaling-stroke' for text.

Since recently our text-rendering handling for geometricPrecision was aligned with Chrome/Blink we're plagued by the same issue, breaking 'vector-effect: non-scaling-stroke'.

Here's a breakdown of the problem/issue:

RenderSVGInlineText chooses a FontDescription with a size "close" to the final on-screen size (mapping the <text> object through all ancestor-defined transformations until either a composited ancestor or the root RenderView is reached).

When painting with such a "scaled font", one needs to scale e.g. the used stroke-width by the scale factor used to select the "scaled font". To implement support for non-scaling stroke, one can simply omit the scaling factor (that was missing so far in WebKit, and is implemented like this in Blink).

However when text-rendering: geometricPrecision is used, we do NOT select a "scaled font", but instead use the font-size as specified in the document, and rely on scaling the CTM prior to rendering with that font. Therefore the reported scalingFactor is 1 - omitting a scale factor of 1 or applying it has the same result - therefore non-scaling-stroke is broken, when implemented this way.

Trying the following in Chrome and Firefox:

<svg xmlns="http://www.w3.org/2000/svg">
  <g id="g" style="font: 16px sans-serif; text-rendering: geometricPrecision" transform="translate(0, 100) scale(2)">
    <text x="50" y="50" stroke="blue" stroke-width="3" vector-effect="non-scaling-stroke">hello there</text>
  </g>
</svg>

(line 2 from Saids test case)

--> works in Gecko, broken in Blink, and broken in WebKit (when implementing this as in Chromium/Blink).

The full fix needs to handle non-scaling-stroke for the two text-rendering modes: geometricPrecision vs. default text-rendering mode, support for various device scale factors, support for legacy engine and LBSE. PR will follow.
Comment 9 Nikolas Zimmermann 2023-06-14 16:40:49 PDT
Pull request: https://github.com/WebKit/WebKit/pull/14977
Comment 10 Nikolas Zimmermann 2023-06-15 04:20:28 PDT
When webkit.org/b/258120 lands, the PR associated with this ticket implements support for non-scaling-stroke for both the legacy SVG engine & LBSE in one shot.
Comment 11 EWS 2023-06-15 11:32:36 PDT
Committed 265204@main (7eeb61cf4db4): <https://commits.webkit.org/265204@main>

Reviewed commits have been landed. Closing PR #14977 and removing active labels.