Re: [whatwg] remove resetClip from the Canvas 2D spec

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@gmail.com> wrote:

> On Fri, Aug 9, 2013 at 1:40 PM, Justin Novosad <junov@google.com> wrote:
>
> > On Fri, Aug 9, 2013 at 4:20 PM, Ian Hickson <ian@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?
>

Received on Monday, 12 August 2013 18:51:14 UTC