w3c / svgwg

SVG Working Group specifications
Other
706 stars 132 forks source link

Define how meshes are rendered when children of shapes #140

Closed karip closed 8 years ago

karip commented 8 years ago

The child content model of shapes allows paints server elements as children, including ‘mesh’. The mesh gradient chapter says that “Unlike other paint servers, a mesh defined outside of a ‘defs’ section is rendered.”

Does this mean that the mesh is rendered if used as a child paint server? Here’s an example, the mesh is used as a paint server AND rendered as an object:

<svg>
  <rect x=“100” fill=“child” transform=“translate(10, 10) scale(2,2)” opacity=“0.5">
    <mesh transform=“rotate(30)">...</mesh>
  </rect>
</svg>

This raises several questions: how do the transforms of ‘rect’ affect the mesh? Does the ‘rect’ element behave like a ‘g’ element (only transform affects the mesh) or does it behave like an ‘svg’ element (transform and x/y properties affect the mesh)? Things get more hairy if the 'mesh' element is a child of a 'text' or 'tspan' element..

One way to simplify this is to just say that meshes are rendered only when they are children of a container element (‘a’, ‘clipPath’, ‘defs’, ‘g’, ‘marker’, ‘mask’, ‘pattern’, ‘svg’, ‘switch’ and ‘symbol’.). They are not rendered under any other element. Also, a mesh as a child of ‘a’ is not rendered if it is also a child of ‘text’, like this:

<svg>
  <text x=“100” y=“100”>Hello <a href=“https://www.w3.org”><mesh>…</mesh> w3</a></text>
</svg>
AmeliaBR commented 8 years ago

Thanks for identifying this inconsistency, @karip!

Yes, I definitely agree that the sensible approach is to not have a <mesh> render as an independent shape when it is a child of another shape or text. This is consistent with what happens if you put any other shape element as a child of a shape or text. So it's just a matter of finding a clear way to say so, while still supporting the encapsulation approach for easy referencing of child paint servers without id.

(Quite frankly, I personally still don't like the fact that meshes are both paint servers and independent shapes. Horribly confusing to have dual inheritance of the interfaces & functionality. But I think I've lost that battle.)

karip commented 8 years ago

Yes, the dual nature of the mesh element brings up issues.

Actually, meshes are inherited only from SVGGradientElement, so there is no way to read the bbox or ctm of a mesh shape in JS. Perhaps meshes need to inherit SVGGraphicsElement, too. (is that a new issue?)

In the future, I hope that new paint servers will be defined as CSS gradients and made usable in SVG and HTML. Having meshes and hatches in HTML would have been nice, too, but it's probably too late for that.

jarek-foksa commented 8 years ago

What are the use cases where it would be preferable to have standalone <mesh> rendered (rather than just putting the <mesh> in <defs> and applying it on shape)?

tabatkins commented 8 years ago

When you're going to render the mesh directly into the mesh's shape, which iirc was thought to be common when we were designing this. Otherwise you have to recreate the mesh shape with a <path>, and that's non-trivial.

AmeliaBR commented 8 years ago

As noted in #169, we've decided to split the dual nature of mesh into 2 elements: a <mesh> is a graphics element that references a <meshGradient> element, extracting the outer path from the <meshGradient> and then painting accordingly. The referencing could be done with href or through a parent-child relationship (i.e., if a <mesh> does not have an href, use the first child <meshGradient>).

Correspondingly: a <meshGradient>, like other paint servers, would be allowed as a child of a shape, but would not render directly. A <mesh> would be a graphics element and would not be allowed as a child of another graphics element.