protected CairoSurface surface;
private BufferedImage buffer;
private long cairo_t;
-
+
/**
* Create a graphics context from a cairo surface
*/
/**
* Creates another context from a surface.
* Used by create().
- */
+ */
private CairoSurfaceGraphics(CairoSurfaceGraphics copyFrom)
{
surface = copyFrom.surface;
cairo_t = surface.newCairoContext();
copy( copyFrom, cairo_t );
}
-
+
public Graphics create()
{
return new CairoSurfaceGraphics(this);
}
-
+
public GraphicsConfiguration getDeviceConfiguration()
{
return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
}
-
+
protected Rectangle2D getRealBounds()
{
return new Rectangle2D.Double(0.0, 0.0, surface.width, surface.height);
{
surface.copyAreaNative(x, y, width, height, dx, dy, surface.width);
}
-
+
/**
* Overloaded methods that do actual drawing need to account for custom
* composites
{
if (!surface.sharedBuffer)
surface.syncJavaToNative(surface.surfacePointer, surface.getData());
-
+
// 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);
-
+
else
{
createBuffer();
-
+
Graphics2D g2d = (Graphics2D)buffer.getGraphics();
g2d.setStroke(this.getStroke());
g2d.setColor(this.getColor());
g2d.setTransform(transform);
g2d.draw(s);
-
+
drawComposite(r.getBounds2D(), null);
}
-
+
if (!surface.sharedBuffer)
surface.syncNativeToJava(surface.surfacePointer, surface.getData());
}
{
if (!surface.sharedBuffer)
surface.syncJavaToNative(surface.surfacePointer, surface.getData());
-
+
if (comp == null || comp instanceof AlphaComposite)
super.fill(s);
-
+
else
{
createBuffer();
-
+
Graphics2D g2d = (Graphics2D)buffer.getGraphics();
g2d.setPaint(this.getPaint());
g2d.setColor(this.getColor());
g2d.setTransform(transform);
g2d.fill(s);
-
+
drawComposite(s.getBounds2D(), null);
}
-
+
if (!surface.sharedBuffer)
surface.syncNativeToJava(surface.surfacePointer, surface.getData());
}
{
if (!surface.sharedBuffer)
surface.syncJavaToNative(surface.surfacePointer, surface.getData());
-
+
if (comp == null || comp instanceof AlphaComposite)
super.drawRenderedImage(image, xform);
-
+
else
{
createBuffer();
g2d.setRenderingHints(this.getRenderingHints());
g2d.setTransform(transform);
g2d.drawRenderedImage(image, xform);
-
+
drawComposite(buffer.getRaster().getBounds(), null);
}
-
+
if (!surface.sharedBuffer)
surface.syncNativeToJava(surface.surfacePointer, surface.getData());
}
boolean ret;
if (comp == null || comp instanceof AlphaComposite)
ret = super.drawImage(img, xform, bgcolor, obs);
-
+
else
{
// Get buffered image of source
img = Toolkit.getDefaultToolkit().createImage(source);
}
BufferedImage bImg = (BufferedImage) img;
-
+
// Find translated bounds
Rectangle2D bounds = new Rectangle(bImg.getMinX(), bImg.getMinY(),
bImg.getWidth(), bImg.getHeight());
if (xform != null)
bounds = getTransformedBounds(bounds, xform);
-
+
// Create buffer and draw image
createBuffer();
-
+
Graphics2D g2d = (Graphics2D)buffer.getGraphics();
g2d.setRenderingHints(this.getRenderingHints());
g2d.drawImage(img, xform, obs);
// Perform compositing
ret = drawComposite(bounds, obs);
}
-
+
if (!surface.sharedBuffer)
surface.syncNativeToJava(surface.surfacePointer, surface.getData());
-
+
return ret;
}
{
if (!surface.sharedBuffer)
surface.syncJavaToNative(surface.surfacePointer, surface.getData());
-
+
if (comp == null || comp instanceof AlphaComposite)
super.drawGlyphVector(gv, x, y);
-
+
else
{
createBuffer();
g2d.setPaint(this.getPaint());
g2d.setStroke(this.getStroke());
g2d.drawGlyphVector(gv, x, y);
-
+
Rectangle2D bounds = gv.getLogicalBounds();
bounds = new Rectangle2D.Double(x + bounds.getX(), y + bounds.getY(),
bounds.getWidth(), bounds.getHeight());
drawComposite(bounds, null);
}
-
+
if (!surface.sharedBuffer)
surface.syncNativeToJava(surface.surfacePointer, surface.getData());
}
-
+
private boolean drawComposite(Rectangle2D bounds, ImageObserver observer)
{
// Find bounds in device space
devClip = new Rectangle(buffer.getMinX(), buffer.getMinY(),
buffer.getWidth(), buffer.getHeight());
Rectangle2D.intersect(bounds, devClip, bounds);
-
+
// Round bounds as needed, but be careful in our rounding
// (otherwise it may leave unpainted stripes)
double x = bounds.getX();
x = Math.round(x);
y = Math.round(y);
bounds.setRect(x, y, Math.round(maxX - x), Math.round(maxY - y));
-
+
// Find subimage of internal buffer for updating
BufferedImage buffer2 = buffer;
if (!bounds.equals(buffer2.getRaster().getBounds()))
// Perform actual composite operation
compCtx.compose(buffer2.getRaster(), current.getRaster(),
buffer2.getRaster());
-
+
// Set cairo's composite to direct SRC, since we've already done our own
- // compositing
+ // compositing
Composite oldcomp = comp;
setComposite(AlphaComposite.Src);
-
+
// This MUST call directly into the "action" method in CairoGraphics2D,
// not one of the wrappers, to ensure that the composite isn't processed
// more than once!
updateColor();
return rv;
}
-
+
private void createBuffer()
{
if (buffer == null)
else
{
Graphics2D g2d = ((Graphics2D)buffer.getGraphics());
-
+
g2d.setBackground(new Color(0,0,0,0));
g2d.clearRect(0, 0, buffer.getWidth(), buffer.getHeight());
}
}
-
+
protected ColorModel getNativeCM()
{
return CairoSurface.cairoCM_pre;
}
-
+
protected ColorModel getBufferCM()
{
return CairoSurface.cairoColorModel;