From 1020ce5944edde4364baef4d371cd4f9b0dae721 Mon Sep 17 00:00:00 2001 From: doko Date: Sat, 28 Jun 2008 13:29:13 +0000 Subject: libjava/ 2008-06-28 Matthias Klose 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 * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@137223 138bc75d-0d04-0410-961f-82ee72b054a4 --- libjava/classpath/gnu/java/awt/AWTUtilities.java | 2 +- .../classpath/gnu/java/awt/ClasspathToolkit.java | 1 - libjava/classpath/gnu/java/awt/EmbeddedWindow.java | 1 - .../gnu/java/awt/font/GNUGlyphVector.java | 40 +- .../gnu/java/awt/font/OpenTypeFontPeer.java | 563 +++++++++++++++ .../classpath/gnu/java/awt/image/AsyncImage.java | 300 ++++++++ .../gnu/java/awt/image/ImageConverter.java | 528 ++++++++++++++ .../gnu/java/awt/java2d/AbstractGraphics2D.java | 165 +++-- .../gnu/java/awt/java2d/PixelCoverage.java | 132 ++++ .../gnu/java/awt/java2d/ScanlineConverter.java | 29 +- .../gnu/java/awt/java2d/ScanlineCoverage.java | 2 +- .../gnu/java/awt/java2d/ShapeWrapper.java | 119 ++++ .../gnu/java/awt/java2d/TextCacheKey.java | 153 ++++ .../gnu/java/awt/peer/KDEDesktopPeer.java | 2 - .../gnu/java/awt/peer/gtk/CairoGraphics2D.java | 20 +- .../gnu/java/awt/peer/gtk/CairoSurface.java | 5 +- .../gnu/java/awt/peer/gtk/ComponentGraphics.java | 4 +- .../gnu/java/awt/peer/gtk/GdkFontPeer.java | 6 +- .../java/awt/peer/gtk/GdkGraphicsEnvironment.java | 6 +- .../gnu/java/awt/peer/gtk/GdkPixbufDecoder.java | 6 +- .../java/awt/peer/gtk/GdkScreenGraphicsDevice.java | 7 +- .../gnu/java/awt/peer/gtk/GtkComponentPeer.java | 7 +- .../gnu/java/awt/peer/gtk/GtkFramePeer.java | 4 +- .../gnu/java/awt/peer/gtk/GtkMainThread.java | 4 +- .../gnu/java/awt/peer/gtk/GtkToolkit.java | 7 +- .../gnu/java/awt/peer/gtk/GtkWindowPeer.java | 5 +- .../java/awt/peer/gtk/VolatileImageGraphics.java | 4 +- .../classpath/gnu/java/awt/peer/qt/QtMenuPeer.java | 2 +- .../gnu/java/awt/peer/swing/SwingCheckboxPeer.java | 5 - .../gnu/java/awt/peer/swing/SwingMenuBarPeer.java | 2 +- .../gnu/java/awt/peer/swing/SwingTextAreaPeer.java | 1 - .../java/awt/peer/swing/SwingTextFieldPeer.java | 3 +- .../gnu/java/awt/peer/x/ImageConverter.java | 113 --- .../classpath/gnu/java/awt/peer/x/XEventPump.java | 17 +- .../classpath/gnu/java/awt/peer/x/XFontPeer.java | 768 +++++++++++++++++++++ .../classpath/gnu/java/awt/peer/x/XFontPeer2.java | 468 ------------- .../classpath/gnu/java/awt/peer/x/XFramePeer.java | 4 +- .../classpath/gnu/java/awt/peer/x/XGraphics2D.java | 234 ++++++- .../java/awt/peer/x/XGraphicsConfiguration.java | 38 + .../gnu/java/awt/peer/x/XGraphicsEnvironment.java | 9 +- .../classpath/gnu/java/awt/peer/x/XToolkit.java | 69 +- .../classpath/gnu/java/awt/peer/x/XWindowPeer.java | 114 +-- .../gnu/java/awt/peer/x/ZPixmapDataBuffer.java | 5 + .../gnu/java/awt/print/PostScriptGraphics2D.java | 1 - .../gnu/java/awt/print/SpooledDocument.java | 1 - 45 files changed, 3155 insertions(+), 821 deletions(-) create mode 100644 libjava/classpath/gnu/java/awt/font/OpenTypeFontPeer.java create mode 100644 libjava/classpath/gnu/java/awt/image/AsyncImage.java create mode 100644 libjava/classpath/gnu/java/awt/image/ImageConverter.java create mode 100644 libjava/classpath/gnu/java/awt/java2d/PixelCoverage.java create mode 100644 libjava/classpath/gnu/java/awt/java2d/ShapeWrapper.java create mode 100644 libjava/classpath/gnu/java/awt/java2d/TextCacheKey.java delete mode 100644 libjava/classpath/gnu/java/awt/peer/x/ImageConverter.java create mode 100644 libjava/classpath/gnu/java/awt/peer/x/XFontPeer.java delete mode 100644 libjava/classpath/gnu/java/awt/peer/x/XFontPeer2.java (limited to 'libjava/classpath/gnu/java/awt') diff --git a/libjava/classpath/gnu/java/awt/AWTUtilities.java b/libjava/classpath/gnu/java/awt/AWTUtilities.java index 1b68703697f..dcebc67fa25 100644 --- a/libjava/classpath/gnu/java/awt/AWTUtilities.java +++ b/libjava/classpath/gnu/java/awt/AWTUtilities.java @@ -126,7 +126,7 @@ public class AWTUtilities * * @return the next visible Component in the List * - * @throws if there is no next element + * @throws NoSuchElementException if there is no next element */ public Object next() { diff --git a/libjava/classpath/gnu/java/awt/ClasspathToolkit.java b/libjava/classpath/gnu/java/awt/ClasspathToolkit.java index d78fbab4e1e..7bbc70ccb1f 100644 --- a/libjava/classpath/gnu/java/awt/ClasspathToolkit.java +++ b/libjava/classpath/gnu/java/awt/ClasspathToolkit.java @@ -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; diff --git a/libjava/classpath/gnu/java/awt/EmbeddedWindow.java b/libjava/classpath/gnu/java/awt/EmbeddedWindow.java index 99f90c9f85d..7c04e7daf77 100644 --- a/libjava/classpath/gnu/java/awt/EmbeddedWindow.java +++ b/libjava/classpath/gnu/java/awt/EmbeddedWindow.java @@ -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; diff --git a/libjava/classpath/gnu/java/awt/font/GNUGlyphVector.java b/libjava/classpath/gnu/java/awt/font/GNUGlyphVector.java index 2f73dce77b0..22f331e15d1 100644 --- a/libjava/classpath/gnu/java/awt/font/GNUGlyphVector.java +++ b/libjava/classpath/gnu/java/awt/font/GNUGlyphVector.java @@ -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; } diff --git a/libjava/classpath/gnu/java/awt/font/OpenTypeFontPeer.java b/libjava/classpath/gnu/java/awt/font/OpenTypeFontPeer.java new file mode 100644 index 00000000000..2d898a44801 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/font/OpenTypeFontPeer.java @@ -0,0 +1,563 @@ +/* XFontPeer2.java -- A Java based TTF 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.font; + +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; +import java.awt.font.LineMetrics; +import java.awt.font.TextAttribute; +import java.awt.geom.AffineTransform; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; +import java.text.CharacterIterator; +import java.text.StringCharacterIterator; +import java.util.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.peer.ClasspathFontPeer; + +public class OpenTypeFontPeer + extends ClasspathFontPeer +{ + + /** + * The font mapping as specified in the file fonts.properties. + */ + private static Properties fontProperties; + + /** + * The available font family names. + */ + private static Set availableFontNames; + + /** + * Font spec to file mapping. + */ + private static Map> fontToFileMap; + + static + { + fontProperties = new Properties(); + InputStream in = OpenTypeFontPeer.class.getResourceAsStream("fonts.properties"); + try + { + fontProperties.load(in); + } + catch (IOException e) + { + e.printStackTrace(); + } + } + + private class XLineMetrics + extends LineMetrics + { + + private Font font; + private GlyphVector glyphVector; +// private CharacterIterator characterIterator; +// private int begin; +// private int limit; + private FontRenderContext fontRenderContext; + XLineMetrics(Font f, CharacterIterator ci, int b, int l, + FontRenderContext rc) + { + font = f; +// characterIterator = ci; +// begin = b; +// limit = l; + fontRenderContext = rc; + glyphVector = fontDelegate.createGlyphVector(font, fontRenderContext, + ci); + } + + public float getAscent() + { + return fontDelegate.getAscent(font.getSize(), fontRenderContext.getTransform(), + fontRenderContext.isAntiAliased(), + fontRenderContext.usesFractionalMetrics(), true); + } + + public int getBaselineIndex() + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public float[] getBaselineOffsets() + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public float getDescent() + { + return (int) fontDelegate.getDescent(font.getSize(), IDENDITY, false, + false, false); + } + + public float getHeight() + { + return (float) glyphVector.getLogicalBounds().getHeight(); + } + + public float getLeading() + { + return getHeight() - getAscent() - getDescent(); + } + + public int getNumChars() + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public float getStrikethroughOffset() + { + return 0.F; + } + + public float getStrikethroughThickness() + { + return 0.F; + } + + public float getUnderlineOffset() + { + return 0.F; + } + + public float getUnderlineThickness() + { + return 0.F; + } + + } + + private class XFontMetrics + extends FontMetrics + { + /** + * A cached point instance, to be used in #charWidth(). + */ + private Point2D cachedPoint = new Point2D.Double(); + + XFontMetrics(Font f) + { + super(f); + } + + public int getAscent() + { + return (int) fontDelegate.getAscent(getFont().getSize(), IDENDITY, + false, false, false); + } + + public int getDescent() + { + return (int) fontDelegate.getDescent(getFont().getSize(), IDENDITY, + false, false, false); + } + + public int getHeight() + { + GlyphVector gv = fontDelegate.createGlyphVector(getFont(), + new FontRenderContext(IDENDITY, false, false), + new StringCharacterIterator("m")); + Rectangle2D b = gv.getVisualBounds(); + return (int) b.getHeight(); + } + + public int charWidth(char c) + { + int code = fontDelegate.getGlyphIndex(c); + Point2D advance = cachedPoint; + fontDelegate.getAdvance(code, font.getSize2D(), IDENDITY, + false, false, true, advance); + return (int) advance.getX(); + } + + public int charsWidth(char[] chars, int offs, int len) + { + return stringWidth(new String(chars, offs, len)); + } + + public int stringWidth(String s) + { + GlyphVector gv = fontDelegate.createGlyphVector(getFont(), + new FontRenderContext(IDENDITY, false, false), + new StringCharacterIterator(s)); + Rectangle2D b = gv.getVisualBounds(); + return (int) b.getWidth(); + } + } + + /** + * The indendity transform, to be used in several methods. + */ + private static final AffineTransform IDENDITY = new AffineTransform(); + + private FontDelegate fontDelegate; + + public OpenTypeFontPeer(String name, int style, int size) + { + super(name, style, size); + try + { + 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, + fontfile.length()); + fontDelegate = FontFactory.createFonts(buffer)[0]; + } + catch (Exception ex) + { + ex.printStackTrace(); + } + } + + public OpenTypeFontPeer(String name, Map atts) + { + super(name, atts); + try + { + 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, + fontfile.length()); + fontDelegate = FontFactory.createFonts(buffer)[0]; + } + catch (Exception ex) + { + ex.printStackTrace(); + } + } + + public boolean canDisplay(Font font, int c) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public int canDisplayUpTo(Font font, CharacterIterator i, int start, int limit) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public String getSubFamilyName(Font font, Locale locale) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public String getPostScriptName(Font font) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public int getNumGlyphs(Font font) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public int getMissingGlyphCode(Font font) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public byte getBaselineFor(Font font, char c) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public String getGlyphName(Font font, int glyphIndex) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public GlyphVector createGlyphVector(Font font, FontRenderContext frc, CharacterIterator ci) + { + return fontDelegate.createGlyphVector(font, frc, ci); + } + + public GlyphVector createGlyphVector(Font font, FontRenderContext ctx, int[] glyphCodes) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public GlyphVector layoutGlyphVector(Font font, FontRenderContext frc, char[] chars, int start, int limit, int flags) + { + StringCharacterIterator i = new StringCharacterIterator(new String(chars), start, limit, 0); + return fontDelegate.createGlyphVector(font, frc, i); + } + + public FontMetrics getFontMetrics(Font font) + { + return new XFontMetrics(font); + } + + public boolean hasUniformLineMetrics(Font font) + { + // FIXME: Implement this. + throw new UnsupportedOperationException("Not yet implemented"); + } + + public LineMetrics getLineMetrics(Font font, CharacterIterator ci, int begin, int limit, FontRenderContext rc) + { + return new XLineMetrics(font, ci, begin, limit, rc); + } + + public Rectangle2D getMaxCharBounds(Font font, FontRenderContext rc) + { + // FIXME: 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 + */ + public 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 style = 0; + // Detect italic attribute. + Float posture = (Float) atts.get(TextAttribute.POSTURE); + if (posture != null && !posture.equals(TextAttribute.POSTURE_REGULAR)) + style |= Font.ITALIC; + + // Detect bold attribute. + Float weight = (Float) atts.get(TextAttribute.WEIGHT); + if (weight != null && weight.compareTo(TextAttribute.WEIGHT_REGULAR) > 0) + style |= Font.BOLD; + + return encodeFont(name, style); + } + + /** + * 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 + * + * @return the encoded font description + */ + static String encodeFont(String name, int style) + { + StringBuilder key = new StringBuilder(); + key.append(validName(name)); + key.append('/'); + switch (style) + { + case Font.BOLD: + key.append("b"); + break; + case Font.ITALIC: + key.append("i"); + break; + case (Font.BOLD | Font.ITALIC): + key.append("bi"); + break; + case Font.PLAIN: + default: + key.append("p"); + + } + + return key.toString(); + } + + /** + * 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; + Set fontNames = getFontNames(); + if (fontNames.contains(name)) + { + retVal = name; + } + else + { + retVal = "SansSerif"; + } + return retVal; + } + + public static String[] getAvailableFontFamilyNames(Locale l) + { + Set fontNames = getFontNames(); + int numNames = fontNames.size(); + String[] ret = fontNames.toArray(new String[numNames]); + return ret; + } + + private static synchronized Set getFontNames() + { + if (availableFontNames == null) + { + HashSet familyNames = new HashSet(); + 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 null 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>(); + + // 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 specToFileMap = fontToFileMap.get(name); + if (specToFileMap == null) + { + specToFileMap = new HashMap(); + 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 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); + } +} diff --git a/libjava/classpath/gnu/java/awt/image/AsyncImage.java b/libjava/classpath/gnu/java/awt/image/AsyncImage.java new file mode 100644 index 00000000000..935601a8898 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/image/AsyncImage.java @@ -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 null + * 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 null. + * + * @return the real image source, or null 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 observers; + + private volatile boolean complete = false; + + /** + * Creates a new AsyncImage. + */ + AsyncImage() + { + observers = new HashSet(); + } + + 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 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 null. 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(); + } + } + } + } + } +} diff --git a/libjava/classpath/gnu/java/awt/image/ImageConverter.java b/libjava/classpath/gnu/java/awt/image/ImageConverter.java new file mode 100644 index 00000000000..f607b349630 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/image/ImageConverter.java @@ -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:
+ * 1. if no color model was given use the hinted color model
+ * 2. if no color model was given and non was hinted use the default sRGB color model.
+ * Also:
+ * 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; + } +} diff --git a/libjava/classpath/gnu/java/awt/java2d/AbstractGraphics2D.java b/libjava/classpath/gnu/java/awt/java2d/AbstractGraphics2D.java index 15ec90da1c0..36ba0f4304c 100644 --- a/libjava/classpath/gnu/java/awt/java2d/AbstractGraphics2D.java +++ b/libjava/classpath/gnu/java/awt/java2d/AbstractGraphics2D.java @@ -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 = - new ThreadLocal(); + private static final ShapeCache shapeCache = new ShapeCache(); + + /** + * 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 LinkedList scanlineConverters = + new LinkedList(); + + /** + * Caches glyph vectors for better drawing performance. + */ + private static final Map gvCache = + Collections.synchronizedMap(new LRUCache(GV_CACHE_SIZE)); /** - * The scanline converters by thread. + * This key is used to search in the gvCache without allocating a new + * key each time. */ - private static final ThreadLocal scanlineConverters = - new ThreadLocal(); + 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 + * @return a scanline converter */ - private ShapeCache getShapeCache() + private ScanlineConverter getScanlineConverter() { - ShapeCache sc = shapeCache.get(); - if (sc == null) + synchronized (scanlineConverters) { - sc = new ShapeCache(); - shapeCache.set(sc); + ScanlineConverter sc; + if (scanlineConverters.size() > 0) + { + sc = scanlineConverters.removeFirst(); + } + else + { + sc = new ScanlineConverter(); + } + return sc; } - return sc; } /** - * Returns the scanline converter for this thread. + * Puts a scanline converter back in the pool. * - * @return the scanline converter for this thread + * @param sc */ - private ScanlineConverter getScanlineConverter() + private void freeScanlineConverter(ScanlineConverter sc) { - ScanlineConverter sc = scanlineConverters.get(); - if (sc == null) + synchronized (scanlineConverters) { - sc = new ScanlineConverter(); - scanlineConverters.set(sc); + scanlineConverters.addLast(sc); } - return sc; } } diff --git a/libjava/classpath/gnu/java/awt/java2d/PixelCoverage.java b/libjava/classpath/gnu/java/awt/java2d/PixelCoverage.java new file mode 100644 index 00000000000..c83ad1fff8f --- /dev/null +++ b/libjava/classpath/gnu/java/awt/java2d/PixelCoverage.java @@ -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; + } +} diff --git a/libjava/classpath/gnu/java/awt/java2d/ScanlineConverter.java b/libjava/classpath/gnu/java/awt/java2d/ScanlineConverter.java index 2693a0b70c7..cc4bbef28c0 100644 --- a/libjava/classpath/gnu/java/awt/java2d/ScanlineConverter.java +++ b/libjava/classpath/gnu/java/awt/java2d/ScanlineConverter.java @@ -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; } /** diff --git a/libjava/classpath/gnu/java/awt/java2d/ScanlineCoverage.java b/libjava/classpath/gnu/java/awt/java2d/ScanlineCoverage.java index 6db7fb01988..deb603bcb51 100644 --- a/libjava/classpath/gnu/java/awt/java2d/ScanlineCoverage.java +++ b/libjava/classpath/gnu/java/awt/java2d/ScanlineCoverage.java @@ -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 { /** diff --git a/libjava/classpath/gnu/java/awt/java2d/ShapeWrapper.java b/libjava/classpath/gnu/java/awt/java2d/ShapeWrapper.java new file mode 100644 index 00000000000..f4e77f450d0 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/java2d/ShapeWrapper.java @@ -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); + } + +} diff --git a/libjava/classpath/gnu/java/awt/java2d/TextCacheKey.java b/libjava/classpath/gnu/java/awt/java2d/TextCacheKey.java new file mode 100644 index 00000000000..0a60c622676 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/java2d/TextCacheKey.java @@ -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(); + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/KDEDesktopPeer.java b/libjava/classpath/gnu/java/awt/peer/KDEDesktopPeer.java index 676bd891758..30dd89ba7b2 100644 --- a/libjava/classpath/gnu/java/awt/peer/KDEDesktopPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/KDEDesktopPeer.java @@ -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 diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/CairoGraphics2D.java b/libjava/classpath/gnu/java/awt/peer/gtk/CairoGraphics2D.java index db8acd1cda0..fcd3f6acd92 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/CairoGraphics2D.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/CairoGraphics2D.java @@ -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; diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/CairoSurface.java b/libjava/classpath/gnu/java/awt/peer/gtk/CairoSurface.java index b45a79fd6e7..6c8a30d1143 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/CairoSurface.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/CairoSurface.java @@ -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); diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/ComponentGraphics.java b/libjava/classpath/gnu/java/awt/peer/gtk/ComponentGraphics.java index 4ce20a30d32..bfa3bc96ac3 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/ComponentGraphics.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/ComponentGraphics.java @@ -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(); } } -} \ No newline at end of file +} diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontPeer.java index 95a806ac7ee..403671cc63e 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkFontPeer.java @@ -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 (); diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java index d06af84433f..980866c4b67 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java @@ -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(); diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java index e52bf050c09..dbf4a2018c1 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java @@ -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 (); } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GdkScreenGraphicsDevice.java b/libjava/classpath/gnu/java/awt/peer/gtk/GdkScreenGraphicsDevice.java index 7ef4645a257..9ce0b96dac3 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GdkScreenGraphicsDevice.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GdkScreenGraphicsDevice.java @@ -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(); } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java index f658c17afbb..4b8fc128cb7 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java @@ -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]); } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkFramePeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkFramePeer.java index 4278a4579e4..87dbd5e0f56 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkFramePeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkFramePeer.java @@ -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); diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkMainThread.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMainThread.java index e40a04eed92..0ee61df84b7 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkMainThread.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkMainThread.java @@ -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)); } } } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkToolkit.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkToolkit.java index dc9c7155e6e..486304ef010 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkToolkit.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkToolkit.java @@ -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. diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/GtkWindowPeer.java b/libjava/classpath/gnu/java/awt/peer/gtk/GtkWindowPeer.java index 5dc4b2e5b37..9744c3a532e 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/GtkWindowPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/GtkWindowPeer.java @@ -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]); } diff --git a/libjava/classpath/gnu/java/awt/peer/gtk/VolatileImageGraphics.java b/libjava/classpath/gnu/java/awt/peer/gtk/VolatileImageGraphics.java index ad5cd5ecdf2..b5858f90595 100644 --- a/libjava/classpath/gnu/java/awt/peer/gtk/VolatileImageGraphics.java +++ b/libjava/classpath/gnu/java/awt/peer/gtk/VolatileImageGraphics.java @@ -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 ); } diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtMenuPeer.java b/libjava/classpath/gnu/java/awt/peer/qt/QtMenuPeer.java index 7457c38d2ff..87324c71043 100644 --- a/libjava/classpath/gnu/java/awt/peer/qt/QtMenuPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtMenuPeer.java @@ -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 ); diff --git a/libjava/classpath/gnu/java/awt/peer/swing/SwingCheckboxPeer.java b/libjava/classpath/gnu/java/awt/peer/swing/SwingCheckboxPeer.java index a8e3cb01bab..03d6388e9f2 100755 --- a/libjava/classpath/gnu/java/awt/peer/swing/SwingCheckboxPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/swing/SwingCheckboxPeer.java @@ -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; /** diff --git a/libjava/classpath/gnu/java/awt/peer/swing/SwingMenuBarPeer.java b/libjava/classpath/gnu/java/awt/peer/swing/SwingMenuBarPeer.java index bd9dcd77aaa..0033efb025f 100644 --- a/libjava/classpath/gnu/java/awt/peer/swing/SwingMenuBarPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/swing/SwingMenuBarPeer.java @@ -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) { diff --git a/libjava/classpath/gnu/java/awt/peer/swing/SwingTextAreaPeer.java b/libjava/classpath/gnu/java/awt/peer/swing/SwingTextAreaPeer.java index 2c438a1ccb1..5be82f69593 100644 --- a/libjava/classpath/gnu/java/awt/peer/swing/SwingTextAreaPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/swing/SwingTextAreaPeer.java @@ -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; diff --git a/libjava/classpath/gnu/java/awt/peer/swing/SwingTextFieldPeer.java b/libjava/classpath/gnu/java/awt/peer/swing/SwingTextFieldPeer.java index 29a689da42a..28dc5f339bf 100644 --- a/libjava/classpath/gnu/java/awt/peer/swing/SwingTextFieldPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/swing/SwingTextFieldPeer.java @@ -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. } diff --git a/libjava/classpath/gnu/java/awt/peer/x/ImageConverter.java b/libjava/classpath/gnu/java/awt/peer/x/ImageConverter.java deleted file mode 100644 index 6d32448eece..00000000000 --- a/libjava/classpath/gnu/java/awt/peer/x/ImageConverter.java +++ /dev/null @@ -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; - } -} diff --git a/libjava/classpath/gnu/java/awt/peer/x/XEventPump.java b/libjava/classpath/gnu/java/awt/peer/x/XEventPump.java index d376619c595..7f984353316 100644 --- a/libjava/classpath/gnu/java/awt/peer/x/XEventPump.java +++ b/libjava/classpath/gnu/java/awt/peer/x/XEventPump.java @@ -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(); diff --git a/libjava/classpath/gnu/java/awt/peer/x/XFontPeer.java b/libjava/classpath/gnu/java/awt/peer/x/XFontPeer.java new file mode 100644 index 00000000000..0a96a613b4e --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/x/XFontPeer.java @@ -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 c. + * + * @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; + } +} diff --git a/libjava/classpath/gnu/java/awt/peer/x/XFontPeer2.java b/libjava/classpath/gnu/java/awt/peer/x/XFontPeer2.java deleted file mode 100644 index ab3861be1a9..00000000000 --- a/libjava/classpath/gnu/java/awt/peer/x/XFontPeer2.java +++ /dev/null @@ -1,468 +0,0 @@ -/* XFontPeer2.java -- A Java based TTF 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.Font; -import java.awt.FontMetrics; -import java.awt.font.FontRenderContext; -import java.awt.font.GlyphVector; -import java.awt.font.LineMetrics; -import java.awt.font.TextAttribute; -import java.awt.geom.AffineTransform; -import java.awt.geom.Point2D; -import java.awt.geom.Rectangle2D; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.nio.ByteBuffer; -import java.nio.channels.FileChannel; -import java.text.CharacterIterator; -import java.text.StringCharacterIterator; -import java.util.Locale; -import java.util.Map; -import java.util.Properties; - -import gnu.java.awt.font.FontDelegate; -import gnu.java.awt.font.FontFactory; -import gnu.java.awt.peer.ClasspathFontPeer; - -public class XFontPeer2 - extends ClasspathFontPeer -{ - - /** - * The font mapping as specified in the file fonts.properties. - */ - private static Properties fontProperties; - static - { - fontProperties = new Properties(); - InputStream in = XFontPeer2.class.getResourceAsStream("fonts.properties"); - try - { - fontProperties.load(in); - } - catch (IOException e) - { - e.printStackTrace(); - } - } - - private class XLineMetrics - extends LineMetrics - { - - private Font font; - private GlyphVector glyphVector; -// private CharacterIterator characterIterator; -// private int begin; -// private int limit; - private FontRenderContext fontRenderContext; - XLineMetrics(Font f, CharacterIterator ci, int b, int l, - FontRenderContext rc) - { - font = f; -// characterIterator = ci; -// begin = b; -// limit = l; - fontRenderContext = rc; - glyphVector = fontDelegate.createGlyphVector(font, fontRenderContext, - ci); - } - - public float getAscent() - { - return fontDelegate.getAscent(font.getSize(), fontRenderContext.getTransform(), - fontRenderContext.isAntiAliased(), - fontRenderContext.usesFractionalMetrics(), true); - } - - public int getBaselineIndex() - { - // FIXME: Implement this. - throw new UnsupportedOperationException("Not yet implemented"); - } - - public float[] getBaselineOffsets() - { - // FIXME: Implement this. - throw new UnsupportedOperationException("Not yet implemented"); - } - - public float getDescent() - { - return (int) fontDelegate.getDescent(font.getSize(), IDENDITY, false, - false, false); - } - - public float getHeight() - { - return (float) glyphVector.getLogicalBounds().getHeight(); - } - - public float getLeading() - { - return getHeight() - getAscent() - getDescent(); - } - - public int getNumChars() - { - // FIXME: Implement this. - throw new UnsupportedOperationException("Not yet implemented"); - } - - public float getStrikethroughOffset() - { - return 0.F; - } - - public float getStrikethroughThickness() - { - return 0.F; - } - - public float getUnderlineOffset() - { - return 0.F; - } - - public float getUnderlineThickness() - { - return 0.F; - } - - } - - private class XFontMetrics - extends FontMetrics - { - /** - * A cached point instance, to be used in #charWidth(). - */ - private Point2D cachedPoint = new Point2D.Double(); - - XFontMetrics(Font f) - { - super(f); - } - - public int getAscent() - { - return (int) fontDelegate.getAscent(getFont().getSize(), IDENDITY, - false, false, false); - } - - public int getDescent() - { - return (int) fontDelegate.getDescent(getFont().getSize(), IDENDITY, - false, false, false); - } - - public int getHeight() - { - GlyphVector gv = fontDelegate.createGlyphVector(getFont(), - new FontRenderContext(IDENDITY, false, false), - new StringCharacterIterator("m")); - Rectangle2D b = gv.getVisualBounds(); - return (int) b.getHeight(); - } - - public int charWidth(char c) - { - int code = fontDelegate.getGlyphIndex(c); - Point2D advance = cachedPoint; - fontDelegate.getAdvance(code, font.getSize2D(), IDENDITY, - false, false, true, advance); - return (int) advance.getX(); - } - - public int charsWidth(char[] chars, int offs, int len) - { - return stringWidth(new String(chars, offs, len)); - } - - public int stringWidth(String s) - { - GlyphVector gv = fontDelegate.createGlyphVector(getFont(), - new FontRenderContext(IDENDITY, false, false), - new StringCharacterIterator(s)); - Rectangle2D b = gv.getVisualBounds(); - return (int) b.getWidth(); - } - } - - /** - * The indendity transform, to be used in several methods. - */ - private static final AffineTransform IDENDITY = new AffineTransform(); - - private FontDelegate fontDelegate; - - XFontPeer2(String name, int style, int size) - { - super(name, style, size); - try - { - File fontfile = new File("/usr/share/fonts/truetype/freefont/FreeSans.ttf"); - FileInputStream in = new FileInputStream(fontfile); - FileChannel ch = in.getChannel(); - ByteBuffer buffer = ch.map(FileChannel.MapMode.READ_ONLY, 0, - fontfile.length()); - fontDelegate = FontFactory.createFonts(buffer)[0]; - } - catch (Exception ex) - { - ex.printStackTrace(); - } - } - - XFontPeer2(String name, Map atts) - { - super(name, atts); - try - { - File fontfile = new File("/usr/share/fonts/truetype/freefont/FreeSans.ttf"); - FileInputStream in = new FileInputStream(fontfile); - FileChannel ch = in.getChannel(); - ByteBuffer buffer = ch.map(FileChannel.MapMode.READ_ONLY, 0, - fontfile.length()); - fontDelegate = FontFactory.createFonts(buffer)[0]; - } - catch (Exception ex) - { - ex.printStackTrace(); - } - } - - public boolean canDisplay(Font font, int c) - { - // FIXME: Implement this. - throw new UnsupportedOperationException("Not yet implemented"); - } - - public int canDisplayUpTo(Font font, CharacterIterator i, int start, int limit) - { - // FIXME: Implement this. - throw new UnsupportedOperationException("Not yet implemented"); - } - - public String getSubFamilyName(Font font, Locale locale) - { - // FIXME: Implement this. - throw new UnsupportedOperationException("Not yet implemented"); - } - - public String getPostScriptName(Font font) - { - // FIXME: Implement this. - throw new UnsupportedOperationException("Not yet implemented"); - } - - public int getNumGlyphs(Font font) - { - // FIXME: Implement this. - throw new UnsupportedOperationException("Not yet implemented"); - } - - public int getMissingGlyphCode(Font font) - { - // FIXME: Implement this. - throw new UnsupportedOperationException("Not yet implemented"); - } - - public byte getBaselineFor(Font font, char c) - { - // FIXME: Implement this. - throw new UnsupportedOperationException("Not yet implemented"); - } - - public String getGlyphName(Font font, int glyphIndex) - { - // FIXME: Implement this. - throw new UnsupportedOperationException("Not yet implemented"); - } - - public GlyphVector createGlyphVector(Font font, FontRenderContext frc, CharacterIterator ci) - { - return fontDelegate.createGlyphVector(font, frc, ci); - } - - public GlyphVector createGlyphVector(Font font, FontRenderContext ctx, int[] glyphCodes) - { - // FIXME: Implement this. - throw new UnsupportedOperationException("Not yet implemented"); - } - - public GlyphVector layoutGlyphVector(Font font, FontRenderContext frc, char[] chars, int start, int limit, int flags) - { - StringCharacterIterator i = new StringCharacterIterator(new String(chars), start, limit, 0); - return fontDelegate.createGlyphVector(font, frc, i); - } - - public FontMetrics getFontMetrics(Font font) - { - return new XFontMetrics(font); - } - - public boolean hasUniformLineMetrics(Font font) - { - // FIXME: Implement this. - throw new UnsupportedOperationException("Not yet implemented"); - } - - public LineMetrics getLineMetrics(Font font, CharacterIterator ci, int begin, int limit, FontRenderContext rc) - { - return new XLineMetrics(font, ci, begin, limit, rc); - } - - public Rectangle2D getMaxCharBounds(Font font, FontRenderContext rc) - { - // FIXME: Implement this. - throw new UnsupportedOperationException("Not yet implemented"); - } - - /** - * Encodes a font name + style + size specification into a X logical font - * description (XLFD) as described here: - * - * http://www.meretrx.com/e93/docs/xlfd.html - * - * This is implemented to look up the font description in the - * fonts.properties of this package. - * - * @param name the font name - * @param atts the text attributes - * - * @return the encoded font description - */ - static String encodeFont(String name, Map atts) - { - String family = name; - if (family == null || family.equals("")) - family = (String) atts.get(TextAttribute.FAMILY); - if (family == null) - family = "SansSerif"; - - int size = 12; - Float sizeFl = (Float) atts.get(TextAttribute.SIZE); - if (sizeFl != null) - size = sizeFl.intValue(); - - int style = 0; - // Detect italic attribute. - Float posture = (Float) atts.get(TextAttribute.POSTURE); - if (posture != null && !posture.equals(TextAttribute.POSTURE_REGULAR)) - style |= Font.ITALIC; - - // Detect bold attribute. - Float weight = (Float) atts.get(TextAttribute.WEIGHT); - if (weight != null && weight.compareTo(TextAttribute.WEIGHT_REGULAR) > 0) - style |= Font.BOLD; - - return encodeFont(name, style, size); - } - - /** - * Encodes a font name + style + size specification into a X logical font - * description (XLFD) as described here: - * - * http://www.meretrx.com/e93/docs/xlfd.html - * - * This is implemented to look up the font description in the - * fonts.properties of this package. - * - * @param name the font name - * @param style the font style - * @param size the font size - * - * @return the encoded font description - */ - static String encodeFont(String name, int style, int size) - { - StringBuilder key = new StringBuilder(); - key.append(validName(name)); - key.append('.'); - switch (style) - { - case Font.BOLD: - key.append("bold"); - break; - case Font.ITALIC: - key.append("italic"); - break; - case (Font.BOLD | Font.ITALIC): - key.append("bolditalic"); - break; - case Font.PLAIN: - default: - key.append("plain"); - - } - - String protoType = fontProperties.getProperty(key.toString()); - int s = size; - return protoType.replaceFirst("%d", String.valueOf(s * 10)); - } - - /** - * Checks the specified font name for a valid font name. If the font name - * is not known, then this returns 'sansserif' as fallback. - * - * @param name the font name to check - * - * @return a valid font name - */ - static String validName(String name) - { - String retVal; - if (name.equalsIgnoreCase("sansserif") - || name.equalsIgnoreCase("serif") - || name.equalsIgnoreCase("monospaced") - || name.equalsIgnoreCase("dialog") - || name.equalsIgnoreCase("dialoginput")) - { - retVal = name.toLowerCase(); - } - else - { - retVal = "sansserif"; - } - return retVal; - } -} diff --git a/libjava/classpath/gnu/java/awt/peer/x/XFramePeer.java b/libjava/classpath/gnu/java/awt/peer/x/XFramePeer.java index 74e47bc2842..7424dc671ed 100644 --- a/libjava/classpath/gnu/java/awt/peer/x/XFramePeer.java +++ b/libjava/classpath/gnu/java/awt/peer/x/XFramePeer.java @@ -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() diff --git a/libjava/classpath/gnu/java/awt/peer/x/XGraphics2D.java b/libjava/classpath/gnu/java/awt/peer/x/XGraphics2D.java index 73e780cc5a2..95129666a05 100644 --- a/libjava/classpath/gnu/java/awt/peer/x/XGraphics2D.java +++ b/libjava/classpath/gnu/java/awt/peer/x/XGraphics2D.java @@ -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()) + { + // Simply paint the current color over the existing pixels. + xdrawable.fill_rectangle(xgc, x0, y, l, 1); + } + else if (coverageAlpha > 0) { - int red = col.getRed(); - int green = col.getGreen(); - int blue = col.getBlue(); - if (coverageAlpha < c.getMaxCoverage()) + // 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++) { - float alpha = coverageAlpha / maxCoverage; - red = 255 - (int) ((255 - red) * alpha); - green = 255 - (int) ((255 - green) * alpha); - blue = 255 - (int) ((255 - blue) * alpha); + 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); } - xgc.set_foreground(red << 16 | green << 8 | blue); - int x0 = range.getXPos(); - int l = range.getLength(); - xdrawable.fill_rectangle(xgc, x0, y, l, 1); + 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 imageCache = new WeakHashMap(); + 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; + } } diff --git a/libjava/classpath/gnu/java/awt/peer/x/XGraphicsConfiguration.java b/libjava/classpath/gnu/java/awt/peer/x/XGraphicsConfiguration.java index 11a9c9694f1..85f72a4eff4 100644 --- a/libjava/classpath/gnu/java/awt/peer/x/XGraphicsConfiguration.java +++ b/libjava/classpath/gnu/java/awt/peer/x/XGraphicsConfiguration.java @@ -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; + } + } diff --git a/libjava/classpath/gnu/java/awt/peer/x/XGraphicsEnvironment.java b/libjava/classpath/gnu/java/awt/peer/x/XGraphicsEnvironment.java index 65383a6cb0f..8ec8d57bb90 100644 --- a/libjava/classpath/gnu/java/awt/peer/x/XGraphicsEnvironment.java +++ b/libjava/classpath/gnu/java/awt/peer/x/XGraphicsEnvironment.java @@ -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); } } diff --git a/libjava/classpath/gnu/java/awt/peer/x/XToolkit.java b/libjava/classpath/gnu/java/awt/peer/x/XToolkit.java index 08186326ffa..c1724aad55d 100644 --- a/libjava/classpath/gnu/java/awt/peer/x/XToolkit.java +++ b/libjava/classpath/gnu/java/awt/peer/x/XToolkit.java @@ -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 fontCache = + new WeakHashMap(); 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; } - } diff --git a/libjava/classpath/gnu/java/awt/peer/x/XWindowPeer.java b/libjava/classpath/gnu/java/awt/peer/x/XWindowPeer.java index 10d1e96858a..f9184ed1cde 100644 --- a/libjava/classpath/gnu/java/awt/peer/x/XWindowPeer.java +++ b/libjava/classpath/gnu/java/awt/peer/x/XWindowPeer.java @@ -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); } diff --git a/libjava/classpath/gnu/java/awt/peer/x/ZPixmapDataBuffer.java b/libjava/classpath/gnu/java/awt/peer/x/ZPixmapDataBuffer.java index 8043c5b8f46..cf40f4d6977 100644 --- a/libjava/classpath/gnu/java/awt/peer/x/ZPixmapDataBuffer.java +++ b/libjava/classpath/gnu/java/awt/peer/x/ZPixmapDataBuffer.java @@ -59,4 +59,9 @@ class ZPixmapDataBuffer zpixmap.set_data_element(i, (byte) val); } + ZPixmap getZPixmap() + { + return zpixmap; + } + } diff --git a/libjava/classpath/gnu/java/awt/print/PostScriptGraphics2D.java b/libjava/classpath/gnu/java/awt/print/PostScriptGraphics2D.java index 4e052a1d3f4..01894e5a43e 100644 --- a/libjava/classpath/gnu/java/awt/print/PostScriptGraphics2D.java +++ b/libjava/classpath/gnu/java/awt/print/PostScriptGraphics2D.java @@ -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; diff --git a/libjava/classpath/gnu/java/awt/print/SpooledDocument.java b/libjava/classpath/gnu/java/awt/print/SpooledDocument.java index b606a2ef63e..812906b189d 100644 --- a/libjava/classpath/gnu/java/awt/print/SpooledDocument.java +++ b/libjava/classpath/gnu/java/awt/print/SpooledDocument.java @@ -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; -- cgit v1.2.3