123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306 |
- /* 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);
- }
- }
|