81f7282f97
* Makefile.am: added gnu/awt/xlib/XOffScreenImage.java. * Makefile.in: re-generated. * gnu/awt/j2d/IntegerGraphicsState.java (ScreenCoupledImage): new interface. (drawImage): detect ScreenCoupledImage instances. * gnu/awt/xlib/XCanvasPeer.java (createImage) implemented. * gnu/awt/xlib/XEventLoop.java (createEvent): re-formatted, and rearranged to avoid null pointer. * gnu/awt/xlib/XGraphics.java (drawImage): added XOffScreenImage handling. * gnu/awt/xlib/XOffScreenImage.java: new file. * gnu/gcj/xlib/Drawable.java (getDepth): new native method. * gnu/gcj/xlib/GC.java (copyArea): new native method. * gnu/gcj/xlib/XAnyEvent.java (TYPE_KEY_PRESS): new constant. (TYPE_KEY_RELEASE): new constant. (TYPE_MOTION_NOTIFY): new constant. (TYPE_ENTER_NOTIFY): new constant. (TYPE_LEAVE_NOTIFY): new constant. (TYPE_FOCUS_IN): new constant. (TYPE_FOCUS_OUT): new constant. (TYPE_KEYMAP_NOTIFY): new constant. (TYPE_GRAPHICS_EXPOSE): new constant. (TYPE_NO_EXPOSE): new constant. (TYPE_VISIBILITY_NOTIFY): new constant. (TYPE_CREATE_NOTIFY): new constant. (TYPE_DESTROY_NOTIFY): new constant. (TYPE_MAP_REQUEST): new constant. (TYPE_CONFIGURE_REQUEST): new constant. (TYPE_GRAVITY_NOTIFY): new constant. (TYPE_RESIZE_REQUEST): new constant. (TYPE_CIRCULATE_NOTIFY): new constant. (TYPE_CIRCULATE_REQUEST): new constant. (TYPE_PROPERTY_NOTIFY): new constant. (TYPE_SELECTION_CLEAR): new constant. (TYPE_SELECTION_REQUEST): new constant. (TYPE_SELECTION_NOTIFY): new constant. (TYPE_COLORMAP_NOTIFY): new constant. (TYPE_MAPPING_NOTIFY): new constant. * gnu/gcj/xlib/natDrawable.cc (getDepth): new method. * gnu/gcj/xlib/natGC.cc (copyArea): new method * java/awt/Component.java (createImage): changed to use peer method. From-SVN: r70776
424 lines
10 KiB
Java
424 lines
10 KiB
Java
/* Copyright (C) 2000, 2003 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.j2d;
|
|
|
|
import java.awt.Color;
|
|
import java.awt.Image;
|
|
import java.awt.Shape;
|
|
import java.awt.Rectangle;
|
|
import java.awt.Graphics;
|
|
import java.awt.Graphics2D;
|
|
import java.awt.GraphicsConfiguration;
|
|
import java.awt.Font;
|
|
import java.awt.FontMetrics;
|
|
import java.awt.image.BufferedImage;
|
|
import java.awt.image.ImageObserver;
|
|
import java.awt.image.Raster;
|
|
import java.awt.image.WritableRaster;
|
|
import java.awt.image.ColorModel;
|
|
|
|
/**
|
|
* IntegerGraphicsState is one of several graphics state
|
|
* implementations. This graphics state is used when the graphics
|
|
* object has simple properties, (coordinate translation only, no
|
|
* transform) and the backend supports integer coordinates (pixel
|
|
* based). For primitive paint operations, this object translates the
|
|
* coordinates and forwards the request to the backend. For requests
|
|
* to draw arbitrary shapes and paths, this object translates the
|
|
* requests to primitive drawing operations supported by the
|
|
* backend. IntegerGraphicsState is meant to support the most common
|
|
* state of an graphics object. The degree of functionality is roughly
|
|
* equivalent with the old java.awt.Graphics API.
|
|
*/
|
|
public class IntegerGraphicsState extends AbstractGraphicsState
|
|
{
|
|
int tx;
|
|
int ty;
|
|
|
|
DirectRasterGraphics directGfx;
|
|
Shape clip;
|
|
|
|
/** Interface for images which are coupled to a GraphicsConfiguration,
|
|
* as is typically the case for an off-screen buffer used in
|
|
* double-buffering. Any image which implements this interface is
|
|
* rendered directly by DirectRasterGraphics (i.e. by directGfx.drawImage)
|
|
*/
|
|
public interface ScreenCoupledImage
|
|
{
|
|
/** Get the GraphicsConfiguration to which this image is coupled
|
|
* @return the GraphicsConfiguration
|
|
*/
|
|
GraphicsConfiguration getGraphicsConfiguration ();
|
|
}
|
|
|
|
public IntegerGraphicsState(DirectRasterGraphics directGfx)
|
|
{
|
|
this.directGfx = directGfx;
|
|
}
|
|
|
|
public Object clone()
|
|
{
|
|
IntegerGraphicsState clone = (IntegerGraphicsState) super.clone();
|
|
clone.directGfx = (DirectRasterGraphics) directGfx.clone();
|
|
|
|
return clone;
|
|
}
|
|
|
|
public void dispose()
|
|
{
|
|
DirectRasterGraphics lDeviceGfx = directGfx;
|
|
|
|
directGfx = null;
|
|
|
|
if (lDeviceGfx != null)
|
|
lDeviceGfx.dispose();
|
|
|
|
super.dispose();
|
|
}
|
|
|
|
// -------- Graphics methods:
|
|
|
|
public void setColor(Color color)
|
|
{
|
|
directGfx.setColor(color);
|
|
}
|
|
|
|
public void setPaintMode()
|
|
{
|
|
directGfx.setPaintMode();
|
|
}
|
|
|
|
public void setXORMode(Color altColor)
|
|
{
|
|
directGfx.setXORMode(altColor);
|
|
}
|
|
|
|
public void setFont(Font font)
|
|
{
|
|
directGfx.setFont(font);
|
|
}
|
|
|
|
public FontMetrics getFontMetrics(Font font)
|
|
{
|
|
return directGfx.getFontMetrics(font);
|
|
}
|
|
|
|
public void setClip(Shape clip)
|
|
{
|
|
if (clip instanceof Rectangle)
|
|
{
|
|
Rectangle clipRect = (Rectangle) ((Rectangle) clip).clone();
|
|
clipRect.x += tx;
|
|
clipRect.y += ty;
|
|
|
|
this.clip = clipRect;
|
|
|
|
directGfx.setClip(clipRect);
|
|
return;
|
|
}
|
|
|
|
String msg =
|
|
"translating clip shape " + clip + " into device " +
|
|
"coordinate space has not been implemented yet";
|
|
|
|
throw new UnsupportedOperationException(msg);
|
|
}
|
|
|
|
public Shape getClip()
|
|
{
|
|
if (clip instanceof Rectangle)
|
|
{
|
|
Rectangle clipRect = (Rectangle) clip;
|
|
clipRect.x -= tx;
|
|
clipRect.y -= ty;
|
|
return clipRect;
|
|
}
|
|
|
|
String msg =
|
|
"translating clip shape " + clip + " into user " +
|
|
"coordinate space has not been implemented yet";
|
|
|
|
throw new UnsupportedOperationException(msg);
|
|
}
|
|
|
|
public Rectangle getClipBounds()
|
|
{
|
|
Rectangle clipRect = clip.getBounds();
|
|
|
|
clipRect.x -= tx;
|
|
clipRect.y -= ty;
|
|
return clipRect;
|
|
}
|
|
|
|
public void copyArea(int x, int y,
|
|
int width, int height,
|
|
int dx, int dy)
|
|
{
|
|
directGfx.copyArea(x+tx, y+ty, width, height, dx, dy);
|
|
}
|
|
|
|
public void drawLine(int x1, int y1,
|
|
int x2, int y2)
|
|
{
|
|
directGfx.drawLine(x1+tx, y1+ty, x2+tx, y2+ty);
|
|
}
|
|
|
|
public void fillRect(int x, int y,
|
|
int width, int height)
|
|
{
|
|
directGfx.fillRect(x+tx, y+ty, width, height);
|
|
}
|
|
|
|
public void clearRect(int x, int y,
|
|
int width, int height)
|
|
{
|
|
directGfx.setColor(frontend.getBackground());
|
|
directGfx.fillRect(x+tx, y+ty, width, height);
|
|
directGfx.setColor(frontend.getColor());
|
|
}
|
|
|
|
public void drawRoundRect(int x, int y,
|
|
int width, int height,
|
|
int arcWidth, int arcHeight)
|
|
{
|
|
throw new UnsupportedOperationException("not implemented yet");
|
|
}
|
|
|
|
public void fillRoundRect(int x, int y,
|
|
int width, int height,
|
|
int arcWidth, int arcHeight)
|
|
{
|
|
throw new UnsupportedOperationException("not implemented yet");
|
|
}
|
|
|
|
public void drawOval(int x, int y,
|
|
int width, int height)
|
|
{
|
|
drawArc (x, y, width, height, 0, 360);
|
|
}
|
|
|
|
public void fillOval(int x, int y,
|
|
int width, int height)
|
|
{
|
|
fillArc (x, y, width, height, 0, 360);
|
|
}
|
|
|
|
public void drawArc(int x, int y,
|
|
int width, int height,
|
|
int startAngle, int arcAngle)
|
|
{
|
|
directGfx.drawArc(x+tx, y+ty, width, height, startAngle, arcAngle);
|
|
}
|
|
|
|
public void fillArc(int x, int y,
|
|
int width, int height,
|
|
int startAngle, int arcAngle)
|
|
{
|
|
directGfx.fillArc(x+tx, y+ty, width, height, startAngle, arcAngle);
|
|
}
|
|
|
|
public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints)
|
|
{
|
|
if ((tx == 0) && (ty == 0))
|
|
{
|
|
directGfx.drawPolyline(xPoints, yPoints, nPoints);
|
|
return;
|
|
}
|
|
|
|
throw new UnsupportedOperationException("translate not implemented");
|
|
}
|
|
|
|
public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints)
|
|
{
|
|
if ((tx == 0) && (ty == 0))
|
|
{
|
|
directGfx.drawPolygon(xPoints, yPoints, nPoints);
|
|
return;
|
|
}
|
|
|
|
throw new UnsupportedOperationException("translate not implemented");
|
|
}
|
|
|
|
public void fillPolygon (int[] xPoints, int[] yPoints, int nPoints)
|
|
{
|
|
// FIXME: remove tx & ty args once translation via AffineTransform
|
|
// is implemented.
|
|
directGfx.fillPolygon (xPoints, yPoints, nPoints, tx, ty);
|
|
}
|
|
|
|
public boolean drawImage(Image image, int x, int y,
|
|
ImageObserver observer)
|
|
{
|
|
x += tx;
|
|
y += ty;
|
|
|
|
if (image instanceof ScreenCoupledImage)
|
|
{
|
|
GraphicsConfiguration config
|
|
= ((ScreenCoupledImage)image).getGraphicsConfiguration ();
|
|
if (config == frontend.config)
|
|
return directGfx.drawImage (image, x, y, observer);
|
|
}
|
|
if (image instanceof BufferedImage)
|
|
{
|
|
BufferedImage bImage = (BufferedImage) image;
|
|
// FIXME: eliminate? ScreenCoupledImage is probably more efficient
|
|
Object config = bImage.getProperty ("java.awt.GraphicsConfiguration");
|
|
if (config == frontend.config)
|
|
return directGfx.drawImage (image, x, y, observer);
|
|
|
|
int width = image.getWidth (null);
|
|
int height = image.getHeight (null);
|
|
|
|
Rectangle bounds = new Rectangle (x, y, width, height);
|
|
|
|
MappedRaster mr = directGfx.mapRaster (bounds);
|
|
|
|
// manipulate raster here...
|
|
ColorModel colorModel = mr.getColorModel ();
|
|
WritableRaster raster = mr.getRaster ();
|
|
|
|
int xEnd = x + width;
|
|
int yEnd = y + height;
|
|
|
|
// FIXME: Use the following code only as a fallback. It's SLOW!
|
|
|
|
Object rgbElem = null;
|
|
for (int yy=0; yy<height; yy++)
|
|
{
|
|
for (int xx=0; xx<width; xx++)
|
|
{
|
|
int srgb = bImage.getRGB (xx, yy);
|
|
int sa = ((srgb >>> 24) & 0xff) + 1;
|
|
int sr = ((srgb >>> 16) & 0xff) + 1;
|
|
int sg = ((srgb >>> 8) & 0xff) + 1;
|
|
int sb = (srgb & 0xff) + 1;
|
|
|
|
rgbElem = raster.getDataElements (xx+x, yy+y, rgbElem);
|
|
int drgb = colorModel.getRGB (rgbElem);
|
|
int dr = ((drgb >>> 16) & 0xff) + 1;
|
|
int dg = ((drgb >>> 8) & 0xff) + 1;
|
|
int db = (drgb & 0xff) + 1;
|
|
int da = 256 - sa;
|
|
|
|
dr = ((sr*sa + dr*da) >>> 8) - 1;
|
|
dg = ((sg*sa + dg*da) >>> 8) - 1;
|
|
db = ((sb*sa + db*da) >>> 8) - 1;
|
|
|
|
drgb = (dr<<16) | (dg<<8) | db;
|
|
|
|
rgbElem = colorModel.getDataElements (drgb, rgbElem);
|
|
|
|
raster.setDataElements (xx+x, yy+y, rgbElem);
|
|
}
|
|
}
|
|
directGfx.unmapRaster (mr);
|
|
return true;
|
|
|
|
}
|
|
throw new UnsupportedOperationException ("drawing image " + image +
|
|
"not implemented");
|
|
}
|
|
|
|
|
|
// -------- Graphics2D methods:
|
|
|
|
public void draw(Shape shape)
|
|
{
|
|
if (shape instanceof Rectangle)
|
|
{
|
|
Rectangle rect = (Rectangle) shape;
|
|
directGfx.drawRect(rect.x+tx, rect.y+ty, rect.width, rect.height);
|
|
return;
|
|
}
|
|
|
|
throw new UnsupportedOperationException("shape not implemented");
|
|
}
|
|
|
|
public void fill(Shape shape)
|
|
{
|
|
if (shape instanceof Rectangle)
|
|
{
|
|
Rectangle rect = (Rectangle) shape;
|
|
directGfx.fillRect(rect.x+tx, rect.y+ty, rect.width, rect.height);
|
|
return;
|
|
}
|
|
|
|
throw new UnsupportedOperationException("not implemented");
|
|
}
|
|
|
|
public boolean hit(Rectangle rect, Shape text,
|
|
boolean onStroke)
|
|
{
|
|
throw new UnsupportedOperationException("not implemented");
|
|
}
|
|
|
|
public void drawString(String text, int x, int y)
|
|
{
|
|
directGfx.drawString(text, x+tx, y+ty);
|
|
}
|
|
|
|
public void drawString(String text, float x, float y)
|
|
{
|
|
drawString(text, (int) x, (int) y);
|
|
}
|
|
|
|
public void translate(int x, int y)
|
|
{
|
|
tx += x;
|
|
ty += y;
|
|
}
|
|
|
|
public void translate(double tx, double ty)
|
|
{
|
|
if ((tx == 0) && (ty == 0))
|
|
return;
|
|
|
|
needAffineTransform();
|
|
}
|
|
|
|
public void rotate(double theta)
|
|
{
|
|
if (theta == 0)
|
|
return;
|
|
|
|
needAffineTransform();
|
|
}
|
|
|
|
public void rotate(double theta, double x, double y)
|
|
{
|
|
if (theta == 0)
|
|
return;
|
|
|
|
needAffineTransform();
|
|
}
|
|
|
|
public void scale(double scaleX, double scaleY)
|
|
{
|
|
if ((scaleX == 1) && (scaleY == 1))
|
|
return;
|
|
|
|
needAffineTransform();
|
|
}
|
|
|
|
public void shear(double shearX, double shearY)
|
|
{
|
|
if ((shearX == 0) && (shearY == 0))
|
|
return;
|
|
|
|
needAffineTransform();
|
|
}
|
|
|
|
private void needAffineTransform()
|
|
{
|
|
throw new UnsupportedOperationException("state with affine " +
|
|
"transform not implemented");
|
|
}
|
|
}
|