Bug 117454 - add canvas mask support for Cairo
Summary: add canvas mask support for Cairo
Status: NEW
Alias: None
Product: WebKit
Classification: Unclassified
Component: Canvas (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Nobody
URL:
Keywords: DoNotImportToRadar
Depends on:
Blocks: 117002
  Show dependency treegraph
 
Reported: 2013-06-10 17:49 PDT by arno.
Modified: 2022-07-18 14:49 PDT (History)
3 users (show)

See Also:


Attachments
wip patch (14.39 KB, patch)
2013-06-10 18:05 PDT, arno.
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description arno. 2013-06-10 17:49:57 PDT
This bug is for cairo mask support.
Comment 1 arno. 2013-06-10 18:05:58 PDT
Created attachment 204270 [details]
wip patch

WIP patch.
canvas mask api is based on Core Graphics API[1] This means that a call to mask will set the mask for all consecutive drawing operations.

On the contrary, cairo_mask is a drawing operation.

Currently, svg mask is supported by creating a new group and painting current surface on it (in order to allow proper composition). Then, during the actual drawing, the surface is popped and the actual cairo_mask_surface call is performed.

We can extend that by wrapping all drawing calls by a group creation/paint when there is an active mask. This would be a bit slow, but in the basic case (just a few drawing calls with a mask), that may not be a problem.

I tried to apply the mask only when a paint was needed (by implementing paintRenderingResultsToCanvas for 2d context, in order to tell the GraphicsContext that a real paint was needed). But I realize this would not work because cairo_push_group and cairo_pop_group call respectively cairo_save and cairo_restore. And it's not possible to call cairo_restore an a newly created group. So, things such as:

ctx.mask();
ctx.globalCompositeOperation = 'abcd';
ctx.resetMask();

would not have worked correctly.

Therefore, the tricky part of the patch is to detect all cairo drawing calls which may be called from canvas, in order to wrap them in the cairo_push_group/cairo_pop_group operations.

[1]: https://developer.apple.com/library/mac/#documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_images/dq_images.html#//apple_ref/doc/uid/TP30001066-CH212-TPXREF101
Comment 2 Martin Robinson 2013-06-10 18:09:26 PDT
I'm not a fan of doing the mask for every operation. At the very least, we should not slow down image masking to prepare for an API that may never exist.
Comment 3 arno. 2013-06-12 10:14:41 PDT
(In reply to comment #2)
> I'm not a fan of doing the mask for every operation. At the very least, we should not slow down image masking to prepare for an API that may never exist.

Image masking (with css) would not be impacted by this change. css image masking is done with by drawing an image with destination_in, usually wrapped inside beginTransparencyLayer/endTransparencyLayer

svg masking would be impacted by this change is some cases, for example:

<g mask>
<ellipse/>
<ellipse/>
</g>