summaryrefslogtreecommitdiff
path: root/libjava/gnu/awt/xlib/XGraphics.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/gnu/awt/xlib/XGraphics.java')
-rw-r--r--libjava/gnu/awt/xlib/XGraphics.java305
1 files changed, 305 insertions, 0 deletions
diff --git a/libjava/gnu/awt/xlib/XGraphics.java b/libjava/gnu/awt/xlib/XGraphics.java
new file mode 100644
index 000000000..215c04dc1
--- /dev/null
+++ b/libjava/gnu/awt/xlib/XGraphics.java
@@ -0,0 +1,305 @@
+/* Copyright (C) 2000, 2003, 2004 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package gnu.awt.xlib;
+
+import java.awt.*;
+import java.awt.image.WritableRaster;
+import java.awt.image.Raster;
+import java.awt.image.DataBuffer;
+import java.awt.image.ColorModel;
+import java.awt.image.ImageObserver;
+import java.awt.image.BufferedImage;
+import gnu.gcj.xlib.GC;
+import gnu.gcj.xlib.XImage;
+import gnu.gcj.xlib.Drawable;
+import gnu.gcj.xlib.Window;
+import gnu.gcj.xlib.Drawable;
+import gnu.gcj.xlib.Pixmap;
+import gnu.gcj.xlib.Visual;
+import gnu.awt.j2d.DirectRasterGraphics;
+import gnu.awt.j2d.MappedRaster;
+
+public class XGraphics implements Cloneable, DirectRasterGraphics
+{
+ static class XRaster extends MappedRaster
+ {
+ XImage ximage;
+
+ public XRaster(WritableRaster raster, XImage ximage, ColorModel cm)
+ {
+ super(raster, cm);
+ this.ximage = ximage;
+ }
+ }
+
+ GC context;
+ XGraphicsConfiguration config;
+ Rectangle clipBounds;
+
+ XFontMetrics metrics;
+
+
+ public Object clone()
+ {
+ try
+ {
+ XGraphics gfxCopy = (XGraphics) super.clone();
+ gfxCopy.context = context.create();
+
+ return gfxCopy;
+ }
+ catch (CloneNotSupportedException ex)
+ {
+ // This should never happen.
+ throw new InternalError ();
+ }
+ }
+
+ public void dispose()
+ {
+ GC lContext = context;
+ context = null;
+ config = null;
+ clipBounds = null;
+ metrics = null;
+
+ if (lContext != null)
+ {
+ lContext.dispose();
+ }
+ }
+
+ public XGraphics(Drawable drawable, XGraphicsConfiguration config)
+ {
+ context = GC.create(drawable);
+ this.config = config;
+ }
+
+ public void setColor(Color color)
+ {
+ if (color != null)
+ context.setForeground(config.getPixel(color));
+ }
+
+ public void setPaintMode()
+ {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ public void setXORMode(Color c1)
+ {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ public void setFont(Font font)
+ {
+ if (font == null)
+ return;
+ if ((metrics != null) && font.equals(metrics.getFont()))
+ return;
+ metrics = config.getXFontMetrics(font);
+ if (metrics != null)
+ context.setFont(metrics.xfont);
+ }
+
+ public FontMetrics getFontMetrics(Font font)
+ {
+ if ((metrics != null) && font.equals(metrics.getFont()))
+ return metrics;
+
+ return config.getXFontMetrics(font);
+ }
+
+ public void setClip(int x, int y, int width, int height)
+ {
+ Rectangle[] rects = { new Rectangle(x, y, width, height) };
+ context.setClipRectangles(rects);
+ }
+
+ public void setClip(Shape clip)
+ {
+ /* TODO: create a special RectangleUnion shape that can be
+ used to draw advantage of the GCs ability to set multiple
+ rectangles.
+ */
+
+ /* FIXME: creating all these objects is wasteful and can be
+ costly in the long run, since this code is run at every
+ expose. */
+ Rectangle newClipBounds = clip.getBounds();
+
+ /* FIXME: decide whether this test code is worth anything
+ * (as of 2004-01-29, it prints frequently)
+ if ((clipBounds != null) && !clipBounds.contains(newClipBounds))
+ {
+ System.err.println("warning: old clip ("+ clipBounds +") does " +
+ "not fully contain new clip (" +
+ newClipBounds + ")");
+ }
+ */
+ clipBounds = newClipBounds;
+ Rectangle[] rects = { clipBounds };
+ context.setClipRectangles(rects);
+ }
+
+ public void copyArea(int x, int y, int width, int height, int
+ dx, int dy)
+ {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ public void drawLine(int x1, int y1, int x2, int y2)
+ {
+ context.drawLine(x1, y1, x2, y2);
+ }
+
+ public void drawRect(int x, int y, int width, int height)
+ {
+ throw new UnsupportedOperationException("not implemented yet");
+ }
+
+ public void fillRect(int x, int y, int width, int height)
+ {
+ context.fillRectangle(x, y, width, height);
+ }
+
+ public void drawArc(int x, int y, int width, int height, int
+ startAngle, int arcAngle)
+ {
+ context.drawArc (x, y, width, height, startAngle, arcAngle);
+ }
+
+ public void fillArc(int x, int y, int width, int height, int
+ startAngle, int arcAngle)
+ {
+ context.fillArc (x, y, width, height, startAngle, arcAngle);
+ }
+
+ public void drawPolyline(int[] xPoints, int[] yPoints, int
+ nPoints)
+ {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ public void drawPolygon(int[] xPoints, int[] yPoints, int
+ nPoints)
+ {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints,
+ int translateX, int translateY)
+ {
+ context.fillPolygon(xPoints, yPoints, nPoints, translateX, translateY);
+ }
+
+ public void drawString(String str, int x, int y)
+ {
+ context.drawString(str, x, y);
+ }
+
+ public boolean drawImage(Image img, int x, int y,
+ ImageObserver observer)
+ {
+ if (img instanceof XOffScreenImage)
+ {
+ // FIXME: have to enforce clip, or is it OK as-is?
+ XOffScreenImage offScreenImage = (XOffScreenImage) img;
+ Pixmap pixmap = offScreenImage.getPixmap ();
+ context.copyArea (pixmap, 0, 0, x, y,
+ offScreenImage.getWidth (), offScreenImage.getHeight ());
+ return true;
+ }
+ if (clipBounds == null)
+ return false; // ***FIXME***
+
+ if (!(img instanceof BufferedImage))
+ {
+ throw new AWTError("unknown image class");
+ }
+
+ BufferedImage bimg = (BufferedImage) img;
+
+ XImage ximg = (XImage) bimg.getProperty("gnu.gcj.xlib.XImage");
+ if (ximg == null)
+ {
+ System.err.println("FIXME: skipping null XImage, should " +
+ "really do on the spot conversion");
+ return false;
+ }
+
+ /*
+ +------------------
+ | clip
+ | +---------+
+ | img | |
+ | +--+-------+ |
+ | | | | |
+ | | | | |
+ | | +-------+-+
+ | | |
+ | +----------+
+ */
+
+ int iLeft = Math.max(x, clipBounds.x);
+ int iTop = Math.max(y, clipBounds.y);
+ int iRight = Math.min(x + bimg.getWidth(),
+ clipBounds.x + clipBounds.width);
+ int iBottom = Math.min(y + bimg.getHeight(),
+ clipBounds.y + clipBounds.height);
+
+ int srcX = iLeft - x;
+ int srcY = iTop - y;
+
+ int width = iRight - iLeft;
+ int height = iBottom - iTop;
+
+ if ((width > 0) && (height > 0))
+ context.putImage(ximg, srcX, srcY, iLeft, iTop, width, height);
+
+ return true;
+ }
+
+ public MappedRaster mapRaster(Rectangle bounds)
+ {
+ Visual visual = config.getVisual();
+ XImage ximage = new XImage(visual, bounds.width, bounds.height,
+ false // do not auto allocate memory
+ );
+
+ WritableRaster raster =
+ config.createRasterForXImage(ximage,
+ new Point(bounds.x, bounds.y));
+
+ DataBuffer dataB = raster.getDataBuffer();
+ XGraphicsConfiguration.attachData(ximage, dataB, 0);
+
+ Drawable drawable = context.getDrawable();
+
+ // TODO: restrict to clipping
+
+ Rectangle mBounds = drawable.copyIntoXImage(ximage, bounds, 0, 0);
+
+ return new XRaster(raster, ximage, config.imageCM);
+ }
+
+
+ public void unmapRaster(MappedRaster mappedRaster)
+ {
+ XRaster xraster = (XRaster) mappedRaster;
+ XImage ximage = xraster.ximage;
+ Raster raster = xraster.getRaster();
+ int x = raster.getMinX();
+ int y = raster.getMinY();
+ int width = raster.getWidth();
+ int height = raster.getHeight();
+
+ context.putImage(ximage, 0, 0, x, y, width, height);
+ }
+}