Import GNU Classpath (classpath-0_97_2-release).
libjava/ 2008-06-28 Matthias Klose <doko@ubuntu.com> Import GNU Classpath (classpath-0_97_2-release). * Regenerate class and header files. * Regenerate auto* files. * gcj/javaprims.h: Define jobjectRefType. * jni.cc (_Jv_JNI_GetObjectRefType): New (stub only). (_Jv_JNIFunctions): Initialize GetObjectRefType. * gnu/classpath/jdwp/VMVirtualMachine.java, java/security/VMSecureRandom.java: Merge from classpath. * HACKING: Fix typo. * ChangeLog-2007: New file. * configure.ac: Set JAVAC, pass --disable-regen-headers to classpath. libjava/classpath/ 2008-06-28 Matthias Klose <doko@ubuntu.com> * m4/ac_prog_javac.m4: Disable check for JAVAC, when not configured with --enable-java-maintainer-mode. * aclocal.m4, configure: Regenerate. * native/jni/gstreamer-peer/Makefile.am: Do not link with libclasspathnative. * native/jni/gstreamer-peer/Makefile.in: Regenerate. * tools/Makefile.am, lib/Makefile.am: Use JAVAC for setting JCOMPILER, drop flags not understood by gcj. From-SVN: r137223
This commit is contained in:
@@ -126,7 +126,7 @@ public class AWTUtilities
|
||||
*
|
||||
* @return the next visible <code>Component</code> in the List
|
||||
*
|
||||
* @throws if there is no next element
|
||||
* @throws NoSuchElementException if there is no next element
|
||||
*/
|
||||
public Object next()
|
||||
{
|
||||
|
||||
@@ -51,7 +51,6 @@ import java.awt.GraphicsDevice;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.HeadlessException;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.font.TextAttribute;
|
||||
import java.awt.peer.DesktopPeer;
|
||||
import java.awt.peer.RobotPeer;
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -43,7 +43,6 @@ import gnu.java.security.action.SetAccessibleAction;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Toolkit;
|
||||
import java.lang.reflect.Field;
|
||||
import java.security.AccessController;
|
||||
|
||||
|
||||
@@ -37,6 +37,8 @@ exception statement from your version. */
|
||||
|
||||
package gnu.java.awt.font;
|
||||
|
||||
import gnu.java.awt.java2d.ShapeWrapper;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.font.FontRenderContext;
|
||||
import java.awt.font.GlyphMetrics;
|
||||
@@ -82,6 +84,10 @@ public class GNUGlyphVector
|
||||
private AffineTransform[] transforms;
|
||||
private int layoutFlags;
|
||||
|
||||
/**
|
||||
* The cached non-transformed outline of this glyph vector.
|
||||
*/
|
||||
private Shape cleanOutline;
|
||||
|
||||
/**
|
||||
* Constructs a new GNUGlyphVector.
|
||||
@@ -257,7 +263,6 @@ public class GNUGlyphVector
|
||||
*/
|
||||
public Shape getOutline()
|
||||
{
|
||||
validate();
|
||||
return getOutline(0.0f, 0.0f);
|
||||
}
|
||||
|
||||
@@ -273,16 +278,33 @@ public class GNUGlyphVector
|
||||
{
|
||||
validate();
|
||||
|
||||
GeneralPath outline = new GeneralPath();
|
||||
int len = glyphs.length;
|
||||
for (int i = 0; i < len; i++)
|
||||
Shape outline;
|
||||
if (cleanOutline == null)
|
||||
{
|
||||
GeneralPath p = new GeneralPath(getGlyphOutline(i));
|
||||
outline.append(p, false);
|
||||
GeneralPath path = new GeneralPath();
|
||||
int len = glyphs.length;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
GeneralPath p = new GeneralPath(getGlyphOutline(i));
|
||||
path.append(p, false);
|
||||
}
|
||||
// Protect the cached instance from beeing modified by application
|
||||
// code.
|
||||
cleanOutline = new ShapeWrapper(path);
|
||||
outline = cleanOutline;
|
||||
}
|
||||
else
|
||||
{
|
||||
outline = cleanOutline;
|
||||
}
|
||||
if (x != 0 || y != 0)
|
||||
{
|
||||
GeneralPath path = new GeneralPath(outline);
|
||||
AffineTransform t = new AffineTransform();
|
||||
t.translate(x, y);
|
||||
path.transform(t);
|
||||
outline = path;
|
||||
}
|
||||
AffineTransform t = new AffineTransform();
|
||||
t.translate(x, y);
|
||||
outline.transform(t);
|
||||
return outline;
|
||||
}
|
||||
|
||||
|
||||
+132
-37
@@ -35,7 +35,7 @@ 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;
|
||||
package gnu.java.awt.font;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
@@ -54,15 +54,16 @@ import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.text.CharacterIterator;
|
||||
import java.text.StringCharacterIterator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
import gnu.java.awt.font.FontDelegate;
|
||||
import gnu.java.awt.font.FontFactory;
|
||||
import gnu.java.awt.peer.ClasspathFontPeer;
|
||||
|
||||
public class XFontPeer2
|
||||
public class OpenTypeFontPeer
|
||||
extends ClasspathFontPeer
|
||||
{
|
||||
|
||||
@@ -70,10 +71,21 @@ public class XFontPeer2
|
||||
* The font mapping as specified in the file fonts.properties.
|
||||
*/
|
||||
private static Properties fontProperties;
|
||||
|
||||
/**
|
||||
* The available font family names.
|
||||
*/
|
||||
private static Set<String> availableFontNames;
|
||||
|
||||
/**
|
||||
* Font spec to file mapping.
|
||||
*/
|
||||
private static Map<String,Map<String,String>> fontToFileMap;
|
||||
|
||||
static
|
||||
{
|
||||
fontProperties = new Properties();
|
||||
InputStream in = XFontPeer2.class.getResourceAsStream("fonts.properties");
|
||||
InputStream in = OpenTypeFontPeer.class.getResourceAsStream("fonts.properties");
|
||||
try
|
||||
{
|
||||
fontProperties.load(in);
|
||||
@@ -234,12 +246,14 @@ public class XFontPeer2
|
||||
|
||||
private FontDelegate fontDelegate;
|
||||
|
||||
XFontPeer2(String name, int style, int size)
|
||||
public OpenTypeFontPeer(String name, int style, int size)
|
||||
{
|
||||
super(name, style, size);
|
||||
try
|
||||
{
|
||||
File fontfile = new File("/usr/share/fonts/truetype/freefont/FreeSans.ttf");
|
||||
String fontSpec = encodeFont(name, style);
|
||||
String filename = mapFontToFilename(fontSpec);
|
||||
File fontfile = new File(filename);
|
||||
FileInputStream in = new FileInputStream(fontfile);
|
||||
FileChannel ch = in.getChannel();
|
||||
ByteBuffer buffer = ch.map(FileChannel.MapMode.READ_ONLY, 0,
|
||||
@@ -252,12 +266,14 @@ public class XFontPeer2
|
||||
}
|
||||
}
|
||||
|
||||
XFontPeer2(String name, Map atts)
|
||||
public OpenTypeFontPeer(String name, Map atts)
|
||||
{
|
||||
super(name, atts);
|
||||
try
|
||||
{
|
||||
File fontfile = new File("/usr/share/fonts/truetype/freefont/FreeSans.ttf");
|
||||
String fontSpec = encodeFont(name, atts);
|
||||
String filename = mapFontToFilename(fontSpec);
|
||||
File fontfile = new File(filename);
|
||||
FileInputStream in = new FileInputStream(fontfile);
|
||||
FileChannel ch = in.getChannel();
|
||||
ByteBuffer buffer = ch.map(FileChannel.MapMode.READ_ONLY, 0,
|
||||
@@ -371,7 +387,7 @@ public class XFontPeer2
|
||||
*
|
||||
* @return the encoded font description
|
||||
*/
|
||||
static String encodeFont(String name, Map atts)
|
||||
public static String encodeFont(String name, Map atts)
|
||||
{
|
||||
String family = name;
|
||||
if (family == null || family.equals(""))
|
||||
@@ -379,11 +395,6 @@ public class XFontPeer2
|
||||
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);
|
||||
@@ -395,49 +406,43 @@ public class XFontPeer2
|
||||
if (weight != null && weight.compareTo(TextAttribute.WEIGHT_REGULAR) > 0)
|
||||
style |= Font.BOLD;
|
||||
|
||||
return encodeFont(name, style, size);
|
||||
return encodeFont(name, style);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* Encodes a font name + style into a combined string.
|
||||
*
|
||||
* 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)
|
||||
static String encodeFont(String name, int style)
|
||||
{
|
||||
StringBuilder key = new StringBuilder();
|
||||
key.append(validName(name));
|
||||
key.append('.');
|
||||
key.append('/');
|
||||
switch (style)
|
||||
{
|
||||
case Font.BOLD:
|
||||
key.append("bold");
|
||||
key.append("b");
|
||||
break;
|
||||
case Font.ITALIC:
|
||||
key.append("italic");
|
||||
key.append("i");
|
||||
break;
|
||||
case (Font.BOLD | Font.ITALIC):
|
||||
key.append("bolditalic");
|
||||
key.append("bi");
|
||||
break;
|
||||
case Font.PLAIN:
|
||||
default:
|
||||
key.append("plain");
|
||||
key.append("p");
|
||||
|
||||
}
|
||||
|
||||
String protoType = fontProperties.getProperty(key.toString());
|
||||
int s = size;
|
||||
return protoType.replaceFirst("%d", String.valueOf(s * 10));
|
||||
return key.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -451,18 +456,108 @@ public class XFontPeer2
|
||||
static String validName(String name)
|
||||
{
|
||||
String retVal;
|
||||
if (name.equalsIgnoreCase("sansserif")
|
||||
|| name.equalsIgnoreCase("serif")
|
||||
|| name.equalsIgnoreCase("monospaced")
|
||||
|| name.equalsIgnoreCase("dialog")
|
||||
|| name.equalsIgnoreCase("dialoginput"))
|
||||
Set<String> fontNames = getFontNames();
|
||||
if (fontNames.contains(name))
|
||||
{
|
||||
retVal = name.toLowerCase();
|
||||
retVal = name;
|
||||
}
|
||||
else
|
||||
{
|
||||
retVal = "sansserif";
|
||||
retVal = "SansSerif";
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public static String[] getAvailableFontFamilyNames(Locale l)
|
||||
{
|
||||
Set<String> fontNames = getFontNames();
|
||||
int numNames = fontNames.size();
|
||||
String[] ret = fontNames.toArray(new String[numNames]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static synchronized Set<String> getFontNames()
|
||||
{
|
||||
if (availableFontNames == null)
|
||||
{
|
||||
HashSet<String> familyNames = new HashSet<String>();
|
||||
for (Object o : fontProperties.keySet())
|
||||
{
|
||||
if (o instanceof String)
|
||||
{
|
||||
String key = (String) o;
|
||||
int slashIndex = key.indexOf('/');
|
||||
String name = key.substring(0, slashIndex);
|
||||
familyNames.add(name);
|
||||
}
|
||||
}
|
||||
availableFontNames = familyNames;
|
||||
}
|
||||
return availableFontNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a font spec as returned by {@link #encodeFont(String, int)},
|
||||
* and returns the corresponding font file, or <code>null</code> if no such
|
||||
* font mapping exists.
|
||||
*
|
||||
* @param fontSpec font name and style as returned by
|
||||
* {@link #encodeFont(String, int)}
|
||||
*
|
||||
* @return filename of the corresponding font file
|
||||
*/
|
||||
private synchronized String mapFontToFilename(String fontSpec)
|
||||
{
|
||||
if (fontToFileMap == null)
|
||||
{
|
||||
fontToFileMap = new HashMap<String,Map<String,String>>();
|
||||
|
||||
// Initialize font spec to file mapping according to the
|
||||
// font.properties.
|
||||
for (Object o : fontProperties.keySet())
|
||||
{
|
||||
if (o instanceof String)
|
||||
{
|
||||
String key = (String) o;
|
||||
int slashIndex = key.indexOf('/');
|
||||
String name = key.substring(0, slashIndex);
|
||||
String spec = key.substring(slashIndex + 1);
|
||||
// Handle aliases in the 2nd pass below.
|
||||
if (! spec.equals("a"))
|
||||
{
|
||||
Map<String,String> specToFileMap = fontToFileMap.get(name);
|
||||
if (specToFileMap == null)
|
||||
{
|
||||
specToFileMap = new HashMap<String,String>();
|
||||
fontToFileMap.put(name, specToFileMap);
|
||||
}
|
||||
specToFileMap.put(spec, fontProperties.getProperty(key));
|
||||
}
|
||||
}
|
||||
}
|
||||
// 2nd pass for handling aliases.
|
||||
for (Object o : fontProperties.keySet())
|
||||
{
|
||||
if (o instanceof String)
|
||||
{
|
||||
String key = (String) o;
|
||||
int slashIndex = key.indexOf('/');
|
||||
String name = key.substring(0, slashIndex);
|
||||
String spec = key.substring(slashIndex + 1);
|
||||
// Handle aliases in the 2nd pass below.
|
||||
if (spec.equals("a"))
|
||||
{
|
||||
String alias = fontProperties.getProperty(key);
|
||||
Map<String,String> specToFileMap = fontToFileMap.get(alias);
|
||||
fontToFileMap.put(name, specToFileMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Look up font file.
|
||||
int slashIndex = fontSpec.indexOf('/');
|
||||
String name = fontSpec.substring(0, slashIndex);
|
||||
String spec = fontSpec.substring(slashIndex + 1);
|
||||
return fontToFileMap.get(name).get(spec);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,300 @@
|
||||
/* AsyncImage.java -- Loads images asynchronously
|
||||
Copyright (C) 2008 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.image;
|
||||
|
||||
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Image;
|
||||
import java.awt.image.ImageConsumer;
|
||||
import java.awt.image.ImageObserver;
|
||||
import java.awt.image.ImageProducer;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* Supports asynchronous loading of images.
|
||||
*/
|
||||
public class AsyncImage
|
||||
extends Image
|
||||
{
|
||||
|
||||
/**
|
||||
* The image source for AsyncImages.
|
||||
*/
|
||||
private class AsyncImageSource
|
||||
implements ImageProducer
|
||||
{
|
||||
/**
|
||||
* The real image source, if already present, or <code>null</code>
|
||||
* otherwise.
|
||||
*/
|
||||
private ImageProducer realSource;
|
||||
|
||||
public void addConsumer(ImageConsumer ic)
|
||||
{
|
||||
startProduction(ic);
|
||||
}
|
||||
|
||||
public boolean isConsumer(ImageConsumer ic)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public void removeConsumer(ImageConsumer ic)
|
||||
{
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
public void requestTopDownLeftRightResend(ImageConsumer ic)
|
||||
{
|
||||
startProduction(ic);
|
||||
}
|
||||
|
||||
public void startProduction(ImageConsumer ic)
|
||||
{
|
||||
ImageProducer ip = getRealSource();
|
||||
if (ip == null)
|
||||
{
|
||||
ic.setDimensions(1, 1);
|
||||
ic.imageComplete(ImageConsumer.SINGLEFRAMEDONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
ip.startProduction(ic);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the real image source, if already present. Otherwise, this
|
||||
* returns <code>null</code>.
|
||||
*
|
||||
* @return the real image source, or <code>null</code> if not present
|
||||
*/
|
||||
private ImageProducer getRealSource()
|
||||
{
|
||||
synchronized (AsyncImage.this)
|
||||
{
|
||||
ImageProducer source = realSource;
|
||||
if (source == null)
|
||||
{
|
||||
Image ri = realImage;
|
||||
if (ri != null)
|
||||
{
|
||||
realSource = source = ri.getSource();
|
||||
}
|
||||
}
|
||||
return source;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The real image. This is null as long as the image is not complete.
|
||||
*/
|
||||
private volatile Image realImage;
|
||||
|
||||
/**
|
||||
* The image observers.
|
||||
*
|
||||
* This is package private to avoid accessor methods.
|
||||
*/
|
||||
HashSet<ImageObserver> observers;
|
||||
|
||||
private volatile boolean complete = false;
|
||||
|
||||
/**
|
||||
* Creates a new AsyncImage.
|
||||
*/
|
||||
AsyncImage()
|
||||
{
|
||||
observers = new HashSet<ImageObserver>();
|
||||
}
|
||||
|
||||
public void flush()
|
||||
{
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
public Graphics getGraphics()
|
||||
{
|
||||
Image r = realImage;
|
||||
Graphics g = null;
|
||||
if (r != null)
|
||||
g = r.getGraphics(); // Should we return some dummy graphics instead?
|
||||
return g;
|
||||
}
|
||||
|
||||
public boolean isComplete() {
|
||||
return complete;
|
||||
}
|
||||
|
||||
public int getHeight(ImageObserver observer)
|
||||
{
|
||||
addObserver(observer);
|
||||
int height = -1;
|
||||
waitForImage(observer);
|
||||
Image r = realImage;
|
||||
if (r != null)
|
||||
height = r.getHeight(observer);
|
||||
return height;
|
||||
}
|
||||
|
||||
public Object getProperty(String name, ImageObserver observer)
|
||||
{
|
||||
addObserver(observer);
|
||||
Image r = realImage;
|
||||
Object prop = null;
|
||||
if (r != null)
|
||||
prop = r.getProperty(name, observer);
|
||||
return prop;
|
||||
}
|
||||
|
||||
public ImageProducer getSource()
|
||||
{
|
||||
return new AsyncImageSource();
|
||||
}
|
||||
|
||||
public int getWidth(ImageObserver observer)
|
||||
{
|
||||
addObserver(observer);
|
||||
int width = -1;
|
||||
waitForImage(observer);
|
||||
Image r = realImage;
|
||||
if (r != null)
|
||||
width = r.getWidth(observer);
|
||||
return width;
|
||||
}
|
||||
|
||||
public void addObserver(ImageObserver obs)
|
||||
{
|
||||
if (obs != null)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
// This field gets null when image loading is complete and we don't
|
||||
// need to store any more observers.
|
||||
HashSet<ImageObserver> observs = observers;
|
||||
if (observs != null)
|
||||
{
|
||||
observs.add(obs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean prepareImage(int w, int h, ImageObserver obs)
|
||||
{
|
||||
addObserver(obs);
|
||||
return realImage != null;
|
||||
}
|
||||
|
||||
public int checkImage(int w, int h, ImageObserver obs)
|
||||
{
|
||||
addObserver(obs);
|
||||
int flags = 0;
|
||||
if (realImage != null)
|
||||
flags = ImageObserver.ALLBITS | ImageObserver.WIDTH
|
||||
| ImageObserver.HEIGHT | ImageObserver.PROPERTIES;
|
||||
return flags;
|
||||
}
|
||||
|
||||
public Image getRealImage()
|
||||
{
|
||||
return realImage;
|
||||
}
|
||||
|
||||
public void setRealImage(Image im)
|
||||
{
|
||||
realImage = im;
|
||||
int status = ImageObserver.HEIGHT | ImageObserver.WIDTH;
|
||||
notifyObservers(status, 0, 0, im.getWidth(null), im.getHeight(null));
|
||||
}
|
||||
|
||||
public void notifyObservers(int status, int x, int y, int w, int h)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
HashSet observs = observers;
|
||||
if (observs != null)
|
||||
{
|
||||
Iterator i = observs.iterator();
|
||||
while (i.hasNext())
|
||||
{
|
||||
ImageObserver obs = (ImageObserver) i.next();
|
||||
boolean complete = obs.imageUpdate(this, status, x, y, realImage.getWidth(obs), realImage.getHeight(obs));
|
||||
if (complete) // Remove completed observers.
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
if ((status & ImageObserver.ALLBITS) != 0)
|
||||
{
|
||||
complete = true;
|
||||
notifyAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for the image to be loaded completely, if the image observer
|
||||
* is <code>null</code>. Otherwise this is not necessary, because the
|
||||
* image observer can be notified about later completion.
|
||||
*
|
||||
* @param observer the image observer
|
||||
*/
|
||||
public void waitForImage(ImageObserver observer)
|
||||
{
|
||||
if (!complete && observer == null)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
while (! complete)
|
||||
{
|
||||
try
|
||||
{
|
||||
wait();
|
||||
}
|
||||
catch (InterruptedException ex)
|
||||
{
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,528 @@
|
||||
/* ImageConverter.java -- Loads images asynchronously
|
||||
Copyright (C) 2008 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.image;
|
||||
|
||||
import gnu.java.awt.image.AsyncImage;
|
||||
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Image;
|
||||
import java.awt.Transparency;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.awt.image.ImageConsumer;
|
||||
import java.awt.image.IndexColorModel;
|
||||
import java.awt.image.ImageObserver;
|
||||
import java.awt.image.SinglePixelPackedSampleModel;
|
||||
import java.awt.image.WritableRaster;
|
||||
import java.util.Hashtable;
|
||||
|
||||
/**
|
||||
* Convert an Image to a BufferedImage.
|
||||
*
|
||||
* @author Roman Kennke (kennke@aicas.com)
|
||||
*/
|
||||
public class ImageConverter implements ImageConsumer
|
||||
{
|
||||
|
||||
public static final String IMAGE_TRANSPARENCY_PROPERTY =
|
||||
"gnu.awt.image.transparency";
|
||||
|
||||
public static final String IMAGE_PROPERTIES_PROPERTY =
|
||||
"gnu.awt.image.properties";
|
||||
|
||||
private AsyncImage image;
|
||||
private BufferedImage bImage;
|
||||
private Hashtable imageProperties;
|
||||
private int width, height;
|
||||
private ColorModel colorModel;
|
||||
private ColorModel targetColorModel;
|
||||
|
||||
public ImageConverter()
|
||||
{
|
||||
width = 0;
|
||||
height = 0;
|
||||
image = new AsyncImage();
|
||||
}
|
||||
|
||||
public void setDimensions(int w, int h)
|
||||
{
|
||||
width = w;
|
||||
height = h;
|
||||
}
|
||||
|
||||
public void setProperties(Hashtable props)
|
||||
{
|
||||
// Ignore for now.
|
||||
}
|
||||
|
||||
public void setColorModel(ColorModel model)
|
||||
{
|
||||
colorModel = model;
|
||||
}
|
||||
|
||||
public void setHints(int flags)
|
||||
{
|
||||
// Ignore for now.
|
||||
}
|
||||
|
||||
public void setPixels(int x, int y, int w, int h, ColorModel model,
|
||||
byte[] pixels, int offset, int scansize)
|
||||
{
|
||||
model = setupColorModel(model);
|
||||
|
||||
if (bImage == null)
|
||||
{
|
||||
createImage();
|
||||
}
|
||||
|
||||
Integer t = (Integer) imageProperties.get("gnu.awt.image.transparency");
|
||||
int transparency = t.intValue();
|
||||
|
||||
if(targetColorModel.equals(model))
|
||||
{
|
||||
transparency = transferPixels(x, y, w, h, model, pixels, offset,
|
||||
scansize, transparency);
|
||||
}
|
||||
else if (model instanceof IndexColorModel
|
||||
&& targetColorModel.equals(ColorModel.getRGBdefault()))
|
||||
{
|
||||
transparency = convertIndexColorModelToSRGB(x, y, w, h,
|
||||
(IndexColorModel) model,
|
||||
pixels, offset, scansize,
|
||||
transparency);
|
||||
}
|
||||
else
|
||||
{
|
||||
transparency = convertPixels(x, y, w, h, model, pixels, offset,
|
||||
scansize, transparency);
|
||||
}
|
||||
|
||||
imageProperties.put("gnu.awt.image.transparency",
|
||||
Integer.valueOf(transparency));
|
||||
}
|
||||
|
||||
public void setPixels(int x, int y, int w, int h, ColorModel model,
|
||||
int[] pixels, int offset, int scansize)
|
||||
{
|
||||
model = setupColorModel(model);
|
||||
if (bImage == null)
|
||||
{
|
||||
createImage();
|
||||
}
|
||||
|
||||
Integer t = (Integer) imageProperties.get(IMAGE_TRANSPARENCY_PROPERTY);
|
||||
int transparency= t.intValue();
|
||||
|
||||
if (targetColorModel.equals(model))
|
||||
{
|
||||
transparency = transferPixels(x, y, w, h, model, pixels, offset,
|
||||
scansize, transparency);
|
||||
}
|
||||
else if (model instanceof IndexColorModel
|
||||
&& targetColorModel.equals(ColorModel.getRGBdefault()))
|
||||
{
|
||||
transparency = convertIndexColorModelToSRGB(x, y, w, h,
|
||||
(IndexColorModel) model,
|
||||
pixels, offset, scansize,
|
||||
transparency);
|
||||
}
|
||||
else
|
||||
{
|
||||
transparency = convertPixels(x, y, w, h, model, pixels, offset,
|
||||
scansize, transparency);
|
||||
}
|
||||
|
||||
imageProperties.put(IMAGE_TRANSPARENCY_PROPERTY,
|
||||
Integer.valueOf(transparency));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the color model for this setPixels run: <br/>
|
||||
* 1. if no color model was given use the hinted color model <br/>
|
||||
* 2. if no color model was given and non was hinted use the default sRGB color model. <br/>
|
||||
* Also:<br/>
|
||||
* If no target color model was set use the color model of the given pixels.
|
||||
* @param model
|
||||
* @return
|
||||
*/
|
||||
private ColorModel setupColorModel(ColorModel model)
|
||||
{
|
||||
// If the given color model is null use the previously hinted color model.
|
||||
if (model == null)
|
||||
model = colorModel;
|
||||
|
||||
// If no color model was given or hinted use default sRGB.
|
||||
if (model == null)
|
||||
model = ColorModel.getRGBdefault();
|
||||
|
||||
// If no specific color model was requested for the target use the current
|
||||
// pixels model.
|
||||
if (targetColorModel == null)
|
||||
targetColorModel = model;
|
||||
targetColorModel = ColorModel.getRGBdefault();
|
||||
return model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the image instance into which the pixel data is converted.
|
||||
*/
|
||||
private void createImage()
|
||||
{
|
||||
if (imageProperties == null)
|
||||
{
|
||||
imageProperties = new Hashtable();
|
||||
}
|
||||
|
||||
imageProperties.put(IMAGE_TRANSPARENCY_PROPERTY,
|
||||
Integer.valueOf(Transparency.OPAQUE));
|
||||
imageProperties.put(IMAGE_PROPERTIES_PROPERTY, imageProperties);
|
||||
|
||||
// For the sRGB case let the GraphicsEnvironment create an image for us.
|
||||
if (ColorModel.getRGBdefault().equals(targetColorModel))
|
||||
{
|
||||
bImage = GraphicsEnvironment.getLocalGraphicsEnvironment()
|
||||
.getDefaultScreenDevice()
|
||||
.getDefaultConfiguration()
|
||||
.createCompatibleImage(width, height, Transparency.TRANSLUCENT);
|
||||
}
|
||||
else
|
||||
{
|
||||
WritableRaster raster =
|
||||
targetColorModel.createCompatibleWritableRaster(width, height);
|
||||
bImage = new BufferedImage(targetColorModel, raster, false,
|
||||
imageProperties);
|
||||
}
|
||||
image.setRealImage(bImage);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfers pixels into a raster of the same color model.
|
||||
*
|
||||
* @param x the X coordinate of the source pixel rectangle
|
||||
* @param y the Y coordinate of the source pixel rectangle
|
||||
* @param w the width of the source pixel rectangle
|
||||
* @param h the height of the source pixel rectangle
|
||||
* @param model the color model of the source pixels
|
||||
* @param pixels the pixel data
|
||||
* @param offset the offset in the pixel array
|
||||
* @param scansize the scanline size
|
||||
* @param transparency the assumed transparency
|
||||
*
|
||||
* @return the determined transparency
|
||||
*/
|
||||
private int transferPixels(int x, int y, int w, int h, ColorModel model,
|
||||
byte[] pixels, int offset, int scansize,
|
||||
int transparency)
|
||||
{
|
||||
// If we have the same color model, then we can simply drop
|
||||
// the pixel value into the target raster.
|
||||
bImage.getRaster().setDataElements(x, y, w, h, pixels);
|
||||
|
||||
for (int yy = 0; yy < h; yy++)
|
||||
{
|
||||
for (int xx = 0; xx < w; xx++)
|
||||
{
|
||||
int pixel = 0xFF & pixels[yy * scansize + xx + offset];
|
||||
int alpha = model.getAlpha(pixel);
|
||||
transparency = updateTransparency(alpha, transparency);
|
||||
}
|
||||
}
|
||||
return transparency;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfers pixels into a raster of the same color model.
|
||||
*
|
||||
* @param x the X coordinate of the source pixel rectangle
|
||||
* @param y the Y coordinate of the source pixel rectangle
|
||||
* @param w the width of the source pixel rectangle
|
||||
* @param h the height of the source pixel rectangle
|
||||
* @param model the color model of the source pixels
|
||||
* @param pixels the pixel data
|
||||
* @param offset the offset in the pixel array
|
||||
* @param scansize the scanline size
|
||||
* @param transparency the assumed transparency
|
||||
*
|
||||
* @return the determined transparency
|
||||
*/
|
||||
private int transferPixels(int x, int y, int w, int h, ColorModel model,
|
||||
int[] pixels, int offset, int scansize,
|
||||
int transparency)
|
||||
{
|
||||
// If we have the same color model, then we can simply drop
|
||||
// the pixel value into the target raster.
|
||||
bImage.getRaster().setDataElements(x, y, w, h, pixels);
|
||||
|
||||
for (int yy = 0; yy < h; yy++)
|
||||
{
|
||||
for (int xx = 0; xx < w; xx++)
|
||||
{
|
||||
int pixel = pixels[yy * scansize + xx + offset];
|
||||
int alpha = model.getAlpha(pixel);
|
||||
transparency = updateTransparency(alpha, transparency);
|
||||
}
|
||||
}
|
||||
return transparency;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts pixel from one color model to another, and stores them in the
|
||||
* target image.
|
||||
*
|
||||
* @param x the X coordinate of the source pixel rectangle
|
||||
* @param y the Y coordinate of the source pixel rectangle
|
||||
* @param w the width of the source pixel rectangle
|
||||
* @param h the height of the source pixel rectangle
|
||||
* @param model the color model of the source pixels
|
||||
* @param pixels the pixel data
|
||||
* @param offset the offset in the pixel array
|
||||
* @param scansize the scanline size
|
||||
* @param transparency the assumed transparency
|
||||
*
|
||||
* @return the determined transparency
|
||||
*/
|
||||
private int convertPixels(int x, int y, int w, int h, ColorModel model,
|
||||
byte[] pixels, int offset, int scansize,
|
||||
int transparency)
|
||||
{
|
||||
// If the color models are not the same, we must convert the
|
||||
// pixel values from one model to the other.
|
||||
Object dataEl = null;
|
||||
// Convert pixels to the destination color model.
|
||||
for (int yy = 0; yy < h; yy++)
|
||||
{
|
||||
for (int xx = 0; xx < w; xx++)
|
||||
{
|
||||
int pixel = 0xFF & pixels[yy * scansize + xx + offset];
|
||||
int rgb = model.getRGB(pixel);
|
||||
int alpha = model.getAlpha(pixel);
|
||||
transparency = updateTransparency(alpha, transparency);
|
||||
dataEl = targetColorModel.getDataElements(rgb, dataEl);
|
||||
bImage.getRaster().setDataElements(x + xx, y + yy, dataEl);
|
||||
}
|
||||
}
|
||||
return transparency;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts pixel from one color model to another, and stores them in the
|
||||
* target image.
|
||||
*
|
||||
* @param x the X coordinate of the source pixel rectangle
|
||||
* @param y the Y coordinate of the source pixel rectangle
|
||||
* @param w the width of the source pixel rectangle
|
||||
* @param h the height of the source pixel rectangle
|
||||
* @param model the color model of the source pixels
|
||||
* @param pixels the pixel data
|
||||
* @param offset the offset in the pixel array
|
||||
* @param scansize the scanline size
|
||||
* @param transparency the assumed transparency
|
||||
*
|
||||
* @return the determined transparency
|
||||
*/
|
||||
private int convertPixels(int x, int y, int w, int h, ColorModel model,
|
||||
int[] pixels, int offset, int scansize,
|
||||
int transparency)
|
||||
{
|
||||
// If the color models are not the same, we must convert the
|
||||
// pixel values from one model to the other.
|
||||
Object dataEl = null;
|
||||
// Convert pixels to the destination color model.
|
||||
for (int yy = 0; yy < h; yy++)
|
||||
{
|
||||
for (int xx = 0; xx < w; xx++)
|
||||
{
|
||||
int pixel = pixels[yy * scansize + xx + offset];
|
||||
int rgb = model.getRGB(pixel);
|
||||
int alpha = model.getAlpha(pixel);
|
||||
transparency = updateTransparency(alpha, transparency);
|
||||
dataEl = targetColorModel.getDataElements(rgb, dataEl);
|
||||
bImage.getRaster().setDataElements(x + xx, y + yy, dataEl);
|
||||
}
|
||||
}
|
||||
return transparency;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts pixels from an index color model to the target image.
|
||||
*
|
||||
* @param x the X coordinate of the source pixel rectangle
|
||||
* @param y the Y coordinate of the source pixel rectangle
|
||||
* @param w the width of the source pixel rectangle
|
||||
* @param h the height of the source pixel rectangle
|
||||
* @param model the color model of the source pixels
|
||||
* @param pixels the pixel data
|
||||
* @param offset the offset in the pixel array
|
||||
* @param scansize the scanline size
|
||||
* @param transparency the assumed transparency
|
||||
*
|
||||
* @return the determined transparency
|
||||
*/
|
||||
private int convertIndexColorModelToSRGB(int x, int y, int w, int h,
|
||||
IndexColorModel model,
|
||||
byte[] pixels, int offset,
|
||||
int scansize, int transparency)
|
||||
{
|
||||
|
||||
int mapSize = model.getMapSize();
|
||||
int[] colorMap = new int[mapSize];
|
||||
for(int i=0; i < mapSize; i++)
|
||||
{
|
||||
colorMap[i] = model.getRGB(i);
|
||||
}
|
||||
|
||||
WritableRaster raster = bImage.getRaster();
|
||||
SinglePixelPackedSampleModel sampleMode =
|
||||
(SinglePixelPackedSampleModel) raster.getSampleModel();
|
||||
DataBuffer dataBuffer = (DataBuffer) raster.getDataBuffer();
|
||||
|
||||
int rasterOffset = sampleMode.getOffset(x,y)+dataBuffer.getOffset();
|
||||
int rasterScanline = sampleMode.getScanlineStride();
|
||||
|
||||
for (int yy = 0; yy < h; yy++)
|
||||
{
|
||||
int xoffset = offset;
|
||||
for (int xx = 0; xx < w; xx++)
|
||||
{
|
||||
int argb = colorMap[(pixels[xoffset++] & 0xFF)];
|
||||
dataBuffer.setElem(rasterOffset+xx, argb);
|
||||
int alpha = (argb >>> 24);
|
||||
transparency = updateTransparency(alpha, transparency);
|
||||
}
|
||||
offset += scansize;
|
||||
rasterOffset += rasterScanline;
|
||||
}
|
||||
|
||||
return transparency;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts pixels from an index color model to the target image.
|
||||
*
|
||||
* @param x the X coordinate of the source pixel rectangle
|
||||
* @param y the Y coordinate of the source pixel rectangle
|
||||
* @param w the width of the source pixel rectangle
|
||||
* @param h the height of the source pixel rectangle
|
||||
* @param model the color model of the source pixels
|
||||
* @param pixels the pixel data
|
||||
* @param offset the offset in the pixel array
|
||||
* @param scansize the scanline size
|
||||
* @param transparency the assumed transparency
|
||||
*
|
||||
* @return the determined transparency
|
||||
*/
|
||||
private int convertIndexColorModelToSRGB(int x, int y, int w, int h,
|
||||
IndexColorModel model, int[] pixels,
|
||||
int offset, int scansize,
|
||||
int transparency)
|
||||
{
|
||||
int mapSize = model.getMapSize();
|
||||
int[] colorMap = new int[mapSize];
|
||||
for(int i=0; i < mapSize; i++)
|
||||
{
|
||||
colorMap[i] = model.getRGB(i);
|
||||
}
|
||||
|
||||
WritableRaster raster = bImage.getRaster();
|
||||
SinglePixelPackedSampleModel sampleMode =
|
||||
(SinglePixelPackedSampleModel) raster.getSampleModel();
|
||||
DataBuffer dataBuffer = (DataBuffer)raster.getDataBuffer();
|
||||
|
||||
int rasterOffset = sampleMode.getOffset(x, y) + dataBuffer.getOffset();
|
||||
int rasterScanline = sampleMode.getScanlineStride();
|
||||
|
||||
for (int yy = 0; yy < h; yy++)
|
||||
{
|
||||
int xoffset = offset;
|
||||
for (int xx = 0; xx < w; xx++)
|
||||
{
|
||||
int argb = colorMap[pixels[xoffset++]];
|
||||
dataBuffer.setElem(rasterOffset + xx, argb);
|
||||
int alpha = (argb >>> 24);
|
||||
transparency = updateTransparency(alpha, transparency);
|
||||
}
|
||||
offset += scansize;
|
||||
rasterOffset += rasterScanline;
|
||||
}
|
||||
|
||||
return transparency;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the transparency information according to the alpha pixel value.
|
||||
*
|
||||
* @param alpha the alpha pixel value
|
||||
* @param transparency the old transparency
|
||||
*
|
||||
* @return the updated transparency
|
||||
*/
|
||||
private int updateTransparency(int alpha, int transparency)
|
||||
{
|
||||
if (alpha != 0xFF)
|
||||
{
|
||||
if (alpha == 0x00 && transparency <= Transparency.BITMASK)
|
||||
{
|
||||
transparency = Transparency.BITMASK;
|
||||
}
|
||||
else if (transparency < Transparency.TRANSLUCENT)
|
||||
{
|
||||
transparency = Transparency.TRANSLUCENT;
|
||||
}
|
||||
}
|
||||
return transparency;
|
||||
}
|
||||
|
||||
public void imageComplete(int status)
|
||||
{
|
||||
image.notifyObservers(ImageObserver.ALLBITS, 0, 0, width, height);
|
||||
}
|
||||
|
||||
public void setTargetColorModel(ColorModel model)
|
||||
{
|
||||
targetColorModel = model;
|
||||
}
|
||||
|
||||
public Image getImage()
|
||||
{
|
||||
return image;
|
||||
}
|
||||
}
|
||||
@@ -37,6 +37,8 @@ exception statement from your version. */
|
||||
|
||||
package gnu.java.awt.java2d;
|
||||
|
||||
import gnu.java.util.LRUCache;
|
||||
|
||||
import java.awt.AWTError;
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.AWTPermission;
|
||||
@@ -80,7 +82,9 @@ import java.awt.image.SampleModel;
|
||||
import java.awt.image.WritableRaster;
|
||||
import java.awt.image.renderable.RenderableImage;
|
||||
import java.text.AttributedCharacterIterator;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -151,23 +155,47 @@ public abstract class AbstractGraphics2D
|
||||
implements Cloneable, Pixelizer
|
||||
{
|
||||
|
||||
/**
|
||||
* Wether we use anti aliasing for rendering text by default or not.
|
||||
*/
|
||||
private static final boolean DEFAULT_TEXT_AA =
|
||||
Boolean.getBoolean("gnu.java2d.default_text_aa");
|
||||
|
||||
/**
|
||||
* The default font to use on the graphics object.
|
||||
*/
|
||||
private static final Font FONT = new Font("SansSerif", Font.PLAIN, 12);
|
||||
|
||||
/**
|
||||
* The size of the LRU cache used for caching GlyphVectors.
|
||||
*/
|
||||
private static final int GV_CACHE_SIZE = 50;
|
||||
|
||||
/**
|
||||
* Caches certain shapes to avoid massive creation of such Shapes in
|
||||
* the various draw* and fill* methods.
|
||||
*/
|
||||
private static final ThreadLocal<ShapeCache> shapeCache =
|
||||
new ThreadLocal<ShapeCache>();
|
||||
private static final ShapeCache shapeCache = new ShapeCache();
|
||||
|
||||
/**
|
||||
* The scanline converters by thread.
|
||||
* A pool of scanline converters. It is important to reuse scanline
|
||||
* converters because they keep their datastructures in place. We pool them
|
||||
* for use in multiple threads.
|
||||
*/
|
||||
private static final ThreadLocal<ScanlineConverter> scanlineConverters =
|
||||
new ThreadLocal<ScanlineConverter>();
|
||||
private static final LinkedList<ScanlineConverter> scanlineConverters =
|
||||
new LinkedList<ScanlineConverter>();
|
||||
|
||||
/**
|
||||
* Caches glyph vectors for better drawing performance.
|
||||
*/
|
||||
private static final Map<TextCacheKey,GlyphVector> gvCache =
|
||||
Collections.synchronizedMap(new LRUCache<TextCacheKey,GlyphVector>(GV_CACHE_SIZE));
|
||||
|
||||
/**
|
||||
* This key is used to search in the gvCache without allocating a new
|
||||
* key each time.
|
||||
*/
|
||||
private static final TextCacheKey searchTextKey = new TextCacheKey();
|
||||
|
||||
/**
|
||||
* The transformation for this Graphics2D instance
|
||||
@@ -484,14 +512,25 @@ public abstract class AbstractGraphics2D
|
||||
*/
|
||||
public void drawString(String text, int x, int y)
|
||||
{
|
||||
if (isOptimized)
|
||||
rawDrawString(text, x, y);
|
||||
else
|
||||
GlyphVector gv;
|
||||
synchronized (searchTextKey)
|
||||
{
|
||||
FontRenderContext ctx = getFontRenderContext();
|
||||
GlyphVector gv = font.createGlyphVector(ctx, text.toCharArray());
|
||||
drawGlyphVector(gv, x, y);
|
||||
TextCacheKey tck = searchTextKey;
|
||||
FontRenderContext frc = getFontRenderContext();
|
||||
tck.setString(text);
|
||||
tck.setFont(font);
|
||||
tck.setFontRenderContext(frc);
|
||||
if (gvCache.containsKey(tck))
|
||||
{
|
||||
gv = gvCache.get(tck);
|
||||
}
|
||||
else
|
||||
{
|
||||
gv = font.createGlyphVector(frc, text.toCharArray());
|
||||
gvCache.put(new TextCacheKey(text, font, frc), gv);
|
||||
}
|
||||
}
|
||||
drawGlyphVector(gv, x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -949,7 +988,10 @@ public abstract class AbstractGraphics2D
|
||||
|
||||
public FontRenderContext getFontRenderContext()
|
||||
{
|
||||
return new FontRenderContext(transform, false, true);
|
||||
// Protect our own transform from beeing modified.
|
||||
AffineTransform tf = new AffineTransform(transform);
|
||||
// TODO: Determine antialias and fractionalmetrics parameters correctly.
|
||||
return new FontRenderContext(tf, false, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -992,8 +1034,10 @@ public abstract class AbstractGraphics2D
|
||||
// Copy the clip. If it's a Rectangle, preserve that for optimization.
|
||||
if (clip instanceof Rectangle)
|
||||
copy.clip = new Rectangle((Rectangle) clip);
|
||||
else
|
||||
else if (clip != null)
|
||||
copy.clip = new GeneralPath(clip);
|
||||
else
|
||||
copy.clip = null;
|
||||
|
||||
copy.renderingHints = new RenderingHints(null);
|
||||
copy.renderingHints.putAll(renderingHints);
|
||||
@@ -1163,7 +1207,7 @@ public abstract class AbstractGraphics2D
|
||||
}
|
||||
else
|
||||
{
|
||||
ShapeCache sc = getShapeCache();
|
||||
ShapeCache sc = shapeCache;
|
||||
if (sc.line == null)
|
||||
sc.line = new Line2D.Float();
|
||||
sc.line.setLine(x1, y1, x2, y2);
|
||||
@@ -1175,11 +1219,13 @@ public abstract class AbstractGraphics2D
|
||||
{
|
||||
if (isOptimized)
|
||||
{
|
||||
rawDrawRect(x, y, w, h);
|
||||
int tx = (int) transform.getTranslateX();
|
||||
int ty = (int) transform.getTranslateY();
|
||||
rawDrawRect(x + tx, y + ty, w, h);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShapeCache sc = getShapeCache();
|
||||
ShapeCache sc = shapeCache;
|
||||
if (sc.rect == null)
|
||||
sc.rect = new Rectangle();
|
||||
sc.rect.setBounds(x, y, w, h);
|
||||
@@ -1204,7 +1250,7 @@ public abstract class AbstractGraphics2D
|
||||
}
|
||||
else
|
||||
{
|
||||
ShapeCache sc = getShapeCache();
|
||||
ShapeCache sc = shapeCache;
|
||||
if (sc.rect == null)
|
||||
sc.rect = new Rectangle();
|
||||
sc.rect.setBounds(x, y, width, height);
|
||||
@@ -1249,7 +1295,7 @@ public abstract class AbstractGraphics2D
|
||||
public void drawRoundRect(int x, int y, int width, int height, int arcWidth,
|
||||
int arcHeight)
|
||||
{
|
||||
ShapeCache sc = getShapeCache();
|
||||
ShapeCache sc = shapeCache;
|
||||
if (sc.roundRect == null)
|
||||
sc.roundRect = new RoundRectangle2D.Float();
|
||||
sc.roundRect.setRoundRect(x, y, width, height, arcWidth, arcHeight);
|
||||
@@ -1269,7 +1315,7 @@ public abstract class AbstractGraphics2D
|
||||
public void fillRoundRect(int x, int y, int width, int height, int arcWidth,
|
||||
int arcHeight)
|
||||
{
|
||||
ShapeCache sc = getShapeCache();
|
||||
ShapeCache sc = shapeCache;
|
||||
if (sc.roundRect == null)
|
||||
sc.roundRect = new RoundRectangle2D.Float();
|
||||
sc.roundRect.setRoundRect(x, y, width, height, arcWidth, arcHeight);
|
||||
@@ -1286,7 +1332,7 @@ public abstract class AbstractGraphics2D
|
||||
*/
|
||||
public void drawOval(int x, int y, int width, int height)
|
||||
{
|
||||
ShapeCache sc = getShapeCache();
|
||||
ShapeCache sc = shapeCache;
|
||||
if (sc.ellipse == null)
|
||||
sc.ellipse = new Ellipse2D.Float();
|
||||
sc.ellipse.setFrame(x, y, width, height);
|
||||
@@ -1303,7 +1349,7 @@ public abstract class AbstractGraphics2D
|
||||
*/
|
||||
public void fillOval(int x, int y, int width, int height)
|
||||
{
|
||||
ShapeCache sc = getShapeCache();
|
||||
ShapeCache sc = shapeCache;
|
||||
if (sc.ellipse == null)
|
||||
sc.ellipse = new Ellipse2D.Float();
|
||||
sc.ellipse.setFrame(x, y, width, height);
|
||||
@@ -1316,7 +1362,7 @@ public abstract class AbstractGraphics2D
|
||||
public void drawArc(int x, int y, int width, int height, int arcStart,
|
||||
int arcAngle)
|
||||
{
|
||||
ShapeCache sc = getShapeCache();
|
||||
ShapeCache sc = shapeCache;
|
||||
if (sc.arc == null)
|
||||
sc.arc = new Arc2D.Float();
|
||||
sc.arc.setArc(x, y, width, height, arcStart, arcAngle, Arc2D.OPEN);
|
||||
@@ -1329,7 +1375,7 @@ public abstract class AbstractGraphics2D
|
||||
public void fillArc(int x, int y, int width, int height, int arcStart,
|
||||
int arcAngle)
|
||||
{
|
||||
ShapeCache sc = getShapeCache();
|
||||
ShapeCache sc = shapeCache;
|
||||
if (sc.arc == null)
|
||||
sc.arc = new Arc2D.Float();
|
||||
sc.arc.setArc(x, y, width, height, arcStart, arcAngle, Arc2D.PIE);
|
||||
@@ -1338,7 +1384,7 @@ public abstract class AbstractGraphics2D
|
||||
|
||||
public void drawPolyline(int[] xPoints, int[] yPoints, int npoints)
|
||||
{
|
||||
ShapeCache sc = getShapeCache();
|
||||
ShapeCache sc = shapeCache;
|
||||
if (sc.polyline == null)
|
||||
sc.polyline = new GeneralPath();
|
||||
GeneralPath p = sc.polyline;
|
||||
@@ -1355,7 +1401,7 @@ public abstract class AbstractGraphics2D
|
||||
*/
|
||||
public void drawPolygon(int[] xPoints, int[] yPoints, int npoints)
|
||||
{
|
||||
ShapeCache sc = getShapeCache();
|
||||
ShapeCache sc = shapeCache;
|
||||
if (sc.polygon == null)
|
||||
sc.polygon = new Polygon();
|
||||
sc.polygon.reset();
|
||||
@@ -1370,7 +1416,7 @@ public abstract class AbstractGraphics2D
|
||||
*/
|
||||
public void fillPolygon(int[] xPoints, int[] yPoints, int npoints)
|
||||
{
|
||||
ShapeCache sc = getShapeCache();
|
||||
ShapeCache sc = shapeCache;
|
||||
if (sc.polygon == null)
|
||||
sc.polygon = new Polygon();
|
||||
sc.polygon.reset();
|
||||
@@ -1559,8 +1605,9 @@ public abstract class AbstractGraphics2D
|
||||
{
|
||||
Object v = renderingHints.get(RenderingHints.KEY_TEXT_ANTIALIASING);
|
||||
// We default to antialiasing for text rendering.
|
||||
antialias = (v == RenderingHints.VALUE_TEXT_ANTIALIAS_ON
|
||||
|| v == RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT);
|
||||
antialias = v == RenderingHints.VALUE_TEXT_ANTIALIAS_ON
|
||||
|| (v == RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT
|
||||
&& DEFAULT_TEXT_AA);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1569,12 +1616,15 @@ public abstract class AbstractGraphics2D
|
||||
}
|
||||
ScanlineConverter sc = getScanlineConverter();
|
||||
int resolution = 0;
|
||||
int yRes = 0;
|
||||
if (antialias)
|
||||
{
|
||||
// Adjust resolution according to rendering hints.
|
||||
resolution = 2;
|
||||
yRes = 4;
|
||||
}
|
||||
sc.renderShape(this, s, clip, transform, resolution, renderingHints);
|
||||
sc.renderShape(this, s, clip, transform, resolution, yRes, renderingHints);
|
||||
freeScanlineConverter(sc);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1606,7 +1656,7 @@ public abstract class AbstractGraphics2D
|
||||
*/
|
||||
protected void rawDrawLine(int x0, int y0, int x1, int y1)
|
||||
{
|
||||
ShapeCache sc = getShapeCache();
|
||||
ShapeCache sc = shapeCache;
|
||||
if (sc.line == null)
|
||||
sc.line = new Line2D.Float();
|
||||
sc.line.setLine(x0, y0, x1, y1);
|
||||
@@ -1615,29 +1665,13 @@ public abstract class AbstractGraphics2D
|
||||
|
||||
protected void rawDrawRect(int x, int y, int w, int h)
|
||||
{
|
||||
ShapeCache sc = getShapeCache();
|
||||
ShapeCache sc = shapeCache;
|
||||
if (sc.rect == null)
|
||||
sc.rect = new Rectangle();
|
||||
sc.rect.setBounds(x, y, w, h);
|
||||
draw(sc.rect);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws a string in optimization mode. The implementation should respect the
|
||||
* clip and translation. It can assume that the clip is a rectangle and that
|
||||
* the transform is only a translating transform.
|
||||
*
|
||||
* @param text the string to be drawn
|
||||
* @param x the start of the baseline, X coordinate
|
||||
* @param y the start of the baseline, Y coordinate
|
||||
*/
|
||||
protected void rawDrawString(String text, int x, int y)
|
||||
{
|
||||
FontRenderContext ctx = getFontRenderContext();
|
||||
GlyphVector gv = font.createGlyphVector(ctx, text.toCharArray());
|
||||
drawGlyphVector(gv, x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears a rectangle in optimization mode. The implementation should respect the
|
||||
* clip and translation. It can assume that the clip is a rectangle and that
|
||||
@@ -1667,7 +1701,7 @@ public abstract class AbstractGraphics2D
|
||||
*/
|
||||
protected void rawFillRect(int x, int y, int w, int h)
|
||||
{
|
||||
ShapeCache sc = getShapeCache();
|
||||
ShapeCache sc = shapeCache;
|
||||
if (sc.rect == null)
|
||||
sc.rect = new Rectangle();
|
||||
sc.rect.setBounds(x, y, w, h);
|
||||
@@ -1918,35 +1952,38 @@ public abstract class AbstractGraphics2D
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ShapeCache for the calling thread.
|
||||
* Returns a free scanline converter from the pool.
|
||||
*
|
||||
* @return the ShapeCache for the calling thread
|
||||
*/
|
||||
private ShapeCache getShapeCache()
|
||||
{
|
||||
ShapeCache sc = shapeCache.get();
|
||||
if (sc == null)
|
||||
{
|
||||
sc = new ShapeCache();
|
||||
shapeCache.set(sc);
|
||||
}
|
||||
return sc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the scanline converter for this thread.
|
||||
*
|
||||
* @return the scanline converter for this thread
|
||||
* @return a scanline converter
|
||||
*/
|
||||
private ScanlineConverter getScanlineConverter()
|
||||
{
|
||||
ScanlineConverter sc = scanlineConverters.get();
|
||||
if (sc == null)
|
||||
synchronized (scanlineConverters)
|
||||
{
|
||||
sc = new ScanlineConverter();
|
||||
scanlineConverters.set(sc);
|
||||
ScanlineConverter sc;
|
||||
if (scanlineConverters.size() > 0)
|
||||
{
|
||||
sc = scanlineConverters.removeFirst();
|
||||
}
|
||||
else
|
||||
{
|
||||
sc = new ScanlineConverter();
|
||||
}
|
||||
return sc;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts a scanline converter back in the pool.
|
||||
*
|
||||
* @param sc
|
||||
*/
|
||||
private void freeScanlineConverter(ScanlineConverter sc)
|
||||
{
|
||||
synchronized (scanlineConverters)
|
||||
{
|
||||
scanlineConverters.addLast(sc);
|
||||
}
|
||||
return sc;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
package gnu.java.awt.java2d;
|
||||
|
||||
/**
|
||||
* Stores and handles the pixel converage for a scanline. The pixel coverage
|
||||
* is stored as sorted list of buckets, 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.
|
||||
*/
|
||||
final class PixelCoverage
|
||||
{
|
||||
|
||||
/**
|
||||
* One bucket in the list.
|
||||
*/
|
||||
private static final class Bucket
|
||||
{
|
||||
/**
|
||||
* The X coordinate on the scanline to which this bucket belongs.
|
||||
*/
|
||||
int xPos;
|
||||
|
||||
/**
|
||||
* The X coverage.
|
||||
*/
|
||||
int xCov;
|
||||
|
||||
/**
|
||||
* The Y coverage.
|
||||
*/
|
||||
int yCov;
|
||||
|
||||
/**
|
||||
* Implements a linked list. This points to the next element of the list.
|
||||
*/
|
||||
Bucket next;
|
||||
|
||||
/**
|
||||
* Implements a linked list. This points to the previous element of the
|
||||
* list.
|
||||
*/
|
||||
Bucket prev;
|
||||
}
|
||||
|
||||
/**
|
||||
* The head of the sorted list of buckets.
|
||||
*/
|
||||
private Bucket 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 Bucket current;
|
||||
|
||||
/**
|
||||
* 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 Bucket last;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
void rewind()
|
||||
{
|
||||
current = head;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
void clear()
|
||||
{
|
||||
last = head;
|
||||
}
|
||||
|
||||
/**
|
||||
* This adds the specified x and y coverage to the pixel at the specified
|
||||
* X position.
|
||||
*
|
||||
* @param x the X position
|
||||
* @param xc the x coverage
|
||||
* @param yc the y coverage
|
||||
*/
|
||||
void add(int x, int xc, int yc)
|
||||
{
|
||||
Bucket bucket = findOrInsert(x);
|
||||
bucket.xCov += xc;
|
||||
bucket.yCov += yc;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 Bucket findOrInsert(int x)
|
||||
{
|
||||
// First search for a matching bucket.
|
||||
if (head == null)
|
||||
{
|
||||
// Special case: the list is still empty.
|
||||
head = new Bucket();
|
||||
current = head;
|
||||
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 not more then 1 or 2 buckets away from
|
||||
// the one we're looking for.
|
||||
Bucket match = current;
|
||||
while (match != null && match.xPos != x)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return match;
|
||||
}
|
||||
}
|
||||
@@ -61,11 +61,6 @@ public final class ScanlineConverter
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
@@ -93,6 +88,11 @@ public final class ScanlineConverter
|
||||
*/
|
||||
private int resolution;
|
||||
|
||||
/**
|
||||
* The number of significant bits for the 'Y' resolution.
|
||||
*/
|
||||
private int yResolution;
|
||||
|
||||
/**
|
||||
* One half step according to the resolution. This is stored to avoid
|
||||
* unnecessary operations during rendering.
|
||||
@@ -145,14 +145,15 @@ public final class ScanlineConverter
|
||||
* @param trans the transform
|
||||
*/
|
||||
public void renderShape(Pixelizer p, Shape shape, Shape clip,
|
||||
AffineTransform trans, int res, RenderingHints hints)
|
||||
AffineTransform trans, int res, int yRes,
|
||||
RenderingHints hints)
|
||||
{
|
||||
// TODO: Do something useful with the rendering hints. Like, adjusting
|
||||
// the resolution.
|
||||
|
||||
// Prepare resolution and upper bounds.
|
||||
clear();
|
||||
setResolution(res);
|
||||
setResolution(res, yRes);
|
||||
|
||||
boolean haveClip = clip != null;
|
||||
|
||||
@@ -278,10 +279,10 @@ public final class ScanlineConverter
|
||||
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);
|
||||
frac0 = frac0 >> (FIXED_DIGITS - yResolution);
|
||||
frac1 = frac1 >> (FIXED_DIGITS - yResolution);
|
||||
scanlineCoverage.add(pix0, 1 * (1 << yResolution), frac0);
|
||||
scanlineCoverage.add(pix1, -1 * (1 << yResolution), -frac1);
|
||||
}
|
||||
if (edge.isClip)
|
||||
inClip = ! inClip;
|
||||
@@ -306,14 +307,16 @@ public final class ScanlineConverter
|
||||
*
|
||||
* @param res the resolution
|
||||
*/
|
||||
private void setResolution(int res)
|
||||
private void setResolution(int res, int yRes)
|
||||
{
|
||||
int scanlinesPerPixel = 1 << res;
|
||||
int one = Fixed.fixedValue(FIXED_DIGITS, 1);
|
||||
resolution = one / (scanlinesPerPixel);
|
||||
halfStep = resolution / 2;
|
||||
|
||||
scanlineCoverage.setMaxCoverage(scanlinesPerPixel << Y_RESOLUTION);
|
||||
scanlineCoverage.setMaxCoverage(scanlinesPerPixel << yResolution);
|
||||
|
||||
yResolution = yRes;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -157,7 +157,7 @@ public final class ScanlineCoverage
|
||||
* 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
|
||||
{
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
/* ShapeWrapper.java -- Protects shapes by wrapping them
|
||||
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;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.PathIterator;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
|
||||
/**
|
||||
* Protects any other shape from beeing modified by wrapping it.
|
||||
*/
|
||||
public class ShapeWrapper
|
||||
implements Shape
|
||||
{
|
||||
|
||||
/**
|
||||
* The shape to be protected.
|
||||
*/
|
||||
private Shape shape;
|
||||
|
||||
/**
|
||||
* Creates a new ShapeWrapper.
|
||||
*
|
||||
* @param other the shape to be protected
|
||||
*/
|
||||
public ShapeWrapper(Shape other)
|
||||
{
|
||||
shape = other;
|
||||
}
|
||||
|
||||
public boolean contains(double x, double y)
|
||||
{
|
||||
return shape.contains(x, y);
|
||||
}
|
||||
|
||||
public boolean contains(Point2D p)
|
||||
{
|
||||
return shape.contains(p);
|
||||
}
|
||||
|
||||
public boolean contains(double x, double y, double w, double h)
|
||||
{
|
||||
return shape.contains(x, y, w, h);
|
||||
}
|
||||
|
||||
public boolean contains(Rectangle2D r)
|
||||
{
|
||||
return shape.contains(r);
|
||||
}
|
||||
|
||||
public Rectangle getBounds()
|
||||
{
|
||||
return shape.getBounds();
|
||||
}
|
||||
|
||||
public Rectangle2D getBounds2D()
|
||||
{
|
||||
return shape.getBounds2D();
|
||||
}
|
||||
|
||||
public PathIterator getPathIterator(AffineTransform transform)
|
||||
{
|
||||
return shape.getPathIterator(transform);
|
||||
}
|
||||
|
||||
public PathIterator getPathIterator(AffineTransform transform, double flatness)
|
||||
{
|
||||
return shape.getPathIterator(transform, flatness);
|
||||
}
|
||||
|
||||
public boolean intersects(double x, double y, double w, double h)
|
||||
{
|
||||
return shape.intersects(x, y, w, h);
|
||||
}
|
||||
|
||||
public boolean intersects(Rectangle2D r)
|
||||
{
|
||||
return shape.intersects(r);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
/* TextCacheKey.java -- Key to use for caching texts with their rendered layout
|
||||
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;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.font.FontRenderContext;
|
||||
|
||||
/**
|
||||
* A key object to be used when caching pre-rendered text.
|
||||
*/
|
||||
public class TextCacheKey
|
||||
{
|
||||
|
||||
/**
|
||||
* The actual string.
|
||||
*/
|
||||
private String string;
|
||||
|
||||
/**
|
||||
* The font render context.
|
||||
*/
|
||||
private FontRenderContext fontRenderContext;
|
||||
|
||||
/**
|
||||
* The font.
|
||||
*/
|
||||
private Font font;
|
||||
|
||||
/**
|
||||
* Creates a new TextCacheKey.
|
||||
*
|
||||
* This is intended to be used as search key. It is important to initialize
|
||||
* the values using the setter methods before using this key, otherwise
|
||||
* it will throw NPEs.
|
||||
*/
|
||||
public TextCacheKey()
|
||||
{
|
||||
// No-arg constructor.
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new TextCacheKey with initial values.
|
||||
*
|
||||
* @param s the string
|
||||
* @param f the font
|
||||
* @param frc the font render context
|
||||
*/
|
||||
public TextCacheKey(String s, Font f, FontRenderContext frc)
|
||||
{
|
||||
string = s;
|
||||
font = f;
|
||||
fontRenderContext = frc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-sets the string. This is intented to be used in search keys only.
|
||||
*
|
||||
* @param s the string to set
|
||||
*/
|
||||
public void setString(String s)
|
||||
{
|
||||
string = s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the font render context.
|
||||
* This is intented to be used in search keys only.
|
||||
*
|
||||
* @param frc the new font render context
|
||||
*/
|
||||
public void setFontRenderContext(FontRenderContext frc)
|
||||
{
|
||||
fontRenderContext = frc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the font.
|
||||
* This is intented to be used in search keys only.
|
||||
*
|
||||
* @param f the font to set
|
||||
*/
|
||||
public void setFont(Font f)
|
||||
{
|
||||
font = f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if two objects are equal.
|
||||
*
|
||||
* @see Object#equals(Object)
|
||||
*/
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
boolean eq;
|
||||
if (o instanceof TextCacheKey)
|
||||
{
|
||||
TextCacheKey other = (TextCacheKey) o;
|
||||
eq = other.string.equals(string)
|
||||
&& other.font.equals(font)
|
||||
&& other.fontRenderContext.equals(fontRenderContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
eq = false;
|
||||
}
|
||||
return eq;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes a hashcode for this key.
|
||||
*
|
||||
* @see Object#hashCode()
|
||||
*/
|
||||
public int hashCode()
|
||||
{
|
||||
return string.hashCode() ^ font.hashCode() ^ fontRenderContext.hashCode();
|
||||
}
|
||||
}
|
||||
@@ -37,10 +37,8 @@
|
||||
|
||||
package gnu.java.awt.peer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* @author Mario Torre <neugens@limasoftware.net>
|
||||
|
||||
@@ -38,6 +38,8 @@ exception statement from your version. */
|
||||
|
||||
package gnu.java.awt.peer.gtk;
|
||||
|
||||
import gnu.classpath.Configuration;
|
||||
|
||||
import gnu.java.awt.ClasspathToolkit;
|
||||
|
||||
import java.awt.AWTPermission;
|
||||
@@ -120,7 +122,10 @@ public abstract class CairoGraphics2D extends Graphics2D
|
||||
{
|
||||
static
|
||||
{
|
||||
System.loadLibrary("gtkpeer");
|
||||
if (Configuration.INIT_LOAD_LIBRARY)
|
||||
{
|
||||
System.loadLibrary("gtkpeer");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -222,7 +227,7 @@ public abstract class CairoGraphics2D extends Graphics2D
|
||||
|
||||
/**
|
||||
* Sets up the default values and allocates the native cairographics2d structure
|
||||
* @param cairo_t_pointer, a native pointer to a cairo_t of the context.
|
||||
* @param cairo_t_pointer a native pointer to a cairo_t of the context.
|
||||
*/
|
||||
public void setup(long cairo_t_pointer)
|
||||
{
|
||||
@@ -341,7 +346,8 @@ public abstract class CairoGraphics2D extends Graphics2D
|
||||
|
||||
/**
|
||||
* Draw pixels as an RGBA int matrix
|
||||
* @param w, h - width and height
|
||||
* @param w - width
|
||||
* @param h - height
|
||||
* @param stride - stride of the array width
|
||||
* @param i2u - affine transform array
|
||||
*/
|
||||
@@ -2113,10 +2119,10 @@ public abstract class CairoGraphics2D extends Graphics2D
|
||||
private static Rectangle 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 x2 = rect.x;
|
||||
int y2 = rect.y;
|
||||
int w2 = rect.width;
|
||||
int h2 = rect.height;
|
||||
|
||||
int dx = (x > x2) ? x : x2;
|
||||
int dy = (y > y2) ? y : y2;
|
||||
|
||||
@@ -43,9 +43,7 @@ import gnu.java.awt.Buffers;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Shape;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.DataBuffer;
|
||||
@@ -102,7 +100,8 @@ public class CairoSurface extends WritableRaster
|
||||
0x000000FF);
|
||||
/**
|
||||
* Allocates and clears the buffer and creates the cairo surface.
|
||||
* @param width, height - the image size
|
||||
* @param width - the image size
|
||||
* @param height - the image size
|
||||
* @param stride - the buffer row stride. (in ints)
|
||||
*/
|
||||
private native void create(int width, int height, int stride, int[] buf);
|
||||
|
||||
@@ -153,7 +153,7 @@ public class ComponentGraphics extends CairoGraphics2D
|
||||
/**
|
||||
* Creates a cairo_t for a volatile image
|
||||
*/
|
||||
protected native long initFromVolatile( long pixmapPtr, int width, int height);
|
||||
protected native long initFromVolatile( long pixmapPtr);
|
||||
|
||||
/**
|
||||
* Grab lock
|
||||
@@ -938,4 +938,4 @@ public class ComponentGraphics extends CairoGraphics2D
|
||||
unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ exception statement from your version. */
|
||||
|
||||
package gnu.java.awt.peer.gtk;
|
||||
|
||||
import gnu.classpath.Configuration;
|
||||
import gnu.classpath.Pointer;
|
||||
|
||||
import gnu.java.awt.ClasspathToolkit;
|
||||
@@ -166,7 +167,10 @@ public class GdkFontPeer extends ClasspathFontPeer
|
||||
|
||||
static
|
||||
{
|
||||
System.loadLibrary("gtkpeer");
|
||||
if (Configuration.INIT_LOAD_LIBRARY)
|
||||
{
|
||||
System.loadLibrary("gtkpeer");
|
||||
}
|
||||
|
||||
initStaticState ();
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ exception statement from your version. */
|
||||
|
||||
package gnu.java.awt.peer.gtk;
|
||||
|
||||
import gnu.classpath.Configuration;
|
||||
import gnu.java.awt.ClasspathGraphicsEnvironment;
|
||||
|
||||
import java.awt.Font;
|
||||
@@ -72,7 +73,10 @@ public class GdkGraphicsEnvironment extends ClasspathGraphicsEnvironment
|
||||
|
||||
static
|
||||
{
|
||||
System.loadLibrary("gtkpeer");
|
||||
if (Configuration.INIT_LOAD_LIBRARY)
|
||||
{
|
||||
System.loadLibrary("gtkpeer");
|
||||
}
|
||||
|
||||
GtkToolkit.initializeGlobalIDs();
|
||||
initIDs();
|
||||
|
||||
@@ -68,13 +68,17 @@ import javax.imageio.spi.ImageWriterSpi;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
|
||||
import gnu.classpath.Configuration;
|
||||
import gnu.classpath.Pointer;
|
||||
|
||||
public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
|
||||
{
|
||||
static
|
||||
{
|
||||
System.loadLibrary("gtkpeer");
|
||||
if (Configuration.INIT_LOAD_LIBRARY)
|
||||
{
|
||||
System.loadLibrary("gtkpeer");
|
||||
}
|
||||
|
||||
initStaticState ();
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ import java.awt.Rectangle;
|
||||
import java.awt.Window;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import gnu.classpath.Configuration;
|
||||
import gnu.classpath.Pointer;
|
||||
|
||||
class GdkScreenGraphicsDevice extends GraphicsDevice
|
||||
@@ -98,7 +99,11 @@ class GdkScreenGraphicsDevice extends GraphicsDevice
|
||||
|
||||
static
|
||||
{
|
||||
System.loadLibrary("gtkpeer");
|
||||
if (Configuration.INIT_LOAD_LIBRARY)
|
||||
{
|
||||
System.loadLibrary("gtkpeer");
|
||||
}
|
||||
|
||||
GtkToolkit.initializeGlobalIDs();
|
||||
initIDs();
|
||||
}
|
||||
|
||||
@@ -105,7 +105,9 @@ public class GtkComponentPeer extends GtkGenericPeer
|
||||
native void gtkWidgetGetDimensions (int[] dim);
|
||||
native void gtkWidgetGetPreferredDimensions (int[] dim);
|
||||
native void gtkWindowGetLocationOnScreen (int[] point);
|
||||
native void gtkWindowGetLocationOnScreenUnlocked (int[] point);
|
||||
native void gtkWidgetGetLocationOnScreen (int[] point);
|
||||
native void gtkWidgetGetLocationOnScreenUnlocked (int[] point);
|
||||
native void gtkWidgetSetCursor (int type, GtkImage image, int x, int y);
|
||||
native void gtkWidgetSetCursorUnlocked (int type, GtkImage image,
|
||||
int x, int y);
|
||||
@@ -250,7 +252,10 @@ public class GtkComponentPeer extends GtkGenericPeer
|
||||
public Point getLocationOnScreen ()
|
||||
{
|
||||
int point[] = new int[2];
|
||||
gtkWidgetGetLocationOnScreen (point);
|
||||
if (Thread.currentThread() == GtkMainThread.mainThread)
|
||||
gtkWidgetGetLocationOnScreenUnlocked (point);
|
||||
else
|
||||
gtkWidgetGetLocationOnScreen (point);
|
||||
return new Point (point[0], point[1]);
|
||||
}
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ public class GtkFramePeer extends GtkWindowPeer
|
||||
{
|
||||
// We're adding a menubar where there was no menubar before.
|
||||
gtkFixedSetVisible (false);
|
||||
menuBar = (MenuBarPeer) ((MenuBar) bar).getPeer();
|
||||
menuBar = (MenuBarPeer) bar.getPeer();
|
||||
setMenuBarPeer (menuBar);
|
||||
int menuBarWidth =
|
||||
awtComponent.getWidth () - insets.left - insets.right;
|
||||
@@ -109,7 +109,7 @@ public class GtkFramePeer extends GtkWindowPeer
|
||||
int oldHeight = menuBarHeight;
|
||||
int menuBarWidth =
|
||||
awtComponent.getWidth () - insets.left - insets.right;
|
||||
menuBar = (MenuBarPeer) ((MenuBar) bar).getPeer ();
|
||||
menuBar = (MenuBarPeer) bar.getPeer ();
|
||||
setMenuBarPeer (menuBar);
|
||||
if (menuBarWidth > 0)
|
||||
setMenuBarWidth (menuBar, menuBarWidth);
|
||||
|
||||
@@ -134,7 +134,7 @@ public class GtkMainThread extends Thread
|
||||
}
|
||||
}
|
||||
GtkGenericPeer.q()
|
||||
.postEvent(new NativeEventLoopRunningEvent(new Boolean(true)));
|
||||
.postEvent(new NativeEventLoopRunningEvent(Boolean.TRUE));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -161,7 +161,7 @@ public class GtkMainThread extends Thread
|
||||
}
|
||||
}
|
||||
GtkGenericPeer.q()
|
||||
.postEvent(new NativeEventLoopRunningEvent(new Boolean(false)));
|
||||
.postEvent(new NativeEventLoopRunningEvent(Boolean.FALSE));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,8 @@ exception statement from your version. */
|
||||
|
||||
package gnu.java.awt.peer.gtk;
|
||||
|
||||
import gnu.classpath.Configuration;
|
||||
|
||||
import gnu.java.awt.AWTUtilities;
|
||||
import gnu.java.awt.EmbeddedWindow;
|
||||
import gnu.java.awt.dnd.GtkMouseDragGestureRecognizer;
|
||||
@@ -170,7 +172,10 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
|
||||
|
||||
static
|
||||
{
|
||||
System.loadLibrary("gtkpeer");
|
||||
if (Configuration.INIT_LOAD_LIBRARY)
|
||||
{
|
||||
System.loadLibrary("gtkpeer");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gotta do that first.
|
||||
|
||||
@@ -396,7 +396,10 @@ public class GtkWindowPeer extends GtkContainerPeer
|
||||
public Point getLocationOnScreen()
|
||||
{
|
||||
int point[] = new int[2];
|
||||
gtkWindowGetLocationOnScreen(point);
|
||||
if (Thread.currentThread() == GtkMainThread.mainThread)
|
||||
gtkWindowGetLocationOnScreenUnlocked(point);
|
||||
else
|
||||
gtkWindowGetLocationOnScreen(point);
|
||||
return new Point(point[0], point[1]);
|
||||
}
|
||||
|
||||
|
||||
@@ -68,14 +68,14 @@ public class VolatileImageGraphics extends ComponentGraphics
|
||||
public VolatileImageGraphics(GtkVolatileImage img)
|
||||
{
|
||||
this.owner = img;
|
||||
cairo_t = initFromVolatile( owner.nativePointer, img.width, img.height );
|
||||
cairo_t = initFromVolatile( owner.nativePointer );
|
||||
setup( cairo_t );
|
||||
}
|
||||
|
||||
private VolatileImageGraphics(VolatileImageGraphics copy)
|
||||
{
|
||||
this.owner = copy.owner;
|
||||
cairo_t = initFromVolatile(owner.nativePointer, owner.width, owner.height);
|
||||
cairo_t = initFromVolatile(owner.nativePointer);
|
||||
copy( copy, cairo_t );
|
||||
}
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ public class QtMenuPeer extends QtMenuComponentPeer implements MenuPeer
|
||||
Menu o = (Menu)owner;
|
||||
for( int i=0; i < o.getItemCount(); i++ )
|
||||
{
|
||||
MenuItem ci = (MenuItem)o.getItem(i);
|
||||
MenuItem ci = o.getItem(i);
|
||||
if (ci instanceof Menu && ci.getPeer() != null)
|
||||
((QtMenuPeer)ci.getPeer()).addItems();
|
||||
addItem( ci );
|
||||
|
||||
@@ -37,16 +37,12 @@ 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;
|
||||
@@ -56,7 +52,6 @@ import java.awt.peer.CheckboxPeer;
|
||||
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JToggleButton;
|
||||
|
||||
/**
|
||||
|
||||
@@ -174,7 +174,7 @@ public class SwingMenuBarPeer
|
||||
/**
|
||||
* Adds a help menu to the menu bar.
|
||||
*
|
||||
* @param m the menu to add
|
||||
* @param menu the menu to add
|
||||
*/
|
||||
public void addHelpMenu(Menu menu)
|
||||
{
|
||||
|
||||
@@ -37,7 +37,6 @@ exception statement from your version. */
|
||||
|
||||
package gnu.java.awt.peer.swing;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
|
||||
@@ -36,7 +36,6 @@ 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.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
@@ -328,7 +327,7 @@ public class SwingTextFieldPeer
|
||||
* @param startPos the start index of the selection
|
||||
* @param endPos the start index of the selection
|
||||
*/
|
||||
public void select(int start_pos, int endPos)
|
||||
public void select(int startPos, int endPos)
|
||||
{
|
||||
// TODO: Must be implemented.
|
||||
}
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
/* ImageConverter.java -- Convert arbitrary Image impl to XImage
|
||||
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.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.ImageConsumer;
|
||||
import java.util.Hashtable;
|
||||
|
||||
/**
|
||||
* Convert a non-XImage to an XImage.
|
||||
*
|
||||
* @author Roman Kennke (kennke@aicas.com)
|
||||
*/
|
||||
public class ImageConverter implements ImageConsumer
|
||||
{
|
||||
|
||||
private XImage image;
|
||||
private Graphics imageGraphics;
|
||||
|
||||
public void setDimensions(int width, int height)
|
||||
{
|
||||
image = new XImage(width, height);
|
||||
}
|
||||
|
||||
public void setProperties(Hashtable props)
|
||||
{
|
||||
// Ignore for now.
|
||||
}
|
||||
|
||||
public void setColorModel(ColorModel model)
|
||||
{
|
||||
// Ignore for now.
|
||||
}
|
||||
|
||||
public void setHints(int flags)
|
||||
{
|
||||
// Ignore for now.
|
||||
}
|
||||
|
||||
public void setPixels(int x, int y, int w, int h, ColorModel model,
|
||||
byte[] pixels, int offset, int scansize)
|
||||
{
|
||||
// FIXME: Implement this.
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
}
|
||||
|
||||
public void setPixels(int x, int y, int w, int h, ColorModel model,
|
||||
int[] pixels, int offset, int scansize)
|
||||
{
|
||||
System.err.println("transferType: " + model.getTransferType());
|
||||
System.err.println("colorModel: " + model);
|
||||
if (imageGraphics == null)
|
||||
imageGraphics = image.getGraphics();
|
||||
int xend = x + w;
|
||||
int yend = y + h;
|
||||
for (int yy = y; yy < yend; yy++)
|
||||
{
|
||||
for (int xx = x; xx < xend; xx++)
|
||||
{
|
||||
int pixel = pixels[yy * scansize + xx + offset];
|
||||
imageGraphics.setColor(new Color(model.getRGB(pixel)));
|
||||
imageGraphics.fillRect(xx, yy, 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void imageComplete(int status)
|
||||
{
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
XImage getXImage()
|
||||
{
|
||||
return image;
|
||||
}
|
||||
}
|
||||
@@ -39,6 +39,7 @@ exception statement from your version. */
|
||||
package gnu.java.awt.peer.x;
|
||||
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.Window;
|
||||
@@ -223,16 +224,21 @@ public class XEventPump
|
||||
System.err.println("resize request for window id: " + key);
|
||||
|
||||
// Detect and report size changes.
|
||||
if (c.width() != awtWindow.getWidth()
|
||||
|| c.height() != awtWindow.getHeight())
|
||||
XWindowPeer xwindow = (XWindowPeer) awtWindow.getPeer();
|
||||
Insets i = xwindow.insets();
|
||||
if (c.width() != awtWindow.getWidth() - i.left - i.right
|
||||
|| c.height() != awtWindow.getHeight() - i.top - i.bottom)
|
||||
{
|
||||
if (XToolkit.DEBUG)
|
||||
System.err.println("Setting size on AWT window: " + c.width()
|
||||
+ ", " + c.height() + ", " + awtWindow.getWidth()
|
||||
+ ", " + awtWindow.getHeight());
|
||||
((XWindowPeer) awtWindow.getPeer()).callback = true;
|
||||
awtWindow.setSize(c.width(), c.height());
|
||||
((XWindowPeer) awtWindow.getPeer()).callback = false;
|
||||
xwindow.callback = true;
|
||||
xwindow.xwindow.width = c.width();
|
||||
xwindow.xwindow.height = c.height();
|
||||
awtWindow.setSize(c.width() + i.left + i.right,
|
||||
c.height() + i.top + i.bottom);
|
||||
xwindow.callback = false;
|
||||
}
|
||||
break;
|
||||
case Expose.CODE:
|
||||
@@ -245,6 +251,7 @@ public class XEventPump
|
||||
exp.height());
|
||||
//System.err.println("expose paint: " + r);
|
||||
// We need to clear the background of the exposed rectangle.
|
||||
assert awtWindow != null : "awtWindow == null for window ID: " + key;
|
||||
Graphics g = awtWindow.getGraphics();
|
||||
g.clearRect(r.x, r.y, r.width, r.height);
|
||||
g.dispose();
|
||||
|
||||
@@ -0,0 +1,768 @@
|
||||
/* 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("xfonts.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.FontInfo 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.FontInfo 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;
|
||||
Fontable.FontInfo.CharInfo[] charInfos = info.char_infos();
|
||||
for (Fontable.FontInfo.CharInfo charInfo : charInfos)
|
||||
{
|
||||
charWidths[index] = charInfo.character_width();
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
private void readCharWidthsNonLinear(Fontable.FontInfo 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.TextExtentInfo 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)
|
||||
{
|
||||
if (name == null)
|
||||
{
|
||||
name = "SansSerif";
|
||||
}
|
||||
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, int 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.");
|
||||
}
|
||||
|
||||
public Rectangle2D getStringBounds(Font font, CharacterIterator ci,
|
||||
int begin, int limit, FontRenderContext frc)
|
||||
{
|
||||
// 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(family, 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));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
@@ -65,6 +65,7 @@ public class XFramePeer
|
||||
XFramePeer(Frame f)
|
||||
{
|
||||
super(f);
|
||||
setTitle(f.getTitle());
|
||||
}
|
||||
|
||||
public void setIconImage(Image image)
|
||||
@@ -87,8 +88,7 @@ public class XFramePeer
|
||||
|
||||
public void setTitle(String title)
|
||||
{
|
||||
// TODO: Implement this.
|
||||
throw new UnsupportedOperationException("Not yet implemented.");
|
||||
xwindow.set_wm_name (title);
|
||||
}
|
||||
|
||||
public int getState()
|
||||
|
||||
@@ -38,6 +38,7 @@ exception statement from your version. */
|
||||
package gnu.java.awt.peer.x;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.Image;
|
||||
@@ -45,12 +46,18 @@ import java.awt.Paint;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Shape;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.Transparency;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.awt.image.ImageObserver;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.peer.FontPeer;
|
||||
import java.util.HashMap;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import gnu.java.awt.image.AsyncImage;
|
||||
import gnu.java.awt.java2d.AbstractGraphics2D;
|
||||
import gnu.java.awt.java2d.ScanlineCoverage;
|
||||
import gnu.x11.Colormap;
|
||||
@@ -62,6 +69,14 @@ public class XGraphics2D
|
||||
extends AbstractGraphics2D
|
||||
{
|
||||
|
||||
/**
|
||||
* When this property is set to true, then images are always rendered as
|
||||
* opaque images, ignoring their translucence. This is intended for
|
||||
* debugging and demonstration purposes.
|
||||
*/
|
||||
private static final boolean RENDER_OPAQUE =
|
||||
Boolean.getBoolean("escherpeer.renderopaque");
|
||||
|
||||
/**
|
||||
* The X Drawable to draw on.
|
||||
*/
|
||||
@@ -92,11 +107,19 @@ public class XGraphics2D
|
||||
//setClip(new Rectangle(0, 0, xdrawable.width, xdrawable.height));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void rawDrawLine(int x0, int y0, int x1, int y1)
|
||||
{
|
||||
xdrawable.segment(xgc, x0, y0, x1, y1);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void rawDrawRect(int x, int y, int w, int h)
|
||||
{
|
||||
xdrawable.rectangle(xgc, x, y, w, h, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void rawFillRect(int x, int y, int w, int h)
|
||||
{
|
||||
xdrawable.rectangle(xgc, x, y, w, h, true);
|
||||
@@ -217,55 +240,65 @@ public class XGraphics2D
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderScanline(int y, ScanlineCoverage c)
|
||||
{
|
||||
if (y >= xdrawable.height)
|
||||
return;
|
||||
|
||||
// TODO: Handle Composite and Paint.
|
||||
ScanlineCoverage.Iterator iter = c.iterate();
|
||||
float coverageAlpha = 0;
|
||||
int 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 x0 = range.getXPos();
|
||||
int l = range.getLength();
|
||||
if (coverageAlpha == c.getMaxCoverage())
|
||||
{
|
||||
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();
|
||||
// Simply paint the current color over the existing pixels.
|
||||
xdrawable.fill_rectangle(xgc, x0, y, l, 1);
|
||||
}
|
||||
else if (coverageAlpha > 0)
|
||||
{
|
||||
// Composite the current color with the existing pixels.
|
||||
int x1 = x0 + l;
|
||||
x0 = Math.min(Math.max(0, x0), xdrawable.width - 1);
|
||||
x1 = Math.min(Math.max(0, x1), xdrawable.width - 1);
|
||||
if ((x1 - x0) < 1)
|
||||
continue;
|
||||
l = x1 - x0;
|
||||
gnu.x11.image.ZPixmap existing = (ZPixmap)
|
||||
xdrawable.image(x0, y, l, 1, 0xFFFFFFFF,
|
||||
gnu.x11.image.Image.Format.ZPIXMAP);
|
||||
for (int x = 0; x < l; x++)
|
||||
{
|
||||
Color col = getColor();
|
||||
if (col == null)
|
||||
{
|
||||
col = Color.BLACK;
|
||||
}
|
||||
int red = col.getRed();
|
||||
int green = col.getGreen();
|
||||
int blue = col.getBlue();
|
||||
int redOut = existing.get_red(x, 0);
|
||||
int greenOut = existing.get_green(x, 0);
|
||||
int blueOut = existing.get_blue(x, 0);
|
||||
int outAlpha = maxCoverage - coverageAlpha;
|
||||
redOut = redOut * outAlpha + red * coverageAlpha;
|
||||
redOut = redOut / maxCoverage;
|
||||
greenOut = greenOut * outAlpha + green * coverageAlpha;
|
||||
greenOut = greenOut / maxCoverage;
|
||||
blueOut = blueOut * outAlpha + blue * coverageAlpha;
|
||||
blueOut = blueOut / maxCoverage;
|
||||
existing.set(x, 0, redOut, greenOut, blueOut);
|
||||
}
|
||||
xdrawable.put_image(xgc, existing, x0, y);
|
||||
}
|
||||
}
|
||||
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()
|
||||
@@ -278,6 +311,7 @@ public class XGraphics2D
|
||||
super.setPaint(p);
|
||||
if (p instanceof Color)
|
||||
{
|
||||
// TODO: Optimize for different standard bit-depths.
|
||||
Color c = (Color) p;
|
||||
XToolkit tk = (XToolkit) Toolkit.getDefaultToolkit();
|
||||
HashMap colorMap = tk.colorMap;
|
||||
@@ -302,8 +336,11 @@ public class XGraphics2D
|
||||
}
|
||||
}
|
||||
|
||||
private static WeakHashMap<Image,ZPixmap> imageCache = new WeakHashMap<Image,ZPixmap>();
|
||||
|
||||
protected boolean rawDrawImage(Image image, int x, int y, ImageObserver obs)
|
||||
{
|
||||
image = unwrap(image);
|
||||
boolean ret;
|
||||
if (image instanceof XImage)
|
||||
{
|
||||
@@ -319,6 +356,87 @@ public class XGraphics2D
|
||||
pvi.getHeight(obs), x, y);
|
||||
ret = true;
|
||||
}
|
||||
else if (image instanceof BufferedImage)
|
||||
{
|
||||
BufferedImage bi = (BufferedImage) image;
|
||||
DataBuffer db = bi.getRaster().getDataBuffer();
|
||||
if (db instanceof ZPixmapDataBuffer)
|
||||
{
|
||||
ZPixmapDataBuffer zpmdb = (ZPixmapDataBuffer) db;
|
||||
ZPixmap zpixmap = zpmdb.getZPixmap();
|
||||
xdrawable.put_image(xgc, zpixmap, x, y);
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
int transparency = bi.getTransparency();
|
||||
int w = bi.getWidth();
|
||||
int h = bi.getHeight();
|
||||
if (imageCache.containsKey(image))
|
||||
{
|
||||
ZPixmap zpixmap = imageCache.get(image);
|
||||
xdrawable.put_image(xgc, zpixmap, x, y);
|
||||
}
|
||||
else if (transparency == Transparency.OPAQUE || RENDER_OPAQUE)
|
||||
{
|
||||
XGraphicsDevice gd = XToolkit.getDefaultDevice();
|
||||
ZPixmap zpixmap = new ZPixmap(gd.getDisplay(), w, h);
|
||||
for (int yy = 0; yy < h; yy++)
|
||||
{
|
||||
for (int xx = 0; xx < w; xx++)
|
||||
{
|
||||
int rgb = bi.getRGB(xx, yy);
|
||||
zpixmap.set(xx, yy, rgb);
|
||||
}
|
||||
}
|
||||
xdrawable.put_image(xgc, zpixmap, x, y);
|
||||
imageCache.put(image, zpixmap);
|
||||
} else {
|
||||
ZPixmap zpixmap = (ZPixmap) xdrawable.image(x, y, w, h,
|
||||
0xffffffff,
|
||||
gnu.x11.image.Image.Format.ZPIXMAP);
|
||||
for (int yy = 0; yy < h; yy++)
|
||||
{
|
||||
for (int xx = 0; xx < w; xx++)
|
||||
{
|
||||
int rgb = bi.getRGB(xx, yy);
|
||||
int alpha = 0xff & (rgb >> 24);
|
||||
if (alpha == 0)
|
||||
{
|
||||
// Completely translucent.
|
||||
rgb = zpixmap.get_red(xx, yy) << 16
|
||||
| zpixmap.get_green(xx, yy) << 8
|
||||
| zpixmap.get_blue(xx, yy);
|
||||
}
|
||||
else if (alpha < 255)
|
||||
{
|
||||
// Composite pixels.
|
||||
int red = 0xff & (rgb >> 16);
|
||||
red = red * alpha
|
||||
+ (255 - alpha) * zpixmap.get_red(xx, yy);
|
||||
red = red / 255;
|
||||
int green = 0xff & (rgb >> 8);
|
||||
green = green * alpha
|
||||
+ (255 - alpha) * zpixmap.get_green(xx, yy);
|
||||
green = green / 255;
|
||||
int blue = 0xff & rgb;
|
||||
blue = blue * alpha
|
||||
+ (255 - alpha) * zpixmap.get_blue(xx, yy);
|
||||
blue = blue / 255;
|
||||
rgb = red << 16 | green << 8 | blue;
|
||||
}
|
||||
// else keep rgb value from source image.
|
||||
|
||||
zpixmap.set(xx, yy, rgb);
|
||||
}
|
||||
}
|
||||
xdrawable.put_image(xgc, zpixmap, x, y);
|
||||
// We can't cache prerendered translucent images, because
|
||||
// we never know how the background changes.
|
||||
}
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = super.rawDrawImage(image, x, y, obs);
|
||||
@@ -326,6 +444,50 @@ public class XGraphics2D
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void setFont(Font f)
|
||||
{
|
||||
super.setFont(f);
|
||||
FontPeer p = getFont().getPeer();
|
||||
if (p instanceof XFontPeer)
|
||||
{
|
||||
XFontPeer xFontPeer = (XFontPeer) p;
|
||||
xgc.set_font(xFontPeer.getXFont());
|
||||
}
|
||||
}
|
||||
|
||||
public void drawString(String s, int x, int y)
|
||||
{
|
||||
FontPeer p = getFont().getPeer();
|
||||
if (p instanceof XFontPeer)
|
||||
{
|
||||
int tx = (int) transform.getTranslateX();
|
||||
int ty = (int) transform.getTranslateY();
|
||||
xdrawable.text(xgc, x + tx, y + ty, s);
|
||||
}
|
||||
else
|
||||
{
|
||||
super.drawString(s, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts an image instance out of an AsyncImage. If the image isn't
|
||||
* an AsyncImage, then the original instance is returned.
|
||||
*
|
||||
* @param im the image
|
||||
*
|
||||
* @return the image to render
|
||||
*/
|
||||
private Image unwrap(Image im)
|
||||
{
|
||||
Image image = im;
|
||||
if (image instanceof AsyncImage)
|
||||
{
|
||||
AsyncImage aIm = (AsyncImage) image;
|
||||
image = aIm.getRealImage();
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,10 @@ exception statement from your version. */
|
||||
|
||||
package gnu.java.awt.peer.x;
|
||||
|
||||
import gnu.x11.Display;
|
||||
import gnu.x11.Screen;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.Point;
|
||||
@@ -158,4 +162,38 @@ public class XGraphicsConfiguration
|
||||
throw new UnsupportedOperationException("Not yet implemented.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the size of the primary screen.
|
||||
*
|
||||
* @return the size of the primary screen
|
||||
*/
|
||||
Dimension getSize()
|
||||
{
|
||||
// TODO: A GraphicsConfiguration should correspond to a Screen instance.
|
||||
Display d = device.getDisplay();
|
||||
Screen screen = d.default_screen;
|
||||
int w = screen.width;
|
||||
int h = screen.height;
|
||||
return new Dimension(w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the resolution of the primary screen in pixel-per-inch.
|
||||
*
|
||||
* @returnthe resolution of the primary screen in pixel-per-inch
|
||||
*/
|
||||
int getResolution()
|
||||
{
|
||||
Display d = device.getDisplay();
|
||||
Screen screen = d.default_screen;
|
||||
int w = screen.width * 254;
|
||||
int h = screen.height * 254;
|
||||
int wmm = screen.width_in_mm * 10;
|
||||
int hmm = screen.height_in_mm * 10;
|
||||
int xdpi = w / wmm;
|
||||
int ydpi = h / hmm;
|
||||
int dpi = (xdpi + ydpi) / 2;
|
||||
return dpi;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ exception statement from your version. */
|
||||
|
||||
package gnu.java.awt.peer.x;
|
||||
|
||||
import gnu.java.awt.font.OpenTypeFontPeer;
|
||||
import gnu.java.awt.java2d.RasterGraphics;
|
||||
import gnu.x11.Display;
|
||||
|
||||
@@ -189,14 +190,14 @@ public class XGraphicsEnvironment
|
||||
|
||||
public String[] getAvailableFontFamilyNames()
|
||||
{
|
||||
// TODO: Implement this.
|
||||
throw new UnsupportedOperationException("Not yet implemented.");
|
||||
return getAvailableFontFamilyNames(Locale.getDefault());
|
||||
}
|
||||
|
||||
public String[] getAvailableFontFamilyNames(Locale l)
|
||||
{
|
||||
// TODO: Implement this.
|
||||
throw new UnsupportedOperationException("Not yet implemented.");
|
||||
// TODO: This doesn't work when we are using X fonts.
|
||||
// Fix this.
|
||||
return OpenTypeFontPeer.getAvailableFontFamilyNames(l);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ import java.awt.FileDialog;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Frame;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Image;
|
||||
@@ -117,6 +118,8 @@ import javax.imageio.ImageIO;
|
||||
import gnu.classpath.SystemProperties;
|
||||
import gnu.java.awt.ClasspathToolkit;
|
||||
import gnu.java.awt.EmbeddedWindow;
|
||||
import gnu.java.awt.font.OpenTypeFontPeer;
|
||||
import gnu.java.awt.image.ImageConverter;
|
||||
import gnu.java.awt.peer.ClasspathFontPeer;
|
||||
import gnu.java.awt.peer.EmbeddedWindowPeer;
|
||||
import gnu.java.awt.peer.swing.SwingCanvasPeer;
|
||||
@@ -155,7 +158,8 @@ public class XToolkit
|
||||
/**
|
||||
* The cached fonts.
|
||||
*/
|
||||
private WeakHashMap fontCache = new WeakHashMap();
|
||||
private WeakHashMap<String,ClasspathFontPeer> fontCache =
|
||||
new WeakHashMap<String,ClasspathFontPeer>();
|
||||
|
||||
public XToolkit()
|
||||
{
|
||||
@@ -179,21 +183,32 @@ public class XToolkit
|
||||
*/
|
||||
public ClasspathFontPeer getClasspathFontPeer(String name, Map attrs)
|
||||
{
|
||||
String canonical = XFontPeer2.encodeFont(name, attrs);
|
||||
ClasspathFontPeer font;
|
||||
if (!fontCache.containsKey(canonical))
|
||||
if ("true".equals(System.getProperty("escherpeer.usexfonts")))
|
||||
{
|
||||
String graphics2d =
|
||||
SystemProperties.getProperty("gnu.xawt.graphics2d");
|
||||
//if (graphics2d != null && graphics2d.equals("gl"))
|
||||
font = new XFontPeer2(name, attrs);
|
||||
// else
|
||||
// font = new XFontPeer(name, attrs);
|
||||
fontCache.put(canonical, font);
|
||||
String canonical = XFontPeer.encodeFont(name, attrs);
|
||||
if (!fontCache.containsKey(canonical))
|
||||
{
|
||||
font = new XFontPeer(name, attrs);
|
||||
fontCache.put(canonical, font);
|
||||
}
|
||||
else
|
||||
{
|
||||
font = fontCache.get(canonical);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
font = (ClasspathFontPeer) fontCache.get(canonical);
|
||||
String canonical = OpenTypeFontPeer.encodeFont(name, attrs);
|
||||
if (!fontCache.containsKey(canonical))
|
||||
{
|
||||
font = new OpenTypeFontPeer(name, attrs);
|
||||
fontCache.put(canonical, font);
|
||||
}
|
||||
else
|
||||
{
|
||||
font = fontCache.get(canonical);
|
||||
}
|
||||
}
|
||||
return font;
|
||||
}
|
||||
@@ -338,14 +353,22 @@ public class XToolkit
|
||||
|
||||
public Dimension getScreenSize()
|
||||
{
|
||||
// FIXME: This is only a hack to get some apps working.
|
||||
return new Dimension(1024, 768);
|
||||
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
GraphicsDevice gd = ge.getDefaultScreenDevice();
|
||||
GraphicsConfiguration gc = gd.getDefaultConfiguration();
|
||||
XGraphicsConfiguration xgc = (XGraphicsConfiguration) gc;
|
||||
|
||||
return xgc.getSize();
|
||||
}
|
||||
|
||||
public int getScreenResolution()
|
||||
{
|
||||
// TODO: Implement this.
|
||||
throw new UnsupportedOperationException("Not yet implemented.");
|
||||
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
GraphicsDevice gd = ge.getDefaultScreenDevice();
|
||||
GraphicsConfiguration gc = gd.getDefaultConfiguration();
|
||||
XGraphicsConfiguration xgc = (XGraphicsConfiguration) gc;
|
||||
|
||||
return xgc.getResolution();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -363,8 +386,8 @@ public class XToolkit
|
||||
|
||||
public String[] getFontList()
|
||||
{
|
||||
// TODO: Implement this.
|
||||
throw new UnsupportedOperationException("Not yet implemented.");
|
||||
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||
return ge.getAvailableFontFamilyNames();
|
||||
}
|
||||
|
||||
public FontMetrics getFontMetrics(Font name)
|
||||
@@ -505,7 +528,7 @@ public class XToolkit
|
||||
{
|
||||
ImageConverter conv = new ImageConverter();
|
||||
producer.startProduction(conv);
|
||||
Image image = conv.getXImage();
|
||||
Image image = conv.getImage();
|
||||
return image;
|
||||
}
|
||||
|
||||
@@ -602,19 +625,17 @@ public class XToolkit
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isModalExclusionTypeSupported
|
||||
(Dialog.ModalExclusionType modalExclusionType)
|
||||
public boolean isModalExclusionTypeSupported(ModalExclusionType modalExclusionType)
|
||||
{
|
||||
// TODO: Implement properly.
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isModalityTypeSupported(Dialog.ModalityType modalityType)
|
||||
public boolean isModalityTypeSupported(ModalityType modalityType)
|
||||
{
|
||||
// TODO: Implement properly.
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -39,9 +39,11 @@ exception statement from your version. */
|
||||
package gnu.java.awt.peer.x;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Dialog;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.GraphicsDevice;
|
||||
@@ -54,9 +56,12 @@ import java.awt.event.PaintEvent;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.image.VolatileImage;
|
||||
|
||||
import gnu.x11.Atom;
|
||||
import gnu.x11.Window;
|
||||
import gnu.x11.event.Event;
|
||||
|
||||
import gnu.java.awt.font.OpenTypeFontPeer;
|
||||
import gnu.java.awt.peer.ClasspathFontPeer;
|
||||
import gnu.java.awt.peer.swing.SwingWindowPeer;
|
||||
|
||||
public class XWindowPeer
|
||||
@@ -84,7 +89,12 @@ public class XWindowPeer
|
||||
/**
|
||||
* The X window.
|
||||
*/
|
||||
private Window xwindow;
|
||||
protected Window xwindow;
|
||||
|
||||
/**
|
||||
* The frame insets. These get updated in {@link #show()}.
|
||||
*/
|
||||
private Insets insets;
|
||||
|
||||
XWindowPeer(java.awt.Window window)
|
||||
{
|
||||
@@ -92,15 +102,47 @@ public class XWindowPeer
|
||||
XGraphicsDevice dev = XToolkit.getDefaultDevice();
|
||||
|
||||
// TODO: Maybe initialize lazily in show().
|
||||
Window.Attributes atts = new Window.Attributes();
|
||||
// FIXME: Howto generate a Window without decorations?
|
||||
int x = Math.max(window.getX(), 0);
|
||||
int y = Math.max(window.getY(), 0);
|
||||
int w = Math.max(window.getWidth(), 1);
|
||||
int h = Math.max(window.getHeight(), 1);
|
||||
xwindow = new Window(dev.getDisplay().default_root, x, y, w, h);
|
||||
xwindow.create();
|
||||
xwindow = new Window(dev.getDisplay().default_root, x, y, w, h, 0, atts);
|
||||
xwindow.select_input(standardSelect);
|
||||
dev.getEventPump().registerWindow(xwindow, window);
|
||||
|
||||
boolean undecorated;
|
||||
if (awtComponent instanceof Frame)
|
||||
{
|
||||
Frame f = (Frame) awtComponent;
|
||||
undecorated = f.isUndecorated();
|
||||
}
|
||||
else if (awtComponent instanceof Dialog)
|
||||
{
|
||||
Dialog d = (Dialog) awtComponent;
|
||||
undecorated = d.isUndecorated();
|
||||
}
|
||||
else
|
||||
{
|
||||
undecorated = true;
|
||||
}
|
||||
if (undecorated)
|
||||
{
|
||||
// First try the Motif implementation of undecorated frames. This
|
||||
// is semantically closest and supported by all major window
|
||||
// managers.
|
||||
// TODO: At the time of writing this, there's no freedesktop.org
|
||||
// standard extension that matches the required semantic. Maybe
|
||||
// undecorated frames are added in the future, if so, then use these.
|
||||
Atom at = Atom.intern(dev.getDisplay(), "_MOTIF_WM_HINTS");
|
||||
if (at != null)
|
||||
{
|
||||
xwindow.change_property(Window.REPLACE, at, at, 32,
|
||||
new int[]{1 << 1, 0, 0, 0, 0}, 0, 5);
|
||||
}
|
||||
}
|
||||
insets = new Insets(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
public void toBack()
|
||||
@@ -139,7 +181,11 @@ public class XWindowPeer
|
||||
*/
|
||||
public Graphics getGraphics()
|
||||
{
|
||||
return new XGraphics2D(xwindow);
|
||||
XGraphics2D xg2d = new XGraphics2D(xwindow);
|
||||
xg2d.setColor(awtComponent.getForeground());
|
||||
xg2d.setBackground(awtComponent.getBackground());
|
||||
xg2d.setFont(awtComponent.getFont());
|
||||
return xg2d;
|
||||
}
|
||||
|
||||
public Image createImage(int w, int h)
|
||||
@@ -164,16 +210,11 @@ public class XWindowPeer
|
||||
*/
|
||||
public void show()
|
||||
{
|
||||
// // Prevent ResizeRedirect events.
|
||||
// //xwindow.select_input(noResizeRedirectSelect);
|
||||
// Window.Attributes atts = new Window.Attributes();
|
||||
// atts.set_override_redirect(true);
|
||||
// xwindow.change_attributes(atts);
|
||||
|
||||
// Prevent ResizeRedirect events.
|
||||
//xwindow.select_input(Event.NO_EVENT_MASK);
|
||||
//xwindow.select_input(noResizeRedirectSelect);
|
||||
|
||||
XGraphicsDevice dev = XToolkit.getDefaultDevice();
|
||||
xwindow.map();
|
||||
EventQueue eq = XToolkit.getDefaultToolkit().getSystemEventQueue();
|
||||
java.awt.Window w = (java.awt.Window) super.awtComponent;
|
||||
@@ -188,6 +229,20 @@ public class XWindowPeer
|
||||
// // Reset input selection.
|
||||
// atts.set_override_redirect(false);
|
||||
// xwindow.change_attributes(atts);
|
||||
|
||||
// Determine the frame insets.
|
||||
Atom atom = (Atom) Atom.intern(dev.getDisplay(), "_NET_FRAME_EXTENTS");
|
||||
Window.Property p = xwindow.get_property(false, atom, Atom.CARDINAL, 0,
|
||||
Window.MAX_WM_LENGTH);
|
||||
if (p.format() != 0)
|
||||
{
|
||||
insets = new Insets(p.value(0), p.value(1), p.value(2), p.value(3));
|
||||
Window.Changes ch = new Window.Changes();
|
||||
ch.width(awtComponent.getWidth() - insets.left - insets.top);
|
||||
ch.height(awtComponent.getHeight() - insets.top - insets.bottom);
|
||||
xwindow.configure(ch);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -214,40 +269,19 @@ public class XWindowPeer
|
||||
*/
|
||||
public void reshape(int x, int y, int width, int height)
|
||||
{
|
||||
// Prevent ResizeRedirect events.
|
||||
// //xwindow.select_input(noResizeRedirectSelect);
|
||||
// Window.Attributes atts = new Window.Attributes();
|
||||
// atts.set_override_redirect(true);
|
||||
// xwindow.change_attributes(atts);
|
||||
|
||||
// Need to substract insets because AWT size is including insets,
|
||||
// and X size is excuding insets.
|
||||
Insets i = insets();
|
||||
xwindow.move_resize(x - i.left, y - i.right, width - i.left - i.right,
|
||||
height - i.top - i.bottom);
|
||||
|
||||
// Reset input selection.
|
||||
// atts = new Window.Attributes();
|
||||
// atts.set_override_redirect(false);
|
||||
// xwindow.change_attributes(atts);
|
||||
// and X size is excluding insets.
|
||||
if (! callback)
|
||||
{
|
||||
Insets i = insets;
|
||||
xwindow.move_resize(x - i.left, y - i.right, width - i.left - i.right,
|
||||
height - i.top - i.bottom);
|
||||
}
|
||||
}
|
||||
|
||||
public Insets insets()
|
||||
{
|
||||
Insets i = new Insets(0, 0, 0, 0);
|
||||
// Window.GeometryReply g = xwindow.geometry();
|
||||
// int b = g.border_width();
|
||||
// Insets i = new Insets(b, b, b, b);
|
||||
// Window.WMSizeHints wmSize = xwindow.wm_normal_hints();
|
||||
// if (wmSize != null)
|
||||
// {
|
||||
// i.left = wmSize.x() - g.x();
|
||||
// i.right = wmSize.width() - g.width() - i.left ;
|
||||
// i.top = wmSize.y() - g.y();
|
||||
// i.bottom = wmSize.height() - g.height() - i.top;
|
||||
// }
|
||||
// System.err.println("insets: " + i);
|
||||
return i;
|
||||
return (Insets) insets.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -257,7 +291,7 @@ public class XWindowPeer
|
||||
*/
|
||||
public FontMetrics getFontMetrics(Font font)
|
||||
{
|
||||
XFontPeer2 fontPeer = (XFontPeer2) font.getPeer();
|
||||
ClasspathFontPeer fontPeer = (ClasspathFontPeer) font.getPeer();
|
||||
return fontPeer.getFontMetrics(font);
|
||||
}
|
||||
|
||||
|
||||
@@ -59,4 +59,9 @@ class ZPixmapDataBuffer
|
||||
zpixmap.set_data_element(i, (byte) val);
|
||||
}
|
||||
|
||||
ZPixmap getZPixmap()
|
||||
{
|
||||
return zpixmap;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -74,7 +74,6 @@ import java.awt.print.Pageable;
|
||||
import java.awt.print.Paper;
|
||||
import java.awt.print.Printable;
|
||||
import java.awt.print.PrinterException;
|
||||
import java.awt.print.PrinterGraphics;
|
||||
import java.awt.print.PrinterJob;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
|
||||
@@ -41,7 +41,6 @@ import javax.print.Doc;
|
||||
import javax.print.DocFlavor;
|
||||
import javax.print.attribute.DocAttributeSet;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.Reader;
|
||||
|
||||
Reference in New Issue
Block a user