| /* Copyright (C) 2000 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.GraphicsConfiguration; |
| import java.awt.Rectangle; |
| import java.awt.Graphics2D; |
| import java.awt.Graphics; |
| import java.awt.Point; |
| import java.awt.Color; |
| import java.awt.color.ColorSpace; |
| import java.awt.image.*; |
| import java.awt.geom.AffineTransform; |
| import gnu.gcj.xlib.GC; |
| import gnu.gcj.xlib.Drawable; |
| import gnu.gcj.xlib.Window; |
| import gnu.gcj.xlib.XImage; |
| import gnu.gcj.xlib.Visual; |
| import gnu.gcj.xlib.Colormap; |
| import gnu.gcj.xlib.XColor; |
| import gnu.gcj.xlib.Screen; |
| import gnu.gcj.xlib.Display; |
| import gnu.gcj.awt.Buffers; |
| import java.util.Hashtable; |
| |
| public class XGraphicsConfiguration extends GraphicsConfiguration |
| { |
| //public abstract GraphicsDevice getDevice(); |
| |
| Visual visual; |
| int format; |
| Colormap colormap; |
| ColorModel imageCM; |
| ColorModel pixelCM; |
| |
| public XGraphicsConfiguration(Visual visual) |
| { |
| this.visual = visual; |
| } |
| |
| public BufferedImage createCompatibleImage(int width, int height) |
| { |
| XImage ximg = new XImage(visual, width, height, |
| false // do not auto allocate memory |
| ); |
| |
| Point origin = new Point(0, 0); |
| WritableRaster raster = createRasterForXImage(ximg, origin); |
| |
| /* This is not a good way of doing this. Multiple toolkits may |
| want to share the BufferedImage. */ |
| Hashtable props = new Hashtable(); |
| props.put("gnu.gcj.xlib.XImage", ximg); |
| props.put("java.awt.GraphicsConfiguration", this); |
| |
| BufferedImage bimg = new BufferedImage(imageCM,raster, false, props); |
| |
| DataBuffer dataB = raster.getDataBuffer(); |
| attachData(ximg, dataB, 0); |
| return bimg; |
| } |
| |
| WritableRaster createRasterForXImage(XImage ximage, Point origin) |
| { |
| if (imageCM == null) prepareColorModel(ximage); |
| |
| /* |
| This will not work, since it creates a sample model that |
| does not necessarily match the format of the XImage. |
| |
| WritableRaster raster = |
| imageCM.createCompatibleWritableRaster(width, height); */ |
| |
| // Create a sample model matching the XImage: |
| |
| SampleModel imageSM = null; |
| |
| int width = ximage.getWidth(); |
| int height = ximage.getHeight(); |
| int bitsPerPixel = ximage.getBitsPerPixel(); |
| int dataType = |
| Buffers.smallestAppropriateTransferType(bitsPerPixel); |
| int bitsPerDataElement = DataBuffer.getDataTypeSize(dataType); |
| int scanlineStride = ximage.getBytesPerLine()*8/bitsPerDataElement; |
| |
| if (imageCM instanceof IndexColorModel) |
| { |
| int[] bandOffsets = {0}; |
| imageSM = new ComponentSampleModel(dataType, |
| width, height, |
| 1, // pixel stride |
| scanlineStride, |
| bandOffsets); |
| } |
| else if (imageCM instanceof PackedColorModel) |
| { |
| PackedColorModel pcm = (PackedColorModel) imageCM; |
| int[] masks = pcm.getMasks(); |
| |
| imageSM = new SinglePixelPackedSampleModel(dataType, |
| width, height, |
| scanlineStride, |
| masks); |
| } |
| |
| if (imageSM == null) |
| { |
| throw new UnsupportedOperationException("creating sample model " + |
| "for " + imageCM + |
| " not implemented"); |
| } |
| |
| WritableRaster raster = Raster.createWritableRaster(imageSM, origin); |
| return raster; |
| } |
| |
| |
| |
| /** |
| * Attach a the memory of a data buffer to an XImage |
| * structure. [This method is not gnu.awt.xlib specific, and should |
| * maybe be moved to a different location.] |
| * |
| * @param offset Offset to data. The given offset does not include |
| * data buffer offset, which will also be added. */ |
| static void attachData(XImage ximage, DataBuffer dataB, int offset) |
| { |
| offset += dataB.getOffset(); |
| switch (dataB.getDataType()) |
| { |
| case DataBuffer.TYPE_BYTE: |
| ximage.setData(((DataBufferByte) dataB).getData(), offset); |
| break; |
| case DataBuffer.TYPE_USHORT: |
| ximage.setData(((DataBufferUShort) dataB).getData(), offset); |
| break; |
| case DataBuffer.TYPE_INT: |
| ximage.setData(((DataBufferInt) dataB).getData(), offset); |
| break; |
| default: |
| throw |
| new UnsupportedOperationException("Do not know how to " + |
| "set data for data " + |
| "type " + |
| dataB.getDataType()); |
| } |
| } |
| |
| void prepareColorModel(XImage ximage) |
| { |
| format = ximage.getFormat(); |
| int bitsPerPixel = ximage.getBitsPerPixel(); |
| switch (format) { |
| case XImage.ZPIXMAP_FORMAT: |
| calcZPixmapModels(bitsPerPixel); |
| break; |
| |
| default: |
| throw new UnsupportedOperationException("unimplemented format"); |
| } |
| } |
| |
| void calcZPixmapModels(int bitsPerPixel) |
| { |
| switch (visual.getVisualClass()) |
| { |
| case Visual.VC_TRUE_COLOR: |
| calcDecomposedRGBModels(bitsPerPixel); |
| break; |
| case Visual.VC_PSEUDO_COLOR: |
| calcPseudoColorModels(bitsPerPixel); |
| break; |
| default: |
| String msg = "unimplemented visual class"; |
| throw new UnsupportedOperationException(msg); |
| } |
| } |
| |
| void calcDecomposedRGBModels(int bitsPerPixel) |
| { |
| int dataType = Buffers.smallestAppropriateTransferType(bitsPerPixel); |
| |
| |
| if (DataBuffer.getDataTypeSize(dataType) == bitsPerPixel) |
| { |
| ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB); |
| |
| imageCM = new DirectColorModel(cs, |
| visual.getDepth(), |
| visual.getRedMask(), |
| visual.getGreenMask(), |
| visual.getBlueMask(), |
| 0, // no alpha |
| false, |
| dataType); |
| } |
| else |
| { |
| throw new |
| UnsupportedOperationException("unimplemented bits per pixel"); |
| } |
| } |
| |
| void calcPseudoColorModels(int bitsPerPixel) |
| { |
| if (colormap == null) |
| colormap = visual.getScreen().getDefaultColormap(); |
| |
| XColor[] colArray = colormap.getXColors(); |
| |
| int numCol = colArray.length; |
| byte[] rmap = new byte[numCol]; |
| byte[] gmap = new byte[numCol]; |
| byte[] bmap = new byte[numCol]; |
| byte[] amap = new byte[numCol]; |
| |
| for (int i=0; i < numCol; i++) |
| { |
| XColor color = colArray[i]; |
| if (color.getFlags() == Colormap.FLAG_SHARED) |
| { |
| rmap[i] = (byte) (color.getRed() >> 8); |
| gmap[i] = (byte) (color.getGreen() >> 8); |
| bmap[i] = (byte) (color.getBlue() >> 8); |
| amap[i] = (byte) 0xff; |
| } // else, leave default zero values... |
| } |
| |
| imageCM = new IndexColorModel(visual.getDepth(), numCol, |
| rmap, gmap, bmap, amap); |
| } |
| |
| public BufferedImage createCompatibleImage(int width, |
| int height, |
| int transparency) |
| { |
| throw new UnsupportedOperationException("not implemented"); |
| } |
| |
| /** |
| * FIXME: I'm not sure which color model that should be returned here. |
| */ |
| public ColorModel getColorModel() |
| { |
| if (pixelCM == null) |
| preparePixelCM(); |
| return pixelCM; |
| } |
| |
| void preparePixelCM() |
| { |
| switch (visual.getVisualClass()) |
| { |
| case Visual.VC_TRUE_COLOR: |
| pixelCM = new DirectColorModel(visual.getDepth(), |
| visual.getRedMask(), |
| visual.getGreenMask(), |
| visual.getBlueMask()); |
| break; |
| case Visual.VC_PSEUDO_COLOR: |
| |
| if (colormap == null) |
| colormap = visual.getScreen().getDefaultColormap(); |
| |
| XColor[] colArray = colormap.getXColors(); |
| |
| int numCol = colArray.length; |
| byte[] rmap = new byte[numCol]; |
| byte[] gmap = new byte[numCol]; |
| byte[] bmap = new byte[numCol]; |
| byte[] amap = new byte[numCol]; |
| |
| for (int i=0; i < numCol; i++) |
| { |
| XColor color = colArray[i]; |
| if (color.getFlags() == Colormap.FLAG_SHARED) { |
| rmap[i] = (byte) (color.getRed() >> 8); |
| gmap[i] = (byte) (color.getGreen() >> 8); |
| bmap[i] = (byte) (color.getBlue() >> 8); |
| amap[i] = (byte) 0xff; |
| } // else, leave default zero values... |
| |
| } |
| |
| pixelCM = new IndexColorModel(visual.getDepth(), numCol, |
| rmap, gmap, bmap, amap); |
| break; |
| default: |
| throw new UnsupportedOperationException("not implemented"); |
| } |
| } |
| |
| public ColorModel getColorModel(int transparency) |
| { |
| throw new UnsupportedOperationException("not implemented"); |
| } |
| |
| public AffineTransform getDefaultTransform() |
| { |
| throw new UnsupportedOperationException("not implemented"); |
| } |
| |
| public AffineTransform getNormalizingTransform() |
| { |
| throw new UnsupportedOperationException("not implemented"); |
| } |
| |
| public Rectangle getBounds() |
| { |
| throw new UnsupportedOperationException("not implemented"); |
| } |
| |
| Visual getVisual() |
| { |
| return visual; |
| } |
| |
| /* FIXME: This should be moved to XGraphicsDevice... */ |
| XFontMetrics getXFontMetrics(java.awt.Font awtFont) |
| { |
| // FIXME: do caching... |
| |
| String family = "*"; |
| String name = awtFont.getName(); |
| String weight = awtFont.isBold() ? "bold" : "medium"; |
| String slant = awtFont.isItalic() ? "i" : "r"; |
| String addStyle = "*"; |
| String pixelSize = "*"; |
| String pointSize = awtFont.getSize() + "0"; |
| String xres = "*"; |
| String yres = "*"; |
| String spacing = "*"; |
| String averageWidth = "*"; |
| String charset = "*"; |
| |
| String logicalFontDescription = |
| family + "-" + name + "-" + weight + "-" + |
| slant + "-" + addStyle + "-" + pixelSize + "-" + |
| pointSize + "-" + xres + "-" + yres + "-" + |
| spacing + "-" + averageWidth + "-" + charset; |
| |
| Display display = visual.getScreen().getDisplay(); |
| gnu.gcj.xlib.Font xfont = |
| new gnu.gcj.xlib.Font(display, logicalFontDescription); |
| return new XFontMetrics(xfont, awtFont); |
| } |
| |
| int getPixel(Color color) |
| { |
| int[] components = |
| { |
| color.getRed(), |
| color.getGreen(), |
| color.getBlue(), |
| 0xff |
| }; |
| |
| ColorModel cm = getColorModel(); |
| return cm.getDataElement(components, 0); |
| } |
| } |