Open Bug 829803 Opened 12 years ago Updated 2 years ago

Add support for masking to Canvas

Categories

(Core :: Graphics: Canvas2D, task)

task

Tracking

()

People

(Reporter: cabanier, Unassigned)

References

Details

(Whiteboard: [shumway])

Attachments

(5 files, 1 obsolete file)

User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.101 Safari/537.11

Steps to reproduce:

Currently, there is no support for alpha or luminosity masking in canvas.
This makes it almost impossible to efficiently implement soft masks for pdf.js.

I found several people that provided workaround and shims for this feature.
Component: Untriaged → Canvas: 2D
Product: Firefox → Core
Attached patch Example implementation for Core Graphics (obsolete) (deleted) — Splinter Review
Attachment #701331 - Flags: feedback?
Attachment #701331 - Attachment is patch: true
I attached an example implementation that will only work with the CG backend.

the proposed API is as follows:
   void mask(CanvasImageSource image, 
                     unrestricted double sx, unrestricted double sy, unrestricted double sw, unrestricted double sh, 
                     unrestricted double dx, unrestricted double dy, unrestricted double dw, unrestricted double dh);

the first parameter points to an image source
sx, sy, sw, and sh point to a rectangle in the source image that you want to use as a mask
dx, dy, dw and dh point to the destination area that you want the mask to apply to.

The API currently converts colors+alpha to luminosity so the pdf.js people can play with this.
white = use the foreground colors
black = use the background colors
The mask is also part of the graphics state, so it will respond to save/restore.

jsfiddle example: http://jsfiddle.net/NDYV8/11/
Comment on attachment 701331 [details] [diff] [review]
Example implementation for Core Graphics

Maybe 'maskImage' is a better API
Attachment #701331 - Flags: feedback? → feedback?(bzbarsky)
Comment on attachment 701331 [details] [diff] [review]
Example implementation for Core Graphics

Going to punt this to someone who knows graphics things.  ;)
Attachment #701331 - Flags: feedback?(bzbarsky) → feedback?(jmuizelaar)
Rik,
I'll hopefully have time to play with this later today or tomorrow to see if it would meet pdf.js needs.
Great!
I think it will need 2 more parameters to cover all the bases (cliptomask and invert) but you should be able to experiment as-is.
Attached image screenshot of blending issue (deleted) —
I think something may be screwy with blending the source and backdrop with blend modes.  I hacked up pdf.js to use mask at https://github.com/brendandahl/pdf.js/commit/765a421df04499afc14b5bcbeab0856e160a18b3 ). Using the example pdf from http://bugs.ghostscript.com/attachment.cgi?id=4177 I get the attached result.  If I comment out the blending modes code in pdf.js I can see the blue squares drawn, but with blending modes on it seems it is not blending the colors where the backdrop is empty (only where the orange circle is).

I can try to come up with a simpler example that doesn't use pdf.js, but if you have any ideas let me know.
Attached image my screen shot (deleted) —
it looks fine to me.
I wonder what the stuff at the bottom is though...
(In reply to Rik Cabanier from comment #9)
> Created attachment 702608 [details]
> my screen shot

Looks like you don't have the blending modes turned on.  Compare the pdf to acrobat and you'll see that there shouldn't be any blue over the orange circle.

(In reply to Rik Cabanier from comment #10)
> it looks fine to me.
> I wonder what the stuff at the bottom is though...

That's the soft mask, I just added it for debugging purposes to see it.
Attached image acrobat screenshot (deleted) —
Not sure what you're seeing.
There's blue over the circle in acrobat too... See screenshot
Sorry about that I linked to the wrong pdf in that bug it should be http://bugs.ghostscript.com/attachment.cgi?id=4358
(In reply to Brendan Dahl from comment #13)
> Sorry about that I linked to the wrong pdf in that bug it should be
> http://bugs.ghostscript.com/attachment.cgi?id=4358

Are you executing the form in its own canvas context?
From what I can tell, you execute it in the same context so the first gstate blows the blend mode away.
Execute the form in its own state and its own temporary canvas and then do a drawimage with the result.
I am drawing the form/soft mask to a separate canvas (https://github.com/brendandahl/pdf.js/commit/765a421df04499afc14b5bcbeab0856e160a18b3#L0R1477).

The issue I found out was from the pdf.js viewer filling the page with white before we rendered it (https://github.com/mozilla/pdf.js/blob/master/web/viewer.js#L2053). Since the blend mode was screen, white remained white.  Once I removed that everything looks as expected.

I'll play around with adding transparency groups next.  I still need to copy over the state of the current canvas to the form canvas since according to the spec it is suppose to inherit all the graphics state except blend mode, soft mask, and alpha constant.
What are you thoughts on creating a function to clear or remove the mask?  It seems kind of clunky right now to have to create new empty mask or having to use save/restore.
the transparency group itself also need to be put in its own temporary canvas
> The issue I found out was from the pdf.js viewer filling the page with white
> before we rendered it
> (https://github.com/mozilla/pdf.js/blob/master/web/viewer.js#L2053). Since
> the blend mode was screen, white remained white.  Once I removed that
> everything looks as expected.
> 
yes, matting is done as the last step
(In reply to Brendan Dahl from comment #16)
> What are you thoughts on creating a function to clear or remove the mask? 
> It seems kind of clunky right now to have to create new empty mask or having
> to use save/restore.

I think that sounds reasonable.
do you have suggestions for the syntax? resetMask()
(In reply to Brendan Dahl from comment #15)
> I am drawing the form/soft mask to a separate canvas
> (https://github.com/brendandahl/pdf.js/commit/
> 765a421df04499afc14b5bcbeab0856e160a18b3#L0R1477).
> 
> The issue I found out was from the pdf.js viewer filling the page with white
> before we rendered it
> (https://github.com/mozilla/pdf.js/blob/master/web/viewer.js#L2053). Since
> the blend mode was screen, white remained white.  Once I removed that
> everything looks as expected.
> 
> I'll play around with adding transparency groups next.  I still need to copy
> over the state of the current canvas to the form canvas since according to
> the spec it is suppose to inherit all the graphics state except blend mode,
> soft mask, and alpha constant.
yes, I think that's correct.
Almost all the time, the first thing a group does is reset that all to an initial state though so if it's complex, you might want to add that later.
Depends on: 849307, 767926
I've been looking at implementing this for just canvas image sources (since the IDL compiler still doesn't support unions).
The Core Graphics implementation is complete and I'm looking at cairo next. 
What's the best way to submit this? Can I just provide a patch with my current work and then provide patches for the different backends and more image sources?
It would probably be best to post some patches so you can get feedback as you go. Also, support for unions landed a few weeks ago.
updated implementation. Still need to add support for unions
Attachment #701331 - Attachment is obsolete: true
Attachment #701331 - Flags: feedback?(jmuizelaar)
Assignee: nobody → cabanier
OS: Mac OS X → All
Hardware: x86 → All
Whiteboard: [shumway]
Keywords: feature
Michael says Shumway can emulate this. Is this a dupe or dependent of other gfx work on CSS blend modes and filters for canvas?
No longer blocks: shumway-m4
Status: UNCONFIRMED → ASSIGNED
Ever confirmed: true
Assignee: cabanier → nobody
Status: ASSIGNED → NEW
Type: defect → task
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: