[css-masking] Define "raw geometry" for <clipPath> clipping · Issue #170 · w3c/fxtf-drafts (original) (raw)

@AmeliaBR

The CSS Masking module description of <clipPath> states (copying SVG 1.1 ):

The raw geometry of each child element exclusive of rendering properties such as fill, stroke, stroke-width within a clipPath conceptually defines a 1-bit mask (with the possible exception of anti-aliasing along the edge of the geometry) which represents the silhouette of the graphics associated with that element. ...

"Raw geometry" isn't a defined term anywhere. And some style properties do affect the clipping result. In addition to the clip-path, display, and visibility properties that are currently called out in the spec, all text layout & font-selections properties would affect <text> elements inside the clipping path, and all the SVG 2 geometric properties (attributes in SVG 1) and transform. Possibly others I haven't thought of yet.

PS, See also #17, about expanding the content model for <clipPath>.

@tigt

My interpretation and some basic browser testing leans toward defining this as if the following properties were always set:

clipPath * { fill: #000; fill-opacity: 1; stroke: none; }

But maybe that's begging the question in some way.

@AmeliaBR

@tigt That's one way of thinking about it. But the list of unset properties is much longer than that (markers, masks, filters would be others). And for implementations, a deeper issue is that they aren't actually calculating a final rasterized graphic layer at all, they are only implementing the first step.

@fsoder

That's indeed one way to frame it - and this pretty much how Blink (and IIRC, WebKit) handles this in the general case (modulo other details, as @AmeliaBR mentions.) It really boils down to engine architecture and requirements on that based on the rendering architecture/pipeline. (In Presto we handled this in a similar, but not exactly the same way, for instance.)
I believe the "Raw geometry" formulation (and whatever it used to say, ISTR it was slightly different) - as well as the limited content model - was there to allow an implementation to just "collect" a list of geometric primitives based on the element types, and construct the clip path from that. (Engines commonly do that for their fast-paths, and that in itself tends to be slippery slope because of all the cases you need to consider even then...)
With the history lesson out of the way, I wonder which way would be the easiest to specify this: Properties to ignore and properties to replace (like using clip-rule instead of fill-rule) - or - properties that do apply (and properties to replace...) Or some other way. <text> indeed seems to be the big trouble maker here (lots of properties that could be considered to be affecting the "geometry".)

@dirkschulze

There are roughly 3 not further specified categories of properties that are interesting for us. Properties

  1. which affect the geometry of the shape,
  2. which affect the paint (in the spec: rendering) behavior of the shape/element,
  3. all others, including meta properties or accessibility properties.

The spec says:

The raw geometry of each child element exclusive of rendering properties [...]

Ideally we could reuse one of the Media Groups of CSS 2.1 to specify a set of allowed properties. Sadly, many properties like transform, font-family, font-size are part of the visual group beside fill, stroke and stroke-width. The former properties must be taken into account the later must not.

We could add a list of CSS properties that are affecting the geometry into CSS Masking. I wonder if we can add another, more specific Media Group for geometry properties instead. All specs that define geometry affecting properties would need to get updated. But otherwise the Masking spec might get outdated quickly when new properties arrive.

Also, at least at the moment, just properties that affect the visuals of SVG elements are of interest. CC @fantasai @tabatkins

@dirkschulze

For now we need to investigate which properties are affecting clipping paths across implementations.

@dirkschulze

Thinking about it more, I think it is a mistake to talk about 1-bit masks in the normative code in general. This is a mistake inherited from SVG.

At the end the main differences between masking and clipping is that the former fundamentally is a pixel based operation. The latter is defining an area. I'd still like to keep this text in as informative note.

To the normative part:

The geometry of a text or shape defines the "clipping region". The geometry of text or shapes may be affected by CSS properties and settings like (but not limited to) font-style, font-family, font-size, font-kerning, font-weight or font variants. Neither the fill, stroke nor visual properties like box-shadow or filter of a text or shape contribute to the geometry and therefore do not contribute to the "clipping region". Specifications defining CSS properties, features and behaviors should normatively state when the specified behavior or feature contributes to the geometry of a text or shape.

IIRC (and I'll check) we should have normative text for visibility, display, clip-path and transform.

@AmeliaBR I agree that ideally CSS would define a group of properties and settings that contribute to the clipping region (geometry of the shape). But with the absence of such a definition I think that is the best we can do for level 1. I am not sure if the term "geometry" needs a definition in any W3C spec. CSS and SVG depend on the knowledge of common terms like that.

@AmeliaBR

Continuing to leave it unspecified would not make the situation any worse. I think we have interop about what properties are used, but we don't have comprehensive tests, so I don't know.

I think the text should also specifically call out SVG geometry properties and attributes, and maybe have a prose description for "any properties or attributes that determine glyph selection and position" in text elements.