Hi,
I encountered an issue with the DiskMemImageGraphics class, which
involves clipping. I encountered this issue at first when rendering
SVGs using batik to a DiskMemImage, but I seem to have managed to
extract the specific issue so that there are no external
dependencies.
Basically the issue is that when DiskMemImageGraphics.clip() is
called, this clip is applied without taking the already set
AffineTransform into account. While Graphics2D says that clipping is
specified in user space, and should be applied the graphics object's
transformation, in MemDiskImageGraphics' case, this does not happen.
if you take documentation of Graphics2D.clip(Shape):
http://docs.oracle.com/javase/7/docs/api/java/awt/Graphics2D.html#clip(java.awt.Shape)
it says:
Intersects the current Clip with the interior of the specified Shape
and sets the Clip to the resulting intersection. The specified Shape
is transformed with the current Graphics2D Transform before being
intersected with the current Clip.
But it seems that DiskMemImageGraphics does not translate the
clipping region to the target region.
Do demonstrate the issue, see the sample code here:
http://pastebin.com/AYhgWkMn
(sorry, it's a bit messy). the transform & size values are taken
from a specific SVG rendering trace I first encountered the issue
with.
when running the above sample using a BufferedImage, the rectangle
specified in the code is drawn on the target image, and the output
is:
s bounds: java.awt.Rectangle[x=343,y=502,width=97,height=84]
grr transform: AffineTransform[[0.318755336305853, 0.0,
310.40200361261435], [0.0, 0.318755336305853, 85.32332454819294]]
grr clip:
java.awt.geom.Rectangle2D$Float[x=343.92856,y=502.51584,w=96.0,h=83.0]
grr clip bounds: java.awt.Rectangle[x=343,y=502,width=97,height=84]
intersects: true
now, if the same code is run using a MemDiskImageGraphics object
(uncomment / comment to 'select'), the rectangle does not appear on
the target image, and the output is:
s bounds: java.awt.Rectangle[x=343,y=502,width=97,height=84]
grr transform: AffineTransform[[0.318755336305853, 0.0,
310.40200361261435], [0.0, 0.318755336305853, 85.32332454819294]]
grr clip: java.awt.geom.Area@12f64b73
grr clip bounds: java.awt.Rectangle[x=0,y=0,width=96,height=83]
intersects: false
one can clearly see the difference: in one case, the clip area has
been translated, so that it coincides with the translated rectangle
area, in the second case, it has not.
the reason I put the intersect() test into the code is that batik
uses the same test to see if a shape should be drawn - and as a
result, it will not draw some SVG shapes, as this test fails. (for
people interested, the test is at
org.apache.batik.gvt.AbstractGraphicsNode.paint(), line 491.)
when looking at the source code of BufferedImage.clip() (see for
example here:
http://javasourcecode.org/html/open-source/jdk/jdk-6u23/java/awt/Graphics2D.java.html
), it's clear that there they make an effort to translate the clip
region into device space, and 'untranslate' it whet getClip() needs
to return the clip region. I wonder if something similar should be
done in the case of MemDiskImageGraphics.
Akos