[whatwg] whatwg Digest, Vol 114, Issue 19

Rashmi Shyamasundar rashmi.shyam at gmail.com
Thu Sep 12 03:48:54 PDT 2013


Hi All,

This is regarding the resetClip() API for canvas. Please take a look at my
patches to the bug https://bugs.webkit.org/show_bug.cgi?id=82801.
resetClip() can be implemented in Cairo, without any overhead, since Cairo
supports resetClip.

I tried to implement the API in CG, using the below approach :- (Please
check https://bugs.webkit.org/show_bug.cgi?id=82801#c9 )

Steps :-
When resetClip() is called,
1. Save the imageData from canvas imageBuffer
2. Save the GraphicsContextState
3. Clear the canvas buffer. This will delete the buffer and
GraphicsContextStateSaver.
4. Copy the saved imageData to a new imageBuffer
5. Set the graphicsContextState to the saved state.
GraphicsContextState does not have information about any clip.


The drawback with the above approach is that clipping-region cannot be
restored since it is not part of the GraphicsContextState or
CanvasRenderingContext2D::State.

Currently clipping-region is not saved in GraphicsContextState or
CanvasRenderingContext2D::State. If clipping-region is somehow saved
in GraphicsContextState and CanvasRenderingContext2D::State then,
through step#5, clipping region can also be restored.


Below is an example which will not work in CG (But, Works perfectly in
Cairo), if clipping-region is not saved in GraphicsContextState and
CanvasRenderingContext2D::State :-

ctx.clip();
ctx.save();
ctx.resetClip();
...; // draw with no clip
ctx.restore();
...; // draw with a clip (This draw does not contain any clip)


Thanks,

Rashmi




>
> Message: 7
> Date: Thu, 12 Sep 2013 01:08:10 +0000 (UTC)
> From: Ian Hickson <ian at hixie.ch>
> To: WHATWG List <whatwg at whatwg.org>
> Subject: Re: [whatwg] remove resetClip from the Canvas 2D spec
> Message-ID:
>         <alpine.DEB.2.00.1309120056550.12199 at ps20323.dreamhostps.com>
> Content-Type: TEXT/PLAIN; charset=US-ASCII
>
> On Fri, 9 Aug 2013, Simon Sarris wrote:
> >
> > As an alternative [to resetClip()] I would propose something like
> > setClip() or setClip(path) (with the former working on the current path,
> > just like clip()/fill()/stroke() does).
>
> Seems like this would have the same problems as resetClip(), since it's
> essentially the same as a call to resetClip() followed by a call to clip().
>
>
> On Fri, 9 Aug 2013, Justin Novosad wrote:
> >
> > 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.
> >
> > Also, resetMatrix could be defined to do the same.
>
> Wouldn't that be the same as just save()/clip()/restore() ?
>
>
> On Mon, 12 Aug 2013, Rik Cabanier wrote:
> >
> > It would be good to hear specific use cases for 'resetClip' so we can
> make
> > that call.
>
> The main use case would be something like:
>
>    c.save();
>    c.resetTransform();
>    c.resetClip();
>    // draw something at the top right...
>    c.restore();
>
> ...deep inside some draw code.
>
>
> > > Also, resetMatrix could be defined to do the same.
> >
> > Is that API defined somewhere?
>
> I think Justin meant resetTransform().
>
>
> On Mon, 12 Aug 2013, Simon Sarris wrote:
> >
> > 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
>
> I'm pretty sure save() and restore() are the right solution here. If those
> don't work, we should fix those, not add more features that might have
> their own issues.
>
>
> > 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.
>
> Again, if settings fonts is slow, that should be fixed independently of
> resetClip().
>
>
> On Mon, 12 Aug 2013, Justin Novosad wrote:
> >
> > Good point, I think part of the problem has to do with the fact that save
> > is non-selective (saves all of the state).
> > Might be worthwhile to have a selective save that pushes only a
> > user-specified subset of the current state onto the stack.
>
> There's no reason save() and restore() need be slow just because they save
> a lot. It's relatively easy to have a stack that only saves the things
> that have changed (e.g. by setting a bit when you change things, so you
> know what has changed, and then only pushing onto the stack the
> instructions to change the stuff that has changed).
>
>
> On Mon, 12 Aug 2013, Simon Sarris wrote:
> >
> > Yes, since save() and restore() save and restore everything, it creates
> > the side effect of needing to set ctx.font/fillStyle/strokeStyle more
> > often than otherwise, which are slow to set, probably because of some
> > CSS parser activity, but I'm not wise enough to know.
>
> save() and restore() should have no reason to go through the CSS parser.
>
>
> On Mon, 12 Aug 2013, Justin Novosad wrote:
> >
> > Ok, so here is a simple proposal:
> >
> > IDL:
> > enum CanvasSaveMode { "all", "transform", "clip", "transform-and-clip" };
> > save(optional CanvasSaveMode mode);
> >
> > Modes:
> > all: save the entire rendering context state
> > transform: save only the current transform
> > clip: save only the current clip
> >
> > if mode is not specified, the entire context state is saved (for backward
> > compatibility)
> >
> > The restore method's interface does not change. It restores whatever
> state
> > was saved by the matching save call.
>
> I don't understand what problem this is solving.
>
>
> On Tue, 13 Aug 2013, Simon Sarris wrote:
> >
> > I'd argue its not strictly a performance issue. More generally its
> > awkward that you can reset any piece of the canvas context state except
> > the clipping region. The clipping region alone requires you to clobber
> > all state in order to reset it.
> >
> > You can set the fillStyle back to black, you can set the transformation
> > matrix back to identity, etc. But you can't set the clipping region back
> > to the entire canvas area without save()/restore() or
> > can.width=can.width. It's the only thing like that.
> >
> > That ought to be considered bad on principle I think. It makes clipping
> > a really odd operation compared to anything else, and at the least it
> > makes the one part of the API unintuitive.
>
> This is the argument for resetClip(), though the only use case seems to be
> the one I mentioned (drawing something at the top right, or whatever, deep
> inside some code that has clipped and transformed).
>
> I've marked the resetClip() feature in the spec as being considered form
> removal. If no browser implement it in due course, I'll remove it. Despite
> being relatively commonly requested, it must be admitted that the use
> cases for this feature aren't that compelling.
>
> --
> Ian Hickson               U+1047E                )\._.,--....,'``.    fL
> http://ln.hixie.ch/       U+263A                /,   _.. \   _\  ;`._ ,.
> Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'
>
>
> ------------------------------
>
>


More information about the whatwg mailing list