Bug 49516 - [PATCH] FOP with SVG - gradient fill opacity incorrectly inherits stroke opacity of previous svg element
Summary: [PATCH] FOP with SVG - gradient fill opacity incorrectly inherits stroke opac...
Status: RESOLVED FIXED
Alias: None
Product: XMLGraphicsCommons - Now in Jira
Classification: Unclassified
Component: java2D (show other bugs)
Version: Trunk
Hardware: PC Windows Vista
: P3 normal (vote)
Target Milestone: --
Assignee: XML Graphics Project Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-06-29 04:03 UTC by dleung
Modified: 2012-10-27 16:49 UTC (History)
0 users



Attachments
svg with three rectangles (931 bytes, image/svg+xml)
2010-06-29 04:03 UTC, dleung
Details
fo to accompany above SVG (1.04 KB, application/octet-stream)
2010-06-29 04:03 UTC, dleung
Details
PDF with incorrect fill opacity on bottom left rectangle (6.15 KB, application/pdf)
2010-06-29 04:06 UTC, dleung
Details
PDF after fix (hack) (6.06 KB, application/pdf)
2010-06-29 04:07 UTC, dleung
Details
Workaround hack (715 bytes, patch)
2010-06-29 04:08 UTC, dleung
Details | Diff
Work around hack v2 (1.15 KB, patch)
2010-06-29 20:35 UTC, dleung
Details | Diff
patch for xmlgraphics (2.56 KB, patch)
2012-08-13 23:20 UTC, Luis Bernardo
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description dleung 2010-06-29 04:03:08 UTC
Created attachment 25652 [details]
svg with three rectangles

To reproduce:

1) Have an FO file in which an SVG (I have only tested with external-graphics)

2) Inside the SVG, have a gradient defined and two elements e.g. rectangles. Set the stroke opacity of the first element to a value near 0. NOTE: The order is important - the stroke opacity must be set on the element preceding the gradient filled element.

3) Make the second element have a gradient fill.

RESULT: The second element's gradient fill will have the same opacity as the stroke of the preceding element.

** Possible cause **
This is due to Batik's GraphicContext.setPaint() method replacing the "foreground" Color attribute if it receives a Color instance as a parameter (due to a "paint instanceof Color" check). The "foreground" of the GraphicsContext is later used to set the fill opacity in the line inside PDFGraphics2D.fill() method:

applyAlpha(c.getAlpha(), OPAQUE);

However in this case, batik's GraphicContext.setPaint() is receiving a LinearGradientPaint object which does not inherit from Color. Thus it does not set the "foreground" attribute, meaning that an alpha from a previous setPaint() will be used - in this case, the stroke opacity of the preceding SVG elemnt.

** Possible hack **
Since the applyAlpha line in PDFGraphics2D.fill() will not be correct when the paint returned by getPaint() is a gradient, I added an instanceof check so that it only runs when getPaint() returns an instance of Color. This is not a thouroughly thought-out fix and therefore should just be regarded as a workaround hack.

Attaching SVG file and FO, plus hack (most likely not suitable as fix) to get around issue.
Comment 1 dleung 2010-06-29 04:03:49 UTC
Created attachment 25653 [details]
fo to accompany above SVG
Comment 2 dleung 2010-06-29 04:04:16 UTC
Comment on attachment 25652 [details]
svg with three rectangles

SVG with three rectangles. The bottom left rectangle should have a fully opaque gradient fill, but does not in FOP's PDF output.
Comment 3 dleung 2010-06-29 04:06:24 UTC
Created attachment 25654 [details]
PDF with incorrect fill opacity on bottom left rectangle
Comment 4 dleung 2010-06-29 04:07:42 UTC
Created attachment 25655 [details]
PDF after fix (hack)
Comment 5 dleung 2010-06-29 04:08:32 UTC
Created attachment 25656 [details]
Workaround hack
Comment 6 dleung 2010-06-29 20:34:53 UTC
Comment on attachment 25656 [details]
Workaround hack

Doesn't work, see next patch upload
Comment 7 dleung 2010-06-29 20:35:47 UTC
Created attachment 25664 [details]
Work around hack v2
Comment 8 Glenn Adams 2012-04-07 01:42:23 UTC
resetting P2 open bugs to P3 pending further review
Comment 9 Luis Bernardo 2012-08-13 23:20:38 UTC
Created attachment 29221 [details]
patch for xmlgraphics

the patch previously submitted is not the best approach in my opinion. the problem in fact happens in xmlgraphics, not fop, and is due to the fact that the GraphicContext.setPaint() does not update the foreground color if the paint in not a Color (if it is a LinearGradientPaint, as in the example submitted). this means that the opacity from the previous element is used in the new element. the patch submitted avoids that by resetting the foreground color to the default (black, full opacity).
Comment 10 Luis Bernardo 2012-10-27 16:49:39 UTC
applied: http://svn.apache.org/viewvc?view=revision&revision=1402820