diff options
-rw-r--r-- | ChangeLog | 19 | ||||
-rw-r--r-- | gnu/java/awt/peer/gtk/BufferedImageGraphics.java | 42 | ||||
-rw-r--r-- | gnu/java/awt/peer/gtk/CairoGraphics2D.java | 65 | ||||
-rw-r--r-- | gnu/java/awt/peer/gtk/ComponentGraphics.java | 51 |
4 files changed, 98 insertions, 79 deletions
@@ -1,5 +1,24 @@ 2006-11-21 Francis Kung <fkung@redhat.com> + * gnu/java/awt/peer/gtk/BufferedImageGraphics.java + (draw): Include stroke width when calculating bounds. + (updateBufferedImage): Round bounds more generously, handle negative + height/width values, and clip more intelligently. + * gnu/java/awt/peer/gtk/CairoGraphics2D.java + (createPath): Add shortcut optimization for lines. + (draw): Include stroke width when calculating bounds. + (drawLine): Delegate to main draw() method. + (drawRect): Likewise. + (fillRect): Delegate to main fill() method. + (findStrokedBounds): New method. + (setCustomPaint): Round bounds more generously. + * gnu/java/awt/peer/gtk/ComponentGraphics.java + (drawLine): Removed. + (drawRect): Removed. + (fillRect): Removed. + +2006-11-21 Francis Kung <fkung@redhat.com> + * gnu/java/awt/java2d/TexturePaintContext.java (getRaster): Handle negative coordinate values. * gnu/java/awt/peer/gtk/CairoGraphics2D.java diff --git a/gnu/java/awt/peer/gtk/BufferedImageGraphics.java b/gnu/java/awt/peer/gtk/BufferedImageGraphics.java index f83be870d..d58b6c258 100644 --- a/gnu/java/awt/peer/gtk/BufferedImageGraphics.java +++ b/gnu/java/awt/peer/gtk/BufferedImageGraphics.java @@ -188,16 +188,32 @@ public class BufferedImageGraphics extends CairoGraphics2D transform.transform(points, 0, points, 0, 2); x = (int)points[0]; y = (int)points[1]; - width = (int)(points[2] - x); - height = (int)(points[3] - y); + width = (int)Math.ceil(points[2] - points[0]); + height = (int)Math.ceil(points[3] - points[1]); int[] pixels = surface.getPixels(imageWidth * imageHeight); if( x > imageWidth || y > imageHeight ) return; + + // Deal with negative width/height. + if (height < 0) + { + y += height; + height = -height; + } + if (width < 0) + { + x += width; + width = -width; + } + // Clip edges. - if( x < 0 ){ width = width + x; x = 0; } - if( y < 0 ){ height = height + y; y = 0; } + if( x < 0 ) + x = 0; + if( y < 0 ) + y = 0; + if( x + width > imageWidth ) width = imageWidth - x; if( y + height > imageHeight ) @@ -247,15 +263,19 @@ public class BufferedImageGraphics extends CairoGraphics2D */ public void draw(Shape s) { + // Find total bounds of shape + Rectangle r = findStrokedBounds(s); + if (shiftDrawCalls) + { + r.width++; + r.height++; + } + + // Do the drawing if (comp == null || comp instanceof AlphaComposite) { super.draw(s); - Rectangle r = s.getBounds(); - - if (shiftDrawCalls) - updateBufferedImage(r.x, r.y, r.width+1, r.height+1); - else - updateBufferedImage(r.x, r.y, r.width, r.height); + updateBufferedImage(r.x, r.y, r.width, r.height); } else { @@ -266,7 +286,7 @@ public class BufferedImageGraphics extends CairoGraphics2D g2d.setColor(this.getColor()); g2d.draw(s); - drawComposite(s.getBounds2D(), null); + drawComposite(r.getBounds2D(), null); } } diff --git a/gnu/java/awt/peer/gtk/CairoGraphics2D.java b/gnu/java/awt/peer/gtk/CairoGraphics2D.java index bb4debbf9..e7d8036fa 100644 --- a/gnu/java/awt/peer/gtk/CairoGraphics2D.java +++ b/gnu/java/awt/peer/gtk/CairoGraphics2D.java @@ -71,6 +71,7 @@ import java.awt.geom.Arc2D; import java.awt.geom.Area; import java.awt.geom.Ellipse2D; import java.awt.geom.GeneralPath; +import java.awt.geom.Line2D; import java.awt.geom.NoninvertibleTransformException; import java.awt.geom.PathIterator; import java.awt.geom.Point2D; @@ -764,8 +765,8 @@ public abstract class CairoGraphics2D extends Graphics2D null); int deviceX = (int)origin.getX(); int deviceY = (int)origin.getY(); - int deviceWidth = (int)extreme.getX() - deviceX; - int deviceHeight = (int)extreme.getY() - deviceY; + int deviceWidth = (int)Math.ceil(extreme.getX() - origin.getX()); + int deviceHeight = (int)Math.ceil(extreme.getY() - origin.getY()); // Get raster of the paint background PaintContext pc = paint.createContext(CairoSurface.cairoColorModel, @@ -864,6 +865,33 @@ public abstract class CairoGraphics2D extends Graphics2D } } + /** + * Utility method to find the bounds of a shape, including the stroke width. + * + * @param s the shape + * @return the bounds of the shape, including stroke width + */ + protected Rectangle findStrokedBounds(Shape s) + { + Rectangle r = s.getBounds(); + + if (stroke instanceof BasicStroke) + { + int strokeWidth = (int)Math.ceil(((BasicStroke)stroke).getLineWidth()); + r.x -= strokeWidth / 2; + r.y -= strokeWidth / 2; + r.height += strokeWidth; + r.width += strokeWidth; + } + else + { + Shape s2 = stroke.createStrokedShape(s); + r = s2.getBounds(); + } + + return r; + } + public void setPaintMode() { setComposite(AlphaComposite.SrcOver); @@ -1089,7 +1117,10 @@ public abstract class CairoGraphics2D extends Graphics2D } if (customPaint) - setCustomPaint(s.getBounds()); + { + Rectangle r = findStrokedBounds(s); + setCustomPaint(r); + } createPath(s, true); cairoStroke(nativePointer); @@ -1120,6 +1151,16 @@ public abstract class CairoGraphics2D extends Graphics2D shifted(r.getY(), shiftDrawCalls && isDraw), r.getWidth(), r.getHeight()); } + + // Lines are easy too + else if (s instanceof Line2D) + { + Line2D l = (Line2D) s; + cairoMoveTo(nativePointer, shifted(l.getX1(), shiftDrawCalls && isDraw), + shifted(l.getY1(), shiftDrawCalls && isDraw)); + cairoLineTo(nativePointer, shifted(l.getX2(), shiftDrawCalls && isDraw), + shifted(l.getY2(), shiftDrawCalls && isDraw)); + } // We can optimize ellipses too; however we don't bother optimizing arcs: // the iterator is fast enough (an ellipse requires 5 steps using the @@ -1203,22 +1244,15 @@ public abstract class CairoGraphics2D extends Graphics2D // The coordinates being pairwise identical means one wants // to draw a single pixel. This is emulated by drawing // a one pixel sized rectangle. - if (customPaint) - setCustomPaint(new Rectangle(x1, y1, x2 - x1, y2 - y1)); - if (x1 == x2 && y1 == y2) - cairoFillRect(nativePointer, x1, y1, 1, 1); + fill(new Rectangle(x1, y1, 1, 1)); else - cairoDrawLine(nativePointer, x1 + 0.5, y1 + 0.5, x2 + 0.5, y2 + 0.5); + draw(new Line2D.Double(x1 + 0.5, y1 + 0.5, x2 + 0.5, y2 + 0.5)); } public void drawRect(int x, int y, int width, int height) { - if (customPaint) - setCustomPaint(new Rectangle(x, y, width, height)); - - cairoDrawRect(nativePointer, shifted(x, shiftDrawCalls), - shifted(y, shiftDrawCalls), width, height); + draw(new Rectangle(x, y, width, height)); } public void fillArc(int x, int y, int width, int height, int startAngle, @@ -1231,10 +1265,7 @@ public abstract class CairoGraphics2D extends Graphics2D public void fillRect(int x, int y, int width, int height) { - fill(new Rectangle(x, y, width, height)); - // TODO: If we want to use the more efficient - //cairoFillRect(nativePointer, x, y, width, height); - // we need to override this method in subclasses + fill (new Rectangle(x, y, width, height)); } public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints) diff --git a/gnu/java/awt/peer/gtk/ComponentGraphics.java b/gnu/java/awt/peer/gtk/ComponentGraphics.java index c8ec2c95e..612efd628 100644 --- a/gnu/java/awt/peer/gtk/ComponentGraphics.java +++ b/gnu/java/awt/peer/gtk/ComponentGraphics.java @@ -480,57 +480,6 @@ public class ComponentGraphics extends CairoGraphics2D return super.drawImage(bimg, x, y, width, height, observer); } - public void drawLine(int x1, int y1, int x2, int y2) - { - lock(); - try - { - if (comp == null || comp instanceof AlphaComposite) - super.drawLine(x1, y1, x2, y2); - - else - draw(new Line2D.Double(x1, y1, x2, y2)); - } - finally - { - unlock(); - } - } - - public void drawRect(int x, int y, int width, int height) - { - lock(); - try - { - if (comp == null || comp instanceof AlphaComposite) - super.drawRect(x, y, width, height); - - else - draw(new Rectangle2D.Double(x, y, width, height)); - } - finally - { - unlock(); - } - } - - public void fillRect(int x, int y, int width, int height) - { - lock(); - try - { - if (comp == null || comp instanceof AlphaComposite) - super.fillRect(x, y, width, height); - - else - fill(new Rectangle2D.Double(x, y, width, height)); - } - finally - { - unlock(); - } - } - public void setClip(Shape s) { lock(); |