Summary: | Add Canvas blend modes to Cairo | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Product: | WebKit | Reporter: | arno. <a.renevier> | ||||||||||||
Component: | Canvas | Assignee: | arno. <a.renevier> | ||||||||||||
Status: | RESOLVED FIXED | ||||||||||||||
Severity: | Normal | CC: | cabanier, d-r, mrobinson, webkit.review.bot | ||||||||||||
Priority: | P2 | ||||||||||||||
Version: | 528+ (Nightly build) | ||||||||||||||
Hardware: | Unspecified | ||||||||||||||
OS: | Unspecified | ||||||||||||||
Bug Depends on: | |||||||||||||||
Bug Blocks: | 100069 | ||||||||||||||
Attachments: |
|
Description
arno.
2012-12-14 17:03:41 PST
I tried to add support for blending modes in cairo. While most modes work correctly, color-burn, color-dogde, hue, luminosity and saturation mode do not work. That's Pixman implementation is based on svg specification; and I think there is a difference between svg specification and the tests added in bug #104176 (and possibly also with pdf specification). Pdf specification[1] states that the resulting color for color-burn compositing will be Cr = (1 – as / ar) * Cb + as / ar × [( 1 – ab) × Cs + ab × B(Cb, Cs)] with B(Cb, Cs) = 1 - min(1, (1 - Cb) / Cs) if Cs > 0, or 0 otherwise So if we have a opaque source and backdrops (a = 1) and a color component of 0 for source, and 1 for backdrop, the result should be: (1 - 1) * 1 + 1 / 1 * ((1 - 1) * 0 + 1 * 0) => 0 That is what is assumed in the tests for #104176. But svg specification[2] states that result for color-burn compositing: if Sca == 0 and Dca == Da Dca' = Sa × Da + Sca × (1 - Da) + Dca × (1 - Sa) = Sa × Da + Dca × (1 - Sa) otherwise if Sca == 0 Dca' = Sca × (1 - Da) + Dca × (1 - Sa) = Dca × (1 - Sa) otherwise if Sca > 0 Dca' = Sa × Da - Sa × Da × min(1, (1 - Dca/Da) × Sa/Sca) + Sca × (1 - Da) + Dca × (1 - Sa) = Sa × Da × (1 - min(1, (1 - Dca/Da) × Sa/Sca)) + Sca × (1 - Da) + Dca × (1 - Sa) For the same backdrop and sources, we have Sca = 0; Sa = 1 Dca = 1; Da = 1 So, we are in the first case, and the result should be: 1 * 1 + 0 * (1 - 1) + 1 * (1 - 1) => 1 This is what pixman computes. (By the way, I don't really understand why there is this Dca == Da check). I have not checked other modes yet, but I suppose there may be a the same problem there. So am I correct, is the a difference between pdf specification and svg specification. If so, which one are we supposed to follow now ? [1]: http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/PDF32000_2008.pdf 11.3.5 [2]: http://www.w3.org/TR/SVGCompositing/#comp-op-property (In reply to comment #1) > I tried to add support for blending modes in cairo. > While most modes work correctly, color-burn, color-dogde, hue, luminosity and saturation mode do not work. > > That's Pixman implementation is based on svg specification; and I think there is a difference between svg specification and the tests added in bug #104176 (and possibly also with pdf specification). > > Pdf specification[1] states that the resulting color for color-burn compositing will be > > Cr = (1 – as / ar) * Cb + as / ar × [( 1 – ab) × Cs + ab × B(Cb, Cs)] > with B(Cb, Cs) = 1 - min(1, (1 - Cb) / Cs) if Cs > 0, or 0 otherwise > > So if we have a opaque source and backdrops (a = 1) and a color component of 0 for source, and 1 for backdrop, the result should be: > (1 - 1) * 1 + 1 / 1 * ((1 - 1) * 0 + 1 * 0) => 0 > That is what is assumed in the tests for #104176. > > But svg specification[2] states that result for color-burn compositing: > > if Sca == 0 and Dca == Da > Dca' = Sa × Da + Sca × (1 - Da) + Dca × (1 - Sa) > = Sa × Da + Dca × (1 - Sa) > otherwise if Sca == 0 > Dca' = Sca × (1 - Da) + Dca × (1 - Sa) > = Dca × (1 - Sa) > otherwise if Sca > 0 > Dca' = Sa × Da - Sa × Da × min(1, (1 - Dca/Da) × Sa/Sca) + Sca × (1 - Da) + Dca × (1 - Sa) > = Sa × Da × (1 - min(1, (1 - Dca/Da) × Sa/Sca)) + Sca × (1 - Da) + Dca × (1 - Sa) > > For the same backdrop and sources, we have > Sca = 0; Sa = 1 > Dca = 1; Da = 1 > So, we are in the first case, and the result should be: > 1 * 1 + 0 * (1 - 1) + 1 * (1 - 1) => 1 > This is what pixman computes. > (By the way, I don't really understand why there is this Dca == Da check). > > I have not checked other modes yet, but I suppose there may be a the same problem there. > > So am I correct, is the a difference between pdf specification and svg specification. If so, which one are we supposed to follow now ? In this case, the formula in the SVG specification is correct for color-burn and color-dodge. I didn't update the formula in the CSS compositing spec yet, but will do so shortly. I'm surprised to see that hue, luminosity and saturation mode do not work. Are they very different? > I didn't update the formula in the CSS compositing spec yet, but will do so shortly. Updated the spec. See: https://dvcs.w3.org/hg/FXTF/rawfile/tip/compositing/index.html#blendingcolordodge Created attachment 180248 [details]
wip patch
wip patch.
Some changes are needed in CanvasRenderingContext2D are needed to have it working. They are currently implemented in #100070
I'll finish the patch when that bug is fixed.
Created attachment 180756 [details]
patch proposal
(In reply to comment #5) > Created an attachment (id=180756) [details] > patch proposal This looks reasonable. Can you remove the exception for the testexpectations file so this can be tested? Created attachment 180808 [details]
test diff
Actually, I still get test errors.
This time with
color-burn alpha on solid and alpha on alpha.
hue alpha on solid and alpha on alpha.
saturation alpha on solid and alpha on alpha.
color alpha on solid and alpha on alpha.
Is the test or pixman more likely incorrect ?
(In reply to comment #7) > Created an attachment (id=180808) [details] > test diff > > Actually, I still get test errors. > This time with > > color-burn alpha on solid and alpha on alpha. > hue alpha on solid and alpha on alpha. > saturation alpha on solid and alpha on alpha. > color alpha on solid and alpha on alpha. > > Is the test or pixman more likely incorrect ? the results are pretty close so cairo probably needs a bit of tweaking. Can you point me to wiki that tell me how I can build your code? (In reply to comment #8) > Can you point me to wiki that tell me how I can build your code? Here is how to build WebKitGTK http://trac.webkit.org/wiki/BuildingGtk (In reply to comment #1) > I tried to add support for blending modes in cairo. > While most modes work correctly, color-burn, color-dogde, hue, luminosity and saturation mode do not work. > > That's Pixman implementation is based on svg specification; and I think there is a difference between svg specification and the tests added in bug #104176 (and possibly also with pdf specification). > > Pdf specification[1] states that the resulting color for color-burn compositing will be > > Cr = (1 – as / ar) * Cb + as / ar × [( 1 – ab) × Cs + ab × B(Cb, Cs)] > with B(Cb, Cs) = 1 - min(1, (1 - Cb) / Cs) if Cs > 0, or 0 otherwise > > So if we have a opaque source and backdrops (a = 1) and a color component of 0 for source, and 1 for backdrop, the result should be: > (1 - 1) * 1 + 1 / 1 * ((1 - 1) * 0 + 1 * 0) => 0 > That is what is assumed in the tests for #104176. > > But svg specification[2] states that result for color-burn compositing: > > if Sca == 0 and Dca == Da > Dca' = Sa × Da + Sca × (1 - Da) + Dca × (1 - Sa) > = Sa × Da + Dca × (1 - Sa) > otherwise if Sca == 0 > Dca' = Sca × (1 - Da) + Dca × (1 - Sa) > = Dca × (1 - Sa) > otherwise if Sca > 0 > Dca' = Sa × Da - Sa × Da × min(1, (1 - Dca/Da) × Sa/Sca) + Sca × (1 - Da) + Dca × (1 - Sa) > = Sa × Da × (1 - min(1, (1 - Dca/Da) × Sa/Sca)) + Sca × (1 - Da) + Dca × (1 - Sa) > > For the same backdrop and sources, we have > Sca = 0; Sa = 1 > Dca = 1; Da = 1 > So, we are in the first case, and the result should be: > 1 * 1 + 0 * (1 - 1) + 1 * (1 - 1) => 1 > This is what pixman computes. > (By the way, I don't really understand why there is this Dca == Da check). > > I have not checked other modes yet, but I suppose there may be a the same problem there. > Looking at libpixman, their implementation has a number of bugs. For instance, if you look at color-burn, you can see that the comments describe the formula correctly, but the implementation is different. It seems that this should be fixed first. (In reply to comment #10) > (In reply to comment #1) > > I tried to add support for blending modes in cairo. > > While most modes work correctly, color-burn, color-dogde, hue, luminosity and saturation mode do not work. > > > > That's Pixman implementation is based on svg specification; and I think there is a difference between svg specification and the tests added in bug #104176 (and possibly also with pdf specification). > > > > Pdf specification[1] states that the resulting color for color-burn compositing will be > > > > Cr = (1 – as / ar) * Cb + as / ar × [( 1 – ab) × Cs + ab × B(Cb, Cs)] > > with B(Cb, Cs) = 1 - min(1, (1 - Cb) / Cs) if Cs > 0, or 0 otherwise > > > > So if we have a opaque source and backdrops (a = 1) and a color component of 0 for source, and 1 for backdrop, the result should be: > > (1 - 1) * 1 + 1 / 1 * ((1 - 1) * 0 + 1 * 0) => 0 > > That is what is assumed in the tests for #104176. > > > > But svg specification[2] states that result for color-burn compositing: > > > > if Sca == 0 and Dca == Da > > Dca' = Sa × Da + Sca × (1 - Da) + Dca × (1 - Sa) > > = Sa × Da + Dca × (1 - Sa) > > otherwise if Sca == 0 > > Dca' = Sca × (1 - Da) + Dca × (1 - Sa) > > = Dca × (1 - Sa) > > otherwise if Sca > 0 > > Dca' = Sa × Da - Sa × Da × min(1, (1 - Dca/Da) × Sa/Sca) + Sca × (1 - Da) + Dca × (1 - Sa) > > = Sa × Da × (1 - min(1, (1 - Dca/Da) × Sa/Sca)) + Sca × (1 - Da) + Dca × (1 - Sa) > > > > For the same backdrop and sources, we have > > Sca = 0; Sa = 1 > > Dca = 1; Da = 1 > > So, we are in the first case, and the result should be: > > 1 * 1 + 0 * (1 - 1) + 1 * (1 - 1) => 1 > > This is what pixman computes. > > (By the way, I don't really understand why there is this Dca == Da check). > > > > I have not checked other modes yet, but I suppose there may be a the same problem there. > > > > Looking at libpixman, their implementation has a number of bugs. > For instance, if you look at color-burn, you can see that the comments describe the formula correctly, but the implementation is different. > > It seems that this should be fixed first. Looking at this some more, it looks like cairo is correct, but not CG. Maybe you should submit this path with platform specific results and I will try to fix it later. Created attachment 182601 [details]
patch with platform specific expected files
Comment on attachment 182601 [details] patch with platform specific expected files Rejecting attachment 182601 [details] from commit-queue. Failed to run "['/mnt/git/webkit-commit-queue/Tools/Scripts/webkit-patch', '--status-host=queues.webkit.org', '-..." exit_code: 1 cwd: /mnt/git/webkit-commit-queue /mnt/git/webkit-commit-queue/LayoutTests/ChangeLog neither lists a valid reviewer nor contains the string "Unreviewed" or "Rubber stamp" (case insensitive). Full output: http://queues.webkit.org/results/15868673 Created attachment 182849 [details]
same patch with Reviewed by NOBODY (OOPS!) added to LayoutTests/ChangeLog
OOPS. Sorry for the mistake
Comment on attachment 182849 [details] same patch with Reviewed by NOBODY (OOPS!) added to LayoutTests/ChangeLog Clearing flags on attachment: 182849 Committed r139804: <http://trac.webkit.org/changeset/139804> All reviewed patches have been landed. Closing bug. |