[whatwg] remove resetClip from the Canvas 2D spec
Simon Sarris
simon.sarris at gmail.com
Mon Aug 12 11:50:48 PDT 2013
I think most performance-minded use cases will be fine with junov's idea
since they will not want to touch the stack in the first place.
Here's a simple use case: Suppose there are nested objects to be drawn,
Panels, TextBlocks, and other visual elements. Panels are containers that
draw a background and all of their children - and they contain any number
of Panels or TextBlocks or other elements, and TextBlocks set the context
font (to their font) and draw some text.
The drawing structure is hierarchical, and drawn elements may be offset
from their immediate parent. So a drawing hierarchy might look like this:
Panel(A)
Panel(B)
TextBlock
TextBlock
That is, Panel(A) contains Panel(B) and a TextBlock. And Panel(B) contains
another TextBlock. In practice, nesting could be much deeper and more
complicated.
Now suppose also that Panels have some settings, such as a maximum width,
that might cause their visual elements to be clipped. So a panel might need
to save(), clip(), draw all of its children, and then restore(). Nesting
means multiple levels of clipping, for instance with the above hierarchy it
might look like:
Panel(A)
clip (save)
drawChildren:
Panel(B)
clip (save)
drawChildren:
TextBlock
sets font X
fillText
restore
TextBlock
sets font X
fillText
restore
This is problematic, because it means:
1. I must use save() and restore(), which are slow in their own right
2. The usage of save() and restore() means that, even if all (or most) of
my fonts are set to the same value, I have to keep setting them over and
over. Setting the font is slow in practice, even if it is set to the same
value as before, and so it should be cached if at all possible. See:
http://jsperf.com/can-attribs
and
http://jsperf.com/cached-attributes
(fill/stroke styles should be cached too, but the performance diff is not
as drastic)
With a nested drawing structure,when using clipping, I am much less able to
cache the canvas font/fillStyle/strokeStyle. This hurts performance. It's
still possible, some of the time, but its harder to realize gains.
All the while this is happening I am translating, rotating, and scaling the
transformation matrix to position nested visual elements, but this is not a
problem since I can undo those either with setTransform or inverse
transforms, so they do not necessitate use of save() and restore().
Clipping has no such ability, to undo any clipping region I must clobber
the context state with a save and restore.
I hope that was clear. This is a real-world use case for a production
canvas diagramming library.
In general, junov's idea will work well for anyone who wants this because
they need to occasionally clip while keeping their webapp performant, since
those people are unlikely to be touching save() and restore() in the first
place.
On Mon, Aug 12, 2013 at 2:15 PM, Rik Cabanier <cabanier at gmail.com> wrote:
> On Fri, Aug 9, 2013 at 1:40 PM, Justin Novosad <junov at google.com> wrote:
>
> > On Fri, Aug 9, 2013 at 4:20 PM, Ian Hickson <ian at hixie.ch> wrote:
> >
> > >
> > > This is a quite widely requested feature. What should we do to address
> > > this request instead?
> > >
> > >
> > What if resetClip restored the clip to what it was at the save call that
> > created the current state stack level?
> > In other words, restore the clip, but without popping it off the
> > save/restore stack.
> >
>
> It would be good to hear specific use cases for 'resetClip' so we can make
> that call.
> I think your proposal could be made to work with Core Graphics.
>
>
> > Also, resetMatrix could be defined to do the same.
>
>
> Is that API defined somewhere?
>
More information about the whatwg
mailing list