Import GNU Classpath (libgcj-import-20070727).
libjava/ 2007-08-04 Matthias Klose <doko@ubuntu.com> Import GNU Classpath (libgcj-import-20070727). * Regenerate class and header files. * Regenerate auto* files. * include/jvm.h: * jni-libjvm.cc (Jv_JNI_InvokeFunctions): Rename type. * jni.cc (_Jv_JNIFunctions, _Jv_JNI_InvokeFunctions): Likewise. * jni.cc (_Jv_JNI_CallAnyMethodA, _Jv_JNI_CallAnyVoidMethodA, _Jv_JNI_CallMethodA, _Jv_JNI_CallVoidMethodA, _Jv_JNI_CallStaticMethodA, _Jv_JNI_CallStaticVoidMethodA, _Jv_JNI_NewObjectA, _Jv_JNI_SetPrimitiveArrayRegion): Constify jvalue parameter. * java/lang/reflect/natMethod.cc (_Jv_CallAnyMethodA): Likewise. * java/lang/VMFloat.java (toString, parseFloat): New. * gnu/awt/xlib/XToolkit.java (setAlwaysOnTop, isModalityTypeSupported, isModalExclusionTypeSupported): New (stub only). * gnu/awt/xlib/XCanvasPeer.java (requestFocus): Likewise. * gnu/awt/xlib/XFramePeer.java (updateMinimumSize, updateIconImages, updateFocusableWindowState, setModalBlocked, getBoundsPrivate, setAlwaysOnTop): Likewise. * gnu/awt/xlib/XFontPeer.java (canDisplay): Update signature. * scripts/makemake.tcl: Ignore gnu/javax/sound/sampled/gstreamer, ignore javax.sound.sampled.spi.MixerProvider, ignore .in files. * HACKING: Mention --enable-gstreamer-peer, removal of generated files. libjava/classpath/ 2007-08-04 Matthias Klose <doko@ubuntu.com> * java/util/EnumMap.java (clone): Add cast. From-SVN: r127204
This commit is contained in:
parent
2c3de459b6
commit
f06a83c0b2
522 changed files with 13385 additions and 4867 deletions
|
@ -115,8 +115,16 @@ public interface FontDelegate
|
|||
* Returns the number of glyphs in this font face.
|
||||
*/
|
||||
public int getNumGlyphs();
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns the glyph code for the specified character.
|
||||
*
|
||||
* @param c the character to map
|
||||
*
|
||||
* @return the glyph code
|
||||
*/
|
||||
public int getGlyphIndex(int c);
|
||||
|
||||
/**
|
||||
* Returns the index of the glyph which gets displayed if the font
|
||||
* cannot map a Unicode code point to a glyph. Many fonts show this
|
||||
|
|
|
@ -617,7 +617,17 @@ public final class OpenTypeFont
|
|||
return new GNUGlyphVector(this, font, frc, glyphs);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the glyph code for the specified character.
|
||||
*
|
||||
* @param c the character to map
|
||||
*
|
||||
* @return the glyph code
|
||||
*/
|
||||
public int getGlyphIndex(int c)
|
||||
{
|
||||
return getCharGlyphMap().getGlyph(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the advance width for a glyph.
|
||||
|
|
|
@ -51,6 +51,7 @@ import java.awt.Graphics2D;
|
|||
import java.awt.Image;
|
||||
import java.awt.Paint;
|
||||
import java.awt.PaintContext;
|
||||
import java.awt.Point;
|
||||
import java.awt.Polygon;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.RenderingHints;
|
||||
|
@ -75,10 +76,10 @@ import java.awt.image.DataBuffer;
|
|||
import java.awt.image.ImageObserver;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.awt.image.SampleModel;
|
||||
import java.awt.image.WritableRaster;
|
||||
import java.awt.image.renderable.RenderableImage;
|
||||
import java.text.AttributedCharacterIterator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -147,7 +148,7 @@ import java.util.Map;
|
|||
*/
|
||||
public abstract class AbstractGraphics2D
|
||||
extends Graphics2D
|
||||
implements Cloneable
|
||||
implements Cloneable, Pixelizer
|
||||
{
|
||||
|
||||
/**
|
||||
|
@ -155,13 +156,6 @@ public abstract class AbstractGraphics2D
|
|||
*/
|
||||
private static final Font FONT = new Font("SansSerif", Font.PLAIN, 12);
|
||||
|
||||
/**
|
||||
* Accuracy of the sampling in the anti-aliasing shape filler.
|
||||
* Lower values give more speed, while higher values give more quality.
|
||||
* It is advisable to choose powers of two.
|
||||
*/
|
||||
private static final int AA_SAMPLING = 8;
|
||||
|
||||
/**
|
||||
* Caches certain shapes to avoid massive creation of such Shapes in
|
||||
* the various draw* and fill* methods.
|
||||
|
@ -226,17 +220,6 @@ public abstract class AbstractGraphics2D
|
|||
*/
|
||||
private WritableRaster destinationRaster;
|
||||
|
||||
/**
|
||||
* Stores the alpha values for a scanline in the anti-aliasing shape
|
||||
* renderer.
|
||||
*/
|
||||
private transient int[] alpha;
|
||||
|
||||
/**
|
||||
* The edge table for the scanline conversion algorithms.
|
||||
*/
|
||||
private transient ArrayList[] edgeTable;
|
||||
|
||||
/**
|
||||
* Indicates if certain graphics primitives can be rendered in an optimized
|
||||
* fashion. This will be the case if the following conditions are met:
|
||||
|
@ -931,8 +914,8 @@ public abstract class AbstractGraphics2D
|
|||
{
|
||||
// Initialize clip if not already present.
|
||||
if (clip == null)
|
||||
clip = s;
|
||||
|
||||
setClip(s);
|
||||
|
||||
// This is so common, let's optimize this.
|
||||
else if (clip instanceof Rectangle && s instanceof Rectangle)
|
||||
{
|
||||
|
@ -1174,7 +1157,9 @@ public abstract class AbstractGraphics2D
|
|||
{
|
||||
if (isOptimized)
|
||||
{
|
||||
rawDrawLine(x1, y1, x2, y2);
|
||||
int tx = (int) transform.getTranslateX();
|
||||
int ty = (int) transform.getTranslateY();
|
||||
rawDrawLine(x1 + tx, y1 + ty, x2 + tx, y2 + ty);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1214,7 +1199,8 @@ public abstract class AbstractGraphics2D
|
|||
{
|
||||
if (isOptimized)
|
||||
{
|
||||
rawFillRect(x, y, width, height);
|
||||
rawFillRect(x + (int) transform.getTranslateX(),
|
||||
y + (int) transform.getTranslateY(), width, height);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1352,8 +1338,16 @@ public abstract class AbstractGraphics2D
|
|||
|
||||
public void drawPolyline(int[] xPoints, int[] yPoints, int npoints)
|
||||
{
|
||||
// FIXME: Implement this.
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
ShapeCache sc = getShapeCache();
|
||||
if (sc.polyline == null)
|
||||
sc.polyline = new GeneralPath();
|
||||
GeneralPath p = sc.polyline;
|
||||
p.reset();
|
||||
if (npoints > 0)
|
||||
p.moveTo(xPoints[0], yPoints[0]);
|
||||
for (int i = 1; i < npoints; i++)
|
||||
p.lineTo(xPoints[i], yPoints[i]);
|
||||
fill(p);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1364,6 +1358,7 @@ public abstract class AbstractGraphics2D
|
|||
ShapeCache sc = getShapeCache();
|
||||
if (sc.polygon == null)
|
||||
sc.polygon = new Polygon();
|
||||
sc.polygon.reset();
|
||||
sc.polygon.xpoints = xPoints;
|
||||
sc.polygon.ypoints = yPoints;
|
||||
sc.polygon.npoints = npoints;
|
||||
|
@ -1378,6 +1373,7 @@ public abstract class AbstractGraphics2D
|
|||
ShapeCache sc = getShapeCache();
|
||||
if (sc.polygon == null)
|
||||
sc.polygon = new Polygon();
|
||||
sc.polygon.reset();
|
||||
sc.polygon.xpoints = xPoints;
|
||||
sc.polygon.ypoints = yPoints;
|
||||
sc.polygon.npoints = npoints;
|
||||
|
@ -1397,7 +1393,10 @@ public abstract class AbstractGraphics2D
|
|||
{
|
||||
boolean ret;
|
||||
if (isOptimized)
|
||||
ret = rawDrawImage(image, x, y, observer);
|
||||
{
|
||||
ret = rawDrawImage(image, x + (int) transform.getTranslateX(),
|
||||
y + (int) transform.getTranslateY(), observer);
|
||||
}
|
||||
else
|
||||
{
|
||||
AffineTransform t = new AffineTransform();
|
||||
|
@ -1559,17 +1558,15 @@ public abstract class AbstractGraphics2D
|
|||
if (isFont)
|
||||
{
|
||||
Object v = renderingHints.get(RenderingHints.KEY_TEXT_ANTIALIASING);
|
||||
// We default to antialiasing on for text as long as we have no
|
||||
// good hinting implemented.
|
||||
antialias = (v == RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
|
||||
//|| v == RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT);
|
||||
// We default to antialiasing for text rendering.
|
||||
antialias = (v == RenderingHints.VALUE_TEXT_ANTIALIAS_ON
|
||||
|| v == RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT);
|
||||
}
|
||||
else
|
||||
{
|
||||
Object v = renderingHints.get(RenderingHints.KEY_ANTIALIASING);
|
||||
antialias = (v == RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
}
|
||||
|
||||
ScanlineConverter sc = getScanlineConverter();
|
||||
int resolution = 0;
|
||||
if (antialias)
|
||||
|
@ -1577,7 +1574,7 @@ public abstract class AbstractGraphics2D
|
|||
// Adjust resolution according to rendering hints.
|
||||
resolution = 2;
|
||||
}
|
||||
sc.renderShape(this, s, clip, transform, resolution);
|
||||
sc.renderShape(this, s, clip, transform, resolution, renderingHints);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1609,12 +1606,20 @@ public abstract class AbstractGraphics2D
|
|||
*/
|
||||
protected void rawDrawLine(int x0, int y0, int x1, int y1)
|
||||
{
|
||||
draw(new Line2D.Float(x0, y0, x1, y1));
|
||||
ShapeCache sc = getShapeCache();
|
||||
if (sc.line == null)
|
||||
sc.line = new Line2D.Float();
|
||||
sc.line.setLine(x0, y0, x1, y1);
|
||||
draw(sc.line);
|
||||
}
|
||||
|
||||
protected void rawDrawRect(int x, int y, int w, int h)
|
||||
{
|
||||
draw(new Rectangle(x, y, w, h));
|
||||
ShapeCache sc = getShapeCache();
|
||||
if (sc.rect == null)
|
||||
sc.rect = new Rectangle();
|
||||
sc.rect.setBounds(x, y, w, h);
|
||||
draw(sc.rect);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1662,7 +1667,11 @@ public abstract class AbstractGraphics2D
|
|||
*/
|
||||
protected void rawFillRect(int x, int y, int w, int h)
|
||||
{
|
||||
fill(new Rectangle(x, y, w, h));
|
||||
ShapeCache sc = getShapeCache();
|
||||
if (sc.rect == null)
|
||||
sc.rect = new Rectangle();
|
||||
sc.rect.setBounds(x, y, w, h);
|
||||
fill(sc.rect);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1718,10 +1727,38 @@ public abstract class AbstractGraphics2D
|
|||
* @param x1 the right offset
|
||||
* @param y the scanline
|
||||
*/
|
||||
protected void fillScanline(int x0, int x1, int y)
|
||||
public void renderScanline(int y, ScanlineCoverage c)
|
||||
{
|
||||
PaintContext pCtx = paintContext;
|
||||
int x0 = c.getMinX();
|
||||
int x1 = c.getMaxX();
|
||||
Raster paintRaster = pCtx.getRaster(x0, y, x1 - x0, 1);
|
||||
|
||||
// Do the anti aliasing thing.
|
||||
float coverageAlpha = 0;
|
||||
float maxCoverage = c.getMaxCoverage();
|
||||
ColorModel cm = pCtx.getColorModel();
|
||||
DataBuffer db = paintRaster.getDataBuffer();
|
||||
Point loc = new Point(paintRaster.getMinX(), paintRaster.getMinY());
|
||||
SampleModel sm = paintRaster.getSampleModel();
|
||||
WritableRaster writeRaster = Raster.createWritableRaster(sm, db, loc);
|
||||
WritableRaster alphaRaster = cm.getAlphaRaster(writeRaster);
|
||||
int pixel;
|
||||
ScanlineCoverage.Iterator iter = c.iterate();
|
||||
while (iter.hasNext())
|
||||
{
|
||||
ScanlineCoverage.Range range = iter.next();
|
||||
coverageAlpha = range.getCoverage() / maxCoverage;
|
||||
if (coverageAlpha < 1.0)
|
||||
{
|
||||
for (int x = range.getXPos(); x < range.getXPosEnd(); x++)
|
||||
{
|
||||
pixel = alphaRaster.getSample(x, y, 0);
|
||||
pixel = (int) (pixel * coverageAlpha);
|
||||
alphaRaster.setSample(x, y, 0, pixel);
|
||||
}
|
||||
}
|
||||
}
|
||||
ColorModel paintColorModel = pCtx.getColorModel();
|
||||
CompositeContext cCtx = composite.createContext(paintColorModel,
|
||||
getColorModel(),
|
||||
|
@ -1733,66 +1770,6 @@ public abstract class AbstractGraphics2D
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fills a horizontal line between x0 and x1 for anti aliased rendering.
|
||||
* the alpha array contains the deltas of the alpha values from one pixel
|
||||
* to the next.
|
||||
*
|
||||
* @param alpha the alpha values in the scanline
|
||||
* @param x0 the beginning of the scanline
|
||||
* @param yy the y coordinate of the line
|
||||
*/
|
||||
private void fillScanlineAA(int[] alpha, int x0, int yy, int numPixels,
|
||||
PaintContext pCtx, int offs)
|
||||
{
|
||||
CompositeContext cCtx = composite.createContext(pCtx.getColorModel(),
|
||||
getColorModel(),
|
||||
renderingHints);
|
||||
Raster paintRaster = pCtx.getRaster(x0, yy, numPixels, 1);
|
||||
//System.err.println("paintColorModel: " + pCtx.getColorModel());
|
||||
WritableRaster aaRaster = paintRaster.createCompatibleWritableRaster();
|
||||
ColorModel cm = pCtx.getColorModel();
|
||||
double lastAlpha = 0.;
|
||||
int lastAlphaInt = 0;
|
||||
|
||||
Object pixel = null;
|
||||
int[] comps = null;
|
||||
int x1 = x0 + numPixels;
|
||||
for (int x = x0; x < x1; x++)
|
||||
{
|
||||
int i = x - offs;
|
||||
if (alpha[i] != 0)
|
||||
{
|
||||
lastAlphaInt += alpha[i];
|
||||
lastAlpha = (double) lastAlphaInt / (double) AA_SAMPLING;
|
||||
alpha[i] = 0;
|
||||
}
|
||||
pixel = paintRaster.getDataElements(x - x0, 0, pixel);
|
||||
comps = cm.getComponents(pixel, comps, 0);
|
||||
if (cm.hasAlpha() && ! cm.isAlphaPremultiplied())
|
||||
comps[comps.length - 1] *= lastAlpha;
|
||||
else
|
||||
{
|
||||
int max;
|
||||
if (cm.hasAlpha())
|
||||
max = comps.length - 2;
|
||||
else
|
||||
max = comps.length - 1;
|
||||
for (int j = 0; j < max; j++)
|
||||
comps[j] *= lastAlpha;
|
||||
}
|
||||
pixel = cm.getDataElements(comps, 0, pixel);
|
||||
aaRaster.setDataElements(x - x0, 0, pixel);
|
||||
}
|
||||
|
||||
WritableRaster targetChild =
|
||||
destinationRaster.createWritableTranslatedChild(-x0, -yy);
|
||||
cCtx.compose(aaRaster, targetChild, targetChild);
|
||||
updateRaster(destinationRaster, x0, yy, numPixels, 1);
|
||||
|
||||
cCtx.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes this graphics object. This must be called by subclasses in
|
||||
* order to correctly initialize the state of this object.
|
||||
|
@ -1971,4 +1948,5 @@ public abstract class AbstractGraphics2D
|
|||
}
|
||||
return sc;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* XLightweightPeer.java -- A lightweight peer for X
|
||||
Copyright (C) 2006 Free Software Foundation, Inc.
|
||||
/* Pixelizer.java -- Interface for the target of the rasterizer
|
||||
Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
|
@ -35,22 +35,22 @@ this exception to your version of the library, but you are not
|
|||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
package gnu.java.awt.java2d;
|
||||
|
||||
package gnu.java.awt.peer.x;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.peer.LightweightPeer;
|
||||
|
||||
import gnu.java.awt.peer.swing.SwingContainerPeer;
|
||||
|
||||
public class XLightweightPeer
|
||||
extends SwingContainerPeer
|
||||
implements LightweightPeer
|
||||
/**
|
||||
* A pixelizer is responsible for actually manipulating the pixel of a drawing
|
||||
* surface after the scanline conversion process. It receives coverage
|
||||
* information for a scanline and adjusts the surface pixels accordingly.
|
||||
*/
|
||||
public interface Pixelizer
|
||||
{
|
||||
|
||||
XLightweightPeer(Component c)
|
||||
{
|
||||
super(c);
|
||||
init(c, null);
|
||||
}
|
||||
/**
|
||||
* Renders the pixel for one scanline at the Y location <code>y</code>
|
||||
* and using the coverage information in <code>sc</code>.
|
||||
*
|
||||
* @param y the scanline Y coordinate
|
||||
* @param sc the coverage information
|
||||
*/
|
||||
void renderScanline(int y, ScanlineCoverage sc);
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/* ScanlineConverter.java -- Rasterizes Shapes
|
||||
Copyright (C) 2006 Free Software Foundation, Inc.
|
||||
Copyright (C) 2006, 2007 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
|
@ -40,6 +40,7 @@ package gnu.java.awt.java2d;
|
|||
|
||||
import gnu.java.math.Fixed;
|
||||
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.PathIterator;
|
||||
|
@ -47,7 +48,7 @@ import java.awt.geom.PathIterator;
|
|||
/**
|
||||
* Rasterizes {@link Shape} objects on an AbstractGraphics2D.
|
||||
*/
|
||||
final class ScanlineConverter
|
||||
public final class ScanlineConverter
|
||||
{
|
||||
|
||||
/**
|
||||
|
@ -56,10 +57,15 @@ final class ScanlineConverter
|
|||
private static int FIXED_DIGITS = 6;
|
||||
|
||||
/**
|
||||
* The fixed value for the number 1.
|
||||
* The fixed point constant for the number one.
|
||||
*/
|
||||
private static int ONE = Fixed.fixedValue(FIXED_DIGITS, 1);
|
||||
|
||||
/**
|
||||
* The number of significant bits for the Y resolution.
|
||||
*/
|
||||
private static int Y_RESOLUTION = 4;
|
||||
|
||||
/**
|
||||
* The actual number of scanlines.
|
||||
*/
|
||||
|
@ -109,6 +115,13 @@ final class ScanlineConverter
|
|||
|
||||
private int minY;
|
||||
private int maxY;
|
||||
private int minX;
|
||||
private int maxX;
|
||||
|
||||
/**
|
||||
* Holds and manages information about the pixel coverage.
|
||||
*/
|
||||
private ScanlineCoverage scanlineCoverage;
|
||||
|
||||
/**
|
||||
* Create a new ScanlineConverter.
|
||||
|
@ -120,18 +133,23 @@ final class ScanlineConverter
|
|||
activeEdges = new ActiveEdges();
|
||||
edgePool = new PolyEdge();
|
||||
edgePoolLast = edgePool;
|
||||
scanlineCoverage = new ScanlineCoverage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the specified shape using the specified clip and transform.
|
||||
*
|
||||
* @param p the pixelizer that receives the coverage information
|
||||
* @param shape the shape to render
|
||||
* @param clip the clip
|
||||
* @param trans the transform
|
||||
*/
|
||||
void renderShape(AbstractGraphics2D g, Shape shape, Shape clip,
|
||||
AffineTransform trans, int res)
|
||||
public void renderShape(Pixelizer p, Shape shape, Shape clip,
|
||||
AffineTransform trans, int res, RenderingHints hints)
|
||||
{
|
||||
// TODO: Do something useful with the rendering hints. Like, adjusting
|
||||
// the resolution.
|
||||
|
||||
// Prepare resolution and upper bounds.
|
||||
clear();
|
||||
setResolution(res);
|
||||
|
@ -139,11 +157,12 @@ final class ScanlineConverter
|
|||
boolean haveClip = clip != null;
|
||||
|
||||
// Add shapes.
|
||||
PathIterator path = shape.getPathIterator(trans, resolution);
|
||||
float flatness = Fixed.floatValue(FIXED_DIGITS, resolution / 2);
|
||||
PathIterator path = shape.getPathIterator(trans, flatness);
|
||||
addShape(path, false);
|
||||
if (haveClip)
|
||||
{
|
||||
path= clip.getPathIterator(trans, resolution);
|
||||
path= clip.getPathIterator(trans, flatness);
|
||||
addShape(path, true);
|
||||
}
|
||||
|
||||
|
@ -157,11 +176,11 @@ final class ScanlineConverter
|
|||
}
|
||||
|
||||
int y = upperBounds;
|
||||
int lastIndex = scanlineIndex(y - resolution);
|
||||
int index;
|
||||
activeEdges.clear();
|
||||
// The render loop...
|
||||
Scanline scanline = null;
|
||||
int lastRealY = Fixed.intValue(FIXED_DIGITS, y);
|
||||
while (y <= maxY)
|
||||
{
|
||||
// First we put together our list of active edges.
|
||||
|
@ -184,15 +203,16 @@ final class ScanlineConverter
|
|||
activeEdges.intersectSortAndPack(FIXED_DIGITS, y + halfStep);
|
||||
|
||||
// Ok, now we can perform the actual scanlining.
|
||||
boolean push = lastIndex != index;
|
||||
doScanline(g, y, push, haveClip);
|
||||
int realY = Fixed.intValue(FIXED_DIGITS, y + resolution);
|
||||
boolean push = lastRealY != realY;
|
||||
doScanline(p, y, push, haveClip);
|
||||
|
||||
// Remove obsolete active edges.
|
||||
//activeEdges.remove(y + halfStep);
|
||||
|
||||
// Go on with the next line...
|
||||
y += resolution;
|
||||
lastIndex = index;
|
||||
lastRealY = realY;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -212,17 +232,31 @@ final class ScanlineConverter
|
|||
sl.clear();
|
||||
}
|
||||
|
||||
// Reset scanline coverage.
|
||||
scanlineCoverage.clear();
|
||||
|
||||
// Reset bounds.
|
||||
minY = Integer.MAX_VALUE;
|
||||
maxY = Integer.MIN_VALUE;
|
||||
minX = Integer.MAX_VALUE;
|
||||
maxX = Integer.MIN_VALUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the scanlining on the current set of active edges.
|
||||
*
|
||||
* @param p the pixelizer to receive the pixel coverage data
|
||||
* @param y the Y coordinate
|
||||
* @param push true when the scanline is ready to be pushed to the
|
||||
* pixelizer
|
||||
* @param haveClip true when there's a clip, false otherwise
|
||||
*/
|
||||
private void doScanline(AbstractGraphics2D g, int y, boolean push,
|
||||
private void doScanline(Pixelizer p, int y, boolean push,
|
||||
boolean haveClip)
|
||||
{
|
||||
// First, rewind the scanline coverage.
|
||||
scanlineCoverage.rewind();
|
||||
|
||||
// We begin outside the clip and outside the shape. We only draw when
|
||||
// we are inside the clip AND inside the shape.
|
||||
boolean inClip = ! haveClip;
|
||||
|
@ -238,22 +272,16 @@ final class ScanlineConverter
|
|||
int x0 = lastEdge.xIntersection;
|
||||
int x1 = edge.xIntersection;
|
||||
assert x0 <= x1;
|
||||
if (push)
|
||||
{
|
||||
if (resolution == ONE)
|
||||
{
|
||||
// Non-AA rendering.
|
||||
g.fillScanline(Fixed.intValue(FIXED_DIGITS, x0),
|
||||
Fixed.intValue(FIXED_DIGITS, x1 - resolution),
|
||||
Fixed.intValue(FIXED_DIGITS, y));
|
||||
}
|
||||
else
|
||||
{
|
||||
// AA rendering.
|
||||
// FIXME: Implement.
|
||||
System.err.println("Implement AA rendering.");
|
||||
}
|
||||
}
|
||||
|
||||
int pix0 = Fixed.intValue(FIXED_DIGITS, x0);
|
||||
int pix1 = Fixed.intValue(FIXED_DIGITS, x1);
|
||||
int frac0 = ONE - Fixed.trunc(FIXED_DIGITS, x0);
|
||||
int frac1 = ONE - Fixed.trunc(FIXED_DIGITS, x1);
|
||||
// Only keep the first 4 digits after the point.
|
||||
frac0 = frac0 >> (FIXED_DIGITS - Y_RESOLUTION);
|
||||
frac1 = frac1 >> (FIXED_DIGITS - Y_RESOLUTION);
|
||||
scanlineCoverage.add(pix0, 1 * (1 << Y_RESOLUTION), frac0);
|
||||
scanlineCoverage.add(pix1, -1 * (1 << Y_RESOLUTION), -frac1);
|
||||
}
|
||||
if (edge.isClip)
|
||||
inClip = ! inClip;
|
||||
|
@ -262,7 +290,15 @@ final class ScanlineConverter
|
|||
|
||||
lastEdge = edge;
|
||||
}
|
||||
}
|
||||
|
||||
// Push out the whole scanline to the pixelizer.
|
||||
if (push && ! scanlineCoverage.isEmpty())
|
||||
{
|
||||
p.renderScanline(Fixed.intValue(FIXED_DIGITS, y), scanlineCoverage);
|
||||
scanlineCoverage.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the resolution. A value of 0 rasterizes the shape normally without
|
||||
|
@ -272,9 +308,12 @@ final class ScanlineConverter
|
|||
*/
|
||||
private void setResolution(int res)
|
||||
{
|
||||
int scanlinesPerPixel = 1 << res;
|
||||
int one = Fixed.fixedValue(FIXED_DIGITS, 1);
|
||||
resolution = one / (1 << res);
|
||||
resolution = one / (scanlinesPerPixel);
|
||||
halfStep = resolution / 2;
|
||||
|
||||
scanlineCoverage.setMaxCoverage(scanlinesPerPixel << Y_RESOLUTION);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -309,6 +348,8 @@ final class ScanlineConverter
|
|||
startY = lastY = Fixed.fixedValue(FIXED_DIGITS, coords[1]);
|
||||
minY = Math.min(startY, minY);
|
||||
maxY = Math.max(startY, maxY);
|
||||
minX = Math.min(startX, minX);
|
||||
maxX = Math.max(startX, maxX);
|
||||
break;
|
||||
case PathIterator.SEG_LINETO:
|
||||
int x = Fixed.fixedValue(FIXED_DIGITS, coords[0]);
|
||||
|
@ -318,6 +359,8 @@ final class ScanlineConverter
|
|||
lastY = y;
|
||||
minY = Math.min(lastY, minY);
|
||||
maxY = Math.max(lastY, maxY);
|
||||
minX = Math.min(lastX, minX);
|
||||
maxX = Math.max(lastX, maxX);
|
||||
break;
|
||||
case PathIterator.SEG_CLOSE:
|
||||
edgePoolAdd(lastX, lastY, startX, startY, clip);
|
||||
|
@ -371,7 +414,7 @@ final class ScanlineConverter
|
|||
{
|
||||
int val1 = Fixed.div(FIXED_DIGITS, y, resolution);
|
||||
int rounded = Fixed.round(FIXED_DIGITS, val1);
|
||||
return Fixed.div(FIXED_DIGITS, rounded, resolution);
|
||||
return Fixed.mul(FIXED_DIGITS, rounded, resolution);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
630
libjava/classpath/gnu/java/awt/java2d/ScanlineCoverage.java
Normal file
630
libjava/classpath/gnu/java/awt/java2d/ScanlineCoverage.java
Normal file
|
@ -0,0 +1,630 @@
|
|||
/* ScanlineCoverage.java -- Manages coverage information for a scanline
|
||||
Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
package gnu.java.awt.java2d;
|
||||
|
||||
/**
|
||||
* Stores and handles the pixel converage for a scanline. The pixel coverage
|
||||
* is stored as sorted list of {@linke Covergage} entries, each of which holds
|
||||
* information about the coverage for the X and Y axis. This is utilized to
|
||||
* compute the actual coverage for each pixel on the scanline and finding
|
||||
* chunks of pixels with equal coverage quickly.
|
||||
*/
|
||||
public final class ScanlineCoverage
|
||||
{
|
||||
|
||||
/**
|
||||
* Iterates over the coverage list and calculates the actual coverage
|
||||
* ranges on a scanline.
|
||||
*/
|
||||
public final class Iterator
|
||||
{
|
||||
/**
|
||||
* This instance is reused in the iteration.
|
||||
*/
|
||||
private Range range;
|
||||
|
||||
/**
|
||||
* The pointer to the current item in the iteration.
|
||||
*/
|
||||
private Coverage currentItem;
|
||||
|
||||
/**
|
||||
* The current coverage value.
|
||||
*/
|
||||
private int currentCoverage;
|
||||
|
||||
/**
|
||||
* True when the current pixel coverage has already been handled, false
|
||||
* otherwise.
|
||||
*/
|
||||
private boolean handledPixelCoverage;
|
||||
|
||||
/**
|
||||
* Creates a new CoverageIterator.
|
||||
*/
|
||||
Iterator()
|
||||
{
|
||||
range = new Range();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next coverage range on the scanline. The returned object
|
||||
* will always be the same object, but with different values. Keep that
|
||||
* in mind when dealing with this object.
|
||||
*
|
||||
* @return the next coverage range on the scanline
|
||||
*/
|
||||
public Range next()
|
||||
{
|
||||
// TODO: Lump together the single-pixel coverage and the
|
||||
// between-pixel coverage when the pixel coverage delta is 0.
|
||||
if (handledPixelCoverage == false)
|
||||
{
|
||||
// Handle single pixel coverage.
|
||||
range.setXPos(currentItem.xPos);
|
||||
range.setLength(1);
|
||||
range.setCoverage(currentCoverage + currentItem.pixelCoverage);
|
||||
handledPixelCoverage = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Handle pixel span coverage.
|
||||
currentCoverage += currentItem.covDelta;
|
||||
range.setCoverage(currentCoverage);
|
||||
range.setXPos(currentItem.xPos + 1);
|
||||
currentItem = currentItem.next;
|
||||
range.setLength(currentItem.xPos - range.xPos);
|
||||
handledPixelCoverage = false;
|
||||
}
|
||||
return range;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@ true} when there are more coverage ranges to iterate,
|
||||
* {@ false} otherwise.
|
||||
*
|
||||
* @return {@ true} when there are more coverage ranges to iterate,
|
||||
* {@ false} otherwise
|
||||
*/
|
||||
public boolean hasNext()
|
||||
{
|
||||
boolean hasNext;
|
||||
if (currentItem != null && handledPixelCoverage == false)
|
||||
{
|
||||
// We have at least one more coverage item when there's a pixel
|
||||
// coverage piece left.
|
||||
hasNext = true;
|
||||
}
|
||||
else if (currentItem == null || currentItem.next == null
|
||||
|| currentItem.next == last)
|
||||
{
|
||||
hasNext = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
hasNext = true;
|
||||
}
|
||||
return hasNext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets this iterator to the start of the list.
|
||||
*/
|
||||
void reset()
|
||||
{
|
||||
currentItem = head;
|
||||
currentCoverage = 0;
|
||||
handledPixelCoverage = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A data object that carries information about pixel coverage on a scanline.
|
||||
* The data consists of a starting X position on the scanline, the
|
||||
* length of the range in pixels and the actual coverage value.
|
||||
´ */
|
||||
public static final class Range
|
||||
{
|
||||
/**
|
||||
* The X position on the scanline, in pixels.
|
||||
*/
|
||||
private int xPos;
|
||||
|
||||
/**
|
||||
* The length of the range, in pixels.
|
||||
*/
|
||||
private int length;
|
||||
|
||||
/**
|
||||
* The actual coverage. The relation depends on
|
||||
* {@link ScanlineCoverage#maxCoverage}.
|
||||
*/
|
||||
private int coverage;
|
||||
|
||||
/**
|
||||
* Creates a new CoverageRange object.
|
||||
*/
|
||||
Range()
|
||||
{
|
||||
// Nothing to do. The values get initialized in the corresponding
|
||||
// setters.
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the X start position (left) on the scanline. This value is
|
||||
* considered to be in pixels and device space.
|
||||
*
|
||||
* @param x the x position
|
||||
*/
|
||||
void setXPos(int x)
|
||||
{
|
||||
xPos = x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the X start position (left) on the scanline. This value
|
||||
* is considered to be in pixels and device space.
|
||||
*
|
||||
* @return the X position on the scanline
|
||||
*/
|
||||
public int getXPos()
|
||||
{
|
||||
return xPos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the length of the pixel range. This is in pixel units.
|
||||
*
|
||||
* @param l the length of the range
|
||||
*/
|
||||
void setLength(int l)
|
||||
{
|
||||
length = l;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of the range in pixel units.
|
||||
*
|
||||
* @return the length of the range in pixel units
|
||||
*/
|
||||
public int getLength()
|
||||
{
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first X position after the range.
|
||||
*
|
||||
* @return the first X position after the range
|
||||
*/
|
||||
public int getXPosEnd()
|
||||
{
|
||||
return xPos + length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the coverage of the pixel range. The relation of that value
|
||||
* depends on {@link ScanlineCoverage#maxCoverage}.
|
||||
*
|
||||
* @param cov the coverage value for the pixel range
|
||||
*/
|
||||
void setCoverage(int cov)
|
||||
{
|
||||
coverage = cov;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the coverage of the pixel range. The relation of this value
|
||||
* depends on {@link ScanlineCoverage#getMaxCoverage()}.
|
||||
*
|
||||
* @return the coverage of the pixel range
|
||||
*/
|
||||
public int getCoverage()
|
||||
{
|
||||
return coverage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation.
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return "Coverage range: xPos=" + xPos + ", length=" + length
|
||||
+ ", coverage: " + coverage;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* One bucket in the list.
|
||||
*/
|
||||
private static final class Coverage
|
||||
{
|
||||
/**
|
||||
* The X coordinate on the scanline to which this bucket belongs.
|
||||
*/
|
||||
int xPos;
|
||||
|
||||
/**
|
||||
* The coverage delta from the pixel at xPos to xPos + 1.
|
||||
*/
|
||||
int covDelta;
|
||||
|
||||
/**
|
||||
* The delta for the pixel at xPos. This is added to the pixel at xPos,
|
||||
* but not to the following pixel.
|
||||
*/
|
||||
int pixelCoverage;
|
||||
|
||||
/**
|
||||
* Implements a linked list. This points to the next element of the list.
|
||||
*/
|
||||
Coverage next;
|
||||
|
||||
/**
|
||||
* Returns the X coordinate for this entry.
|
||||
*
|
||||
* @return the X coordinate for this entry
|
||||
*/
|
||||
public int getXPos()
|
||||
{
|
||||
return xPos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the coverage delta for this entry.
|
||||
*
|
||||
* @return the coverage delta for this entry
|
||||
*/
|
||||
public int getCoverageDelta()
|
||||
{
|
||||
return covDelta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation.
|
||||
*
|
||||
* @return a string representation
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return "Coverage: xPos: " + xPos + ", covDelta: " + covDelta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this entry and all the following
|
||||
* in the linked list.
|
||||
*
|
||||
* @return a string representation of this entry and all the following
|
||||
* in the linked list
|
||||
*/
|
||||
public String list()
|
||||
{
|
||||
String str = toString();
|
||||
if (next != null)
|
||||
str = str + " --> " + next.list();
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The head of the sorted list of buckets.
|
||||
*/
|
||||
private Coverage head;
|
||||
|
||||
/**
|
||||
* The current bucket. We make use of the fact that the scanline converter
|
||||
* always scans the scanline (and thus this list) from left to right to
|
||||
* quickly find buckets or insertion points.
|
||||
*/
|
||||
private Coverage current;
|
||||
|
||||
/**
|
||||
* The item that is before current in the list.
|
||||
*/
|
||||
private Coverage currentPrev;
|
||||
|
||||
/**
|
||||
* The bucket after the last valid bucket. Unused buckets are not thrown
|
||||
* away and garbage collected. Instead, we keep them at the tail of the list
|
||||
* and reuse them when necessary.
|
||||
*/
|
||||
private Coverage last;
|
||||
|
||||
/**
|
||||
* The last valid entry.
|
||||
*/
|
||||
private Coverage lastPrev;
|
||||
|
||||
/**
|
||||
* The minimum X coordinate of this scanline.
|
||||
*/
|
||||
private int minX;
|
||||
|
||||
/**
|
||||
* The maximum X coordinate of this scanline.
|
||||
*/
|
||||
private int maxX;
|
||||
|
||||
/**
|
||||
* The maximum coverage value.
|
||||
*/
|
||||
private int maxCoverage;
|
||||
|
||||
/**
|
||||
* The iterator over the ranges of this scanline.
|
||||
*/
|
||||
private Iterator iterator;
|
||||
|
||||
/**
|
||||
* Creates a new ScanlineCoverage instance.
|
||||
*/
|
||||
public ScanlineCoverage()
|
||||
{
|
||||
iterator = new Iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the the next scan of the scanline begins and that the next
|
||||
* request will be at the beginning of this list. This makes searching and
|
||||
* sorting of this list very quick.
|
||||
*/
|
||||
public void rewind()
|
||||
{
|
||||
current = head;
|
||||
currentPrev = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the list. This does not throw away the old buckets but only
|
||||
* resets the end-pointer of the list to the first element. All buckets are
|
||||
* then unused and are reused when the list is filled again.
|
||||
*/
|
||||
public void clear()
|
||||
{
|
||||
last = head;
|
||||
lastPrev = null;
|
||||
current = head;
|
||||
currentPrev = null;
|
||||
minX = Integer.MAX_VALUE;
|
||||
maxX = Integer.MIN_VALUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* This adds the specified coverage to the pixel at the specified
|
||||
* X position.
|
||||
*
|
||||
* @param x the X position
|
||||
* @param xc the x coverage
|
||||
* @param yc the y coverage
|
||||
*/
|
||||
public void add(int x, int xc, int yc)
|
||||
{
|
||||
Coverage bucket = findOrInsert(x);
|
||||
bucket.covDelta += xc;
|
||||
bucket.pixelCoverage += yc;
|
||||
minX = Math.min(minX, x);
|
||||
maxX = Math.max(maxX, x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum coverage value for the scanline.
|
||||
*
|
||||
* @return the maximum coverage value for the scanline
|
||||
*/
|
||||
public int getMaxCoverage()
|
||||
{
|
||||
return maxCoverage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum coverage value for the scanline.
|
||||
*
|
||||
* @param maxCov the maximum coverage value for the scanline
|
||||
*/
|
||||
void setMaxCoverage(int maxCov)
|
||||
{
|
||||
maxCoverage = maxCov;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum X coordinate of the current scanline.
|
||||
*
|
||||
* @return the maximum X coordinate of the current scanline
|
||||
*/
|
||||
public int getMaxX()
|
||||
{
|
||||
return maxX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the minimum X coordinate of the current scanline.
|
||||
*
|
||||
* @return the minimum X coordinate of the current scanline
|
||||
*/
|
||||
public int getMinX()
|
||||
{
|
||||
return minX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the bucket in the list with the specified X coordinate.
|
||||
* If no such bucket is found, then a new one is fetched (either a cached
|
||||
* bucket from the end of the list or a newly allocated one) inserted at the
|
||||
* correct position and returned.
|
||||
*
|
||||
* @param x the X coordinate
|
||||
*
|
||||
* @return a bucket to hold the coverage data
|
||||
*/
|
||||
private Coverage findOrInsert(int x)
|
||||
{
|
||||
// First search for a matching bucket.
|
||||
if (head == null)
|
||||
{
|
||||
// Special case: the list is still empty.
|
||||
// Testpoint 1.
|
||||
head = new Coverage();
|
||||
head.xPos = x;
|
||||
current = head;
|
||||
currentPrev = null;
|
||||
return head;
|
||||
}
|
||||
|
||||
// This performs a linear search, starting from the current bucket.
|
||||
// This is reasonably efficient because access to this list is always done
|
||||
// in a linear fashion and we are usually not more then 1 or 2 buckets away
|
||||
// from the one we're looking for.
|
||||
Coverage match = current;
|
||||
Coverage prev = currentPrev;
|
||||
while (match != last && match.xPos < x)
|
||||
{
|
||||
prev = match;
|
||||
match = match.next;
|
||||
}
|
||||
|
||||
// At this point we have either found an entry with xPos >= x, or reached
|
||||
// the end of the list (match == last || match == null).
|
||||
if (match == null)
|
||||
{
|
||||
// End of the list. No cached items to reuse.
|
||||
// Testpoint 2.
|
||||
match = new Coverage();
|
||||
match.xPos = x;
|
||||
if (prev != null)
|
||||
prev.next = match;
|
||||
current = match;
|
||||
currentPrev = prev;
|
||||
return match;
|
||||
}
|
||||
else if (match == last)
|
||||
{
|
||||
// End of the list. Reuse this item. Expand list.
|
||||
// Testpoint 3.
|
||||
last = match.next;
|
||||
lastPrev = match;
|
||||
match.xPos = x;
|
||||
match.covDelta = 0;
|
||||
match.pixelCoverage = 0;
|
||||
// Keep link to last element or null, indicating the end of the list.
|
||||
current = match;
|
||||
currentPrev = prev;
|
||||
return match;
|
||||
}
|
||||
|
||||
if (x == match.xPos)
|
||||
{
|
||||
// Special case: We have another coverage entry at the same location
|
||||
// as an already existing entry. Return this.
|
||||
// Testpoint 4.
|
||||
current = match;
|
||||
currentPrev = prev;
|
||||
return match;
|
||||
}
|
||||
else // x <= match.xPos
|
||||
{
|
||||
assert (x <= match.xPos);
|
||||
assert (prev == null ||x > prev.xPos);
|
||||
|
||||
// Create new entry, or reuse existing one.
|
||||
Coverage cov;
|
||||
if (last != null)
|
||||
{
|
||||
// Testpoint 5.
|
||||
cov = last;
|
||||
last = cov.next;
|
||||
lastPrev.next = last;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Testpoint 6.
|
||||
cov = new Coverage();
|
||||
}
|
||||
|
||||
cov.xPos = x;
|
||||
cov.covDelta = 0;
|
||||
cov.pixelCoverage = 0;
|
||||
|
||||
// Insert this item in the list.
|
||||
if (prev != null)
|
||||
{
|
||||
// Testpoint 5 & 6.
|
||||
prev.next = cov;
|
||||
cov.next = match;
|
||||
current = cov;
|
||||
currentPrev = prev;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Testpoint 7.
|
||||
assert (match == head);
|
||||
// Insert at head.
|
||||
head = cov;
|
||||
head.next = match;
|
||||
current = head;
|
||||
currentPrev = null;
|
||||
}
|
||||
return cov;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* (Re-)Starts iterating the coverage values for the scanline.
|
||||
* Use the returned iterator to get the consecutive coverage ranges.
|
||||
*
|
||||
* @return the iterator
|
||||
*/
|
||||
public Iterator iterate()
|
||||
{
|
||||
iterator.reset();
|
||||
return iterator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@ true} if this object has no entries for the current scanline,
|
||||
* {@ false} otherwise.
|
||||
*
|
||||
* @return {@ true} if this object has no entries for the current scanline,
|
||||
* {@ false} otherwise
|
||||
*/
|
||||
public boolean isEmpty()
|
||||
{
|
||||
return head == null || head == last
|
||||
|| head.next == null || head.next == last;
|
||||
}
|
||||
|
||||
}
|
|
@ -42,6 +42,7 @@ import java.awt.Polygon;
|
|||
import java.awt.Rectangle;
|
||||
import java.awt.geom.Arc2D;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.GeneralPath;
|
||||
import java.awt.geom.Line2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
|
||||
|
@ -82,4 +83,8 @@ public class ShapeCache
|
|||
*/
|
||||
public Polygon polygon;
|
||||
|
||||
/**
|
||||
* A cached polyline.
|
||||
*/
|
||||
public GeneralPath polyline;
|
||||
}
|
||||
|
|
|
@ -644,7 +644,7 @@ public abstract class ClasspathFontPeer
|
|||
* be ignored.
|
||||
*/
|
||||
|
||||
public abstract boolean canDisplay (Font font, char c);
|
||||
public abstract boolean canDisplay (Font font, int c);
|
||||
|
||||
/**
|
||||
* Implementation of {@link Font#canDisplay(String)},
|
||||
|
|
|
@ -449,4 +449,13 @@ public class GLightweightPeer
|
|||
{
|
||||
// Nothing to do here for lightweights.
|
||||
}
|
||||
|
||||
public boolean requestFocus(Component lightweightChild, boolean temporary,
|
||||
boolean focusedWindowChangeAllowed,
|
||||
long time, sun.awt.CausedFocusEvent.Cause cause)
|
||||
{
|
||||
// Always grant focus request.
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1726,7 +1726,8 @@ public abstract class CairoGraphics2D extends Graphics2D
|
|||
.equals(RenderingHints.VALUE_TEXT_ANTIALIAS_OFF));
|
||||
ignoreAA = true;
|
||||
|
||||
if (gv instanceof FreetypeGlyphVector && alpha == 1.0)
|
||||
if (gv instanceof FreetypeGlyphVector && alpha == 1.0
|
||||
&& !((FreetypeGlyphVector)gv).hasTransforms())
|
||||
{
|
||||
int n = gv.getNumGlyphs ();
|
||||
int[] codes = gv.getGlyphCodes (0, n, null);
|
||||
|
@ -2164,4 +2165,4 @@ public abstract class CairoGraphics2D extends Graphics2D
|
|||
|
||||
return new Rectangle2D.Double(minX, minY, (maxX - minX), (maxY - minY));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -938,4 +938,4 @@ public class ComponentGraphics extends CairoGraphics2D
|
|||
unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -43,6 +43,8 @@ import java.awt.font.FontRenderContext;
|
|||
import java.awt.font.GlyphJustificationInfo;
|
||||
import java.awt.font.GlyphMetrics;
|
||||
import java.awt.font.GlyphVector;
|
||||
import java.awt.font.TextAttribute;
|
||||
import java.awt.font.TransformAttribute;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.GeneralPath;
|
||||
import java.awt.geom.Point2D;
|
||||
|
@ -86,7 +88,10 @@ public class FreetypeGlyphVector extends GlyphVector
|
|||
private long[] fontSet = null;
|
||||
|
||||
/**
|
||||
* Glyph transforms. (de facto only the translation is used)
|
||||
* Glyph transforms. Supports all transform operations.
|
||||
*
|
||||
* The identity transform should not be stored in this array; use a null
|
||||
* instead (will result in performance improvements).
|
||||
*/
|
||||
private AffineTransform[] glyphTransforms;
|
||||
|
||||
|
@ -185,9 +190,12 @@ public class FreetypeGlyphVector extends GlyphVector
|
|||
fontSet = new long[nGlyphs];
|
||||
glyphPositions = new float[(nGlyphs + 1) * 2];
|
||||
glyphTransforms = new AffineTransform[ nGlyphs ];
|
||||
Arrays.fill(glyphTransforms, null);
|
||||
|
||||
for(int i = 0; i < nGlyphs; i++ )
|
||||
{
|
||||
glyphTransforms[ i ] = new AffineTransform( gv.glyphTransforms[ i ] );
|
||||
if (gv.glyphTransforms[i] != null)
|
||||
glyphTransforms[ i ] = new AffineTransform(gv.glyphTransforms[i]);
|
||||
glyphCodes[i] = gv.glyphCodes[ i ];
|
||||
}
|
||||
System.arraycopy(gv.glyphPositions, 0, glyphPositions, 0,
|
||||
|
@ -313,6 +321,25 @@ public class FreetypeGlyphVector extends GlyphVector
|
|||
}
|
||||
glyphPositions[nGlyphs * 2] = x;
|
||||
glyphPositions[nGlyphs * 2 + 1] = y;
|
||||
|
||||
// Apply any transform that may be in the font's attributes
|
||||
TransformAttribute ta;
|
||||
ta = (TransformAttribute)font.getAttributes().get(TextAttribute.TRANSFORM);
|
||||
if (ta != null)
|
||||
{
|
||||
AffineTransform tx = ta.getTransform();
|
||||
|
||||
// Transform glyph positions
|
||||
tx.transform(glyphPositions, 0, glyphPositions, 0,
|
||||
glyphPositions.length / 2);
|
||||
|
||||
// Also store per-glyph scale/shear/rotate (but not translation)
|
||||
double[] matrix = new double[4];
|
||||
tx.getMatrix(matrix);
|
||||
AffineTransform deltaTx = new AffineTransform(matrix);
|
||||
if (!deltaTx.isIdentity())
|
||||
Arrays.fill(glyphTransforms, deltaTx);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -375,7 +402,7 @@ public class FreetypeGlyphVector extends GlyphVector
|
|||
p.getY() + r.getY() + r.getHeight()};
|
||||
|
||||
if (glyphTransforms[glyphIndex] != null)
|
||||
glyphTransforms[glyphIndex].transform(bounds, 0, bounds, 0, 4);
|
||||
glyphTransforms[glyphIndex].transform(bounds, 0, bounds, 0, 2);
|
||||
|
||||
return new Rectangle2D.Double(bounds[0], bounds[1], bounds[2] - bounds[0],
|
||||
bounds[3] - bounds[1]);
|
||||
|
@ -473,7 +500,19 @@ public class FreetypeGlyphVector extends GlyphVector
|
|||
{
|
||||
return glyphTransforms[glyphIndex];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks whether any transform has been set on any glyphs.
|
||||
*/
|
||||
protected boolean hasTransforms()
|
||||
{
|
||||
for (int i = 0; i < glyphTransforms.length; i++)
|
||||
if (glyphTransforms[i] != null)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the visual bounds of a glyph
|
||||
* May be off by a pixel or two due to hinting/rasterization.
|
||||
|
@ -570,6 +609,19 @@ public class FreetypeGlyphVector extends GlyphVector
|
|||
*/
|
||||
public void setGlyphTransform(int glyphIndex, AffineTransform newTX)
|
||||
{
|
||||
// The identity transform should never be in the glyphTransforms array;
|
||||
// using and checking for nulls can be much faster.
|
||||
if (newTX != null && newTX.isIdentity())
|
||||
newTX = null;
|
||||
|
||||
// If the old and new transforms are identical, bail
|
||||
if (glyphTransforms[glyphIndex] == null && newTX == null)
|
||||
return;
|
||||
|
||||
if (newTX != null && newTX.equals(glyphTransforms[glyphIndex]))
|
||||
return;
|
||||
|
||||
// Invalidate bounds cache and set new transform
|
||||
logicalBounds = null;
|
||||
glyphTransforms[glyphIndex] = newTX;
|
||||
}
|
||||
|
|
|
@ -38,6 +38,8 @@ exception statement from your version. */
|
|||
|
||||
package gnu.java.awt.peer.gtk;
|
||||
|
||||
import gnu.classpath.Pointer;
|
||||
|
||||
import gnu.java.awt.ClasspathToolkit;
|
||||
import gnu.java.awt.peer.ClasspathFontPeer;
|
||||
import gnu.java.awt.font.opentype.NameDecoder;
|
||||
|
@ -172,6 +174,14 @@ public class GdkFontPeer extends ClasspathFontPeer
|
|||
|
||||
private ByteBuffer nameTable = null;
|
||||
|
||||
/**
|
||||
* The pointer to the native font data.
|
||||
*
|
||||
* This field is manipulated by native code. Don't change or remove
|
||||
* without adjusting the native code.
|
||||
*/
|
||||
private Pointer nativeFont;
|
||||
|
||||
private native void initState ();
|
||||
private native void dispose ();
|
||||
private native void setFont (String family, int style, int size);
|
||||
|
@ -351,7 +361,7 @@ public class GdkFontPeer extends ClasspathFontPeer
|
|||
return NameDecoder.getName(nameTable, name, locale);
|
||||
}
|
||||
|
||||
public boolean canDisplay (Font font, char c)
|
||||
public boolean canDisplay (Font font, int c)
|
||||
{
|
||||
// FIXME: inquire with pango
|
||||
return true;
|
||||
|
|
|
@ -52,6 +52,8 @@ import java.awt.image.SampleModel;
|
|||
import java.awt.image.WritableRaster;
|
||||
import java.util.Locale;
|
||||
|
||||
import gnu.classpath.Pointer;
|
||||
|
||||
public class GdkGraphicsEnvironment extends ClasspathGraphicsEnvironment
|
||||
{
|
||||
private final int native_state = GtkGenericPeer.getUniqueInteger ();
|
||||
|
@ -59,15 +61,24 @@ public class GdkGraphicsEnvironment extends ClasspathGraphicsEnvironment
|
|||
private GdkScreenGraphicsDevice defaultDevice;
|
||||
|
||||
private GdkScreenGraphicsDevice[] devices;
|
||||
|
||||
|
||||
/**
|
||||
* The pointer to the native display resource.
|
||||
*
|
||||
* This field is manipulated by native code. Don't change or remove
|
||||
* without adjusting the native code.
|
||||
*/
|
||||
private Pointer display;
|
||||
|
||||
static
|
||||
{
|
||||
System.loadLibrary("gtkpeer");
|
||||
|
||||
initStaticState ();
|
||||
GtkToolkit.initializeGlobalIDs();
|
||||
initIDs();
|
||||
}
|
||||
|
||||
static native void initStaticState();
|
||||
private static native void initIDs();
|
||||
|
||||
public GdkGraphicsEnvironment ()
|
||||
{
|
||||
|
|
|
@ -68,6 +68,8 @@ import javax.imageio.spi.ImageWriterSpi;
|
|||
import javax.imageio.stream.ImageInputStream;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
|
||||
import gnu.classpath.Pointer;
|
||||
|
||||
public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
|
||||
{
|
||||
static
|
||||
|
@ -94,6 +96,14 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
|
|||
// the current set of ImageConsumers for this decoder
|
||||
Vector curr;
|
||||
|
||||
/**
|
||||
* The pointer to the native pixbuf loader.
|
||||
*
|
||||
* This field is manipulated by native code. Don't change or remove
|
||||
* without adjusting the native code.
|
||||
*/
|
||||
private Pointer nativeDecoder;
|
||||
|
||||
// interface to GdkPixbuf
|
||||
// These native functions should be called with the pixbufLock held.
|
||||
native void initState ();
|
||||
|
|
|
@ -91,4 +91,9 @@ public class GdkRobotPeer implements RobotPeer
|
|||
|
||||
return pixels;
|
||||
}
|
||||
|
||||
public void dispose()
|
||||
{
|
||||
// Nothing to do here yet.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,6 +46,8 @@ import java.awt.Rectangle;
|
|||
import java.awt.Window;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import gnu.classpath.Pointer;
|
||||
|
||||
class GdkScreenGraphicsDevice extends GraphicsDevice
|
||||
{
|
||||
private final int native_state = GtkGenericPeer.getUniqueInteger ();
|
||||
|
@ -85,15 +87,23 @@ class GdkScreenGraphicsDevice extends GraphicsDevice
|
|||
* method must be called.
|
||||
*/
|
||||
DisplayMode fixedDisplayMode;
|
||||
|
||||
|
||||
/**
|
||||
* The pointer to the native screen resource.
|
||||
*
|
||||
* This field is manipulated by native code. Don't change or remove
|
||||
* without adjusting the native code.
|
||||
*/
|
||||
private Pointer screen;
|
||||
|
||||
static
|
||||
{
|
||||
System.loadLibrary("gtkpeer");
|
||||
|
||||
initStaticState ();
|
||||
GtkToolkit.initializeGlobalIDs();
|
||||
initIDs();
|
||||
}
|
||||
|
||||
static native void initStaticState();
|
||||
static native void initIDs();
|
||||
|
||||
GdkScreenGraphicsDevice (GdkGraphicsEnvironment e)
|
||||
{
|
||||
|
|
|
@ -616,11 +616,18 @@ public class GtkComponentPeer extends GtkGenericPeer
|
|||
setVisible (true);
|
||||
}
|
||||
|
||||
protected void postMouseEvent(int id, long when, int mods, int x, int y,
|
||||
protected void postMouseEvent(int id, long when, int mods, int x, int y,
|
||||
int clickCount, boolean popupTrigger)
|
||||
{
|
||||
q().postEvent(new MouseEvent(awtComponent, id, when, mods, x, y,
|
||||
clickCount, popupTrigger));
|
||||
// It is important to do the getLocationOnScreen() here, instead
|
||||
// of using the old MouseEvent constructors, because
|
||||
// Component.getLocationOnScreen() locks on the AWT lock, which can
|
||||
// trigger a deadlock. You don't want this.
|
||||
Point locOnScreen = getLocationOnScreen();
|
||||
q().postEvent(new MouseEvent(awtComponent, id, when, mods, x, y,
|
||||
locOnScreen.x + x, locOnScreen.y + y,
|
||||
clickCount, popupTrigger,
|
||||
MouseEvent.NOBUTTON));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -899,4 +906,14 @@ public class GtkComponentPeer extends GtkGenericPeer
|
|||
// FIXME: implement
|
||||
|
||||
}
|
||||
|
||||
public boolean requestFocus(Component lightweightChild, boolean temporary,
|
||||
boolean focusedWindowChangeAllowed,
|
||||
long time, sun.awt.CausedFocusEvent.Cause cause)
|
||||
{
|
||||
// TODO: Implement this properly and remove the other requestFocus()
|
||||
// methods.
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -244,6 +244,13 @@ public class GtkFramePeer extends GtkWindowPeer
|
|||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
public Rectangle getBoundsPrivate()
|
||||
{
|
||||
// TODO: Implement this properly.
|
||||
throw new InternalError("Not yet implemented");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -43,6 +43,8 @@ import java.awt.Font;
|
|||
import java.awt.Toolkit;
|
||||
import java.awt.event.ActionEvent;
|
||||
|
||||
import gnu.classpath.Pointer;
|
||||
|
||||
public class GtkGenericPeer
|
||||
{
|
||||
// Used by Native State Association (NSA) functions to map
|
||||
|
@ -55,6 +57,40 @@ public class GtkGenericPeer
|
|||
// The widget or other java-side object we wrap.
|
||||
protected final Object awtWidget;
|
||||
|
||||
/**
|
||||
* The pointer to the native GTK widget.
|
||||
*
|
||||
* This field is manipulated by native code. Don't change or remove
|
||||
* without adjusting the native code.
|
||||
*/
|
||||
private Pointer widget;
|
||||
|
||||
/**
|
||||
* The pointer to the global reference to this object. The native
|
||||
* code creates a JNI global reference of the peer object to be able
|
||||
* to pass it to the event callbacks. It gets stored here, so that
|
||||
* we can later delete it in the dispose() method.
|
||||
*
|
||||
* This field is manipulated by native code. Don't change or remove
|
||||
* without adjusting the native code.
|
||||
*/
|
||||
private Pointer globalRef;
|
||||
|
||||
/**
|
||||
* We initialize the field IDs that are used by native code here because
|
||||
* these remain valid until a class gets unloaded.
|
||||
*/
|
||||
static
|
||||
{
|
||||
GtkToolkit.initializeGlobalIDs();
|
||||
initIDs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the field IDs that are used by the native code.
|
||||
*/
|
||||
private static native void initIDs();
|
||||
|
||||
/**
|
||||
* Dispose of our native state. Calls gtk_widget_destroy on the
|
||||
* native widget and removes the awtWidget from the native state
|
||||
|
|
|
@ -144,10 +144,39 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
|
|||
|
||||
static native void gtkQuit();
|
||||
|
||||
/**
|
||||
* Initializes field IDs that are used by native code.
|
||||
*/
|
||||
private static native void initIDs();
|
||||
|
||||
/**
|
||||
* True when the field IDs are already initialized, false otherwise.
|
||||
*/
|
||||
private static boolean initializedGlobalIDs = false;
|
||||
|
||||
/**
|
||||
* Initializes some global fieldIDs for use in the native code. This is
|
||||
* called by a couple of classes in the GTK peers to ensure that
|
||||
* some necessary stuff is loaded.
|
||||
*/
|
||||
static synchronized void initializeGlobalIDs()
|
||||
{
|
||||
if (! initializedGlobalIDs)
|
||||
{
|
||||
initIDs();
|
||||
initializedGlobalIDs = true;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
{
|
||||
System.loadLibrary("gtkpeer");
|
||||
|
||||
|
||||
/**
|
||||
* Gotta do that first.
|
||||
*/
|
||||
initializeGlobalIDs();
|
||||
|
||||
int portableNativeSync;
|
||||
String portNatSyncProp =
|
||||
System.getProperty("gnu.classpath.awt.gtk.portable.native.sync");
|
||||
|
@ -716,4 +745,17 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
|
|||
|
||||
public native int getMouseNumberOfButtons();
|
||||
|
||||
@Override
|
||||
public boolean isModalExclusionTypeSupported
|
||||
(Dialog.ModalExclusionType modalExclusionType)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isModalityTypeSupported(Dialog.ModalityType modalityType)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
} // class GtkToolkit
|
||||
|
|
|
@ -398,4 +398,29 @@ public class GtkWindowPeer extends GtkContainerPeer
|
|||
{
|
||||
return new Rectangle(x, y, width, height);
|
||||
}
|
||||
|
||||
public void updateIconImages()
|
||||
{
|
||||
// TODO: Implement properly.
|
||||
}
|
||||
|
||||
public void updateMinimumSize()
|
||||
{
|
||||
// TODO: Implement properly.
|
||||
}
|
||||
|
||||
public void setModalBlocked(java.awt.Dialog d, boolean b)
|
||||
{
|
||||
// TODO: Implement properly.
|
||||
}
|
||||
|
||||
public void updateFocusableWindowState()
|
||||
{
|
||||
// TODO: Implement properly.
|
||||
}
|
||||
|
||||
public void setAlwaysOnTop(boolean b)
|
||||
{
|
||||
// TODO: Implement properly.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,7 +86,17 @@ public class VolatileImageGraphics extends ComponentGraphics
|
|||
|
||||
public GraphicsConfiguration getDeviceConfiguration()
|
||||
{
|
||||
return owner.component.getGraphicsConfiguration();
|
||||
GraphicsConfiguration conf;
|
||||
if (owner.component != null)
|
||||
{
|
||||
conf = owner.component.getGraphicsConfiguration();
|
||||
}
|
||||
else
|
||||
{
|
||||
return java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment()
|
||||
.getDefaultScreenDevice().getDefaultConfiguration();
|
||||
}
|
||||
return conf;
|
||||
}
|
||||
|
||||
public Graphics create()
|
||||
|
|
|
@ -368,4 +368,18 @@ public class HeadlessToolkit
|
|||
return graphicsEnv;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isModalExclusionTypeSupported
|
||||
(Dialog.ModalExclusionType modalExclusionType)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isModalityTypeSupported(Dialog.ModalityType modalityType)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -821,4 +821,14 @@ public class QtComponentPeer extends NativeWrapper implements ComponentPeer
|
|||
{
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
public boolean requestFocus(Component lightweightChild, boolean temporary,
|
||||
boolean focusedWindowChangeAllowed,
|
||||
long time, sun.awt.CausedFocusEvent.Cause cause)
|
||||
{
|
||||
// TODO: Implement this properly and remove the other requestFocus()
|
||||
// methods.
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ public class QtFontMetrics extends FontMetrics
|
|||
|
||||
// ****************** Package private ***************************
|
||||
|
||||
native boolean canDisplay( char c );
|
||||
native boolean canDisplay( int c );
|
||||
|
||||
// ****************** Public methods ****************************
|
||||
|
||||
|
|
|
@ -98,7 +98,7 @@ public class QtFontPeer extends ClasspathFontPeer
|
|||
|
||||
// ****************** ClasspathFontPeer Methods.
|
||||
|
||||
public boolean canDisplay (Font font, char c)
|
||||
public boolean canDisplay (Font font, int c)
|
||||
{
|
||||
return metrics.canDisplay( c );
|
||||
}
|
||||
|
|
|
@ -155,4 +155,10 @@ public class QtFramePeer extends QtWindowPeer implements FramePeer
|
|||
return false;
|
||||
}
|
||||
|
||||
public Rectangle getBoundsPrivate()
|
||||
{
|
||||
// TODO: Implement this properly.
|
||||
throw new InternalError("Not yet implemented");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -452,4 +452,19 @@ public class QtToolkit extends ClasspathToolkit
|
|||
// return new QtEmbeddedWindowPeer( this, w );
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isModalExclusionTypeSupported
|
||||
(Dialog.ModalExclusionType modalExclusionType)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isModalityTypeSupported(Dialog.ModalityType modalityType)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -77,4 +77,29 @@ public class QtWindowPeer extends QtContainerPeer implements WindowPeer
|
|||
return false;
|
||||
}
|
||||
|
||||
public void updateIconImages()
|
||||
{
|
||||
// TODO: Implement properly.
|
||||
}
|
||||
|
||||
public void updateMinimumSize()
|
||||
{
|
||||
// TODO: Implement properly.
|
||||
}
|
||||
|
||||
public void setModalBlocked(java.awt.Dialog d, boolean b)
|
||||
{
|
||||
// TODO: Implement properly.
|
||||
}
|
||||
|
||||
public void updateFocusableWindowState()
|
||||
{
|
||||
// TODO: Implement properly.
|
||||
}
|
||||
|
||||
public void setAlwaysOnTop(boolean b)
|
||||
{
|
||||
// TODO: Implement properly.
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SwingButtonPeer.java -- A Swing based peer for AWT buttons
|
||||
Copyright (C) 2006 Free Software Foundation, Inc.
|
||||
Copyright (C) 2006, 2007 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
|
@ -44,6 +44,7 @@ import java.awt.Image;
|
|||
import java.awt.Point;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.peer.ButtonPeer;
|
||||
|
@ -70,12 +71,12 @@ public class SwingButtonPeer
|
|||
extends JButton
|
||||
implements SwingComponent
|
||||
{
|
||||
Button button;
|
||||
Button button;
|
||||
|
||||
SwingButton(Button button)
|
||||
{
|
||||
this.button = button;
|
||||
}
|
||||
SwingButton(Button button)
|
||||
{
|
||||
this.button = button;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overridden so that this method returns the correct value even without a
|
||||
|
@ -184,6 +185,26 @@ public class SwingButtonPeer
|
|||
par = button.getParent();
|
||||
return par;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles focus events by forwarding it to
|
||||
* <code>processFocusEvent()</code>.
|
||||
*
|
||||
* @param ev the Focus event
|
||||
*/
|
||||
public void handleFocusEvent(FocusEvent ev)
|
||||
{
|
||||
processFocusEvent(ev);
|
||||
}
|
||||
|
||||
public void requestFocus() {
|
||||
SwingButtonPeer.this.requestFocus(awtComponent, false, true, 0);
|
||||
}
|
||||
|
||||
public boolean requestFocus(boolean temporary) {
|
||||
return SwingButtonPeer.this.requestFocus(awtComponent, temporary,
|
||||
true, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
261
libjava/classpath/gnu/java/awt/peer/swing/SwingCheckboxPeer.java
Executable file
261
libjava/classpath/gnu/java/awt/peer/swing/SwingCheckboxPeer.java
Executable file
|
@ -0,0 +1,261 @@
|
|||
/* SwingCheckboxPeer.java -- A Swing based peer for AWT checkboxes
|
||||
Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
package gnu.java.awt.peer.swing;
|
||||
|
||||
import java.awt.Button;
|
||||
import java.awt.Checkbox;
|
||||
import java.awt.CheckboxGroup;
|
||||
import java.awt.Container;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Image;
|
||||
import java.awt.Label;
|
||||
import java.awt.Point;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.peer.CheckboxPeer;
|
||||
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JToggleButton;
|
||||
|
||||
/**
|
||||
* A CheckboxPeer implementation that is backed by the Swing JCheckBox.
|
||||
*/
|
||||
public class SwingCheckboxPeer extends SwingComponentPeer implements
|
||||
CheckboxPeer {
|
||||
|
||||
/**
|
||||
* A spezialized Swing checkbox used to paint the checkbox for the
|
||||
* AWT checkbox.
|
||||
*/
|
||||
private class SwingCheckbox
|
||||
extends JCheckBox
|
||||
implements SwingComponent
|
||||
{
|
||||
Checkbox checkbox;
|
||||
|
||||
SwingCheckbox(Checkbox checkbox)
|
||||
{
|
||||
this.checkbox = checkbox;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this checkbox.
|
||||
*
|
||||
* @return <code>this</code>
|
||||
*/
|
||||
public JComponent getJComponent()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles mouse events by forwarding it to
|
||||
* <code>processMouseEvent()</code>.
|
||||
*
|
||||
* @param ev the mouse event
|
||||
*/
|
||||
public void handleMouseEvent(MouseEvent ev)
|
||||
{
|
||||
ev.setSource(this);
|
||||
processMouseEvent(ev);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles mouse motion events by forwarding it to
|
||||
* <code>processMouseMotionEvent()</code>.
|
||||
*
|
||||
* @param ev the mouse motion event
|
||||
*/
|
||||
public void handleMouseMotionEvent(MouseEvent ev)
|
||||
{
|
||||
ev.setSource(this);
|
||||
processMouseMotionEvent(ev);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles key events by forwarding it to <code>processKeyEvent()</code>.
|
||||
*
|
||||
* @param ev the mouse event
|
||||
*/
|
||||
public void handleKeyEvent(KeyEvent ev)
|
||||
{
|
||||
ev.setSource(this);
|
||||
processKeyEvent(ev);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles focus events by forwarding it to
|
||||
* <code>processFocusEvent()</code>.
|
||||
*
|
||||
* @param ev the Focus event
|
||||
*/
|
||||
public void handleFocusEvent(FocusEvent ev)
|
||||
{
|
||||
processFocusEvent(ev);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overridden so that this method returns the correct value even without a
|
||||
* peer.
|
||||
*
|
||||
* @return the screen location of the button
|
||||
*/
|
||||
public Point getLocationOnScreen()
|
||||
{
|
||||
return SwingCheckboxPeer.this.getLocationOnScreen();
|
||||
}
|
||||
|
||||
/**
|
||||
* Overridden so that the isShowing method returns the correct value
|
||||
* for the swing button, even if it has no peer on its own.
|
||||
*
|
||||
* @return <code>true</code> if the button is currently showing,
|
||||
* <code>false</code> otherwise
|
||||
*/
|
||||
public boolean isShowing()
|
||||
{
|
||||
boolean retVal = false;
|
||||
if (checkbox != null)
|
||||
retVal = checkbox.isShowing();
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overridden, so that the Swing button can create an Image without its
|
||||
* own peer.
|
||||
*
|
||||
* @param w the width of the image
|
||||
* @param h the height of the image
|
||||
*
|
||||
* @return an image
|
||||
*/
|
||||
public Image createImage(int w, int h)
|
||||
{
|
||||
return SwingCheckboxPeer.this.createImage(w, h);
|
||||
}
|
||||
|
||||
public Graphics getGraphics()
|
||||
{
|
||||
return SwingCheckboxPeer.this.getGraphics();
|
||||
}
|
||||
|
||||
public Container getParent()
|
||||
{
|
||||
Container par = null;
|
||||
if (checkbox != null)
|
||||
par = checkbox.getParent();
|
||||
return par;
|
||||
}
|
||||
|
||||
public void requestFocus() {
|
||||
SwingCheckboxPeer.this.requestFocus(awtComponent, false, true, 0);
|
||||
}
|
||||
|
||||
public boolean requestFocus(boolean temporary) {
|
||||
return SwingCheckboxPeer.this.requestFocus(awtComponent, temporary,
|
||||
true, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens for ActionEvents on the Swing button and triggers corresponding
|
||||
* ActionEvents on the AWT button.
|
||||
*/
|
||||
class SwingCheckboxListener implements ItemListener
|
||||
{
|
||||
Checkbox awtCheckbox;
|
||||
|
||||
SwingCheckboxListener(Checkbox checkbox)
|
||||
{
|
||||
awtCheckbox = checkbox;
|
||||
}
|
||||
|
||||
/**
|
||||
* Receives notification when an action was performend on the button.
|
||||
*
|
||||
* @param event the action event
|
||||
*/
|
||||
public void itemStateChanged(ItemEvent event)
|
||||
{
|
||||
awtCheckbox.setState(event.getStateChange()==ItemEvent.SELECTED);
|
||||
ItemListener[] l = awtCheckbox.getItemListeners();
|
||||
if (l.length == 0)
|
||||
return;
|
||||
ItemEvent ev = new ItemEvent(awtCheckbox, ItemEvent.ITEM_STATE_CHANGED,
|
||||
awtCheckbox, event.getStateChange());
|
||||
for (int i = 0; i < l.length; ++i)
|
||||
l[i].itemStateChanged(ev);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new SwingCheckboxPeer instance.
|
||||
*/
|
||||
public SwingCheckboxPeer(Checkbox checkbox)
|
||||
{
|
||||
SwingCheckbox swingCheckbox = new SwingCheckbox(checkbox);
|
||||
swingCheckbox.addItemListener(new SwingCheckboxListener(checkbox));
|
||||
|
||||
init(checkbox, swingCheckbox);
|
||||
setLabel(checkbox.getLabel());
|
||||
setState(checkbox.getState());
|
||||
}
|
||||
|
||||
public void setCheckboxGroup(CheckboxGroup group)
|
||||
{
|
||||
// TODO: Implement this.
|
||||
}
|
||||
|
||||
public void setLabel(String label)
|
||||
{
|
||||
((JToggleButton) swingComponent).setText(label);
|
||||
}
|
||||
|
||||
public void setState(boolean state)
|
||||
{
|
||||
((JToggleButton) swingComponent).setSelected(state);
|
||||
}
|
||||
|
||||
}
|
|
@ -37,6 +37,7 @@ exception statement from your version. */
|
|||
|
||||
package gnu.java.awt.peer.swing;
|
||||
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseEvent;
|
||||
|
||||
|
@ -86,4 +87,13 @@ public interface SwingComponent
|
|||
* @param ev the key event
|
||||
*/
|
||||
void handleKeyEvent(KeyEvent ev);
|
||||
|
||||
/**
|
||||
* Handles a focus event. This is usually forwarded to
|
||||
* {@link Component#processFocusEvent(FocusEvent)} of the swing
|
||||
* component.
|
||||
*
|
||||
* @param ev the focus event
|
||||
*/
|
||||
void handleFocusEvent(FocusEvent ev);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SwingComponentPeer.java -- An abstract base class for Swing based peers
|
||||
Copyright (C) 2006 Free Software Foundation, Inc.
|
||||
Copyright (C) 2006, 2007 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
|
@ -45,6 +45,7 @@ import java.awt.Component;
|
|||
import java.awt.Container;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics;
|
||||
|
@ -54,6 +55,7 @@ import java.awt.Point;
|
|||
import java.awt.Rectangle;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.BufferCapabilities.FlipContents;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.PaintEvent;
|
||||
|
@ -349,12 +351,7 @@ public class SwingComponentPeer
|
|||
*/
|
||||
public Dimension getMinimumSize()
|
||||
{
|
||||
Dimension retVal;
|
||||
if (swingComponent != null)
|
||||
retVal = swingComponent.getJComponent().getMinimumSize();
|
||||
else
|
||||
retVal = new Dimension(0, 0);
|
||||
return retVal;
|
||||
return minimumSize();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -367,12 +364,7 @@ public class SwingComponentPeer
|
|||
*/
|
||||
public Dimension getPreferredSize()
|
||||
{
|
||||
Dimension retVal;
|
||||
if (swingComponent != null)
|
||||
retVal = swingComponent.getJComponent().getPreferredSize();
|
||||
else
|
||||
retVal = new Dimension(0, 0);
|
||||
return retVal;
|
||||
return preferredSize();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -395,30 +387,28 @@ public class SwingComponentPeer
|
|||
public void handleEvent(AWTEvent e)
|
||||
{
|
||||
switch (e.getID())
|
||||
{
|
||||
{
|
||||
case PaintEvent.UPDATE:
|
||||
case PaintEvent.PAINT:
|
||||
// Need to synchronize to avoid threading problems on the
|
||||
// paint event list.
|
||||
// We must synchronize on the tree lock first to avoid deadlock,
|
||||
// because Container.paint() will grab it anyway.
|
||||
synchronized (this)
|
||||
if (awtComponent.isShowing())
|
||||
{
|
||||
assert paintArea != null;
|
||||
if (awtComponent.isShowing())
|
||||
Rectangle clip ;
|
||||
synchronized (this)
|
||||
{
|
||||
Graphics g = awtComponent.getGraphics();
|
||||
try
|
||||
{
|
||||
Rectangle clip = paintArea;
|
||||
g.clipRect(clip.x, clip.y, clip.width, clip.height);
|
||||
peerPaint(g, e.getID() == PaintEvent.UPDATE);
|
||||
}
|
||||
finally
|
||||
{
|
||||
g.dispose();
|
||||
paintArea = null;
|
||||
}
|
||||
coalescePaintEvent((PaintEvent) e);
|
||||
assert paintArea != null;
|
||||
clip = paintArea;
|
||||
paintArea = null;
|
||||
}
|
||||
Graphics g = awtComponent.getGraphics();
|
||||
try
|
||||
{
|
||||
g.clipRect(clip.x, clip.y, clip.width, clip.height);
|
||||
peerPaint(g, e.getID() == PaintEvent.UPDATE);
|
||||
}
|
||||
finally
|
||||
{
|
||||
g.dispose();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -438,10 +428,14 @@ public class SwingComponentPeer
|
|||
case KeyEvent.KEY_TYPED:
|
||||
handleKeyEvent((KeyEvent) e);
|
||||
break;
|
||||
case FocusEvent.FOCUS_GAINED:
|
||||
case FocusEvent.FOCUS_LOST:
|
||||
handleFocusEvent((FocusEvent)e);
|
||||
break;
|
||||
default:
|
||||
// Other event types are not handled here.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -574,13 +568,16 @@ public class SwingComponentPeer
|
|||
* This is implemented to call repaint() on the Swing component.
|
||||
*
|
||||
* @param tm number of milliseconds to wait with repainting
|
||||
* @param x the X coordinate of the upper left corner of the damaged rectangle
|
||||
* @param y the Y coordinate of the upper left corner of the damaged rectangle
|
||||
* @param x the X coordinate of the upper left corner of the damaged
|
||||
* rectangle
|
||||
* @param y the Y coordinate of the upper left corner of the damaged
|
||||
* rectangle
|
||||
* @param width the width of the damaged rectangle
|
||||
* @param height the height of the damaged rectangle
|
||||
*/
|
||||
public void repaint(long tm, int x, int y, int width, int height)
|
||||
{
|
||||
// NOTE: This is never called by AWT but is mandated by the peer interface.
|
||||
if (swingComponent != null)
|
||||
swingComponent.getJComponent().repaint(tm, x, y, width, height);
|
||||
else
|
||||
|
@ -602,8 +599,10 @@ public class SwingComponentPeer
|
|||
*/
|
||||
public void requestFocus()
|
||||
{
|
||||
if (swingComponent != null)
|
||||
swingComponent.getJComponent().requestFocus();
|
||||
// NOTE: This is never called by AWT but is mandated by the peer interface.
|
||||
Toolkit tk = Toolkit.getDefaultToolkit();
|
||||
EventQueue q = tk.getSystemEventQueue();
|
||||
q.postEvent(new FocusEvent(awtComponent, FocusEvent.FOCUS_GAINED, false));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -612,18 +611,22 @@ public class SwingComponentPeer
|
|||
*
|
||||
* This calls requestFocus() on the Swing component.
|
||||
*
|
||||
* @param source TODO
|
||||
* @param bool1 TODO
|
||||
* @param bool2 TODO
|
||||
* @param x TODO
|
||||
* @param source the actual component that requests focus (may be a
|
||||
* lightweight descendant of the heavyweight container)
|
||||
* @param tmp true when the change is temporary
|
||||
* @param allowWindowFocus
|
||||
* @param tm the timestamp of the focus change
|
||||
*
|
||||
* @return TODO
|
||||
* @return true when the focus change is guaranteed to be granted, false
|
||||
* otherwise
|
||||
*/
|
||||
public boolean requestFocus(Component source, boolean bool1, boolean bool2, long x)
|
||||
public boolean requestFocus(Component source, boolean tmp,
|
||||
boolean allowWindowFocus, long tm)
|
||||
{
|
||||
if (swingComponent != null)
|
||||
swingComponent.getJComponent().requestFocus();
|
||||
return swingComponent != null;
|
||||
Toolkit tk = Toolkit.getDefaultToolkit();
|
||||
EventQueue q = tk.getSystemEventQueue();
|
||||
q.postEvent(new FocusEvent(source, FocusEvent.FOCUS_GAINED, tmp));
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1100,6 +1103,19 @@ public class SwingComponentPeer
|
|||
swingComponent.handleKeyEvent(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles focus events on the component. This is usually forwarded to the
|
||||
* SwingComponent's processFocusEvent() method.
|
||||
*
|
||||
* @param e the key event
|
||||
*/
|
||||
protected void handleFocusEvent(FocusEvent e)
|
||||
{
|
||||
if (swingComponent != null)
|
||||
swingComponent.handleFocusEvent(e);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the AWT component for this peer.
|
||||
*
|
||||
|
@ -1109,4 +1125,12 @@ public class SwingComponentPeer
|
|||
{
|
||||
return awtComponent;
|
||||
}
|
||||
|
||||
public boolean requestFocus(Component lightweightChild, boolean temporary,
|
||||
boolean focusedWindowChangeAllowed,
|
||||
long time, sun.awt.CausedFocusEvent.Cause cause)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SwingContainerPeer.java -- A Swing based peer for AWT containers
|
||||
Copyright (C) 2006 Free Software Foundation, Inc.
|
||||
Copyright (C) 2006, 2007 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
|
@ -92,7 +92,7 @@ public class SwingContainerPeer
|
|||
* @see #peerPaintChildren(Graphics)
|
||||
* @see #removeHeavyweightDescendent(Component)
|
||||
*/
|
||||
synchronized void addHeavyweightDescendent(Component comp)
|
||||
protected synchronized void addHeavyweightDescendent(Component comp)
|
||||
{
|
||||
heavyweightDescendents.add(comp);
|
||||
focusOwner = null;
|
||||
|
@ -106,12 +106,24 @@ public class SwingContainerPeer
|
|||
* @see #peerPaintChildren(Graphics)
|
||||
* @see #addHeavyweightDescendent(Component)
|
||||
*/
|
||||
synchronized void removeHeavyweightDescendent(Component comp)
|
||||
protected synchronized void removeHeavyweightDescendent(Component comp)
|
||||
{
|
||||
heavyweightDescendents.remove(comp);
|
||||
focusOwner = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all registered heavyweight descendents.
|
||||
*
|
||||
* @return all registered heavyweight descendents
|
||||
*/
|
||||
protected Component[] getHeavyweightDescendents()
|
||||
{
|
||||
Component[] heavyweights = new Component[heavyweightDescendents.size()];
|
||||
heavyweights = (Component[]) heavyweightDescendents.toArray(heavyweights);
|
||||
return heavyweights;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the insets of the container.
|
||||
*
|
||||
|
@ -339,7 +351,7 @@ public class SwingContainerPeer
|
|||
{
|
||||
Component owner = getFocusOwner();
|
||||
if(owner != null)
|
||||
owner.dispatchEvent(e);
|
||||
owner.getPeer().handleEvent(e);
|
||||
else
|
||||
super.handleKeyEvent(e);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SwingLabelPeer.java -- A Swing based peer for AWT labels
|
||||
Copyright (C) 2006 Free Software Foundation, Inc.
|
||||
Copyright (C) 2006, 2007 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
|
@ -42,6 +42,7 @@ import java.awt.Graphics;
|
|||
import java.awt.Image;
|
||||
import java.awt.Label;
|
||||
import java.awt.Point;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.peer.LabelPeer;
|
||||
|
@ -119,6 +120,17 @@ public class SwingLabelPeer
|
|||
processKeyEvent(ev);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles focus events by forwarding it to
|
||||
* <code>processFocusEvent()</code>.
|
||||
*
|
||||
* @param ev the Focus event
|
||||
*/
|
||||
public void handleFocusEvent(FocusEvent ev)
|
||||
{
|
||||
processFocusEvent(ev);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overridden so that this method returns the correct value even without a
|
||||
* peer.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SwingListPeer.java -- A Swing based peer for AWT lists
|
||||
Copyright (C) 2006 Free Software Foundation, Inc.
|
||||
Copyright (C) 2006, 2007 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
|
@ -46,6 +46,7 @@ import java.awt.Image;
|
|||
import java.awt.List;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.peer.ListPeer;
|
||||
|
@ -128,6 +129,17 @@ public class SwingListPeer
|
|||
processKeyEvent(ev);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles focus events by forwarding it to <code>processFocusEvent()</code>.
|
||||
*
|
||||
* @param ev the Focus event
|
||||
*/
|
||||
public void handleFocusEvent(FocusEvent ev)
|
||||
{
|
||||
processFocusEvent(ev);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Overridden so that this method returns the correct value even without a
|
||||
* peer.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SwingPanelPeer.java -- A PanelPeer based on Swing
|
||||
Copyright (C) 2006 Free Software Foundation, Inc.
|
||||
Copyright (C) 2006, 2007 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
|
@ -47,7 +47,7 @@ import java.awt.peer.PanelPeer;
|
|||
* @author Roman Kennke (kennke@aicas.com)
|
||||
*/
|
||||
// TODO: Maybe base implementation on JPanel. However, this doesn't seem
|
||||
// necessary, but might be good for more consistend Look.
|
||||
// necessary, but might be good for more consistent Look.
|
||||
public class SwingPanelPeer
|
||||
extends SwingContainerPeer
|
||||
implements PanelPeer
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SwingTextAreaPeer.java -- A Swing based peer for AWT textareas
|
||||
Copyright (C) 2006 Free Software Foundation, Inc.
|
||||
Copyright (C) 2006, 2007 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
|
@ -45,14 +45,20 @@ import java.awt.Image;
|
|||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.TextArea;
|
||||
import java.awt.event.ComponentEvent;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.HierarchyEvent;
|
||||
import java.awt.event.InputMethodEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseWheelEvent;
|
||||
import java.awt.im.InputMethodRequests;
|
||||
import java.awt.peer.TextAreaPeer;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.JViewport;
|
||||
import javax.swing.text.BadLocationException;
|
||||
|
||||
public class SwingTextAreaPeer
|
||||
|
@ -65,15 +71,19 @@ public class SwingTextAreaPeer
|
|||
*
|
||||
* @author Roman Kennke (kennke@aicas.com)
|
||||
*/
|
||||
private class SwingTextArea
|
||||
private class SwingScrollPane
|
||||
extends JScrollPane
|
||||
implements SwingComponent
|
||||
{
|
||||
|
||||
SwingTextArea(Component comp)
|
||||
SwingTextArea textArea;
|
||||
|
||||
SwingScrollPane(SwingTextArea textArea)
|
||||
{
|
||||
super(comp, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
|
||||
super(textArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
|
||||
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
|
||||
|
||||
this.textArea = textArea;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -94,8 +104,17 @@ public class SwingTextAreaPeer
|
|||
*/
|
||||
public void handleMouseEvent(MouseEvent ev)
|
||||
{
|
||||
ev.setSource(this);
|
||||
dispatchEvent(ev);
|
||||
JViewport viewPort = getViewport();
|
||||
if(viewPort.contains(ev.getPoint()))
|
||||
{
|
||||
ev.setSource(textArea);
|
||||
textArea.dispatchEvent(ev);
|
||||
}
|
||||
else
|
||||
{
|
||||
ev.setSource(this);
|
||||
this.dispatchEvent(ev);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -114,7 +133,7 @@ public class SwingTextAreaPeer
|
|||
*/
|
||||
public void handleMouseMotionEvent(MouseEvent ev)
|
||||
{
|
||||
processMouseMotionEvent(ev);
|
||||
textArea.processMouseMotionEvent(ev);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -124,7 +143,18 @@ public class SwingTextAreaPeer
|
|||
*/
|
||||
public void handleKeyEvent(KeyEvent ev)
|
||||
{
|
||||
processKeyEvent(ev);
|
||||
textArea.processKeyEvent(ev);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles focus events by forwarding it to
|
||||
* <code>processFocusEvent()</code>.
|
||||
*
|
||||
* @param ev the Focus event
|
||||
*/
|
||||
public void handleFocusEvent(FocusEvent ev)
|
||||
{
|
||||
textArea.processFocusEvent(ev);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -179,35 +209,160 @@ public class SwingTextAreaPeer
|
|||
par = SwingTextAreaPeer.this.awtComponent.getParent();
|
||||
return par;
|
||||
}
|
||||
|
||||
public void requestFocus() {
|
||||
SwingTextAreaPeer.this.requestFocus(awtComponent, false, true, 0);
|
||||
}
|
||||
|
||||
public boolean requestFocus(boolean temporary) {
|
||||
return SwingTextAreaPeer.this.requestFocus(awtComponent, temporary,
|
||||
true, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class SwingTextArea extends JTextArea
|
||||
{
|
||||
/**
|
||||
* Make this method accessible in this Package.
|
||||
*/
|
||||
protected final void processComponentKeyEvent(KeyEvent e)
|
||||
{
|
||||
super.processComponentKeyEvent(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make this method accessible in this Package.
|
||||
*/
|
||||
protected final void processMouseMotionEvent(MouseEvent ev)
|
||||
{
|
||||
super.processMouseMotionEvent(ev);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make this method accessible in this Package.
|
||||
*/
|
||||
protected final void processComponentEvent(ComponentEvent e)
|
||||
{
|
||||
super.processComponentEvent(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make this method accessible in this Package.
|
||||
*/
|
||||
protected final void processFocusEvent(FocusEvent e)
|
||||
{
|
||||
super.processFocusEvent(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make this method accessible in this Package.
|
||||
*/
|
||||
protected final void processHierarchyBoundsEvent(HierarchyEvent e)
|
||||
{
|
||||
super.processHierarchyBoundsEvent(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make this method accessible in this Package.
|
||||
*/
|
||||
protected final void processHierarchyEvent(HierarchyEvent e)
|
||||
{
|
||||
super.processHierarchyEvent(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make this method accessible in this Package.
|
||||
*/
|
||||
protected final void processInputMethodEvent(InputMethodEvent e)
|
||||
{
|
||||
super.processInputMethodEvent(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make this method accessible in this Package.
|
||||
*/
|
||||
protected final void processMouseEvent(MouseEvent e)
|
||||
{
|
||||
super.processMouseEvent(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make this method accessible in this Package.
|
||||
*/
|
||||
protected final void processMouseWheelEvent(MouseWheelEvent e)
|
||||
{
|
||||
super.processMouseWheelEvent(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make this method accessible in this Package.
|
||||
*/
|
||||
protected final void processKeyEvent(KeyEvent e)
|
||||
{
|
||||
super.processKeyEvent(e);
|
||||
}
|
||||
|
||||
public void requestFocus() {
|
||||
SwingTextAreaPeer.this.requestFocus(awtComponent, false, true, 0);
|
||||
}
|
||||
|
||||
public boolean requestFocus(boolean temporary) {
|
||||
return SwingTextAreaPeer.this.requestFocus(awtComponent, temporary,
|
||||
true, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The actual JTextArea.
|
||||
*/
|
||||
private JTextArea jTextArea;
|
||||
private SwingTextArea jTextArea;
|
||||
|
||||
public SwingTextAreaPeer(TextArea textArea)
|
||||
{
|
||||
super();
|
||||
System.err.println("new SwingTextAreaPeer");
|
||||
jTextArea = new JTextArea();
|
||||
SwingTextArea swingArea = new SwingTextArea(jTextArea);
|
||||
jTextArea = new SwingTextArea();
|
||||
SwingScrollPane swingArea = new SwingScrollPane(jTextArea);
|
||||
init(textArea, swingArea);
|
||||
|
||||
JViewport viewport = new JViewport()
|
||||
{
|
||||
public Image createImage(int width, int height)
|
||||
{
|
||||
return awtComponent.createImage(width, height);
|
||||
}
|
||||
};
|
||||
|
||||
viewport.setView(jTextArea);
|
||||
swingArea.setViewport(viewport);
|
||||
// Pull over the text from the text area.
|
||||
setText(textArea.getText());
|
||||
|
||||
// Pull over the number of rows and columns
|
||||
// if non were set use default values
|
||||
int columns = textArea.getColumns();
|
||||
int rows = textArea.getRows();
|
||||
|
||||
if(columns == 0 && rows == 0)
|
||||
{
|
||||
columns = 25;
|
||||
textArea.setColumns(columns);
|
||||
rows = 5;
|
||||
textArea.setRows(rows);
|
||||
}
|
||||
|
||||
jTextArea.setColumns(columns);
|
||||
jTextArea.setRows(rows);
|
||||
}
|
||||
|
||||
public Dimension getMinimumSize(int rows, int cols)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
return jTextArea.getMinimumSize();
|
||||
}
|
||||
|
||||
public Dimension getPreferredSize(int rows, int cols)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
return jTextArea.getPreferredSize();
|
||||
}
|
||||
|
||||
public void insert(String text, int pos)
|
||||
|
@ -220,16 +375,24 @@ public class SwingTextAreaPeer
|
|||
jTextArea.insert(text, pos);
|
||||
}
|
||||
|
||||
public Dimension minimumSize()
|
||||
{
|
||||
return jTextArea.getMinimumSize();
|
||||
}
|
||||
|
||||
public Dimension preferredSize()
|
||||
{
|
||||
return jTextArea.getPreferredSize();
|
||||
}
|
||||
|
||||
public Dimension minimumSize(int rows, int cols)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
return jTextArea.getMinimumSize();
|
||||
}
|
||||
|
||||
public Dimension preferredSize(int rows, int cols)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
return jTextArea.getPreferredSize();
|
||||
}
|
||||
|
||||
public void replaceRange(String text, int start, int end)
|
||||
|
@ -310,8 +473,16 @@ public class SwingTextAreaPeer
|
|||
|
||||
public void setText(String text)
|
||||
{
|
||||
System.err.println("setText: " + text);
|
||||
jTextArea.setText(text);
|
||||
}
|
||||
|
||||
public void reshape(int x, int y, int width, int height)
|
||||
{
|
||||
if (swingComponent != null)
|
||||
{
|
||||
swingComponent.getJComponent().setBounds(x, y, width, height);
|
||||
swingComponent.getJComponent().validate();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SwingTextFieldPeer.java -- A Swing based peer for AWT textfields
|
||||
Copyright (C) 2006 Free Software Foundation, Inc.
|
||||
Copyright (C) 2006, 2007 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
|
@ -44,6 +44,7 @@ import java.awt.Image;
|
|||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.TextField;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.im.InputMethodRequests;
|
||||
|
@ -72,13 +73,13 @@ public class SwingTextFieldPeer
|
|||
implements SwingComponent
|
||||
{
|
||||
|
||||
TextField textField;
|
||||
|
||||
SwingTextField(TextField textField)
|
||||
{
|
||||
this.textField = textField;
|
||||
}
|
||||
|
||||
TextField textField;
|
||||
|
||||
SwingTextField(TextField textField)
|
||||
{
|
||||
this.textField = textField;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overridden to provide normal behaviour even without a real peer
|
||||
* attached.
|
||||
|
@ -91,8 +92,8 @@ public class SwingTextFieldPeer
|
|||
}
|
||||
|
||||
/**
|
||||
* Overridden so that the isShowing method returns the correct value for the
|
||||
* swing button, even if it has no peer on its own.
|
||||
* Overridden so that the isShowing method returns the correct value
|
||||
* for the swing button, even if it has no peer on its own.
|
||||
*
|
||||
* @return <code>true</code> if the button is currently showing,
|
||||
* <code>false</code> otherwise
|
||||
|
@ -162,6 +163,18 @@ public class SwingTextFieldPeer
|
|||
processKeyEvent(ev);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles focus events by forwarding it to
|
||||
* <code>processFocusEvent()</code>.
|
||||
*
|
||||
* @param ev the Focus event
|
||||
*/
|
||||
public void handleFocusEvent(FocusEvent ev)
|
||||
{
|
||||
processFocusEvent(ev);
|
||||
}
|
||||
|
||||
|
||||
public Container getParent()
|
||||
{
|
||||
Container par = null;
|
||||
|
@ -174,6 +187,16 @@ public class SwingTextFieldPeer
|
|||
{
|
||||
return SwingTextFieldPeer.this.getGraphics();
|
||||
}
|
||||
|
||||
public void requestFocus() {
|
||||
SwingTextFieldPeer.this.requestFocus(awtComponent, false, true, 0);
|
||||
}
|
||||
|
||||
public boolean requestFocus(boolean temporary) {
|
||||
return SwingTextFieldPeer.this.requestFocus(awtComponent, temporary,
|
||||
true, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -40,6 +40,7 @@ package gnu.java.awt.peer.swing;
|
|||
|
||||
import java.awt.Button;
|
||||
import java.awt.Canvas;
|
||||
import java.awt.Dialog;
|
||||
import java.awt.Label;
|
||||
import java.awt.Menu;
|
||||
import java.awt.MenuBar;
|
||||
|
@ -162,4 +163,19 @@ public abstract class SwingToolkit extends ClasspathToolkit
|
|||
{
|
||||
return new SwingTextFieldPeer(textField);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isModalExclusionTypeSupported
|
||||
(Dialog.ModalExclusionType modalExclusionType)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isModalityTypeSupported(Dialog.ModalityType modalityType)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -71,4 +71,29 @@ public abstract class SwingWindowPeer
|
|||
super(window);
|
||||
init(window, null);
|
||||
}
|
||||
|
||||
public void updateIconImages()
|
||||
{
|
||||
// TODO: Implement properly.
|
||||
}
|
||||
|
||||
public void updateMinimumSize()
|
||||
{
|
||||
// TODO: Implement properly.
|
||||
}
|
||||
|
||||
public void setModalBlocked(java.awt.Dialog d, boolean b)
|
||||
{
|
||||
// TODO: Implement properly.
|
||||
}
|
||||
|
||||
public void updateFocusableWindowState()
|
||||
{
|
||||
// TODO: Implement properly.
|
||||
}
|
||||
|
||||
public void setAlwaysOnTop(boolean b)
|
||||
{
|
||||
// TODO: Implement properly.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -405,8 +405,12 @@ final class KeyboardMapping
|
|||
|
||||
if ((xMods & Input.SHIFT_MASK) != 0)
|
||||
mods |= KeyEvent.SHIFT_MASK | KeyEvent.SHIFT_DOWN_MASK;
|
||||
if ((xMods & Input.META_MASK) != 0)
|
||||
mods |= KeyEvent.META_MASK | KeyEvent.META_DOWN_MASK;
|
||||
if ((xMods & Input.ALT_MASK) != 0)
|
||||
mods |= KeyEvent.ALT_MASK | KeyEvent.ALT_DOWN_MASK;
|
||||
if ((xMods & Input.MOD5_MASK) != 0)
|
||||
mods |= KeyEvent.ALT_GRAPH_MASK | KeyEvent.ALT_GRAPH_DOWN_MASK;
|
||||
if ((xMods & Input.CONTROL_MASK) != 0)
|
||||
mods |= KeyEvent.CTRL_MASK | KeyEvent.CTRL_DOWN_MASK;
|
||||
|
||||
|
|
185
libjava/classpath/gnu/java/awt/peer/x/PixmapVolatileImage.java
Normal file
185
libjava/classpath/gnu/java/awt/peer/x/PixmapVolatileImage.java
Normal file
|
@ -0,0 +1,185 @@
|
|||
/* PixmapVolatileImage.java -- VolatileImage implementation around a Pixmap
|
||||
Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
package gnu.java.awt.peer.x;
|
||||
|
||||
import gnu.x11.GC;
|
||||
import gnu.x11.Pixmap;
|
||||
import gnu.x11.image.Image;
|
||||
import gnu.x11.image.ZPixmap;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.ImageCapabilities;
|
||||
import java.awt.Point;
|
||||
import java.awt.Transparency;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.ComponentColorModel;
|
||||
import java.awt.image.ComponentSampleModel;
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.awt.image.ImageObserver;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.SampleModel;
|
||||
import java.awt.image.VolatileImage;
|
||||
import java.awt.image.WritableRaster;
|
||||
|
||||
/**
|
||||
* A {@link VolatileImage} implementation that wraps an X Pixmap.
|
||||
*/
|
||||
class PixmapVolatileImage
|
||||
extends VolatileImage
|
||||
{
|
||||
|
||||
/**
|
||||
* The shared capabilities instance.
|
||||
*/
|
||||
private static final ImageCapabilities caps = new ImageCapabilities(true);
|
||||
|
||||
/**
|
||||
* The underlying pixmap.
|
||||
*/
|
||||
private Pixmap pixmap;
|
||||
|
||||
/**
|
||||
* Creates a new PixmapVolatileImage.
|
||||
*
|
||||
* @param w the width of the image
|
||||
* @param h the height of the image
|
||||
*/
|
||||
public PixmapVolatileImage(int w, int h)
|
||||
{
|
||||
GraphicsEnvironment env =
|
||||
GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
XGraphicsDevice dev = (XGraphicsDevice) env.getDefaultScreenDevice();
|
||||
pixmap = new Pixmap(dev.getDisplay(), w, h);
|
||||
|
||||
// Clear pixmap.
|
||||
GC gc = new GC(pixmap);
|
||||
gc.set_foreground(0xffffffff);
|
||||
pixmap.fill_rectangle(gc, 0, 0, w, h);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contentsLost()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Graphics2D createGraphics()
|
||||
{
|
||||
return new XGraphics2D(pixmap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageCapabilities getCapabilities()
|
||||
{
|
||||
return caps;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight()
|
||||
{
|
||||
return pixmap.height;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BufferedImage getSnapshot()
|
||||
{
|
||||
// TODO: Support non-24-bit resolutions.
|
||||
int w = pixmap.width;
|
||||
int h = pixmap.height;
|
||||
ZPixmap zpixmap = (ZPixmap) pixmap.image(0, 0, w, h, 0xffffffff,
|
||||
Image.Format.ZPIXMAP);
|
||||
DataBuffer buffer = new ZPixmapDataBuffer(zpixmap);
|
||||
SampleModel sm = new ComponentSampleModel(DataBuffer.TYPE_BYTE, w, h, 4,
|
||||
w * 4,
|
||||
new int[]{0, 1, 2, 3 });
|
||||
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB);
|
||||
ColorModel cm = new ComponentColorModel(cs, true, false,
|
||||
Transparency.OPAQUE,
|
||||
DataBuffer.TYPE_BYTE);
|
||||
WritableRaster raster = Raster.createWritableRaster(sm, buffer,
|
||||
new Point(0, 0));
|
||||
return new BufferedImage(cm, raster, false, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth()
|
||||
{
|
||||
return pixmap.width;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int validate(GraphicsConfiguration gc)
|
||||
{
|
||||
// TODO: Check compatibility with gc.
|
||||
return IMAGE_OK;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight(ImageObserver observer)
|
||||
{
|
||||
return getHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getProperty(String name, ImageObserver observer)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth(ImageObserver observer)
|
||||
{
|
||||
return getWidth();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the underlying X pixmap. This is used for the graphics code.
|
||||
*
|
||||
* @return the underlying X pixmap
|
||||
*/
|
||||
Pixmap getPixmap()
|
||||
{
|
||||
return pixmap;
|
||||
}
|
||||
}
|
|
@ -97,8 +97,9 @@ public class XEventPump
|
|||
display = d;
|
||||
windows = new HashMap();
|
||||
drag = -1;
|
||||
Thread t = new Thread(this);
|
||||
t.start();
|
||||
Thread thread = new Thread(this, "X Event Pump");
|
||||
thread.setDaemon(true);
|
||||
thread.start();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -148,8 +149,9 @@ public class XEventPump
|
|||
|
||||
private void handleEvent(Event xEvent)
|
||||
{
|
||||
Integer key = new Integer(xEvent.window_id());;
|
||||
Window awtWindow = (Window) windows.get(key);
|
||||
|
||||
Integer key = null;
|
||||
Window awtWindow = null;
|
||||
|
||||
if (XToolkit.DEBUG)
|
||||
System.err.println("fetched event: " + xEvent);
|
||||
|
@ -157,26 +159,45 @@ public class XEventPump
|
|||
{
|
||||
case ButtonPress.CODE:
|
||||
ButtonPress bp = (ButtonPress) xEvent;
|
||||
key= new Integer(bp.event_window_id);
|
||||
awtWindow = (Window) windows.get(key);
|
||||
// Create and post the mouse event.
|
||||
int button = bp.detail();
|
||||
|
||||
// AWT cannot handle more than 3 buttons and expects 0 instead.
|
||||
if (button >= gnu.x11.Input.BUTTON3)
|
||||
button = 0;
|
||||
drag = button;
|
||||
|
||||
MouseEvent mp = new MouseEvent(awtWindow, MouseEvent.MOUSE_PRESSED,
|
||||
System.currentTimeMillis(), 0,
|
||||
System.currentTimeMillis(),
|
||||
KeyboardMapping.mapModifiers(bp.state()) | buttonToModifier(button),
|
||||
bp.event_x(), bp.event_y(),
|
||||
1, false, button);
|
||||
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(mp);
|
||||
break;
|
||||
case ButtonRelease.CODE:
|
||||
ButtonRelease br = (ButtonRelease) xEvent;
|
||||
key= new Integer(br.event_window_id);
|
||||
awtWindow = (Window) windows.get(key);
|
||||
|
||||
button = br.detail();
|
||||
// AWT cannot handle more than 3 buttons and expects 0 instead.
|
||||
if (button >= gnu.x11.Input.BUTTON3)
|
||||
button = 0;
|
||||
drag = -1;
|
||||
MouseEvent mr = new MouseEvent(awtWindow, MouseEvent.MOUSE_RELEASED,
|
||||
System.currentTimeMillis(), 0,
|
||||
System.currentTimeMillis(),
|
||||
KeyboardMapping.mapModifiers(br.state()) | buttonToModifier(button),
|
||||
br.event_x(), br.event_y(),
|
||||
1, false, br.detail());
|
||||
1, false, button);
|
||||
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(mr);
|
||||
break;
|
||||
case MotionNotify.CODE:
|
||||
MotionNotify mn = (MotionNotify) xEvent;
|
||||
key= new Integer(mn.event_window_id);
|
||||
awtWindow = (Window) windows.get(key);
|
||||
|
||||
MouseEvent mm;
|
||||
if (drag == -1)
|
||||
{
|
||||
|
@ -195,6 +216,8 @@ public class XEventPump
|
|||
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(mm);
|
||||
break;
|
||||
case ConfigureNotify.CODE:
|
||||
key= new Integer(((ConfigureNotify) xEvent).event_window_id);
|
||||
awtWindow = (Window) windows.get(key);
|
||||
ConfigureNotify c = (ConfigureNotify) xEvent;
|
||||
if (XToolkit.DEBUG)
|
||||
System.err.println("resize request for window id: " + key);
|
||||
|
@ -213,6 +236,8 @@ public class XEventPump
|
|||
}
|
||||
break;
|
||||
case Expose.CODE:
|
||||
key= new Integer(((Expose) xEvent).window_id);
|
||||
awtWindow = (Window) windows.get(key);
|
||||
Expose exp = (Expose) xEvent;
|
||||
if (XToolkit.DEBUG)
|
||||
System.err.println("expose request for window id: " + key);
|
||||
|
@ -228,6 +253,8 @@ public class XEventPump
|
|||
break;
|
||||
case KeyPress.CODE:
|
||||
case KeyRelease.CODE:
|
||||
key = new Integer(((Input) xEvent).event_window_id);
|
||||
awtWindow = (Window) windows.get(key);
|
||||
handleKeyEvent(xEvent, awtWindow);
|
||||
break;
|
||||
default:
|
||||
|
@ -282,6 +309,23 @@ public class XEventPump
|
|||
|
||||
}
|
||||
|
||||
/** Translates an X button identifier to the AWT's MouseEvent modifier
|
||||
* mask. As the AWT cannot handle more than 3 buttons those return
|
||||
* <code>0</code>.
|
||||
*/
|
||||
static int buttonToModifier(int button)
|
||||
{
|
||||
switch (button)
|
||||
{
|
||||
case gnu.x11.Input.BUTTON1:
|
||||
return MouseEvent.BUTTON1_DOWN_MASK | MouseEvent.BUTTON1_MASK;
|
||||
case gnu.x11.Input.BUTTON2:
|
||||
return MouseEvent.BUTTON2_DOWN_MASK | MouseEvent.BUTTON2_MASK;
|
||||
case gnu.x11.Input.BUTTON3:
|
||||
return MouseEvent.BUTTON3_DOWN_MASK | MouseEvent.BUTTON3_MASK;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,759 +0,0 @@
|
|||
/* XFontPeer.java -- The font peer for X
|
||||
Copyright (C) 2006 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.awt.peer.x;
|
||||
|
||||
import java.awt.AWTError;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.font.FontRenderContext;
|
||||
import java.awt.font.GlyphVector;
|
||||
import java.awt.font.LineMetrics;
|
||||
import java.awt.font.TextAttribute;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.text.CharacterIterator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import gnu.java.awt.peer.ClasspathFontPeer;
|
||||
import gnu.x11.Display;
|
||||
import gnu.x11.Fontable;
|
||||
|
||||
/**
|
||||
* The bridge from AWT to X fonts.
|
||||
*
|
||||
* @author Roman Kennke (kennke@aicas.com)
|
||||
*/
|
||||
public class XFontPeer
|
||||
extends ClasspathFontPeer
|
||||
{
|
||||
|
||||
/**
|
||||
* The font mapping as specified in the file fonts.properties.
|
||||
*/
|
||||
private static Properties fontProperties;
|
||||
static
|
||||
{
|
||||
fontProperties = new Properties();
|
||||
InputStream in = XFontPeer.class.getResourceAsStream("fonts.properties");
|
||||
try
|
||||
{
|
||||
fontProperties.load(in);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The FontMetrics implementation for XFontPeer.
|
||||
*/
|
||||
private class XFontMetrics
|
||||
extends FontMetrics
|
||||
{
|
||||
/**
|
||||
* The ascent of the font.
|
||||
*/
|
||||
int ascent;
|
||||
|
||||
/**
|
||||
* The descent of the font.
|
||||
*/
|
||||
int descent;
|
||||
|
||||
/**
|
||||
* The maximum of the character advances.
|
||||
*/
|
||||
private int maxAdvance;
|
||||
|
||||
/**
|
||||
* The internal leading.
|
||||
*/
|
||||
int leading;
|
||||
|
||||
/**
|
||||
* Cached string metrics. This caches string metrics locally so that the
|
||||
* server doesn't have to be asked each time.
|
||||
*/
|
||||
private HashMap metricsCache;
|
||||
|
||||
/**
|
||||
* The widths of the characters indexed by the characters themselves.
|
||||
*/
|
||||
private int[] charWidths;
|
||||
|
||||
/**
|
||||
* Creates a new XFontMetrics for the specified font.
|
||||
*
|
||||
* @param font the font
|
||||
*/
|
||||
protected XFontMetrics(Font font)
|
||||
{
|
||||
super(font);
|
||||
metricsCache = new HashMap();
|
||||
Fontable.FontReply info = getXFont().info();
|
||||
ascent = info.font_ascent();
|
||||
descent = info.font_descent();
|
||||
maxAdvance = info.max_bounds().character_width();
|
||||
leading = 0; // TODO: Not provided by X. Possible not needed.
|
||||
|
||||
if (info.min_byte1() == 0 && info.max_byte1() == 0)
|
||||
readCharWidthsLinear(info);
|
||||
else
|
||||
readCharWidthsNonLinear(info);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the character widths when specified in a linear fashion. That is
|
||||
* when the min-byte1 and max-byte2 fields are both zero in the X protocol.
|
||||
*
|
||||
* @param info the font info reply
|
||||
*/
|
||||
private void readCharWidthsLinear(Fontable.FontReply info)
|
||||
{
|
||||
int startIndex = info.min_char_or_byte2();
|
||||
int endIndex = info.max_char_or_byte2();
|
||||
charWidths = new int[endIndex + 1];
|
||||
// All the characters before startIndex are zero width.
|
||||
for (int i = 0; i < startIndex; i++)
|
||||
{
|
||||
charWidths[i] = 0;
|
||||
}
|
||||
// All the other character info is fetched from the font info.
|
||||
int index = startIndex;
|
||||
Iterator charInfos = info.char_infos().iterator();
|
||||
while (charInfos.hasNext())
|
||||
{
|
||||
Fontable.FontReply.CharInfo charInfo =
|
||||
(Fontable.FontReply.CharInfo) charInfos.next();
|
||||
charWidths[index] = charInfo.character_width();
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
private void readCharWidthsNonLinear(Fontable.FontReply info)
|
||||
{
|
||||
// TODO: Implement.
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ascent of the font.
|
||||
*
|
||||
* @return the ascent of the font
|
||||
*/
|
||||
public int getAscent()
|
||||
{
|
||||
return ascent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the descent of the font.
|
||||
*
|
||||
* @return the descent of the font
|
||||
*/
|
||||
public int getDescent()
|
||||
{
|
||||
return descent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the overall height of the font. This is the distance from
|
||||
* baseline to baseline (usually ascent + descent + leading).
|
||||
*
|
||||
* @return the overall height of the font
|
||||
*/
|
||||
public int getHeight()
|
||||
{
|
||||
return ascent + descent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the leading of the font.
|
||||
*
|
||||
* @return the leading of the font
|
||||
*/
|
||||
public int getLeading()
|
||||
{
|
||||
return leading;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum advance for this font.
|
||||
*
|
||||
* @return the maximum advance for this font
|
||||
*/
|
||||
public int getMaxAdvance()
|
||||
{
|
||||
return maxAdvance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the width of the specified character <code>c</code>.
|
||||
*
|
||||
* @param c the character
|
||||
*
|
||||
* @return the width of the character
|
||||
*/
|
||||
public int charWidth(char c)
|
||||
{
|
||||
int width;
|
||||
if (c > charWidths.length)
|
||||
width = charWidths['?'];
|
||||
else
|
||||
width = charWidths[c];
|
||||
return width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the overall width of the specified string.
|
||||
*
|
||||
* @param c the char buffer holding the string
|
||||
* @param offset the starting offset of the string in the buffer
|
||||
* @param length the number of characters in the string buffer
|
||||
*
|
||||
* @return the overall width of the specified string
|
||||
*/
|
||||
public int charsWidth(char[] c, int offset, int length)
|
||||
{
|
||||
int width = 0;
|
||||
if (c.length > 0 && length > 0)
|
||||
{
|
||||
String s = new String(c, offset, length);
|
||||
width = stringWidth(s);
|
||||
}
|
||||
return width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the overall width of the specified string.
|
||||
*
|
||||
* @param s the string
|
||||
*
|
||||
* @return the overall width of the specified string
|
||||
*/
|
||||
public int stringWidth(String s)
|
||||
{
|
||||
int width = 0;
|
||||
if (s.length() > 0)
|
||||
{
|
||||
if (metricsCache.containsKey(s))
|
||||
{
|
||||
width = ((Integer) metricsCache.get(s)).intValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
Fontable.TextExtentReply extents = getXFont().text_extent(s);
|
||||
/*
|
||||
System.err.println("string: '" + s + "' : ");
|
||||
System.err.println("ascent: " + extents.getAscent());
|
||||
System.err.println("descent: " + extents.getDescent());
|
||||
System.err.println("overall ascent: " + extents.getOverallAscent());
|
||||
System.err.println("overall descent: " + extents.getOverallDescent());
|
||||
System.err.println("overall width: " + extents.getOverallWidth());
|
||||
System.err.println("overall left: " + extents.getOverallLeft());
|
||||
System.err.println("overall right: " + extents.getOverallRight());
|
||||
*/
|
||||
width = extents.overall_width(); // + extents.overall_left();
|
||||
//System.err.println("String: " + s + ", width: " + width);
|
||||
metricsCache.put(s, new Integer(width));
|
||||
}
|
||||
}
|
||||
//System.err.print("stringWidth: '" + s + "': ");
|
||||
//System.err.println(width);
|
||||
return width;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The LineMetrics implementation for the XFontPeer.
|
||||
*/
|
||||
private class XLineMetrics
|
||||
extends LineMetrics
|
||||
{
|
||||
|
||||
/**
|
||||
* Returns the ascent of the font.
|
||||
*
|
||||
* @return the ascent of the font
|
||||
*/
|
||||
public float getAscent()
|
||||
{
|
||||
return fontMetrics.ascent;
|
||||
}
|
||||
|
||||
public int getBaselineIndex()
|
||||
{
|
||||
// FIXME: Implement this.
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public float[] getBaselineOffsets()
|
||||
{
|
||||
// FIXME: Implement this.
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the descent of the font.
|
||||
*
|
||||
* @return the descent of the font
|
||||
*/
|
||||
public float getDescent()
|
||||
{
|
||||
return fontMetrics.descent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the overall height of the font. This is the distance from
|
||||
* baseline to baseline (usually ascent + descent + leading).
|
||||
*
|
||||
* @return the overall height of the font
|
||||
*/
|
||||
public float getHeight()
|
||||
{
|
||||
return fontMetrics.ascent + fontMetrics.descent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the leading of the font.
|
||||
*
|
||||
* @return the leading of the font
|
||||
*/
|
||||
public float getLeading()
|
||||
{
|
||||
return fontMetrics.leading;
|
||||
}
|
||||
|
||||
public int getNumChars()
|
||||
{
|
||||
// FIXME: Implement this.
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public float getStrikethroughOffset()
|
||||
{
|
||||
return 0.F; // TODO: Provided by X??
|
||||
}
|
||||
|
||||
public float getStrikethroughThickness()
|
||||
{
|
||||
return 1.F; // TODO: Provided by X??
|
||||
}
|
||||
|
||||
public float getUnderlineOffset()
|
||||
{
|
||||
return 0.F; // TODO: Provided by X??
|
||||
}
|
||||
|
||||
public float getUnderlineThickness()
|
||||
{
|
||||
return 1.F; // TODO: Provided by X??
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The X font.
|
||||
*/
|
||||
private gnu.x11.Font xfont;
|
||||
|
||||
private String name;
|
||||
|
||||
private int style;
|
||||
|
||||
private int size;
|
||||
|
||||
/**
|
||||
* The font metrics for this font.
|
||||
*/
|
||||
XFontMetrics fontMetrics;
|
||||
|
||||
/**
|
||||
* Creates a new XFontPeer for the specified font name, style and size.
|
||||
*
|
||||
* @param name the font name
|
||||
* @param style the font style (bold / italic / normal)
|
||||
* @param size the size of the font
|
||||
*/
|
||||
public XFontPeer(String name, int style, int size)
|
||||
{
|
||||
super(name, style, size);
|
||||
this.name = name;
|
||||
this.style = style;
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new XFontPeer for the specified font name and style
|
||||
* attributes.
|
||||
*
|
||||
* @param name the font name
|
||||
* @param atts the font attributes
|
||||
*/
|
||||
public XFontPeer(String name, Map atts)
|
||||
{
|
||||
super(name, atts);
|
||||
String family = name;
|
||||
if (family == null || family.equals(""))
|
||||
family = (String) atts.get(TextAttribute.FAMILY);
|
||||
if (family == null)
|
||||
family = "SansSerif";
|
||||
|
||||
int size = 12;
|
||||
Float sizeFl = (Float) atts.get(TextAttribute.SIZE);
|
||||
if (sizeFl != null)
|
||||
size = sizeFl.intValue();
|
||||
|
||||
int style = 0;
|
||||
// Detect italic attribute.
|
||||
Float posture = (Float) atts.get(TextAttribute.POSTURE);
|
||||
if (posture != null && !posture.equals(TextAttribute.POSTURE_REGULAR))
|
||||
style |= Font.ITALIC;
|
||||
|
||||
// Detect bold attribute.
|
||||
Float weight = (Float) atts.get(TextAttribute.WEIGHT);
|
||||
if (weight != null && weight.compareTo(TextAttribute.WEIGHT_REGULAR) > 0)
|
||||
style |= Font.BOLD;
|
||||
|
||||
this.name = name;
|
||||
this.style = style;
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the font peer with the specified attributes. This method is
|
||||
* called from both constructors.
|
||||
*
|
||||
* @param name the font name
|
||||
* @param style the font style
|
||||
* @param size the font size
|
||||
*/
|
||||
private void init(String name, int style, int size)
|
||||
{
|
||||
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
GraphicsDevice dev = env.getDefaultScreenDevice();
|
||||
if (dev instanceof XGraphicsDevice)
|
||||
{
|
||||
Display display = ((XGraphicsDevice) dev).getDisplay();
|
||||
String fontDescr = encodeFont(name, style, size);
|
||||
if (XToolkit.DEBUG)
|
||||
System.err.println("XLFD font description: " + fontDescr);
|
||||
xfont = new gnu.x11.Font(display, fontDescr);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new AWTError("Local GraphicsEnvironment is not XWindowGraphicsEnvironment");
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canDisplay(Font font, char c)
|
||||
{
|
||||
// TODO: Implement this.
|
||||
throw new UnsupportedOperationException("Not yet implemented.");
|
||||
}
|
||||
|
||||
public int canDisplayUpTo(Font font, CharacterIterator i, int start, int limit)
|
||||
{
|
||||
// TODO: Implement this.
|
||||
throw new UnsupportedOperationException("Not yet implemented.");
|
||||
}
|
||||
|
||||
public String getSubFamilyName(Font font, Locale locale)
|
||||
{
|
||||
// TODO: Implement this.
|
||||
throw new UnsupportedOperationException("Not yet implemented.");
|
||||
}
|
||||
|
||||
public String getPostScriptName(Font font)
|
||||
{
|
||||
// TODO: Implement this.
|
||||
throw new UnsupportedOperationException("Not yet implemented.");
|
||||
}
|
||||
|
||||
public int getNumGlyphs(Font font)
|
||||
{
|
||||
// TODO: Implement this.
|
||||
throw new UnsupportedOperationException("Not yet implemented.");
|
||||
}
|
||||
|
||||
public int getMissingGlyphCode(Font font)
|
||||
{
|
||||
// TODO: Implement this.
|
||||
throw new UnsupportedOperationException("Not yet implemented.");
|
||||
}
|
||||
|
||||
public byte getBaselineFor(Font font, char c)
|
||||
{
|
||||
// TODO: Implement this.
|
||||
throw new UnsupportedOperationException("Not yet implemented.");
|
||||
}
|
||||
|
||||
public String getGlyphName(Font font, int glyphIndex)
|
||||
{
|
||||
// TODO: Implement this.
|
||||
throw new UnsupportedOperationException("Not yet implemented.");
|
||||
}
|
||||
|
||||
public GlyphVector createGlyphVector(Font font, FontRenderContext frc,
|
||||
CharacterIterator ci)
|
||||
{
|
||||
// TODO: Implement this.
|
||||
throw new UnsupportedOperationException("Not yet implemented.");
|
||||
}
|
||||
|
||||
public GlyphVector createGlyphVector(Font font, FontRenderContext ctx,
|
||||
int[] glyphCodes)
|
||||
{
|
||||
// TODO: Implement this.
|
||||
throw new UnsupportedOperationException("Not yet implemented.");
|
||||
}
|
||||
|
||||
public GlyphVector layoutGlyphVector(Font font, FontRenderContext frc,
|
||||
char[] chars, int start, int limit,
|
||||
int flags)
|
||||
{
|
||||
// TODO: Implement this.
|
||||
throw new UnsupportedOperationException("Not yet implemented.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the font metrics for the specified font.
|
||||
*
|
||||
* @param font the font for which to fetch the font metrics
|
||||
*
|
||||
* @return the font metrics for the specified font
|
||||
*/
|
||||
public FontMetrics getFontMetrics(Font font)
|
||||
{
|
||||
if (font.getPeer() != this)
|
||||
throw new AWTError("The specified font has a different peer than this");
|
||||
|
||||
if (fontMetrics == null)
|
||||
fontMetrics = new XFontMetrics(font);
|
||||
return fontMetrics;
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees the font in the X server.
|
||||
*/
|
||||
protected void finalize()
|
||||
{
|
||||
if (xfont != null)
|
||||
xfont.close();
|
||||
}
|
||||
|
||||
public boolean hasUniformLineMetrics(Font font)
|
||||
{
|
||||
// TODO: Implement this.
|
||||
throw new UnsupportedOperationException("Not yet implemented.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the line metrics for this font and the specified string and
|
||||
* font render context.
|
||||
*/
|
||||
public LineMetrics getLineMetrics(Font font, CharacterIterator ci, int begin,
|
||||
int limit, FontRenderContext rc)
|
||||
{
|
||||
return new XLineMetrics();
|
||||
}
|
||||
|
||||
public Rectangle2D getMaxCharBounds(Font font, FontRenderContext rc)
|
||||
{
|
||||
// TODO: Implement this.
|
||||
throw new UnsupportedOperationException("Not yet implemented.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a font name + style + size specification into a X logical font
|
||||
* description (XLFD) as described here:
|
||||
*
|
||||
* http://www.meretrx.com/e93/docs/xlfd.html
|
||||
*
|
||||
* This is implemented to look up the font description in the
|
||||
* fonts.properties of this package.
|
||||
*
|
||||
* @param name the font name
|
||||
* @param atts the text attributes
|
||||
*
|
||||
* @return the encoded font description
|
||||
*/
|
||||
static String encodeFont(String name, Map atts)
|
||||
{
|
||||
String family = name;
|
||||
if (family == null || family.equals(""))
|
||||
family = (String) atts.get(TextAttribute.FAMILY);
|
||||
if (family == null)
|
||||
family = "SansSerif";
|
||||
|
||||
int size = 12;
|
||||
Float sizeFl = (Float) atts.get(TextAttribute.SIZE);
|
||||
if (sizeFl != null)
|
||||
size = sizeFl.intValue();
|
||||
|
||||
int style = 0;
|
||||
// Detect italic attribute.
|
||||
Float posture = (Float) atts.get(TextAttribute.POSTURE);
|
||||
if (posture != null && !posture.equals(TextAttribute.POSTURE_REGULAR))
|
||||
style |= Font.ITALIC;
|
||||
|
||||
// Detect bold attribute.
|
||||
Float weight = (Float) atts.get(TextAttribute.WEIGHT);
|
||||
if (weight != null && weight.compareTo(TextAttribute.WEIGHT_REGULAR) > 0)
|
||||
style |= Font.BOLD;
|
||||
|
||||
return encodeFont(name, style, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a font name + style + size specification into a X logical font
|
||||
* description (XLFD) as described here:
|
||||
*
|
||||
* http://www.meretrx.com/e93/docs/xlfd.html
|
||||
*
|
||||
* This is implemented to look up the font description in the
|
||||
* fonts.properties of this package.
|
||||
*
|
||||
* @param name the font name
|
||||
* @param style the font style
|
||||
* @param size the font size
|
||||
*
|
||||
* @return the encoded font description
|
||||
*/
|
||||
static String encodeFont(String name, int style, int size)
|
||||
{
|
||||
StringBuilder key = new StringBuilder();
|
||||
key.append(validName(name));
|
||||
key.append('.');
|
||||
switch (style)
|
||||
{
|
||||
case Font.BOLD:
|
||||
key.append("bold");
|
||||
break;
|
||||
case Font.ITALIC:
|
||||
key.append("italic");
|
||||
break;
|
||||
case (Font.BOLD | Font.ITALIC):
|
||||
key.append("bolditalic");
|
||||
break;
|
||||
case Font.PLAIN:
|
||||
default:
|
||||
key.append("plain");
|
||||
|
||||
}
|
||||
|
||||
String protoType = fontProperties.getProperty(key.toString());
|
||||
int s = validSize(size);
|
||||
return protoType.replaceFirst("%d", String.valueOf(s * 10));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the specified font name for a valid font name. If the font name
|
||||
* is not known, then this returns 'sansserif' as fallback.
|
||||
*
|
||||
* @param name the font name to check
|
||||
*
|
||||
* @return a valid font name
|
||||
*/
|
||||
static String validName(String name)
|
||||
{
|
||||
String retVal;
|
||||
if (name.equalsIgnoreCase("sansserif")
|
||||
|| name.equalsIgnoreCase("serif")
|
||||
|| name.equalsIgnoreCase("monospaced")
|
||||
|| name.equalsIgnoreCase("dialog")
|
||||
|| name.equalsIgnoreCase("dialoginput"))
|
||||
{
|
||||
retVal = name.toLowerCase();
|
||||
}
|
||||
else
|
||||
{
|
||||
retVal = "sansserif";
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates an arbitrary point size to a size that is typically available
|
||||
* on an X server. These are the sizes 8, 10, 12, 14, 18 and 24.
|
||||
*
|
||||
* @param size the queried size
|
||||
* @return the real available size
|
||||
*/
|
||||
private static final int validSize(int size)
|
||||
{
|
||||
int val;
|
||||
if (size <= 9)
|
||||
val = 8;
|
||||
else if (size <= 11)
|
||||
val = 10;
|
||||
else if (size <= 13)
|
||||
val = 12;
|
||||
else if (size <= 17)
|
||||
val = 14;
|
||||
else if (size <= 23)
|
||||
val = 18;
|
||||
else
|
||||
val = 24;
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the X Font reference. This lazily loads the font when first
|
||||
* requested.
|
||||
*
|
||||
* @return the X Font reference
|
||||
*/
|
||||
gnu.x11.Font getXFont()
|
||||
{
|
||||
if (xfont == null)
|
||||
{
|
||||
init(name, style, size);
|
||||
}
|
||||
return xfont;
|
||||
}
|
||||
}
|
|
@ -42,17 +42,21 @@ import java.awt.FontMetrics;
|
|||
import java.awt.font.FontRenderContext;
|
||||
import java.awt.font.GlyphVector;
|
||||
import java.awt.font.LineMetrics;
|
||||
import java.awt.font.TextAttribute;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.text.CharacterIterator;
|
||||
import java.text.StringCharacterIterator;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import gnu.java.awt.font.FontDelegate;
|
||||
import gnu.java.awt.font.FontFactory;
|
||||
|
@ -62,11 +66,30 @@ public class XFontPeer2
|
|||
extends ClasspathFontPeer
|
||||
{
|
||||
|
||||
/**
|
||||
* The font mapping as specified in the file fonts.properties.
|
||||
*/
|
||||
private static Properties fontProperties;
|
||||
static
|
||||
{
|
||||
fontProperties = new Properties();
|
||||
InputStream in = XFontPeer2.class.getResourceAsStream("fonts.properties");
|
||||
try
|
||||
{
|
||||
fontProperties.load(in);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private class XLineMetrics
|
||||
extends LineMetrics
|
||||
{
|
||||
|
||||
private Font font;
|
||||
private GlyphVector glyphVector;
|
||||
// private CharacterIterator characterIterator;
|
||||
// private int begin;
|
||||
// private int limit;
|
||||
|
@ -79,6 +102,8 @@ public class XFontPeer2
|
|||
// begin = b;
|
||||
// limit = l;
|
||||
fontRenderContext = rc;
|
||||
glyphVector = fontDelegate.createGlyphVector(font, fontRenderContext,
|
||||
ci);
|
||||
}
|
||||
|
||||
public float getAscent()
|
||||
|
@ -86,7 +111,7 @@ public class XFontPeer2
|
|||
return fontDelegate.getAscent(font.getSize(), fontRenderContext.getTransform(),
|
||||
fontRenderContext.isAntiAliased(),
|
||||
fontRenderContext.usesFractionalMetrics(), true);
|
||||
}
|
||||
}
|
||||
|
||||
public int getBaselineIndex()
|
||||
{
|
||||
|
@ -102,21 +127,18 @@ public class XFontPeer2
|
|||
|
||||
public float getDescent()
|
||||
{
|
||||
return (int) fontDelegate.getDescent(font.getSize(),
|
||||
new AffineTransform(), false, false,
|
||||
false);
|
||||
return (int) fontDelegate.getDescent(font.getSize(), IDENDITY, false,
|
||||
false, false);
|
||||
}
|
||||
|
||||
public float getHeight()
|
||||
{
|
||||
// FIXME: Implement this.
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
return (float) glyphVector.getLogicalBounds().getHeight();
|
||||
}
|
||||
|
||||
public float getLeading()
|
||||
{
|
||||
// FIXME: Implement this.
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
return getHeight() - getAscent() - getDescent();
|
||||
}
|
||||
|
||||
public int getNumChars()
|
||||
|
@ -150,6 +172,11 @@ public class XFontPeer2
|
|||
private class XFontMetrics
|
||||
extends FontMetrics
|
||||
{
|
||||
/**
|
||||
* A cached point instance, to be used in #charWidth().
|
||||
*/
|
||||
private Point2D cachedPoint = new Point2D.Double();
|
||||
|
||||
XFontMetrics(Font f)
|
||||
{
|
||||
super(f);
|
||||
|
@ -157,22 +184,20 @@ public class XFontPeer2
|
|||
|
||||
public int getAscent()
|
||||
{
|
||||
return (int) fontDelegate.getAscent(getFont().getSize(),
|
||||
new AffineTransform(), false, false,
|
||||
false);
|
||||
return (int) fontDelegate.getAscent(getFont().getSize(), IDENDITY,
|
||||
false, false, false);
|
||||
}
|
||||
|
||||
public int getDescent()
|
||||
{
|
||||
return (int) fontDelegate.getDescent(getFont().getSize(),
|
||||
new AffineTransform(), false, false,
|
||||
false);
|
||||
return (int) fontDelegate.getDescent(getFont().getSize(), IDENDITY,
|
||||
false, false, false);
|
||||
}
|
||||
|
||||
public int getHeight()
|
||||
{
|
||||
GlyphVector gv = fontDelegate.createGlyphVector(getFont(),
|
||||
new FontRenderContext(new AffineTransform(), false, false),
|
||||
new FontRenderContext(IDENDITY, false, false),
|
||||
new StringCharacterIterator("m"));
|
||||
Rectangle2D b = gv.getVisualBounds();
|
||||
return (int) b.getHeight();
|
||||
|
@ -180,8 +205,9 @@ public class XFontPeer2
|
|||
|
||||
public int charWidth(char c)
|
||||
{
|
||||
Point2D advance = new Point2D.Double();
|
||||
fontDelegate.getAdvance(c, getFont().getSize(), new AffineTransform(),
|
||||
int code = fontDelegate.getGlyphIndex(c);
|
||||
Point2D advance = cachedPoint;
|
||||
fontDelegate.getAdvance(code, font.getSize2D(), IDENDITY,
|
||||
false, false, true, advance);
|
||||
return (int) advance.getX();
|
||||
}
|
||||
|
@ -194,13 +220,18 @@ public class XFontPeer2
|
|||
public int stringWidth(String s)
|
||||
{
|
||||
GlyphVector gv = fontDelegate.createGlyphVector(getFont(),
|
||||
new FontRenderContext(new AffineTransform(), false, false),
|
||||
new FontRenderContext(IDENDITY, false, false),
|
||||
new StringCharacterIterator(s));
|
||||
Rectangle2D b = gv.getVisualBounds();
|
||||
return (int) b.getWidth();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The indendity transform, to be used in several methods.
|
||||
*/
|
||||
private static final AffineTransform IDENDITY = new AffineTransform();
|
||||
|
||||
private FontDelegate fontDelegate;
|
||||
|
||||
XFontPeer2(String name, int style, int size)
|
||||
|
@ -208,7 +239,7 @@ public class XFontPeer2
|
|||
super(name, style, size);
|
||||
try
|
||||
{
|
||||
File fontfile = new File("/usr/share/fonts/truetype/ttf-bitstream-vera/Vera.ttf");
|
||||
File fontfile = new File("/usr/share/fonts/truetype/freefont/FreeSans.ttf");
|
||||
FileInputStream in = new FileInputStream(fontfile);
|
||||
FileChannel ch = in.getChannel();
|
||||
ByteBuffer buffer = ch.map(FileChannel.MapMode.READ_ONLY, 0,
|
||||
|
@ -239,7 +270,7 @@ public class XFontPeer2
|
|||
}
|
||||
}
|
||||
|
||||
public boolean canDisplay(Font font, char c)
|
||||
public boolean canDisplay(Font font, int c)
|
||||
{
|
||||
// FIXME: Implement this.
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
|
@ -326,4 +357,112 @@ public class XFontPeer2
|
|||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a font name + style + size specification into a X logical font
|
||||
* description (XLFD) as described here:
|
||||
*
|
||||
* http://www.meretrx.com/e93/docs/xlfd.html
|
||||
*
|
||||
* This is implemented to look up the font description in the
|
||||
* fonts.properties of this package.
|
||||
*
|
||||
* @param name the font name
|
||||
* @param atts the text attributes
|
||||
*
|
||||
* @return the encoded font description
|
||||
*/
|
||||
static String encodeFont(String name, Map atts)
|
||||
{
|
||||
String family = name;
|
||||
if (family == null || family.equals(""))
|
||||
family = (String) atts.get(TextAttribute.FAMILY);
|
||||
if (family == null)
|
||||
family = "SansSerif";
|
||||
|
||||
int size = 12;
|
||||
Float sizeFl = (Float) atts.get(TextAttribute.SIZE);
|
||||
if (sizeFl != null)
|
||||
size = sizeFl.intValue();
|
||||
|
||||
int style = 0;
|
||||
// Detect italic attribute.
|
||||
Float posture = (Float) atts.get(TextAttribute.POSTURE);
|
||||
if (posture != null && !posture.equals(TextAttribute.POSTURE_REGULAR))
|
||||
style |= Font.ITALIC;
|
||||
|
||||
// Detect bold attribute.
|
||||
Float weight = (Float) atts.get(TextAttribute.WEIGHT);
|
||||
if (weight != null && weight.compareTo(TextAttribute.WEIGHT_REGULAR) > 0)
|
||||
style |= Font.BOLD;
|
||||
|
||||
return encodeFont(name, style, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a font name + style + size specification into a X logical font
|
||||
* description (XLFD) as described here:
|
||||
*
|
||||
* http://www.meretrx.com/e93/docs/xlfd.html
|
||||
*
|
||||
* This is implemented to look up the font description in the
|
||||
* fonts.properties of this package.
|
||||
*
|
||||
* @param name the font name
|
||||
* @param style the font style
|
||||
* @param size the font size
|
||||
*
|
||||
* @return the encoded font description
|
||||
*/
|
||||
static String encodeFont(String name, int style, int size)
|
||||
{
|
||||
StringBuilder key = new StringBuilder();
|
||||
key.append(validName(name));
|
||||
key.append('.');
|
||||
switch (style)
|
||||
{
|
||||
case Font.BOLD:
|
||||
key.append("bold");
|
||||
break;
|
||||
case Font.ITALIC:
|
||||
key.append("italic");
|
||||
break;
|
||||
case (Font.BOLD | Font.ITALIC):
|
||||
key.append("bolditalic");
|
||||
break;
|
||||
case Font.PLAIN:
|
||||
default:
|
||||
key.append("plain");
|
||||
|
||||
}
|
||||
|
||||
String protoType = fontProperties.getProperty(key.toString());
|
||||
int s = size;
|
||||
return protoType.replaceFirst("%d", String.valueOf(s * 10));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the specified font name for a valid font name. If the font name
|
||||
* is not known, then this returns 'sansserif' as fallback.
|
||||
*
|
||||
* @param name the font name to check
|
||||
*
|
||||
* @return a valid font name
|
||||
*/
|
||||
static String validName(String name)
|
||||
{
|
||||
String retVal;
|
||||
if (name.equalsIgnoreCase("sansserif")
|
||||
|| name.equalsIgnoreCase("serif")
|
||||
|| name.equalsIgnoreCase("monospaced")
|
||||
|| name.equalsIgnoreCase("dialog")
|
||||
|| name.equalsIgnoreCase("dialoginput"))
|
||||
{
|
||||
retVal = name.toLowerCase();
|
||||
}
|
||||
else
|
||||
{
|
||||
retVal = "sansserif";
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -137,4 +137,10 @@ public class XFramePeer
|
|||
throw new UnsupportedOperationException("Not yet implemented.");
|
||||
}
|
||||
|
||||
public Rectangle getBoundsPrivate()
|
||||
{
|
||||
// TODO: Implement this properly.
|
||||
throw new InternalError("Not yet implemented");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,792 +0,0 @@
|
|||
/* XGraphics.java -- The Graphics implementation for X
|
||||
Copyright (C) 2006 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
|
||||
package gnu.java.awt.peer.x;
|
||||
|
||||
import gnu.x11.Colormap;
|
||||
import gnu.x11.Data;
|
||||
import gnu.x11.Display;
|
||||
import gnu.x11.Drawable;
|
||||
import gnu.x11.GC;
|
||||
import gnu.x11.Pixmap;
|
||||
import gnu.x11.Point;
|
||||
import gnu.x11.image.ZPixmap;
|
||||
|
||||
import java.awt.AWTError;
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Image;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Shape;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.Transparency;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.ImageObserver;
|
||||
import java.awt.image.ImageProducer;
|
||||
import java.text.AttributedCharacterIterator;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class XGraphics
|
||||
extends Graphics
|
||||
implements Cloneable
|
||||
{
|
||||
|
||||
/**
|
||||
* The X Drawable to draw on.
|
||||
*/
|
||||
private Drawable xdrawable;
|
||||
|
||||
/**
|
||||
* The X graphics context (GC).
|
||||
*/
|
||||
private GC xgc;
|
||||
|
||||
/**
|
||||
* The current translation.
|
||||
*/
|
||||
private int translateX;
|
||||
private int translateY;
|
||||
|
||||
/**
|
||||
* The current clip. Possibly null.
|
||||
*/
|
||||
private Rectangle clip;
|
||||
|
||||
/**
|
||||
* The current font, possibly null.
|
||||
*/
|
||||
private Font font;
|
||||
|
||||
/**
|
||||
* The current foreground color, possibly null.
|
||||
*/
|
||||
private Color foreground;
|
||||
|
||||
/**
|
||||
* Indicates if this object has been disposed.
|
||||
*/
|
||||
private boolean disposed = false;
|
||||
|
||||
// TODO: Workaround for limitation in current Escher.
|
||||
private Pixmap.Format pixmapFormat;
|
||||
private int imageByteOrder;
|
||||
private int pixelByteCount;
|
||||
|
||||
/**
|
||||
* Creates a new XGraphics on the specified X Drawable.
|
||||
*
|
||||
* @param d the X Drawable for which we create the Graphics
|
||||
*/
|
||||
XGraphics(Drawable d)
|
||||
{
|
||||
xdrawable = d;
|
||||
xgc = new GC(d);
|
||||
translateX = 0;
|
||||
translateY = 0;
|
||||
clip = new Rectangle(0, 0, d.width, d.height);
|
||||
|
||||
Display display = xdrawable.display;
|
||||
pixmapFormat = display.default_pixmap_format;
|
||||
imageByteOrder = display.image_byte_order;
|
||||
pixelByteCount = pixmapFormat.bits_per_pixel () / 8;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an exact copy of this graphics context.
|
||||
*
|
||||
* @return an exact copy of this graphics context
|
||||
*/
|
||||
public Graphics create()
|
||||
{
|
||||
XGraphics copy = (XGraphics) clone();
|
||||
return copy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates the origin by (x, y).
|
||||
*/
|
||||
public void translate(int x, int y)
|
||||
{
|
||||
translateX += x;
|
||||
translateY += y;
|
||||
if (clip != null)
|
||||
{
|
||||
clip.x -= x;
|
||||
clip.y -= y;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current foreground color, possibly <code>null</code>.
|
||||
*
|
||||
* @return the current foreground color, possibly <code>null</code>
|
||||
*/
|
||||
public Color getColor()
|
||||
{
|
||||
return foreground;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current foreground color. A <code>null</code> value doesn't
|
||||
* change the current setting.
|
||||
*
|
||||
* @param c the foreground color to set
|
||||
*/
|
||||
public void setColor(Color c)
|
||||
{
|
||||
if (c != null)
|
||||
{
|
||||
XToolkit tk = (XToolkit) Toolkit.getDefaultToolkit();
|
||||
HashMap colorMap = tk.colorMap;
|
||||
gnu.x11.Color col = (gnu.x11.Color) colorMap.get(c);
|
||||
if (col == null)
|
||||
{
|
||||
Colormap map = xdrawable.display.default_colormap;
|
||||
col = map.alloc_color (c.getRed() * 256,
|
||||
c.getGreen() * 256,
|
||||
c.getBlue() * 256);
|
||||
colorMap.put(c, col);
|
||||
}
|
||||
xgc.set_foreground(col);
|
||||
foreground = c;
|
||||
}
|
||||
}
|
||||
|
||||
public void setPaintMode()
|
||||
{
|
||||
// FIXME: Implement this.
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
}
|
||||
|
||||
public void setXORMode(Color color)
|
||||
{
|
||||
// FIXME: Implement this.
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current font, possibly <code>null</code>.
|
||||
*
|
||||
* @return the current font, possibly <code>null</code>
|
||||
*/
|
||||
public Font getFont()
|
||||
{
|
||||
return font;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the font on the graphics context. A <code>null</code> value doesn't
|
||||
* change the current setting.
|
||||
*
|
||||
* @param f the font to set
|
||||
*/
|
||||
public void setFont(Font f)
|
||||
{
|
||||
if (f != null)
|
||||
{
|
||||
XFontPeer xFontPeer = (XFontPeer) f.getPeer();
|
||||
xgc.set_font(xFontPeer.getXFont());
|
||||
font = f;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the font metrics for the specified font.
|
||||
*
|
||||
* @param font the font for which we want the font metrics
|
||||
*
|
||||
* @return the font metrics for the specified font
|
||||
*/
|
||||
public FontMetrics getFontMetrics(Font font)
|
||||
{
|
||||
if (font == null)
|
||||
{
|
||||
if (this.font == null)
|
||||
setFont(new Font("Dialog", Font.PLAIN, 12));
|
||||
font = this.font;
|
||||
}
|
||||
XFontPeer xFontPeer = (XFontPeer) font.getPeer();
|
||||
return xFontPeer.getFontMetrics(font);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the bounds of the current clip.
|
||||
*
|
||||
* @return the bounds of the current clip
|
||||
*/
|
||||
public Rectangle getClipBounds()
|
||||
{
|
||||
return clip != null ? clip.getBounds() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clips the current clip with the specified clip.
|
||||
*/
|
||||
public void clipRect(int x, int y, int width, int height)
|
||||
{
|
||||
if (clip == null)
|
||||
{
|
||||
clip = new Rectangle(x, y, width, height);
|
||||
}
|
||||
else
|
||||
{
|
||||
computeIntersection(x, y, width, height, clip);
|
||||
}
|
||||
// Update the X clip setting.
|
||||
setXClip(clip.x, clip.y, clip.width, clip.height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> when the specified rectangle intersects with
|
||||
* the current clip, <code>false</code> otherwise. This is overridden to
|
||||
* avoid unnecessary creation of Rectangles via getBounds().
|
||||
*
|
||||
* @param x the x coordinate of the rectangle
|
||||
* @param y the y coordinate of the rectangle
|
||||
* @param w the width of the rectangle
|
||||
* @param h the height of the rectangle
|
||||
*
|
||||
* @return <code>true</code> when the specified rectangle intersects with
|
||||
* the current clip, <code>false</code> otherwise
|
||||
*/
|
||||
public boolean hitClip(int x, int y, int w, int h)
|
||||
{
|
||||
boolean hit;
|
||||
if (clip == null)
|
||||
{
|
||||
hit = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// It's easier to determine if the rectangle lies outside the clip,
|
||||
// so we determine that and reverse the result (if it's not completely
|
||||
// outside, it most likely hits the clip rectangle).
|
||||
int x2 = x + w;
|
||||
int y2 = y + h;
|
||||
int clipX2 = clip.x + clip.width;
|
||||
int clipY2 = clip.y + clip.height;
|
||||
boolean outside = (x < clip.x && x2 < clip.x) // Left.
|
||||
|| (x > clipX2 && x2 > clipX2) // Right.
|
||||
|| (y < clip.y && y2 < clip.y) // Top.
|
||||
|| (y > clipY2 && y2 > clipY2); // Bottom.
|
||||
hit = ! outside;
|
||||
}
|
||||
return hit;
|
||||
}
|
||||
|
||||
public void setClip(int x, int y, int width, int height)
|
||||
{
|
||||
if (clip != null)
|
||||
clip.setBounds(x, y, width, height);
|
||||
else
|
||||
clip = new Rectangle(x, y, width, height);
|
||||
setXClip(clip.x, clip.y, clip.width, clip.height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the clip on the X server GC. The coordinates are not yet translated,
|
||||
* this will be performed by the X server.
|
||||
*
|
||||
* @param x the clip, X coordinate
|
||||
* @param y the clip, Y coordinate
|
||||
* @param w the clip, width
|
||||
* @param h the clip, height
|
||||
*/
|
||||
private void setXClip(int x, int y, int w, int h)
|
||||
{
|
||||
gnu.x11.Rectangle[] clipRects = new gnu.x11.Rectangle[] {
|
||||
new gnu.x11.Rectangle(x, y, w, h) };
|
||||
xgc.set_clip_rectangles(translateX, translateY, clipRects, GC.YX_BANDED);
|
||||
}
|
||||
|
||||
public Shape getClip()
|
||||
{
|
||||
// Return a copy here, so nobody can trash our clip.
|
||||
return clip == null ? null : clip.getBounds();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current clip.
|
||||
*
|
||||
* @param c the clip to set
|
||||
*/
|
||||
public void setClip(Shape c)
|
||||
{
|
||||
if (c != null)
|
||||
{
|
||||
Rectangle b;
|
||||
if (c instanceof Rectangle)
|
||||
{
|
||||
b = (Rectangle) c;
|
||||
}
|
||||
else
|
||||
{
|
||||
b = c.getBounds();
|
||||
}
|
||||
clip.setBounds(b);
|
||||
setXClip(b.x, b.y, b.width, b.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
clip.setBounds(0, 0, xdrawable.width, xdrawable.height);
|
||||
setXClip(0, 0, xdrawable.width, xdrawable.height);
|
||||
}
|
||||
}
|
||||
|
||||
public void copyArea(int x, int y, int width, int height, int dx, int dy)
|
||||
{
|
||||
// Clip and translate src rectangle.
|
||||
int srcX = Math.min(Math.max(x, clip.x), clip.x + clip.width)
|
||||
+ translateX;
|
||||
int srcY = Math.min(Math.max(y, clip.y), clip.y + clip.height)
|
||||
+ translateY;
|
||||
int srcWidth = Math.min(Math.max(x + width, clip.x),
|
||||
clip.x + clip.width) - x;
|
||||
int srcHeight = Math.min(Math.max(y + height, clip.y),
|
||||
clip.y + clip.height) - y;
|
||||
xdrawable.copy_area(xdrawable, xgc, srcX, srcY, srcWidth, srcHeight,
|
||||
srcX + dx, srcY + dy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws a line from point (x1, y1) to point (x2, y2).
|
||||
*/
|
||||
public void drawLine(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
//System.err.println("drawLine: " + (x1 + translateX) + ", " + ( y1 + translateY) + ", " + (x2 + translateX) + ", " + (y2 + translateY) + " on: " + xdrawable);
|
||||
xdrawable.line(xgc, x1 + translateX, y1 + translateY,
|
||||
x2 + translateX, y2 + translateY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills the specified rectangle.
|
||||
*/
|
||||
public void fillRect(int x, int y, int width, int height)
|
||||
{
|
||||
xdrawable.rectangle(xgc, x + translateX, y + translateY,
|
||||
width, height, true);
|
||||
}
|
||||
|
||||
public void clearRect(int x, int y, int width, int height)
|
||||
{
|
||||
xgc.set_foreground(Color.WHITE.getRGB());
|
||||
xdrawable.rectangle(xgc, x, y, width, height, true);
|
||||
if (foreground != null)
|
||||
xgc.set_foreground(foreground.getRGB());
|
||||
}
|
||||
|
||||
public void drawRoundRect(int x, int y, int width, int height, int arcWidth,
|
||||
int arcHeight)
|
||||
{
|
||||
// Draw 4 lines.
|
||||
int arcRadiusX = arcWidth / 2;
|
||||
int arcRadiusY = arcHeight / 2;
|
||||
drawLine(x + arcRadiusX, y, x + width - arcRadiusX, y);
|
||||
drawLine(x, y + arcRadiusY, x, y + height - arcRadiusY);
|
||||
drawLine(x + arcRadiusX, y + height, x + width - arcRadiusX, y + height);
|
||||
drawLine(x + width, y + arcRadiusY, x + width, y + height - arcRadiusY);
|
||||
|
||||
// Draw the 4 arcs at the corners.
|
||||
// Upper left.
|
||||
drawArc(x, y, arcWidth, arcHeight, 90, 90);
|
||||
// Lower left.
|
||||
drawArc(x, y + height - arcHeight, arcWidth, arcHeight, 180, 90);
|
||||
// Upper right.
|
||||
drawArc(x + width - arcWidth, y, arcWidth, arcHeight, 0, 90);
|
||||
// Lower right.
|
||||
drawArc(x + width - arcWidth, y + height - arcHeight, arcWidth, arcHeight,
|
||||
270, 90);
|
||||
}
|
||||
|
||||
public void fillRoundRect(int x, int y, int width, int height, int arcWidth,
|
||||
int arcHeight)
|
||||
{
|
||||
// Fill the 3 rectangles that make up the inner area.
|
||||
int arcRadiusX = arcWidth / 2;
|
||||
int arcRadiusY = arcHeight / 2;
|
||||
// Left.
|
||||
fillRect(x, y + arcRadiusY, arcRadiusX, height - arcHeight);
|
||||
// Middle.
|
||||
fillRect(x + arcRadiusX, y, width - arcWidth, height);
|
||||
// Right.
|
||||
fillRect(x + width - arcRadiusX, y + arcRadiusY, arcRadiusX,
|
||||
height - arcHeight);
|
||||
|
||||
// Fill the 4 arcs in the corners.
|
||||
// Upper left.
|
||||
fillArc(x, y, arcWidth, arcHeight, 90, 90);
|
||||
// Lower left.
|
||||
fillArc(x, y + height - arcHeight, arcWidth, arcHeight, 180, 90);
|
||||
// Upper right.
|
||||
fillArc(x + width - arcWidth, y, arcWidth, arcHeight, 0, 90);
|
||||
// Lower right.
|
||||
fillArc(x + width - arcWidth, y + height - arcHeight, arcWidth, arcHeight,
|
||||
270, 90);
|
||||
}
|
||||
|
||||
public void drawOval(int x, int y, int width, int height)
|
||||
{
|
||||
xdrawable.arc(xgc, x, y, width, height, 0, 360 * 64, false);
|
||||
}
|
||||
|
||||
public void fillOval(int x, int y, int width, int height)
|
||||
{
|
||||
xdrawable.arc(xgc, x, y, width, height, 0, 360 * 64, true);
|
||||
}
|
||||
|
||||
public void drawArc(int x, int y, int width, int height, int arcStart,
|
||||
int arcAngle)
|
||||
{
|
||||
xdrawable.arc(xgc, x, y, width, height, arcStart * 64, arcAngle * 64, false);
|
||||
}
|
||||
|
||||
public void fillArc(int x, int y, int width, int height, int arcStart,
|
||||
int arcAngle)
|
||||
{
|
||||
xdrawable.arc(xgc, x, y, width, height, arcStart * 64, arcAngle * 64, true);
|
||||
}
|
||||
|
||||
public void drawPolyline(int[] xPoints, int[] yPoints, int npoints)
|
||||
{
|
||||
int numPoints = Math.min(xPoints.length, yPoints.length);
|
||||
Point[] points = new Point[numPoints];
|
||||
// FIXME: Improve Escher API to accept arrays to avoid creation
|
||||
// of many Point objects.
|
||||
for (int i = 0; i < numPoints; i++)
|
||||
points[i] = new Point(xPoints[i], yPoints[i]);
|
||||
xdrawable.poly_line(xgc, points, Drawable.ORIGIN);
|
||||
}
|
||||
|
||||
public void drawPolygon(int[] xPoints, int[] yPoints, int npoints)
|
||||
{
|
||||
int numPoints = Math.min(xPoints.length, yPoints.length);
|
||||
Point[] points = new Point[numPoints];
|
||||
// FIXME: Improve Escher API to accept arrays to avoid creation
|
||||
// of many Point objects.
|
||||
for (int i = 0; i < numPoints; i++)
|
||||
points[i] = new Point(xPoints[i], yPoints[i]);
|
||||
xdrawable.poly_line(xgc, points, Drawable.ORIGIN);
|
||||
}
|
||||
|
||||
public void fillPolygon(int[] xPoints, int[] yPoints, int npoints)
|
||||
{
|
||||
int numPoints = Math.min(xPoints.length, yPoints.length);
|
||||
Point[] points = new Point[numPoints];
|
||||
// FIXME: Improve Escher API to accept arrays to avoid creation
|
||||
// of many Point objects.
|
||||
for (int i = 0; i < numPoints; i++)
|
||||
points[i] = new Point(xPoints[i], yPoints[i]);
|
||||
xdrawable.fill_poly(xgc, points, Drawable.COMPLEX, Drawable.ORIGIN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws the specified string at (x, y).
|
||||
*/
|
||||
public void drawString(String string, int x, int y)
|
||||
{
|
||||
if (disposed)
|
||||
throw new AWTError("XGraphics already disposed");
|
||||
|
||||
xdrawable.text(xgc, x + translateX, y + translateY, string);
|
||||
}
|
||||
|
||||
public void drawString(AttributedCharacterIterator ci, int x, int y)
|
||||
{
|
||||
// FIXME: Implement this.
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws the specified image on the drawable at position (x,y).
|
||||
*/
|
||||
public boolean drawImage(Image image, int x, int y, ImageObserver observer)
|
||||
{
|
||||
if (image instanceof XImage)
|
||||
{
|
||||
XImage xim = (XImage) image;
|
||||
Pixmap pm = xim.pixmap;
|
||||
xdrawable.copy_area(pm, xgc, 0, 0, pm.width, pm.height,
|
||||
x + translateX, y + translateY);
|
||||
}
|
||||
else if (image instanceof BufferedImage
|
||||
&& ((BufferedImage) image).getTransparency() != Transparency.OPAQUE)
|
||||
{
|
||||
BufferedImage bi = (BufferedImage) image;
|
||||
int width = bi.getWidth();
|
||||
int height = bi.getHeight();
|
||||
Data img = xdrawable.image(x + translateX, y + translateY,
|
||||
width, height, 0xFFFFFFFF, 2);
|
||||
|
||||
// Compute line byte count.
|
||||
int lineBitCount = width * pixmapFormat.bits_per_pixel ();
|
||||
int rem = lineBitCount % pixmapFormat.scanline_pad ();
|
||||
int linePadCount = lineBitCount / pixmapFormat.scanline_pad ()
|
||||
+ (rem == 0 ? 0 : 1);
|
||||
int lineByteCount = linePadCount * pixmapFormat.scanline_pad () / 8;
|
||||
|
||||
// Composite source and destination pixel data.
|
||||
int[] trgb = new int[3]; // The device rgb pixels.
|
||||
for (int yy = 0; yy < height; yy++)
|
||||
{
|
||||
for (int xx = 0; xx < width; xx++)
|
||||
{
|
||||
getRGB(xx, yy, img, trgb, lineByteCount);
|
||||
int srgb = bi.getRGB(xx, yy);
|
||||
float alpha = ((srgb >> 24) & 0xff) / 256F;
|
||||
float tAlpha = 1.F - alpha;
|
||||
int red = (srgb >> 16) & 0xFF;
|
||||
int green = (srgb >> 8) & 0xFF;
|
||||
int blue = (srgb) & 0xFF;
|
||||
trgb[0] = (int) (trgb[0] * tAlpha + red * alpha);
|
||||
trgb[1] = (int) (trgb[1] * tAlpha + green * alpha);
|
||||
trgb[2] = (int) (trgb[2] * tAlpha + blue * alpha);
|
||||
setRGB(xx, yy, img, trgb, lineByteCount);
|
||||
}
|
||||
}
|
||||
|
||||
// Now we have the transparent image composited onto the target
|
||||
// Image, now we only must copy it to the Drawable.
|
||||
ZPixmap pm = new ZPixmap(xdrawable.display);
|
||||
pm.width = width;
|
||||
pm.height = height;
|
||||
pm.init();
|
||||
System.arraycopy(img.data, 32, pm.data, 0, img.data.length - 32);
|
||||
xdrawable.put_image(xgc, pm, x + translateX, y + translateY);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Pre-render the image into an XImage.
|
||||
ImageProducer source = image.getSource();
|
||||
ImageConverter conv = new ImageConverter();
|
||||
source.startProduction(conv);
|
||||
XImage xim = conv.getXImage();
|
||||
Pixmap pm = xim.pixmap;
|
||||
xdrawable.copy_area(pm, xgc, 0, 0, pm.width, pm.height,
|
||||
x + translateX, y + translateY);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to work around limitation in the current Escher impl.
|
||||
*
|
||||
* @param x the x position
|
||||
* @param y the y position
|
||||
* @param img the image data
|
||||
* @param rgb an 3-size array that holds the rgb values on method exit
|
||||
*/
|
||||
private void getRGB(int x, int y, Data img, int[] rgb, int lineByteCount)
|
||||
{
|
||||
// TODO: Does this also work on non-RGB devices?
|
||||
int i = y * lineByteCount + pixelByteCount * x;
|
||||
if (imageByteOrder == gnu.x11.image.Image.LSB_FIRST)
|
||||
{//if (i >= 5716-33) System.err.println("lbc: " + lineByteCount + ", " + pixelByteCount);
|
||||
rgb[2] = img.data[32 + i];
|
||||
rgb[1] = img.data[32 + i + 1];
|
||||
rgb[0] = img.data[32 + i + 2];
|
||||
}
|
||||
else
|
||||
{ // MSB_FIRST
|
||||
rgb[0] = img.data[32 + i];
|
||||
rgb[1] = img.data[32 + i + 1];
|
||||
rgb[2] = img.data[32 + i + 2];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to work around limitation in the current Escher impl.
|
||||
*
|
||||
* @param x the x position
|
||||
* @param y the y position
|
||||
* @param img the image data
|
||||
* @param rgb an 3-size array that holds the rgb values on method exit
|
||||
*/
|
||||
private void setRGB(int x, int y, Data img, int[] rgb, int lineByteCount)
|
||||
{
|
||||
// TODO: Does this also work on non-RGB devices?
|
||||
int i = y * lineByteCount + pixelByteCount * x;
|
||||
if (imageByteOrder == gnu.x11.image.Image.LSB_FIRST)
|
||||
{
|
||||
img.data[32 + i] = (byte) rgb[2];
|
||||
img.data[32 + i + 1] = (byte) rgb[1];
|
||||
img.data[32 + i + 2] = (byte) rgb[0];
|
||||
}
|
||||
else
|
||||
{ // MSB_FIRST
|
||||
img.data[32 + i] = (byte) rgb[0];
|
||||
img.data[32 + i + 1] = (byte) rgb[1];
|
||||
img.data[32 + i + 2] = (byte) rgb[2];
|
||||
}
|
||||
}
|
||||
|
||||
public boolean drawImage(Image image, int x, int y, int width, int height,
|
||||
ImageObserver observer)
|
||||
{
|
||||
// FIXME: Implement this.
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
}
|
||||
|
||||
public boolean drawImage(Image image, int x, int y, Color bgcolor,
|
||||
ImageObserver observer)
|
||||
{
|
||||
// FIXME: Implement this.
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
}
|
||||
|
||||
public boolean drawImage(Image image, int x, int y, int width, int height,
|
||||
Color bgcolor, ImageObserver observer)
|
||||
{
|
||||
// FIXME: Implement this.
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
}
|
||||
|
||||
public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2,
|
||||
int sx1, int sy1, int sx2, int sy2,
|
||||
ImageObserver observer)
|
||||
{
|
||||
return drawImage(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null,
|
||||
observer);
|
||||
}
|
||||
|
||||
public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2,
|
||||
int sx1, int sy1, int sx2, int sy2, Color bgcolor,
|
||||
ImageObserver observer)
|
||||
{
|
||||
|
||||
// FIXME: What to do with bgcolor?
|
||||
|
||||
// Scale the image.
|
||||
int sw = image.getWidth(observer);
|
||||
int sh = image.getHeight(observer);
|
||||
double scaleX = Math.abs(dx2 - dx1) / (double) Math.abs(sx2 - sx1);
|
||||
double scaleY = Math.abs(dy2 - dy1) / (double) Math.abs(sy2 - sy1);
|
||||
Image scaled = image.getScaledInstance((int) (scaleX * sw),
|
||||
(int) (scaleY * sh),
|
||||
Image.SCALE_FAST);
|
||||
|
||||
// Scaled source coordinates.
|
||||
int sx1s = (int) (scaleX * Math.min(sx1, sx2));
|
||||
int sx2s = (int) (scaleX * Math.max(sx1, sx2));
|
||||
|
||||
// Temporarily clip to the target rectangle.
|
||||
Rectangle old = clip;
|
||||
clipRect(dx1, dy1, dx2 - dx1, dy2 - dy1);
|
||||
|
||||
// Draw scaled image.
|
||||
boolean res = drawImage(scaled, dx1 - sx1s, dy1 - sx2s, observer);
|
||||
|
||||
// Reset clip.
|
||||
setClip(old);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees any resources associated with this object.
|
||||
*/
|
||||
public void dispose()
|
||||
{
|
||||
if (! disposed)
|
||||
{
|
||||
xgc.free();
|
||||
xdrawable.display.flush();
|
||||
disposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Additional helper methods.
|
||||
|
||||
/**
|
||||
* Creates and returns an exact copy of this XGraphics.
|
||||
*/
|
||||
protected Object clone()
|
||||
{
|
||||
try
|
||||
{
|
||||
XGraphics copy = (XGraphics) super.clone();
|
||||
copy.xgc = xgc.copy();
|
||||
if (clip != null)
|
||||
{
|
||||
copy.clip = new Rectangle(clip);
|
||||
copy.setXClip(clip.x, clip.y, clip.width, clip.height);
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
catch (CloneNotSupportedException ex)
|
||||
{
|
||||
assert false;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the intersection between two rectangles and stores the result
|
||||
* int the second rectangle.
|
||||
*
|
||||
* This method has been copied from {@link javax.swing.SwingUtilities}.
|
||||
*
|
||||
* @param x the x coordinate of the rectangle #1
|
||||
* @param y the y coordinate of the rectangle #1
|
||||
* @param w the width of the rectangle #1
|
||||
* @param h the height of the rectangle #1
|
||||
* @param rect the rectangle #2 and output rectangle
|
||||
*/
|
||||
private static void computeIntersection(int x, int y, int w, int h,
|
||||
Rectangle rect)
|
||||
{
|
||||
int x2 = (int) rect.x;
|
||||
int y2 = (int) rect.y;
|
||||
int w2 = (int) rect.width;
|
||||
int h2 = (int) rect.height;
|
||||
|
||||
int dx = (x > x2) ? x : x2;
|
||||
int dy = (y > y2) ? y : y2;
|
||||
int dw = (x + w < x2 + w2) ? (x + w - dx) : (x2 + w2 - dx);
|
||||
int dh = (y + h < y2 + h2) ? (y + h - dy) : (y2 + h2 - dy);
|
||||
|
||||
if (dw >= 0 && dh >= 0)
|
||||
rect.setBounds(dx, dy, dw, dh);
|
||||
else
|
||||
rect.setBounds(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -37,16 +37,23 @@ exception statement from your version. */
|
|||
|
||||
package gnu.java.awt.peer.x;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.Image;
|
||||
import java.awt.Paint;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Shape;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.ImageObserver;
|
||||
import java.awt.image.Raster;
|
||||
import java.util.HashMap;
|
||||
|
||||
import gnu.java.awt.java2d.AbstractGraphics2D;
|
||||
import gnu.java.awt.java2d.ScanlineCoverage;
|
||||
import gnu.x11.Colormap;
|
||||
import gnu.x11.Drawable;
|
||||
import gnu.x11.GC;
|
||||
import gnu.x11.image.ZPixmap;
|
||||
|
@ -70,6 +77,11 @@ public class XGraphics2D
|
|||
*/
|
||||
private boolean disposed;
|
||||
|
||||
/**
|
||||
* The current foreground color, possibly null.
|
||||
*/
|
||||
private Color foreground;
|
||||
|
||||
XGraphics2D(Drawable d)
|
||||
{
|
||||
super();
|
||||
|
@ -80,31 +92,9 @@ public class XGraphics2D
|
|||
//setClip(new Rectangle(0, 0, xdrawable.width, xdrawable.height));
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws a pixel in the target coordinate space using the specified color.
|
||||
*
|
||||
* @param x the x coordinate
|
||||
* @param y the y coordinate
|
||||
*/
|
||||
protected void rawSetPixel(int x, int y)
|
||||
{
|
||||
xdrawable.point(xgc, x, y);
|
||||
}
|
||||
|
||||
// protected void rawFillPolygon(double[] xpoints, double[] ypoints, int npoints)
|
||||
// {
|
||||
// Point[] points = new Point[npoints];
|
||||
// for (int n = 0; n < npoints; n++)
|
||||
// {
|
||||
// points[n] = new Point((int) xpoints[n], (int) ypoints[n]);
|
||||
// }
|
||||
// xdrawable.fill_poly(xgc, points, Drawable.COMPLEX, Drawable.ORIGIN);
|
||||
// xdrawable.display.flush();
|
||||
// }
|
||||
|
||||
protected void rawDrawLine(int x0, int y0, int x1, int y1)
|
||||
{
|
||||
xdrawable.line(xgc, x0, y0, x1, y1);
|
||||
xdrawable.segment(xgc, x0, y0, x1, y1);
|
||||
}
|
||||
|
||||
protected void rawFillRect(int x, int y, int w, int h)
|
||||
|
@ -112,17 +102,6 @@ public class XGraphics2D
|
|||
xdrawable.rectangle(xgc, x, y, w, h, true);
|
||||
}
|
||||
|
||||
protected void rawSetForeground(java.awt.Color c)
|
||||
{
|
||||
if (c != null)
|
||||
xgc.set_foreground(c.getRGB());
|
||||
}
|
||||
|
||||
protected void rawSetForeground(int r, int g, int b)
|
||||
{
|
||||
xgc.set_foreground( r << 16 | g << 8 | b );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the color model of this Graphics object.
|
||||
*
|
||||
|
@ -178,55 +157,6 @@ public class XGraphics2D
|
|||
return copy;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Draws the specified image on the drawable at position (x,y).
|
||||
// */
|
||||
//
|
||||
// public boolean drawImage(Image image, int x, int y, ImageObserver observer)
|
||||
// {
|
||||
// AffineTransform transform = getTransform();
|
||||
// int translateX = (int) transform.getTranslateX();
|
||||
// int translateY = (int) transform.getTranslateY();
|
||||
// if (image instanceof XImage)
|
||||
// {
|
||||
// XImage xim = (XImage) image;
|
||||
// Pixmap pm = xim.pixmap;
|
||||
// xdrawable.copy_area(pm, xgc, 0, 0, pm.width, pm.height,
|
||||
// x + translateX, y + translateY);
|
||||
// }
|
||||
// else if (image instanceof BufferedImage)
|
||||
// {
|
||||
// BufferedImage bufferedImage = (BufferedImage) image;
|
||||
// Raster raster = bufferedImage.getData();
|
||||
// int w = bufferedImage.getWidth();
|
||||
// int h = bufferedImage.getHeight();
|
||||
// // Push data to X server.
|
||||
// ZPixmap zPixmap = new ZPixmap(xdrawable.display, w, h,
|
||||
// xdrawable.display.default_pixmap_format);
|
||||
// System.err.println("data buffer length: " + zPixmap.data.length);
|
||||
// int[] pixel = new int[4];
|
||||
// for (int tx = 0; tx < w; tx++)
|
||||
// {
|
||||
// for (int ty = 0; ty < h; ty++)
|
||||
// {
|
||||
// pixel = raster.getPixel(tx, ty, pixel);
|
||||
//// System.err.print("r: " + pixel[0]);
|
||||
//// System.err.print(", g: " + pixel[1]);
|
||||
//// System.err.println(", b: " + pixel[2]);
|
||||
// zPixmap.set_red(tx, ty, pixel[0]);
|
||||
// zPixmap.set_green(tx, ty, pixel[1]);
|
||||
// zPixmap.set_blue(tx, ty, pixel[2]);
|
||||
// }
|
||||
// }
|
||||
// xdrawable.put_image(xgc, zPixmap, x, y);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// throw new UnsupportedOperationException("Not yet implemented.");
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
public void setClip(Shape c)
|
||||
{
|
||||
super.setClip(c);
|
||||
|
@ -287,9 +217,115 @@ public class XGraphics2D
|
|||
}
|
||||
}
|
||||
|
||||
public void renderScanline(int y, ScanlineCoverage c)
|
||||
{
|
||||
ScanlineCoverage.Iterator iter = c.iterate();
|
||||
float coverageAlpha = 0;
|
||||
int maxCoverage = c.getMaxCoverage();
|
||||
Color old = getColor();
|
||||
Color col = getColor();
|
||||
if (col == null)
|
||||
col = Color.BLACK;
|
||||
while (iter.hasNext())
|
||||
{
|
||||
ScanlineCoverage.Range range = iter.next();
|
||||
// TODO: Dumb implementation for testing.
|
||||
coverageAlpha = range.getCoverage();
|
||||
if (coverageAlpha > 0)
|
||||
{
|
||||
int red = col.getRed();
|
||||
int green = col.getGreen();
|
||||
int blue = col.getBlue();
|
||||
if (coverageAlpha < c.getMaxCoverage())
|
||||
{
|
||||
float alpha = coverageAlpha / maxCoverage;
|
||||
red = 255 - (int) ((255 - red) * alpha);
|
||||
green = 255 - (int) ((255 - green) * alpha);
|
||||
blue = 255 - (int) ((255 - blue) * alpha);
|
||||
}
|
||||
xgc.set_foreground(red << 16 | green << 8 | blue);
|
||||
int x0 = range.getXPos();
|
||||
int l = range.getLength();
|
||||
xdrawable.fill_rectangle(xgc, x0, y, l, 1);
|
||||
}
|
||||
}
|
||||
if (old != null)
|
||||
xgc.set_foreground(old.getRGB());
|
||||
}
|
||||
|
||||
protected void fillScanline(int x0, int x1, int y)
|
||||
{
|
||||
xdrawable.segment(xgc, x0, y, x1, y);
|
||||
}
|
||||
|
||||
protected void fillScanlineAA(int x0, int x1, int y, int alpha)
|
||||
{
|
||||
//System.err.println("fillScanlineAA: " + x0 + ", " + x1 + ", " + y + ", " + alpha);
|
||||
// FIXME: This is for testing only.
|
||||
Color c = getColor();
|
||||
setColor(new Color(255-alpha, 255-alpha, 255-alpha));
|
||||
xdrawable.segment(xgc, x0, y, x1, y);
|
||||
setColor(c);
|
||||
}
|
||||
|
||||
protected void init()
|
||||
{
|
||||
super.init();
|
||||
}
|
||||
|
||||
public void setPaint(Paint p)
|
||||
{
|
||||
super.setPaint(p);
|
||||
if (p instanceof Color)
|
||||
{
|
||||
Color c = (Color) p;
|
||||
XToolkit tk = (XToolkit) Toolkit.getDefaultToolkit();
|
||||
HashMap colorMap = tk.colorMap;
|
||||
gnu.x11.Color col = (gnu.x11.Color) colorMap.get(c);
|
||||
if (col == null)
|
||||
{
|
||||
Colormap map = xdrawable.display.default_colormap;
|
||||
col = map.alloc_color (c.getRed() * 256,
|
||||
c.getGreen() * 256,
|
||||
c.getBlue() * 256);
|
||||
colorMap.put(c, col);
|
||||
}
|
||||
xgc.set_foreground(col);
|
||||
foreground = c;
|
||||
}
|
||||
}
|
||||
|
||||
protected void fillShape(Shape s, boolean isFont)
|
||||
{
|
||||
synchronized (xdrawable.display) {
|
||||
super.fillShape(s, isFont);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean rawDrawImage(Image image, int x, int y, ImageObserver obs)
|
||||
{
|
||||
boolean ret;
|
||||
if (image instanceof XImage)
|
||||
{
|
||||
XImage xImage = (XImage) image;
|
||||
xdrawable.copy_area(xImage.pixmap, xgc, 0, 0, xImage.getWidth(obs),
|
||||
xImage.getHeight(obs), x, y);
|
||||
ret = true;
|
||||
}
|
||||
else if (image instanceof PixmapVolatileImage)
|
||||
{
|
||||
PixmapVolatileImage pvi = (PixmapVolatileImage) image;
|
||||
xdrawable.copy_area(pvi.getPixmap(), xgc, 0, 0, pvi.getWidth(obs),
|
||||
pvi.getHeight(obs), x, y);
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = super.rawDrawImage(image, x, y, obs);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -39,11 +39,20 @@ package gnu.java.awt.peer.x;
|
|||
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Transparency;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.ComponentColorModel;
|
||||
import java.awt.image.ComponentSampleModel;
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.SampleModel;
|
||||
import java.awt.image.VolatileImage;
|
||||
import java.awt.image.WritableRaster;
|
||||
|
||||
public class XGraphicsConfiguration
|
||||
extends GraphicsConfiguration
|
||||
|
@ -63,26 +72,60 @@ public class XGraphicsConfiguration
|
|||
|
||||
public BufferedImage createCompatibleImage(int w, int h)
|
||||
{
|
||||
return new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
|
||||
return createCompatibleImage(w, h, Transparency.OPAQUE);
|
||||
}
|
||||
|
||||
public BufferedImage createCompatibleImage(int w, int h, int transparency)
|
||||
{
|
||||
BufferedImage bi;
|
||||
switch (transparency)
|
||||
{
|
||||
case Transparency.OPAQUE:
|
||||
DataBuffer buffer = new ZPixmapDataBuffer(w, h);
|
||||
SampleModel sm = new ComponentSampleModel(DataBuffer.TYPE_BYTE, w, h,
|
||||
4, w * 4,
|
||||
new int[]{0, 1, 2, 3 });
|
||||
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB);
|
||||
ColorModel cm = new ComponentColorModel(cs, true, false,
|
||||
Transparency.OPAQUE,
|
||||
DataBuffer.TYPE_BYTE);
|
||||
WritableRaster raster = Raster.createWritableRaster(sm, buffer,
|
||||
new Point(0, 0));
|
||||
bi = new BufferedImage(cm, raster, false, null);
|
||||
break;
|
||||
case Transparency.BITMASK:
|
||||
case Transparency.TRANSLUCENT:
|
||||
bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Illegal transparency: "
|
||||
+ transparency);
|
||||
}
|
||||
return bi;
|
||||
}
|
||||
|
||||
public VolatileImage createCompatibleVolatileImage(int w, int h)
|
||||
{
|
||||
// TODO: Implement this.
|
||||
throw new UnsupportedOperationException("Not yet implemented.");
|
||||
return createCompatibleVolatileImage(w, h, Transparency.OPAQUE);
|
||||
}
|
||||
|
||||
public VolatileImage createCompatibleVolatileImage(int width, int height,
|
||||
int transparency)
|
||||
{
|
||||
// TODO: Implement this.
|
||||
throw new UnsupportedOperationException("Not yet implemented.");
|
||||
}
|
||||
|
||||
public BufferedImage createCompatibleImage(int w, int h, int transparency)
|
||||
{
|
||||
// TODO: Implement this.
|
||||
throw new UnsupportedOperationException("Not yet implemented.");
|
||||
VolatileImage im;
|
||||
switch (transparency)
|
||||
{
|
||||
case Transparency.OPAQUE:
|
||||
im = new PixmapVolatileImage(width, height);
|
||||
break;
|
||||
case Transparency.BITMASK:
|
||||
case Transparency.TRANSLUCENT:
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown transparency type: "
|
||||
+ transparency);
|
||||
}
|
||||
return im;
|
||||
}
|
||||
|
||||
public ColorModel getColorModel()
|
||||
|
|
|
@ -38,15 +38,12 @@ exception statement from your version. */
|
|||
package gnu.java.awt.peer.x;
|
||||
|
||||
import gnu.classpath.SystemProperties;
|
||||
import gnu.java.net.local.LocalSocket;
|
||||
import gnu.java.net.local.LocalSocketAddress;
|
||||
import gnu.x11.Connection;
|
||||
import gnu.x11.Display;
|
||||
|
||||
import java.awt.AWTError;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.net.SocketException;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.net.Socket;
|
||||
|
||||
/**
|
||||
* This class represents an X Display. The actual connection is established
|
||||
|
@ -127,33 +124,21 @@ public class XGraphicsDevice
|
|||
|| displayName.hostname.equals(""))
|
||||
&& SystemProperties.getProperty("gnu.xawt.no_local_sockets") == null)
|
||||
{
|
||||
// TODO: Is this 100% ok?
|
||||
String sockPath = "/tmp/.X11-unix/X" + displayName.display_no;
|
||||
LocalSocketAddress addr = new LocalSocketAddress(sockPath);
|
||||
try
|
||||
Socket socket = createLocalSocket();
|
||||
if (socket != null)
|
||||
{
|
||||
if (XToolkit.DEBUG)
|
||||
System.err.println("connecting to local socket: "
|
||||
+ sockPath);
|
||||
LocalSocket socket = new LocalSocket(addr);
|
||||
display = new Display(socket, "localhost",
|
||||
displayName.display_no,
|
||||
displayName.screen_no);
|
||||
display.connection.send_mode = Connection.ASYNCHRONOUS;
|
||||
if (XToolkit.DEBUG)
|
||||
System.err.println("connected to local socket");
|
||||
}
|
||||
catch (SocketException ex)
|
||||
{
|
||||
AWTError err = new AWTError("could not connect to X server");
|
||||
err.initCause(ex);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
display = new Display(displayName);
|
||||
}
|
||||
|
||||
// The following happens when we are configured to use plain sockets,
|
||||
// when the connection is probably remote or when we couldn't load
|
||||
// the LocalSocket class stuff.
|
||||
if (display == null)
|
||||
display = new Display(displayName);
|
||||
|
||||
eventPump = new XEventPump(display);
|
||||
}
|
||||
return display;
|
||||
|
@ -163,4 +148,36 @@ public class XGraphicsDevice
|
|||
{
|
||||
return eventPump;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to load the LocalSocket class and initiate a connection to the
|
||||
* local X server.
|
||||
*/
|
||||
private Socket createLocalSocket()
|
||||
{
|
||||
Socket socket = null;
|
||||
try
|
||||
{
|
||||
// TODO: Is this 100% ok?
|
||||
String sockPath = "/tmp/.X11-unix/X" + displayName.display_no;
|
||||
Class localSocketAddressClass =
|
||||
Class.forName("gnu.java.net.local.LocalSocketAddress");
|
||||
Constructor localSocketAddressConstr =
|
||||
localSocketAddressClass.getConstructor(new Class[]{ String.class });
|
||||
Object addr =
|
||||
localSocketAddressConstr.newInstance(new Object[]{ sockPath });
|
||||
Class localSocketClass =
|
||||
Class.forName("gnu.java.net.local.LocalSocket");
|
||||
Constructor localSocketConstructor =
|
||||
localSocketClass.getConstructor(new Class[]{localSocketAddressClass});
|
||||
Object localSocket =
|
||||
localSocketConstructor.newInstance(new Object[]{ addr });
|
||||
socket = (Socket) localSocket;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Whatever goes wrong here, we return null.
|
||||
}
|
||||
return socket;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ public class XImage
|
|||
*/
|
||||
public Graphics getGraphics()
|
||||
{
|
||||
XGraphics g = new XGraphics(pixmap);
|
||||
XGraphics2D g = new XGraphics2D(pixmap);
|
||||
return g;
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,6 @@ import java.awt.Canvas;
|
|||
import java.awt.Checkbox;
|
||||
import java.awt.CheckboxMenuItem;
|
||||
import java.awt.Choice;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dialog;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.EventQueue;
|
||||
|
@ -69,6 +68,8 @@ import java.awt.TextArea;
|
|||
import java.awt.TextField;
|
||||
import java.awt.Transparency;
|
||||
import java.awt.Window;
|
||||
import java.awt.Dialog.ModalExclusionType;
|
||||
import java.awt.Dialog.ModalityType;
|
||||
import java.awt.datatransfer.Clipboard;
|
||||
import java.awt.dnd.DragGestureEvent;
|
||||
import java.awt.dnd.peer.DragSourceContextPeer;
|
||||
|
@ -88,7 +89,6 @@ import java.awt.peer.FileDialogPeer;
|
|||
import java.awt.peer.FontPeer;
|
||||
import java.awt.peer.FramePeer;
|
||||
import java.awt.peer.LabelPeer;
|
||||
import java.awt.peer.LightweightPeer;
|
||||
import java.awt.peer.ListPeer;
|
||||
import java.awt.peer.MenuBarPeer;
|
||||
import java.awt.peer.MenuItemPeer;
|
||||
|
@ -179,16 +179,16 @@ public class XToolkit
|
|||
*/
|
||||
public ClasspathFontPeer getClasspathFontPeer(String name, Map attrs)
|
||||
{
|
||||
String canonical = XFontPeer.encodeFont(name, attrs);
|
||||
String canonical = XFontPeer2.encodeFont(name, attrs);
|
||||
ClasspathFontPeer font;
|
||||
if (!fontCache.containsKey(canonical))
|
||||
{
|
||||
String graphics2d =
|
||||
SystemProperties.getProperty("gnu.xawt.graphics2d");
|
||||
if (graphics2d != null && graphics2d.equals("gl"))
|
||||
//if (graphics2d != null && graphics2d.equals("gl"))
|
||||
font = new XFontPeer2(name, attrs);
|
||||
else
|
||||
font = new XFontPeer(name, attrs);
|
||||
// else
|
||||
// font = new XFontPeer(name, attrs);
|
||||
fontCache.put(canonical, font);
|
||||
}
|
||||
else
|
||||
|
@ -601,8 +601,20 @@ public class XToolkit
|
|||
return (XGraphicsDevice) env.getDefaultScreenDevice();
|
||||
}
|
||||
|
||||
protected LightweightPeer createComponent(Component c)
|
||||
@Override
|
||||
public boolean isModalExclusionTypeSupported
|
||||
(Dialog.ModalExclusionType modalExclusionType)
|
||||
{
|
||||
return new XLightweightPeer(c);
|
||||
// TODO: Implement properly.
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isModalityTypeSupported(Dialog.ModalityType modalityType)
|
||||
{
|
||||
// TODO: Implement properly.
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -43,12 +43,16 @@ import java.awt.EventQueue;
|
|||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Image;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.PaintEvent;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.image.VolatileImage;
|
||||
|
||||
import gnu.x11.Window;
|
||||
import gnu.x11.event.Event;
|
||||
|
@ -135,12 +139,22 @@ public class XWindowPeer
|
|||
*/
|
||||
public Graphics getGraphics()
|
||||
{
|
||||
return new XGraphics(xwindow);
|
||||
return new XGraphics2D(xwindow);
|
||||
}
|
||||
|
||||
public Image createImage(int w, int h)
|
||||
{
|
||||
return new XImage(w, h);
|
||||
// FIXME: Should return a buffered image.
|
||||
return createVolatileImage(w, h);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VolatileImage createVolatileImage(int width, int height)
|
||||
{
|
||||
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
GraphicsDevice gd = ge.getDefaultScreenDevice();
|
||||
GraphicsConfiguration gc = gd.getDefaultConfiguration();
|
||||
return gc.createCompatibleVolatileImage(width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -168,6 +182,9 @@ public class XWindowPeer
|
|||
new Rectangle(0, 0, w.getWidth(),
|
||||
w.getHeight())));
|
||||
|
||||
Graphics g = getGraphics();
|
||||
g.clearRect(0, 0, awtComponent.getWidth(), awtComponent.getHeight());
|
||||
g.dispose();
|
||||
// // Reset input selection.
|
||||
// atts.set_override_redirect(false);
|
||||
// xwindow.change_attributes(atts);
|
||||
|
@ -240,7 +257,7 @@ public class XWindowPeer
|
|||
*/
|
||||
public FontMetrics getFontMetrics(Font font)
|
||||
{
|
||||
XFontPeer fontPeer = (XFontPeer) font.getPeer();
|
||||
XFontPeer2 fontPeer = (XFontPeer2) font.getPeer();
|
||||
return fontPeer.getFontMetrics(font);
|
||||
}
|
||||
|
||||
|
|
62
libjava/classpath/gnu/java/awt/peer/x/ZPixmapDataBuffer.java
Normal file
62
libjava/classpath/gnu/java/awt/peer/x/ZPixmapDataBuffer.java
Normal file
|
@ -0,0 +1,62 @@
|
|||
package gnu.java.awt.peer.x;
|
||||
|
||||
import gnu.x11.Display;
|
||||
import gnu.x11.image.ZPixmap;
|
||||
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.image.DataBuffer;
|
||||
|
||||
/**
|
||||
* A DataBuffer implementation that is based on a ZPixmap. This is used
|
||||
* as backing store for BufferedImages.
|
||||
*/
|
||||
class ZPixmapDataBuffer
|
||||
extends DataBuffer
|
||||
{
|
||||
|
||||
/**
|
||||
* The backing ZPixmap.
|
||||
*/
|
||||
private ZPixmap zpixmap;
|
||||
|
||||
/**
|
||||
* Creates a new ZPixmapDataBuffer with a specified width and height.
|
||||
*
|
||||
* @param d the X display
|
||||
* @param w the width
|
||||
* @param h the height
|
||||
*/
|
||||
ZPixmapDataBuffer(int w, int h)
|
||||
{
|
||||
super(TYPE_BYTE, w * h * 3); // TODO: Support non-24-bit-resolutions.
|
||||
GraphicsEnvironment env =
|
||||
GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
XGraphicsDevice dev = (XGraphicsDevice) env.getDefaultScreenDevice();
|
||||
Display d = dev.getDisplay();
|
||||
zpixmap = new ZPixmap(d, w, h, d.default_pixmap_format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a ZPixmapDataBuffer from an existing ZPixmap.
|
||||
*
|
||||
* @param zpixmap the ZPixmap to wrap
|
||||
*/
|
||||
ZPixmapDataBuffer(ZPixmap zpixmap)
|
||||
{
|
||||
super(TYPE_BYTE, zpixmap.get_data_length());
|
||||
this.zpixmap = zpixmap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getElem(int bank, int i)
|
||||
{
|
||||
return 0xff & zpixmap.get_data_element(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setElem(int bank, int i, int val)
|
||||
{
|
||||
zpixmap.set_data_element(i, (byte) val);
|
||||
}
|
||||
|
||||
}
|
|
@ -108,6 +108,19 @@ public final class Fixed
|
|||
return a & -(1 << n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncates the number so that only the digits after the point are left.
|
||||
*
|
||||
* @param n the number of digits
|
||||
* @param a the fixed point value
|
||||
*
|
||||
* @return the truncated value
|
||||
*/
|
||||
public static int trunc(int n, int a)
|
||||
{
|
||||
return a & (0xFFFFFFFF >>> 32 - n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the round value of a fixed point value <code>a</code> with
|
||||
* the <code>n</code> digits.
|
||||
|
|
|
@ -42,6 +42,7 @@ import java.net.URL;
|
|||
import java.net.URLClassLoader;
|
||||
import java.net.URLStreamHandlerFactory;
|
||||
import java.security.CodeSource;
|
||||
import java.security.cert.Certificate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.jar.Manifest;
|
||||
|
||||
|
@ -95,7 +96,7 @@ public abstract class URLLoader
|
|||
this.baseURL = baseURL;
|
||||
this.factory = factory;
|
||||
this.cache = cache;
|
||||
this.noCertCodeSource = new CodeSource(overrideURL, null);
|
||||
this.noCertCodeSource = new CodeSource(overrideURL, (Certificate[]) null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -71,8 +71,12 @@ final class ISO_8859_1 extends Charset
|
|||
/* These names are provided by
|
||||
* http://oss.software.ibm.com/cgi-bin/icu/convexp?s=ALL
|
||||
*/
|
||||
"ISO8859_1", "ISO_8859_1", "ibm-819", "ISO_8859-1:1987",
|
||||
"819"
|
||||
"ISO8859_1",
|
||||
"ISO_8859_1",
|
||||
"ibm-819",
|
||||
"ISO_8859-1:1987",
|
||||
"819",
|
||||
"ISO8859-1"
|
||||
});
|
||||
|
||||
}
|
||||
|
|
|
@ -146,7 +146,7 @@ public final class Engine
|
|||
throw new IllegalArgumentException("Constructor's parameters MUST NOT be null");
|
||||
|
||||
Enumeration enumer = provider.propertyNames();
|
||||
String key;
|
||||
String key = null;
|
||||
String alias;
|
||||
int count = 0;
|
||||
boolean algorithmFound = false;
|
||||
|
@ -193,7 +193,7 @@ public final class Engine
|
|||
Class clazz = null;
|
||||
ClassLoader loader = provider.getClass().getClassLoader();
|
||||
Constructor constructor = null;
|
||||
String className = provider.getProperty(service + "." + algorithm);
|
||||
String className = provider.getProperty(key);
|
||||
sb.append("Class [").append(className).append("] for algorithm [")
|
||||
.append(algorithm).append("] of type [").append(service)
|
||||
.append("] from provider [").append(provider).append("] ");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue