w3c / svgwg

SVG Working Group specifications
Other
704 stars 132 forks source link

Compatibility mid-line rendering attribute to textPath #337

Open msand opened 7 years ago

msand commented 7 years ago

Specification: SVG 2, Text chapter, 11.8.3. Text on a path layout rules https://svgwg.org/svg2-draft/text.html#GlyphMidline And following list item.

Excerpt:

Determine the glyph-midline, which is the vertical line in the glyph's coordinate system that goes through the glyph's x-axis midpoint. (In the picture above, the glyph-midline is shown as a dashed line.)

Position the glyph such that the glyph-midline passes through the midpoint-on-the-path and is perpendicular to the line through the startpoint-on-the-path and the endpoint-on-the-path.

This wording is different from how Chrome, Firefox, Opera etc render text on a path. Only Edge seems to actually implement this. I'm implementing and improving the svg spec conformance of react-native-svg, and have implemented both algorithms almost completely (extending the path for the start to end-point calculation, when midpoint is on the path but either start or end is not, is still missing). https://github.com/react-native-community/react-native-svg/pull/406

I suggest adding a compatibility 'mid-line' attribute for the 'textPath' element, with the values 'sharp | smooth', initial value 'smooth'. The initial value would be the strict interpretation of the spec, and sharp would be the one currently implemented in the wild.

 Name
 mid-line
 Value
 sharp | smooth
 initial value
 smooth
 Animatable
 yes

The current common behavior is that it doesn't e.g., bend text smoothly along a right angle curve, (like Edge does) but keeps the mid-line orthogonal to the mid-point tangent at all times instead.

I've already added this attribute to react-native-svg in my fork: https://github.com/msand/react-native-svg/commit/d08103168a4ee78c163f2614e5f3e8e7cede6b9d

Example screenshot: (Smooth on top, sharp below) screenshot_1501031659

msand commented 7 years ago

Svg used in example:

<svg width="900" height="600" viewBox="180 0 330 220" xmlns="http://www.w3.org/2000/svg">
    <defs>
        <path id="textpath" d="M225,150 v-80 h240 v80 Z"></path>
    </defs>
    <use href="#textpath" stroke="#00f" stroke-width="1px" fill="none"></use>
    <text stroke="#000" word-spacing="0" letter-spacing="2" alignment-baseline="top" style="font-family:AvenirNextLTPro-Regular;font-size:20">
        <textPath href="#textpath" letter-spacing="2">
            <tspan letter-spacing="2" alignment-baseline="bottom" dx="73" dy="-5">SVG Text on a linear path test, testing 1, 2, 3, fi.</tspan>
        </textPath>
    </text>
</svg>
msand commented 7 years ago

Also, I suggest a change in wording in the first paragraph after the layout rules list:

In the calculations above, if either the startpoint-on-the-path or the endpoint-on-the-path is off the end of the path, then extend the path beyond its end points with a straight line that is parallel to the tangent at the path at its end point so that the midpoint-on-the-path can still be calculated.

change:

so that the midpoint-on-the-path can still be calculated.

to:

so that the line through the startpoint-on-the-path and the endpoint-on-the-path can still be calculated.

or to:

so that the angle of the glyph-midline to the x-axis can still be calculated.

msand commented 7 years ago

The two implementations: https://github.com/msand/react-native-svg/blob/0dbddcc2b4b375e8ae122b47d9c5941013b9d2d7/android/src/main/java/com/horcrux/svg/TSpanShadowNode.java#L770-L846

msand commented 7 years ago

@AmeliaBR @karip @BigBadaboom @fsoder Any guidance how to proceed here? Is there anything I can/should do?

fsoder commented 7 years ago

You could file bugs on implementations to gauge any "interest" in fixing the current behavior. The difficult part to assess there is if there's any content (and, if so, how much) that might depend on the current behavior. That's for the feature/behavior as currently speced. For the new feature, it would be possible to do roughly the same (attempt to gather implementer interest.) Actually getting it in the spec seems unlikely to happen before SVG2 work has gained sufficient momentum (IIRC, the current charter puts new features on the back-burner. This does of course not prevent experimentation et.c.)

msand commented 7 years ago

@fsoder This is more about the fact that what the browsers implement (de-facto web standard) and what the SVG specification language specifies are different. Only Edge implements the spec correctly and with some (perhaps?) unexpected results.

So I'm now thinking, would it be best to define the current de-facto standard web browser behaviour as the default? And then, the specification standard as the optional one. Thus, if browsers actually want to implement and make available the standard SVG 1.1 text on a path algorithm (and SVG 2.0), and conform the same way as Edge, then they can choose to expose the new attribute, to enable triggering the non-default, but correct behaviour.

fsoder commented 7 years ago

Regardless of the exact path you want to take, I think the steps will be roughly the same. To get interop on the most widely implemented behavior, there's still one browser that has to change its behavior (Edge.) Then/at the same time the spec has to change (this type of change would seem to fit nicely within the new SVG2 charter though, so this has a decent chance of succeeding.) Then the new feature would be introduced (see my previous comment.) This is really not all that different from what I wrote previously - just one additional step (change current spec.)

msand commented 7 years ago

@fsoder Alright, true. Thanks for your help! I'll look into discussing it with someone on the Edge / SVG team and see what they think about the situation, or if they're even aware of having a different implementation from the rest.

boggydigital commented 6 years ago

Not blocking updated 2.0 CR publication - assigning 2.1 WD milestone