The attached patch fixes stroking with transparency.
Before, attempting to draw a shape with alpha < 1.0 would fill the shape
instead of stroking it. Now, we don't worry about creating a stroked
shape and let Cairo handle it instead. It introduces some extra JNI
calls, but is a nicer solution (hopefully cairo will implement a
stroke-with-alpha function, since all their other functions accept alpha
values) and our benchmark speed is still very good.
I'd appreciate if someone could look it over and comment or approve it.
Regards,
Francis
2006-07-10 Francis Kung <[EMAIL PROTECTED]>
* gnu/java/awt/peer/gtk/CairoGraphics2D.java
(draw): Call native cairoStroke instead of creating our own
stroked shape and filling it.
(setComposite): Added comments.
(updateColor): Added comments.
Index: gnu/java/awt/peer/gtk/CairoGraphics2D.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/CairoGraphics2D.java,v
retrieving revision 1.29
diff -u -r1.29 CairoGraphics2D.java
--- gnu/java/awt/peer/gtk/CairoGraphics2D.java 30 Jun 2006 17:39:14 -0000 1.29
+++ gnu/java/awt/peer/gtk/CairoGraphics2D.java 10 Jul 2006 20:27:53 -0000
@@ -745,6 +745,13 @@
{
if (fg == null)
fg = Color.BLACK;
+
+ // Note that we don't worry about the alpha value from AlphaComposite here
+ // It is usually set within the cairo operation itself
+ // (ie, cairoFill(pointer, alpha))
+ // Also note that the alpha set here and any alpha set in a drawing
+ // operation
+ // is *cumulative*
cairoSetRGBAColor(nativePointer, fg.getRed() / 255.0,
fg.getGreen() / 255.0,fg.getBlue() / 255.0,
fg.getAlpha() / 255.0);
@@ -882,8 +889,11 @@
if (comp instanceof AlphaComposite)
{
- AlphaComposite a = (AlphaComposite) comp;
- cairoSetOperator(nativePointer, a.getRule());
+ // We do not set the alpha value in the Cairo context because it is
+ // usually set when calling the cairo operation
+ // (ie, cairoFill(pointer, alpha))
+ AlphaComposite a = (AlphaComposite) comp;
+ cairoSetOperator(nativePointer, a.getRule());
}
else
{
@@ -902,22 +912,10 @@
public void draw(Shape s)
{
- if ((stroke != null && ! (stroke instanceof BasicStroke))
- || (comp instanceof AlphaComposite
- && ((AlphaComposite) comp).getAlpha() != 1.0))
- {
- // FIXME: This is a hack to work around BasicStrokes's current
- // limitations wrt cubic curves.
- // See CubicSegment.getDisplacedSegments().
- if (stroke instanceof BasicStroke)
- {
- PathIterator flatten = s.getPathIterator(null, 1.0);
- GeneralPath p = new GeneralPath();
- p.append(flatten, false);
- s = p;
- }
- fill(stroke.createStrokedShape(s));
- return;
+ if (stroke != null && ! (stroke instanceof BasicStroke))
+ {
+ fill(stroke.createStrokedShape(s));
+ return;
}
cairoNewPath(nativePointer);
@@ -931,7 +929,23 @@
}
else
walkPath(s.getPathIterator(null), shiftDrawCalls);
- cairoStroke(nativePointer);
+
+ if (comp instanceof AlphaComposite
+ && ((AlphaComposite) comp).getAlpha() != 1.0)
+ {
+ // This is more complicated than most alpha operations since
+ // cairoStroke doesn't take an alpha parameter.
+ cairoSetRGBAColor(nativePointer, fg.getRed() / 255.0,
+ fg.getGreen() / 255.0, fg.getBlue() / 255.0,
+ ((AlphaComposite) comp).getAlpha()
+ * (fg.getAlpha() / 255.0));
+ cairoStroke(nativePointer);
+ cairoSetRGBAColor(nativePointer, fg.getRed() / 255.0,
+ fg.getGreen() / 255.0, fg.getBlue() / 255.0,
+ fg.getAlpha() / 255.0);
+ }
+ else
+ cairoStroke(nativePointer);
}
public void fill(Shape s)