Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Meaning of viewBox should be clearer #15

Closed
Hixie opened this issue Jun 1, 2021 · 11 comments
Closed

Meaning of viewBox should be clearer #15

Hixie opened this issue Jun 1, 2021 · 11 comments

Comments

@Hixie
Copy link
Contributor

Hixie commented Jun 1, 2021

It's not clear what exactly the viewBox means.

  • Must an implementation clip drawing operations outside the viewBox? (Hopefully not, clips are expensive.)
  • May an implementation drop drawing operations outside the viewBox? (Different implementations would have different renderings.)
  • May a drawing draw outside the viewBox?
  • Should an implementation honour the viewBox aspect ratio when rendering the image?
@nigeltao
Copy link
Collaborator

nigeltao commented Jun 1, 2021

You're right that this needs to be explicitly said in the spec. To your specific questions:

Must an implementation clip drawing operations outside the viewBox? (Hopefully not, clips are expensive.)

That's the intention.

I thought that clipping to axis-aligned rectangles is pretty cheap, especially as rasterizers have to do that anyway to avoid overflowing the destination pixel buffer. Let me know if I'm mistaken.

May an implementation drop drawing operations outside the viewBox? (Different implementations would have different renderings.)

It's must, not may, and different implementations should agree, because (as above) it's a clip. Or am I misunderstanding your question?

May a drawing draw outside the viewBox?

Individual path nodes can certainly be outside the viewBox. Entire paths can also be outside of the viewBox, but they should then be entirely clipped out (no-ops).

Should an implementation honour the viewBox aspect ratio when rendering the image?

Aspect ratio is only a hint. Implementations are allowed to draw a "naturally 3:2" IconVG into a 1:1 space.

@Hixie
Copy link
Contributor Author

Hixie commented Jun 1, 2021

I thought that clipping to axis-aligned rectangles is pretty cheap, especially as rasterizers have to do that anyway to avoid overflowing the destination pixel buffer. Let me know if I'm mistaken.

There's not always a way to know if the output buffer is axis-aligned, though. Assuming the user wants anti-aliased clipping in the rotated case, this means the IconVG renderer has to pro-actively use a saveLayer-based clip (in Skia terms), which is the expensive kind.

@nigeltao
Copy link
Collaborator

nigeltao commented Jun 2, 2021

this means the IconVG renderer has to pro-actively use a saveLayer-based clip (in Skia terms)

I may very well be misunderstanding the Skia API, but https://fiddle.skia.org/c/@Canvas_clipRect does a non-axis-aligned rectangular clip while only calling canvas->save(), not canvas->saveLayer().

@Hixie
Copy link
Contributor Author

Hixie commented Jun 2, 2021

Yeah, if you don't have to deal with colour bleed you can do it with only the medium-expensive clips and can skip the saveLayer call. My point is more that if you could avoid clipping entirely you'd be saving a bunch of cycles potentially. Obviously that's a trade-off (and IconVG is not intended to optimize for raw rendering speed above other considerations like file size or convenience).

@nigeltao
Copy link
Collaborator

nigeltao commented Jun 2, 2021

I still think I'd like the IconVG viewBox to implicitly clip. (Does SVG do this? I'd have to check...)

I certainly want to avoid "different implementations would have different renderings".

If clips turn out to be noticably expensive, I suppose that IconVG implementations could make two passes over the vectors (the path nodes). The first pass just calculates a convex hull, which is a very cheap computation. The second pass does the actual rendering but between the two, we could skip the clipRect call if the rectangle entirely contains the convex hull.

@Hixie
Copy link
Contributor Author

Hixie commented Jun 2, 2021

Clipping is definitely a reasonable choice.

@Hixie
Copy link
Contributor Author

Hixie commented Jun 2, 2021

(FWIW in the Dart implementation I just made it configurable and defaulted to a hard (fast but no AA) clip.)

@nigeltao
Copy link
Collaborator

nigeltao commented Jun 2, 2021

I still think I'd like the IconVG viewBox to implicitly clip. (Does SVG do this? I'd have to check...)

IconVG doesn't blindly follow SVG in all its complexity, but for what it's worth, the SVG 1.1 spec section 14.3.3 The ‘overflow’ and ‘clip’ properties gives 7 bullet points for how overflow works (cross-referencing CSS2) and then concludes with:

As a result of the above, the default behavior of SVG user agents is to establish a clipping path to the bounds of the initial viewport

It then goes on to note that, in SVG, viewport is not the same as viewBox. If I'm reading section 14.3.4 Clip to viewport vs. clip to ‘viewBox’ properly, if viewport and viewBox differ then the default clip is to the viewport and shrinking that to the viewBox requires an explicit clip property somewhere.

@nigeltao
Copy link
Collaborator

nigeltao commented Jun 2, 2021

(FWIW in the Dart implementation I just made it configurable and defaulted to a hard (fast but no AA) clip.)

Out of curiosity, does "the Dart implementation" mean a Dart SVG implementation, or does it mean some sort of Dart/Flutter canvas widget, with programmable 2-D vector graphics but not a full SVG implementation?

@nigeltao
Copy link
Collaborator

nigeltao commented Jun 2, 2021

does "the Dart implementation" mean...

Oh, I just saw #25

@Hixie
Copy link
Contributor Author

Hixie commented Jun 2, 2021

I definitely wouldn't follow SVG here, clipping and overflow in the CSS/SVG world is order of magnitude more complex than all of IconVG put together...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants