aboutsummaryrefslogtreecommitdiff
path: root/libjava
diff options
context:
space:
mode:
authorGraydon Hoare <graydon@redhat.com>2003-10-25 18:41:45 +0000
committerGraydon Hoare <graydon@gcc.gnu.org>2003-10-25 18:41:45 +0000
commitc4bcf1418f3057826922bb830d3ee6aaf73adc1d (patch)
treea86497db03f846687cb8c6b5f16cc08c970a7a17 /libjava
parent11f9a0ed8f5cdd0214075bc8501a91c06a835d2a (diff)
downloadgcc-c4bcf1418f3057826922bb830d3ee6aaf73adc1d.zip
gcc-c4bcf1418f3057826922bb830d3ee6aaf73adc1d.tar.gz
gcc-c4bcf1418f3057826922bb830d3ee6aaf73adc1d.tar.bz2
ClasspathToolkit.java: New abstract class.
2003-10-14 Graydon Hoare <graydon@redhat.com> * gnu/java/awt/ClasspathToolkit.java: New abstract class. * gnu/java/awt/peer/ClasspathFontPeer.java: New abstract class. * gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java, jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeer.c: New concrete implementation of ClasspathFontPeer, with native part. * gnu/java/awt/peer/gtk/GdkGlyphVector.java, jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGlyphVector.c: New class, with native part. * gnu/java/awt/peer/gtk/GdkGraphics2D.java, jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c: implement setFont, cairoSetFont, drawGlyphVector, cairoShowGlyphs. From-SVN: r72931
Diffstat (limited to 'libjava')
-rw-r--r--libjava/ChangeLog14
-rw-r--r--libjava/gnu/java/awt/ClasspathToolkit.java334
-rw-r--r--libjava/gnu/java/awt/peer/ClasspathFontPeer.java795
-rw-r--r--libjava/gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java239
-rw-r--r--libjava/gnu/java/awt/peer/gtk/GdkGlyphVector.java342
-rw-r--r--libjava/gnu/java/awt/peer/gtk/GdkGraphics2D.java32
-rw-r--r--libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeer.c160
-rw-r--r--libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGlyphVector.c571
-rw-r--r--libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c95
9 files changed, 2568 insertions, 14 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index 4aef656..b628831 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -1,3 +1,17 @@
+2003-10-25 Graydon Hoare <graydon@redhat.com>
+
+ * gnu/java/awt/ClasspathToolkit.java: New abstract class.
+ * gnu/java/awt/peer/ClasspathFontPeer.java: New abstract class.
+ * gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java,
+ jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeer.c:
+ New concrete implementation of ClasspathFontPeer, with native part.
+ * gnu/java/awt/peer/gtk/GdkGlyphVector.java,
+ jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGlyphVector.c:
+ New class, with native part.
+ * gnu/java/awt/peer/gtk/GdkGraphics2D.java,
+ jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c:
+ implement setFont, cairoSetFont, drawGlyphVector, cairoShowGlyphs.
+
2003-10-25 Bryce McKinlay <bryce@mckinlay.net.nz>
* java/lang/reflect/Method.java (toString): Avoid extra whitespace
diff --git a/libjava/gnu/java/awt/ClasspathToolkit.java b/libjava/gnu/java/awt/ClasspathToolkit.java
new file mode 100644
index 0000000..91401f4
--- /dev/null
+++ b/libjava/gnu/java/awt/ClasspathToolkit.java
@@ -0,0 +1,334 @@
+/* ClasspathToolkit.java -- Abstract superclass for Classpath toolkits.
+ Copyright (C) 2003 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., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 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;
+
+import java.awt.Image;
+import java.awt.Dimension;
+import java.awt.DisplayMode;
+import java.awt.Font;
+import java.awt.FontFormatException;
+import java.awt.FontMetrics;
+import java.awt.GraphicsEnvironment;
+import java.awt.HeadlessException;
+import java.awt.Toolkit;
+import java.awt.image.ColorModel;
+import java.io.File;
+import java.io.InputStream;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+import gnu.java.awt.peer.ClasspathFontPeer;
+
+
+/**
+ * An abstract superclass for Classpath toolkits.
+ *
+ * <p>There exist some parts of AWT and Java2D that are specific to
+ * the underlying platform, but for which the {@link Toolkit} class
+ * does not provide suitable abstractions. Examples include some
+ * methods of {@link Font} or {@link GraphicsEnvironment}. Those
+ * methods use ClasspathToolkit as a central place for obtaining
+ * platform-specific functionality.
+ *
+ * <p>In addition, ClasspathToolkit implements some abstract methods
+ * of {@link java.awt.Toolkit} that are not really platform-specific,
+ * such as the maintenance of a cache of loaded images.
+ *
+ * <p><b>Thread Safety:</b> The methods of this class may safely be
+ * called without external synchronization. This also hold for any
+ * inherited {@link Toolkit} methods. Subclasses are responsible for
+ * the necessary synchronization.
+ *
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ */
+public abstract class ClasspathToolkit
+ extends Toolkit
+{
+ /**
+ * A map from URLs to previously loaded images, used by {@link
+ * #getImage(java.net.URL)}. For images that were loaded via a path
+ * to an image file, the map contains a key with a file URL.
+ */
+ private Map imageCache;
+
+
+ /**
+ * Returns a shared instance of the local, platform-specific
+ * graphics environment.
+ *
+ * <p>This method is specific to GNU Classpath. It gets called by
+ * the Classpath implementation of {@link
+ * GraphicsEnvironment.getLocalGraphcisEnvironment()}.
+ */
+ public abstract GraphicsEnvironment getLocalGraphicsEnvironment();
+
+
+ /**
+ * Determines the current size of the default, primary screen.
+ *
+ * @throws HeadlessException if the local graphics environment is
+ * headless, which means that no screen is attached and no user
+ * interaction is allowed.
+ */
+ public Dimension getScreenSize()
+ {
+ DisplayMode mode;
+
+ // getDefaultScreenDevice throws HeadlessException if the
+ // local graphics environment is headless.
+ mode = GraphicsEnvironment.getLocalGraphicsEnvironment()
+ .getDefaultScreenDevice().getDisplayMode();
+
+ return new Dimension(mode.getWidth(), mode.getHeight());
+ }
+
+
+ /**
+ * Determines the current color model of the default, primary
+ * screen.
+ *
+ * @see GraphicsEnvironment#getDefaultScreenDevice()
+ * @see java.awt.GraphicsDevice#getDefaultConfiguration()
+ * @see java.awt.GraphicsConfiguration#getColorModel()
+ *
+ * @throws HeadlessException if the local graphics environment is
+ * headless, which means that no screen is attached and no user
+ * interaction is allowed.
+ */
+ public ColorModel getColorModel()
+ {
+ // getDefaultScreenDevice throws HeadlessException if the
+ // local graphics environment is headless.
+ return GraphicsEnvironment.getLocalGraphicsEnvironment()
+ .getDefaultScreenDevice().getDefaultConfiguration()
+ .getColorModel();
+ }
+
+ /**
+ * Retrieves the metrics for rendering a font on the screen.
+ *
+ * @param font the font whose metrics are requested.
+ */
+ public FontMetrics getFontMetrics(Font font)
+ {
+ return ((ClasspathFontPeer) font.getPeer ()).getFontMetrics (font);
+ }
+
+
+ /**
+ * Acquires an appropriate {@link ClasspathFontPeer}, for use in
+ * classpath's implementation of {@link java.awt.Font}.
+ *
+ * @param name The logical name of the font. This may be either a face
+ * name or a logical font name, or may even be null. A default
+ * implementation of name decoding is provided in
+ * {@link ClasspathFontPeer}, but may be overridden in other toolkits.
+ *
+ * @param attrs Any extra {@link java.awt.font.TextAttribute} attributes
+ * this font peer should have, such as size, weight, family name, or
+ * transformation.
+ */
+
+ public abstract ClasspathFontPeer getClasspathFontPeer (String name, Map attrs);
+
+
+ /**
+ * Creates a {@link Font}, in a platform-specific manner.
+ *
+ * The default implementation simply constructs a {@link Font}, but some
+ * toolkits may wish to override this, to return {@link Font} subclasses which
+ * implement {@link java.awt.font.OpenType} or
+ * {@link java.awt.font.MultipleMaster}.
+ */
+
+ public Font getFont (String name, Map attrs)
+ {
+ return new Font (name, attrs);
+ }
+
+
+ /**
+ * Creates a font, reading the glyph definitions from a stream.
+ *
+ * <p>This method provides the platform-specific implementation for
+ * the static factory method {@link Font#createFont(int,
+ * java.io.InputStream)}.
+ *
+ * @param format the format of the font data, such as {@link
+ * Font#TRUETYPE_FONT}. An implementation may ignore this argument
+ * if it is able to automatically recognize the font format from the
+ * provided data.
+ *
+ * @param stream an input stream from where the font data is read
+ * in. The stream will be advanced to the position after the font
+ * data, but not closed.
+ *
+ * @throws IllegalArgumentException if <code>format</code> is
+ * not supported.
+ *
+ * @throws FontFormatException if <code>stream</code> does not
+ * contain data in the expected format, or if required tables are
+ * missing from a font.
+ *
+ * @throws IOException if a problem occurs while reading in the
+ * contents of <code>stream</code>.
+ */
+ public abstract Font createFont(int format, InputStream stream);
+
+
+ /**
+ * Returns an image from the specified file, which must be in a
+ * recognized format. The set of recognized image formats may vary
+ * from toolkit to toolkit.
+ *
+ * <p>This method maintains a cache for images. If an image has been
+ * loaded from the same path before, the cached copy will be
+ * returned. The implementation may hold cached copies for an
+ * indefinite time, which can consume substantial resources with
+ * large images. Users are therefore advised to use {@link
+ * #createImage(java.lang.String)} instead.
+ *
+ * <p>The default implementation creates a file URL for the
+ * specified path and invokes {@link #getImage(URL)}.
+ *
+ * @param path A path to the image file.
+ *
+ * @return IllegalArgumentException if <code>path</code> does not
+ * designate a valid path.
+ */
+ public Image getImage(String path)
+ {
+ try
+ {
+ return getImage(new File(path).toURL());
+ }
+ catch (MalformedURLException muex)
+ {
+ throw (IllegalArgumentException) new IllegalArgumentException(path)
+ .initCause(muex);
+ }
+ }
+
+
+ /**
+ * Loads an image from the specified URL. The image data must be in
+ * a recognized format. The set of recognized image formats may vary
+ * from toolkit to toolkit.
+ *
+ * <p>This method maintains a cache for images. If an image has been
+ * loaded from the same URL before, the cached copy will be
+ * returned. The implementation may hold cached copies for an
+ * indefinite time, which can consume substantial resources with
+ * large images. Users are therefore advised to use {@link
+ * #createImage(java.net.URL)} instead.
+ *
+ * @param url the URL from where the image is read.
+ */
+ public Image getImage(URL url)
+ {
+ Image result;
+
+ synchronized (this)
+ {
+ // Many applications never call getImage. Therefore, we lazily
+ // create the image cache when it is actually needed.
+ if (imageCache == null)
+ imageCache = new HashMap();
+ else
+ {
+ result = (Image) imageCache.get(url);
+ if (result != null)
+ return result;
+ }
+
+ // The createImage(URL) method, which is specified by
+ // java.awt.Toolkit, is not implemented by this abstract class
+ // because it is platform-dependent. Once Classpath has support
+ // for the javax.imageio package, it might be worth considering
+ // that toolkits provide native stream readers. Then, the class
+ // ClasspathToolkit could provide a general implementation that
+ // delegates the image format parsing to javax.imageio.
+ result = createImage(url);
+
+ // It is not clear whether it would be a good idea to use weak
+ // references here. The advantage would be reduced memory
+ // consumption, since loaded images would not be kept
+ // forever. But on VMs that frequently perform garbage
+ // collection (which includes VMs with a parallel or incremental
+ // collector), the image might frequently need to be re-loaded,
+ // possibly over a slow network connection.
+ imageCache.put(url, result);
+
+ return result;
+ }
+ }
+
+
+ /**
+ * Returns an image from the specified file, which must be in a
+ * recognized format. The set of recognized image formats may vary
+ * from toolkit to toolkit.
+ *
+ * <p>A new image is created every time this method gets called,
+ * even if the same path has been passed before.
+ *
+ * <p>The default implementation creates a file URL for the
+ * specified path and invokes {@link #createImage(URL)}.
+ *
+ * @param path A path to the file to be read in.
+ */
+ public Image createImage(String path)
+ {
+ try
+ {
+ // The abstract method createImage(URL) is defined by
+ // java.awt.Toolkit, but intentionally not implemented by
+ // ClasspathToolkit because it is platform specific.
+ return createImage(new File(path).toURL());
+ }
+ catch (MalformedURLException muex)
+ {
+ throw (IllegalArgumentException) new IllegalArgumentException(path)
+ .initCause(muex);
+ }
+ }
+}
diff --git a/libjava/gnu/java/awt/peer/ClasspathFontPeer.java b/libjava/gnu/java/awt/peer/ClasspathFontPeer.java
new file mode 100644
index 0000000..3d151c8
--- /dev/null
+++ b/libjava/gnu/java/awt/peer/ClasspathFontPeer.java
@@ -0,0 +1,795 @@
+/* ClasspathFontPeer.java -- Font peer used by GNU Classpath.
+ Copyright (C) 2003 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., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 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;
+
+import java.awt.*;
+import java.awt.peer.*;
+import java.awt.font.*;
+import java.awt.geom.*;
+import java.text.*;
+import java.util.*;
+import gnu.java.awt.*;
+
+
+/**
+ * A peer for fonts that are used inside Classpath. The purpose of
+ * this interface is to abstract from platform-specific font handling
+ * in the Classpath implementation of java.awt.Font and related
+ * classes.
+ *
+ * <p><b>State kept by the peer:</b> a peer is generated for each Font
+ * object in the default implementation. If you wish to share peers between
+ * fonts, you will need to subclass both ClasspathFontPeer and
+ * {@link ClasspathToolKit}.
+ *
+ * <p><b>Thread Safety:</b> Methods of this interface may be called
+ * from arbitrary threads at any time. Implementations of the
+ * <code>ClasspathFontPeer</code> interface are required to perform
+ * the necessary synchronization.
+ *
+ * @see java.awt.Font#getPeer
+ * @see java.awt.Toolkit#getFontPeer
+ *
+ * @author Sascha Brawer (brawer@dandelis.ch)
+ * @author Graydon Hoare (graydon@redhat.com)
+ */
+public abstract class ClasspathFontPeer
+ implements FontPeer
+{
+
+ /*************************************************************************/
+
+ /*
+ * Instance Variables
+ */
+
+ /**
+ * The 3 names of this font. all fonts have 3 names, some of which
+ * may be equal:
+ *
+ * logical -- name the font was constructed from
+ * family -- a designer or brand name (Helvetica)
+ * face -- specific instance of a design (Helvetica Regular)
+ *
+ * @see isLogicalFontName
+ */
+
+ protected String logicalName;
+ protected String familyName;
+ protected String faceName;
+
+ /**
+ * The font style, which is a combination (by OR-ing) of the font style
+ * constants PLAIN, BOLD and ITALIC, in this class.
+ */
+ protected int style;
+
+ /**
+ * The font point size. A point is 1/72 of an inch.
+ */
+ protected float size;
+
+ /**
+ * The affine transformation the font is currently subject to.
+ */
+ protected AffineTransform transform;
+
+ protected static ClasspathToolkit tk()
+ {
+ return (ClasspathToolkit)(Toolkit.getDefaultToolkit ());
+ }
+
+ /*
+ * Confusingly, a Logical Font is a concept unrelated to
+ * a Font's Logical Name.
+ *
+ * A Logical Font is one of 6 built-in, abstract font types
+ * which must be supported by any java environment: SansSerif,
+ * Serif, Monospaced, Dialog, and DialogInput.
+ *
+ * A Font's Logical Name is the name the font was constructed
+ * from. This might be the name of a Logical Font, or it might
+ * be the name of a Font Face.
+ */
+
+ protected static boolean isLogicalFontName(String name)
+ {
+ String uname = name.toUpperCase ();
+ return (uname.equals ("SANSSERIF") ||
+ uname.equals ("SERIF") ||
+ uname.equals ("MONOSPACED") ||
+ uname.equals ("DIALOG") ||
+ uname.equals ("DIALOGINPUT"));
+ }
+
+ protected static String logicalFontNameToFaceName (String name)
+ {
+ String uname = name.toUpperCase ();
+ if (uname.equals("SANSSERIF"))
+ return "Helvetica";
+ else if (uname.equals ("SERIF"))
+ return "Times";
+ else if (uname.equals ("MONOSPACED"))
+ return "Courier";
+ else if (uname.equals ("DIALOG"))
+ return "Helvetica";
+ else if (uname.equals ("DIALOGINPUT"))
+ return "Helvetica";
+ else
+ return "Helvetica";
+ }
+
+ protected static String faceNameToFamilyName (String name)
+ {
+ return name;
+ }
+
+ protected static void copyStyleToAttrs (int style, Map attrs)
+ {
+ if ((style & Font.BOLD) == Font.BOLD)
+ attrs.put (TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
+ else
+ attrs.put (TextAttribute.WEIGHT, TextAttribute.WEIGHT_REGULAR);
+
+ if ((style & Font.ITALIC) == Font.ITALIC)
+ attrs.put (TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
+ else
+ attrs.put (TextAttribute.POSTURE, TextAttribute.POSTURE_REGULAR);
+ }
+
+ protected static void copyFamilyToAttrs (String fam, Map attrs)
+ {
+ if (fam != null)
+ attrs.put (TextAttribute.FAMILY, fam);
+ }
+
+ protected static void copySizeToAttrs (float size, Map attrs)
+ {
+ attrs.put (TextAttribute.SIZE, new Float (size));
+ }
+
+ protected static void copyTransformToAttrs (AffineTransform trans, Map attrs)
+ {
+ if (trans != null)
+ attrs.put(TextAttribute.TRANSFORM, new TransformAttribute (trans));
+ }
+
+
+ protected void setStandardAttributes (String name, String family, int style,
+ float size, AffineTransform trans)
+ {
+ this.logicalName = name;
+
+ if (isLogicalFontName (name))
+ this.faceName = logicalFontNameToFaceName (name);
+ else
+ this.faceName = name;
+
+ if (family != null)
+ this.familyName = family;
+ else
+ this.familyName = faceNameToFamilyName (faceName);
+
+ this.style = style;
+ this.size = size;
+ this.transform = trans;
+ }
+
+
+ protected void setStandardAttributes (String name, Map attribs)
+ {
+ String family = this.familyName;
+ AffineTransform trans = this.transform;
+ float size = this.size;
+ int style = this.style;
+
+ if (attribs.containsKey (TextAttribute.FAMILY))
+ family = (String) attribs.get (TextAttribute.FAMILY);
+
+ if (name == null)
+ name = "SansSerif";
+
+ if (attribs.containsKey (TextAttribute.WEIGHT))
+ {
+ Float weight = (Float) attribs.get (TextAttribute.WEIGHT);
+ if (weight.floatValue () >= TextAttribute.WEIGHT_BOLD.floatValue ())
+ style += Font.BOLD;
+ }
+
+ if (attribs.containsKey (TextAttribute.POSTURE))
+ {
+ Float posture = (Float) attribs.get (TextAttribute.POSTURE);
+ if (posture.floatValue () >= TextAttribute.POSTURE_OBLIQUE.floatValue ())
+ style += Font.ITALIC;
+ }
+
+ if (attribs.containsKey (TextAttribute.SIZE))
+ {
+ Float sz = (Float) attribs.get (TextAttribute.SIZE);
+ size = sz.floatValue ();
+ }
+
+ if (attribs.containsKey (TextAttribute.TRANSFORM))
+ {
+ TransformAttribute ta = (TransformAttribute)
+ attribs.get(TextAttribute.TRANSFORM);
+ trans = ta.getTransform ();
+ }
+
+ setStandardAttributes (name, family, style, size, trans);
+ }
+
+ protected void getStandardAttributes (Map attrs)
+ {
+ copyFamilyToAttrs (this.familyName, attrs);
+ copySizeToAttrs (this.size, attrs);
+ copyStyleToAttrs (this.style, attrs);
+ copyTransformToAttrs (this.transform, attrs);
+ }
+
+
+ /* Begin public API */
+
+ public ClasspathFontPeer (String name, Map attrs)
+ {
+ setStandardAttributes (name, attrs);
+ }
+
+ public ClasspathFontPeer (String name, int style, int size)
+ {
+ setStandardAttributes (name, (String)null, style,
+ (float)size, (AffineTransform)null);
+ }
+
+ /**
+ * Implementation of {@link Font#getName}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public String getName (Font font)
+ {
+ return logicalName;
+ }
+
+ /**
+ * Implementation of {@link Font#getFamily()}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public String getFamily (Font font)
+ {
+ return familyName;
+ }
+
+ /**
+ * Implementation of {@link Font#getFamily(Locale)}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public String getFamily (Font font, Locale lc)
+ {
+ return familyName;
+ }
+
+ /**
+ * Implementation of {@link Font#getFontName()}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public String getFontName (Font font)
+ {
+ return faceName;
+ }
+
+ /**
+ * Implementation of {@link Font#getFontName(Locale)}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public String getFontName (Font font, Locale lc)
+ {
+ return faceName;
+ }
+
+ /**
+ * Implementation of {@link Font#getSize}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public float getSize (Font font)
+ {
+ return size;
+ }
+
+ /**
+ * Implementation of {@link Font#isPlain}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public boolean isPlain (Font font)
+ {
+ return style == Font.PLAIN;
+ }
+
+ /**
+ * Implementation of {@link Font#isBold}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public boolean isBold (Font font)
+ {
+ return ((style & Font.BOLD) == Font.BOLD);
+ }
+
+ /**
+ * Implementation of {@link Font#isItalic}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public boolean isItalic (Font font)
+ {
+ return ((style & Font.ITALIC) == Font.ITALIC);
+ }
+
+ /**
+ * Implementation of {@link Font#deriveFont(float)}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public Font deriveFont (Font font, float size)
+ {
+ Map attrs = new HashMap ();
+ getStandardAttributes (attrs);
+ copySizeToAttrs (size, attrs);
+ return tk().getFont (logicalName, attrs);
+ }
+
+ /**
+ * Implementation of {@link Font#deriveFont(int)}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public Font deriveFont (Font font, int style)
+ {
+ Map attrs = new HashMap ();
+ getStandardAttributes (attrs);
+ copyStyleToAttrs (style, attrs);
+ return tk().getFont (logicalName, attrs);
+ }
+
+ /**
+ * Implementation of {@link Font#deriveFont(int, AffineTransform)}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public Font deriveFont (Font font, int style, AffineTransform t)
+ {
+ Map attrs = new HashMap ();
+ getStandardAttributes (attrs);
+ copyStyleToAttrs (style, attrs);
+ copyTransformToAttrs (t, attrs);
+ return tk().getFont (logicalName, attrs);
+ }
+
+ /**
+ * Implementation of {@link Font#deriveFont(Map)}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public Font deriveFont (Font font, Map attrs)
+ {
+ return tk().getFont (logicalName, attrs);
+ }
+
+ /**
+ * Implementation of {@link Font#getAttributes()}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public Map getAttributes (Font font)
+ {
+ HashMap h = new HashMap ();
+ getStandardAttributes (h);
+ return h;
+ }
+
+ /**
+ * Implementation of {@link Font#getAvailableAttributes()}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public AttributedCharacterIterator.Attribute[] getAvailableAttributes(Font font)
+ {
+ AttributedCharacterIterator.Attribute a[] =
+ new AttributedCharacterIterator.Attribute[5];
+ a[0] = TextAttribute.FAMILY;
+ a[1] = TextAttribute.SIZE;
+ a[2] = TextAttribute.POSTURE;
+ a[3] = TextAttribute.WEIGHT;
+ a[4] = TextAttribute.TRANSFORM;
+ return a;
+ }
+
+ /**
+ * Implementation of {@link Font#getTransform()}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public AffineTransform getTransform (Font font)
+ {
+ return transform;
+ }
+
+ /**
+ * Implementation of {@link Font#isTransformed()}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public boolean isTransformed (Font font)
+ {
+ return ! transform.isIdentity ();
+ }
+
+ /**
+ * Implementation of {@link Font#getItalicAngle()}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public float getItalicAngle (Font font)
+ {
+ if ((style & Font.ITALIC) == Font.ITALIC)
+ return TextAttribute.POSTURE_OBLIQUE.floatValue ();
+ else
+ return TextAttribute.POSTURE_REGULAR.floatValue ();
+ }
+
+
+ /**
+ * Implementation of {@link Font#getStyle()}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public int getStyle (Font font)
+ {
+ return style;
+ }
+
+
+
+
+ /* Remaining methods are abstract */
+
+ /**
+ * Implementation of {@link Font#canDisplay(char)}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public abstract boolean canDisplay (Font font, char c);
+
+ /**
+ * Implementation of {@link Font#canDisplay(String)},
+ * {@link Font#canDisplay(char [], int, int)}, and
+ * {@link Font#canDisplay(CharacterIterator, int, int)}.
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public abstract int canDisplayUpTo (Font font, CharacterIterator i, int start, int limit);
+
+
+ /**
+ * Returns the name of this font face inside the family, for example
+ * <i>&#x201c;Light&#x201d;</i>.
+ *
+ * <p>This method is currently not used by {@link Font}. However,
+ * this name would be needed by any serious desktop publishing
+ * application.
+ *
+ * @param font the font whose sub-family name is requested.
+ *
+ * @param locale the locale for which to localize the name. If
+ * <code>locale</code> is <code>null</code>, the returned name is
+ * localized to the user&#x2019;s default locale.
+ *
+ * @return the name of the face inside its family, or
+ * <code>null</code> if the font does not provide a sub-family name.
+ */
+
+ public abstract String getSubFamilyName (Font font, Locale locale);
+
+
+ /**
+ * Implementation of {@link Font#getPSName()}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public abstract String getPostScriptName (Font font);
+
+
+ /**
+ * Implementation of {@link Font#getNumGlyphs()}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public abstract int getNumGlyphs (Font font);
+
+
+ /**
+ * Implementation of {@link Font#getMissingGlyphCode()}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public abstract int getMissingGlyphCode (Font font);
+
+
+ /**
+ * Implementation of {@link Font#getBaselineFor(char)}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public abstract byte getBaselineFor (Font font, char c);
+
+
+ /**
+ * Returns a name for the specified glyph. This is useful for
+ * generating PostScript or PDF files that embed some glyphs of a
+ * font. If the implementation follows glyph naming conventions
+ * specified by Adobe, search engines can extract the original text
+ * from the generated PostScript and PDF files.
+ *
+ * <p>This method is currently not used by GNU Classpath. However,
+ * it would be very useful for someone wishing to write a good
+ * PostScript or PDF stream provider for the
+ * <code>javax.print</code> package.
+ *
+ * <p><b>Names are not unique:</b> Under some rare circumstances,
+ * the same name can be returned for different glyphs. It is
+ * therefore recommended that printer drivers check whether the same
+ * name has already been returned for antoher glyph, and make the
+ * name unique by adding the string ".alt" followed by the glyph
+ * index.</p>
+ *
+ * <p>This situation would occur for an OpenType or TrueType font
+ * that has a <code>post</code> table of format 3 and provides a
+ * mapping from glyph IDs to Unicode sequences through a
+ * <code>Zapf</code> table. If the same sequence of Unicode
+ * codepoints leads to different glyphs (depending on contextual
+ * position, for example, or on typographic sophistication level),
+ * the same name would get synthesized for those glyphs. To avoid
+ * this, the font peer would have to go through the names of all
+ * glyphs, which would make this operation very inefficient with
+ * large fonts.
+ *
+ * @param font the font containing the glyph whose name is
+ * requested.
+ *
+ * @param glyphIndex the glyph whose name the caller wants to
+ * retrieve.
+ *
+ * @return the glyph name, or <code>null</code> if a font does not
+ * provide glyph names.
+ */
+
+ public abstract String getGlyphName (Font font, int glyphIndex);
+
+
+ /**
+ * Implementation of {@link
+ * Font#createGlyphVector(FontRenderContext, String)}, {@link
+ * Font#createGlyphVector(FontRenderContext, char[])}, and {@link
+ * Font#createGlyphVector(FontRenderContext, CharacterIterator)}.
+ *
+ * @param font the font object that the created GlyphVector will return
+ * when it gets asked for its font. This argument is needed because the
+ * public API of {@link GlyphVector} works with {@link java.awt.Font},
+ * not with font peers.
+ */
+
+ public abstract GlyphVector createGlyphVector (Font font,
+ FontRenderContext frc,
+ CharacterIterator ci);
+
+
+ /**
+ * Implementation of {@link Font#createGlyphVector(FontRenderContext,
+ * int[])}.
+ *
+ * @param font the font object that the created GlyphVector will return
+ * when it gets asked for its font. This argument is needed because the
+ * public API of {@link GlyphVector} works with {@link java.awt.Font},
+ * not with font peers.
+ */
+
+ public abstract GlyphVector createGlyphVector (Font font,
+ FontRenderContext ctx,
+ int[] glyphCodes);
+
+
+ /**
+ * Implementation of {@link Font#layoutGlyphVector(FontRenderContext,
+ * char[], int, int, int)}.
+ *
+ * @param font the font object that the created GlyphVector will return
+ * when it gets asked for its font. This argument is needed because the
+ * public API of {@link GlyphVector} works with {@link java.awt.Font},
+ * not with font peers.
+ */
+
+ public abstract GlyphVector layoutGlyphVector (Font font,
+ FontRenderContext frc,
+ char[] chars, int start,
+ int limit, int flags);
+
+
+ /**
+ * Implementation of {@link Font#getFontMetrics()}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public abstract FontMetrics getFontMetrics (Font font);
+
+
+ /**
+ * Implementation of {@link Font#hasUniformLineMetrics()}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public abstract boolean hasUniformLineMetrics (Font font);
+
+
+ /**
+ * Implementation of {@link Font#getLineMetrics(CharacterIterator, int,
+ * int, FontRenderContext)}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public abstract LineMetrics getLineMetrics (Font font,
+ CharacterIterator ci,
+ int begin, int limit,
+ FontRenderContext rc);
+
+ /**
+ * Implementation of {@link Font#getMaxCharBounds(FontRenderContext)}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public abstract Rectangle2D getMaxCharBounds (Font font,
+ FontRenderContext rc);
+
+ /**
+ * Implementation of {@link Font#getStringBounds(CharacterIterator, int,
+ * int, FontRenderContext)}
+ *
+ * @param font the font this peer is being called from. This may be
+ * useful if you are sharing peers between Font objects. Otherwise it may
+ * be ignored.
+ */
+
+ public abstract Rectangle2D getStringBounds (Font font,
+ CharacterIterator ci,
+ int begin, int limit,
+ FontRenderContext frc);
+
+}
diff --git a/libjava/gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java b/libjava/gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java
new file mode 100644
index 0000000..7e31700
--- /dev/null
+++ b/libjava/gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java
@@ -0,0 +1,239 @@
+/* GdkClasspathFontPeer.java -- backend implementation for Font object
+ Copyright (C) 2003 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., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 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.gtk;
+
+import java.awt.*;
+import java.awt.font.*;
+import java.awt.geom.*;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.Locale;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.text.CharacterIterator;
+import java.text.AttributedCharacterIterator;
+import java.awt.font.TextAttribute;
+import gnu.classpath.Configuration;
+import gnu.java.awt.peer.ClasspathFontPeer;
+
+/**
+ * This class represents a windowing system font using the Pango
+ * unicode/glyph/font library and the Cairo rendering library.
+ *
+ * @author Graydon Hoare (graydon@redhat.com)
+ */
+
+public class GdkClasspathFontPeer extends ClasspathFontPeer
+{
+
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary("gtkpeer");
+ }
+ initStaticState ();
+ }
+ native static void initStaticState ();
+ private final int native_state = GtkGenericPeer.getUniqueInteger ();
+
+
+ /* Instance Variables */
+
+ private native void initState ();
+ private native void dispose ();
+ private native void setFont (String family, int style, int size);
+
+ protected void sync ()
+ {
+ this.setFont (this.familyName, this.style, (int)this.size);
+ }
+
+ protected void finalize ()
+ {
+ dispose ();
+ }
+
+ /*
+ * Helpers for the 3-way overloading that this class seems to suffer
+ * from. Remove them if you feel like they're a performance bottleneck,
+ * for the time being I prefer my code not be written and debugged in
+ * triplicate.
+ */
+
+ private String buildString(CharacterIterator i) {
+ String s = new String ();
+ for(char c = i.first(); c != CharacterIterator.DONE; c = i.next())
+ s += c;
+ return s;
+ }
+
+ private String buildString(CharacterIterator iter, int begin, int limit) {
+ String s = new String ();
+ int i = 0;
+ for(char c = iter.first(); c != CharacterIterator.DONE; c = iter.next(), i++)
+ {
+ if (begin <= i)
+ s += c;
+ if (limit <= i)
+ break;
+ }
+ return s;
+ }
+
+ private String buildString(char[] chars, int begin, int limit) {
+ String s = new String ();
+ for(int i = begin; i <= limit; i++)
+ s += chars[i];
+ return s;
+ }
+
+ /* Public API */
+
+ public GdkClasspathFontPeer (String name, int style, int size)
+ {
+ super(name, style, size);
+ initState ();
+ setFont (this.familyName, this.style, (int)this.size);
+ }
+
+ public GdkClasspathFontPeer (String name, Map attributes)
+ {
+ super(name, attributes);
+ initState ();
+ setFont (this.familyName, this.style, (int)this.size);
+ }
+
+ public String getSubFamilyName(Font font, Locale locale)
+ {
+ return null;
+ }
+
+ public String getPostScriptName(Font font)
+ {
+ return null;
+ }
+
+ public boolean canDisplay (Font font, char c)
+ {
+ throw new UnsupportedOperationException ();
+ }
+
+ public int canDisplayUpTo (Font font, CharacterIterator i, int start, int limit)
+ {
+ throw new UnsupportedOperationException ();
+ }
+
+ public GlyphVector createGlyphVector (Font font,
+ FontRenderContext ctx,
+ CharacterIterator i)
+ {
+ return new GdkGlyphVector(font, this, ctx, buildString (i));
+ }
+
+ public GlyphVector createGlyphVector (Font font,
+ FontRenderContext ctx,
+ int[] glyphCodes)
+ {
+ return new GdkGlyphVector (font, this, ctx, glyphCodes);
+ }
+
+ public byte getBaselineFor (Font font, char c)
+ {
+ throw new UnsupportedOperationException ();
+ }
+
+ public LineMetrics getLineMetrics (Font font, CharacterIterator ci,
+ int begin, int limit, FontRenderContext rc)
+ {
+ throw new UnsupportedOperationException ();
+ }
+
+ public Rectangle2D getMaxCharBounds (Font font, FontRenderContext rc)
+ {
+ throw new UnsupportedOperationException ();
+ }
+
+ public int getMissingGlyphCode (Font font)
+ {
+ throw new UnsupportedOperationException ();
+ }
+
+ public String getGlyphName (Font font, int glyphIndex)
+ {
+ throw new UnsupportedOperationException ();
+ }
+
+ public int getNumGlyphs (Font font)
+ {
+ throw new UnsupportedOperationException ();
+ }
+
+ public Rectangle2D getStringBounds (Font font, CharacterIterator ci,
+ int begin, int limit, FontRenderContext frc)
+ {
+ throw new UnsupportedOperationException ();
+ }
+
+ public boolean hasUniformLineMetrics (Font font)
+ {
+ throw new UnsupportedOperationException ();
+ }
+
+ public GlyphVector layoutGlyphVector (Font font, FontRenderContext frc,
+ char[] chars, int start, int limit,
+ int flags)
+ {
+ throw new UnsupportedOperationException ();
+ }
+
+ public LineMetrics getLineMetrics (Font font, String str,
+ FontRenderContext frc)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public FontMetrics getFontMetrics (Font font)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+}
+
diff --git a/libjava/gnu/java/awt/peer/gtk/GdkGlyphVector.java b/libjava/gnu/java/awt/peer/gtk/GdkGlyphVector.java
new file mode 100644
index 0000000..0ba4539
--- /dev/null
+++ b/libjava/gnu/java/awt/peer/gtk/GdkGlyphVector.java
@@ -0,0 +1,342 @@
+/* GdkGlyphVector.java -- Glyph vector object
+ Copyright (C) 2003 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., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 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.gtk;
+
+import java.awt.*;
+import java.awt.font.*;
+import java.awt.geom.*;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.Locale;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.text.CharacterIterator;
+import java.text.AttributedCharacterIterator;
+import gnu.classpath.Configuration;
+
+public class GdkGlyphVector extends GlyphVector
+{
+
+ static
+ {
+ if (Configuration.INIT_LOAD_LIBRARY)
+ {
+ System.loadLibrary("gtkpeer");
+ }
+ initStaticState ();
+ }
+ native static void initStaticState ();
+ private final int native_state = GtkGenericPeer.getUniqueInteger ();
+
+ private Font font;
+ private FontRenderContext ctx;
+
+ private native void initState (GdkClasspathFontPeer peer, FontRenderContext ctx);
+ private native void setChars (String s);
+ private native void setGlyphCodes (int codes[]);
+ private native void dispose ();
+ private native int glyphCode (int idx);
+ private native int numGlyphs ();
+ private native int glyphCharIndex (int idx);
+ private native double[] allLogicalExtents ();
+ private native double[] allInkExtents ();
+ private native double[] glyphLogicalExtents (int idx);
+ private native double[] glyphInkExtents (int idx);
+ private native boolean glyphIsHorizontal (int idx);
+ private native boolean isEqual (GdkGlyphVector ggv);
+
+
+ /*
+ geometric notes:
+
+ the FRC contains a mapping from points -> pixels.
+
+ typographics points are typically 1/72 of an inch.
+
+ pixel displays are often around 72 dpi.
+
+ so the FRC can get away with using an identity transform on a screen,
+ often. behavior is documented by sun to fall back to an identity
+ transform if the internal transformation is null.
+
+ coordinates coming up from pango are expressed as floats -- in device
+ space, so basically pixels-with-fractional-bits -- derived from their
+ storage format in pango (1024ths of pixels).
+
+ it is not clear from the javadocs whether the results of methods like
+ getGlyphPositions ought to return coordinates in device space, or
+ "point" space, or what. for now I'm returning them in device space.
+
+ */
+
+
+ public GdkGlyphVector (Font f, GdkClasspathFontPeer peer, FontRenderContext c, String s)
+ {
+ font = f;
+ ctx = c;
+ initState (peer, ctx);
+ setChars (s);
+ }
+
+ public GdkGlyphVector (Font f, GdkClasspathFontPeer peer, FontRenderContext c, int codes[])
+ {
+ font = f;
+ ctx = c;
+ initState (peer, ctx);
+ setGlyphCodes (codes);
+ }
+
+ protected void finalize ()
+ {
+ dispose ();
+ }
+
+ public Font getFont ()
+ {
+ return font;
+ }
+
+ public FontRenderContext getFontRenderContext ()
+ {
+ return ctx;
+ }
+
+ public int getGlyphCharIndex (int glyphIndex)
+ {
+ return glyphCharIndex (glyphIndex);
+ }
+
+ public int[] getGlyphCharIndices (int beginGlyphIndex,
+ int numEntries,
+ int[] codeReturn)
+ {
+ int ix[] = codeReturn;
+ if (ix == null)
+ ix = new int[numEntries];
+
+ for (int i = 0; i < numEntries; i++)
+ ix[i] = glyphCharIndex (beginGlyphIndex + i);
+ return ix;
+ }
+
+ public int getGlyphCode (int glyphIndex)
+ {
+ return glyphCode (glyphIndex);
+ }
+
+ public int[] getGlyphCodes (int beginGlyphIndex, int numEntries,
+ int[] codeReturn)
+ {
+ int ix[] = codeReturn;
+ if (ix == null)
+ ix = new int[numEntries];
+
+ for (int i = 0; i < numEntries; i++)
+ ix[i] = glyphCode (beginGlyphIndex + i);
+ return ix;
+ }
+
+ public Shape getGlyphLogicalBounds (int glyphIndex)
+ {
+ double extents[] = glyphLogicalExtents (glyphIndex);
+ return new Rectangle2D.Double (extents[0], extents[1],
+ extents[2], extents[3]);
+ }
+
+ public GlyphMetrics getGlyphMetrics (int glyphIndex)
+ {
+ double extents[] = glyphLogicalExtents (glyphIndex);
+ Rectangle2D log_bounds = new Rectangle2D.Double (extents[0], extents[1],
+ extents[2], extents[3]);
+
+ extents = glyphInkExtents (glyphIndex);
+ Rectangle2D ink_bounds = new Rectangle2D.Double (extents[0], extents[1],
+ extents[2], extents[3]);
+
+ boolean is_horizontal = glyphIsHorizontal (glyphIndex);
+
+ return new GlyphMetrics (is_horizontal,
+ (float)(log_bounds.getWidth() + log_bounds.getX()),
+ (float)(log_bounds.getHeight() + log_bounds.getY()),
+ ink_bounds, GlyphMetrics.STANDARD);
+ }
+
+ public Shape getGlyphOutline (int glyphIndex)
+ {
+ throw new UnsupportedOperationException ();
+ }
+
+ public Shape getGlyphOutline (int glyphIndex, float x, float y)
+ {
+ throw new UnsupportedOperationException ();
+ }
+
+ public Rectangle getGlyphPixelBounds (int glyphIndex,
+ FontRenderContext renderFRC,
+ float x, float y)
+ {
+ double extents[] = glyphInkExtents(glyphIndex);
+ return new Rectangle ((int)x, (int)y, (int)extents[2], (int)extents[3]);
+ }
+
+ public Point2D getGlyphPosition (int glyphIndex)
+ {
+ float[] ret = new float[2 * (glyphIndex + 1)];
+ getGlyphPositions (0, glyphIndex + 1, ret);
+ return new Point2D.Float (ret[2 * glyphIndex],
+ ret[2 * glyphIndex + 1]);
+ }
+
+ public float[] getGlyphPositions (int beginGlyphIndex,
+ int numEntries,
+ float[] positionReturn)
+ {
+ float fx[] = positionReturn;
+ if (fx == null)
+ fx = new float[numEntries * 2];
+
+
+ float x = 0.0f;
+ float y = 0.0f;
+ for (int i = 0; i < numEntries; ++i)
+ {
+ boolean is_horizontal = glyphIsHorizontal (beginGlyphIndex + i);
+ double log_extents[] = glyphLogicalExtents (beginGlyphIndex + i);
+ fx[2*i] = x + (float)log_extents[0]; // x offset
+ fx[2*i + 1] = y + (float)log_extents[1]; // y offset
+ if (is_horizontal)
+ x += (float)log_extents[2]; // x advance ("logical width") in pango-ese
+ else
+ y += (float)log_extents[3]; // y advance ("logical height") in pango-ese
+ }
+ return fx;
+ }
+
+ public AffineTransform getGlyphTransform (int glyphIndex)
+ {
+ // glyphs don't have independent transforms in these simple glyph
+ // vectors; docs specify null is an ok return here.
+ return null;
+ }
+
+ public Shape getGlyphVisualBounds (int glyphIndex)
+ {
+ double extents[] = glyphInkExtents (glyphIndex);
+ return new Rectangle2D.Double (extents[0], extents[1],
+ extents[2], extents[3]);
+ }
+
+ public int getLayoutFlags ()
+ {
+ return 0;
+ }
+
+ public Rectangle2D getLogicalBounds ()
+ {
+ double extents[] = allLogicalExtents ();
+ return new Rectangle2D.Double (extents[0], extents[1],
+ extents[2], extents[3]);
+ }
+
+ public int getNumGlyphs ()
+ {
+ return numGlyphs ();
+ }
+
+ public Shape getOutline ()
+ {
+ throw new UnsupportedOperationException ();
+ }
+
+ public Rectangle getPixelBounds (FontRenderContext renderFRC,
+ float x, float y)
+ {
+ double extents[] = allInkExtents();
+ return new Rectangle ((int)x, (int)y,
+ (int)extents[2], (int)extents[3]);
+ }
+
+ public Rectangle2D getVisualBounds ()
+ {
+ double extents[] = allInkExtents();
+ return new Rectangle2D.Double (extents[0], extents[1],
+ extents[2], extents[3]);
+ }
+
+ public void performDefaultLayout ()
+ {
+ }
+
+ public void setGlyphPosition (int glyphIndex, Point2D newPos)
+ {
+ // should we be ok twiddling pango's structure here?
+ throw new UnsupportedOperationException ();
+ }
+
+ public void setGlyphTransform (int glyphIndex,
+ AffineTransform newTX)
+ {
+ // not yet.. maybe not ever?
+ throw new UnsupportedOperationException ();
+ }
+
+ public boolean equals(GlyphVector gv)
+ {
+ if (gv == null)
+ return false;
+
+ if (! (gv instanceof GdkGlyphVector))
+ return false;
+
+ GdkGlyphVector ggv = (GdkGlyphVector)gv;
+ return isEqual(ggv);
+ }
+
+ public GlyphJustificationInfo getGlyphJustificationInfo(int idx)
+ {
+ throw new UnsupportedOperationException ();
+ }
+
+ public Shape getOutline(float x, float y)
+ {
+ throw new UnsupportedOperationException ();
+ }
+
+}
diff --git a/libjava/gnu/java/awt/peer/gtk/GdkGraphics2D.java b/libjava/gnu/java/awt/peer/gtk/GdkGraphics2D.java
index 11c0371..7adb307 100644
--- a/libjava/gnu/java/awt/peer/gtk/GdkGraphics2D.java
+++ b/libjava/gnu/java/awt/peer/gtk/GdkGraphics2D.java
@@ -48,6 +48,8 @@ import java.awt.image.renderable.*;
import java.text.AttributedCharacterIterator;
import java.util.Map;
import java.lang.Integer;
+import gnu.java.awt.ClasspathToolkit;
+import gnu.java.awt.peer.ClasspathFontPeer;
import gnu.classpath.Configuration;
public class GdkGraphics2D extends Graphics2D
@@ -75,8 +77,8 @@ public class GdkGraphics2D extends Graphics2D
private Shape clip;
private AffineTransform transform;
private GtkComponentPeer component;
- private GdkFont font;
-
+ private Font font;
+
native private int[] initState (GtkComponentPeer component);
native private void initState (int width, int height);
native private void copyState (GdkGraphics2D g);
@@ -172,6 +174,10 @@ public class GdkGraphics2D extends Graphics2D
private native void cairoSetMatrix (double m00, double m10,
double m01, double m11,
double m02, double m12);
+ private native void cairoSetFont (GdkClasspathFontPeer peer);
+ private native void cairoShowGlyphs (int codes[],
+ float positions[],
+ int nglyphs);
private native void cairoSetOperator (int cairoOperator);
private native void cairoSetRGBColor (double red, double green, double blue);
private native void cairoSetAlpha (double alpha);
@@ -1024,8 +1030,14 @@ public class GdkGraphics2D extends Graphics2D
}
public void drawGlyphVector (GlyphVector g, float x, float y)
- {
- throw new java.lang.UnsupportedOperationException ();
+ {
+ cairoSave ();
+ cairoTranslate ((double)x, (double)y);
+ int nglyphs = g.getNumGlyphs ();
+ int codes[] = g.getGlyphCodes (0, nglyphs, (int []) null);
+ float posns[] = g.getGlyphPositions (0, nglyphs, (float []) null);
+ cairoShowGlyphs (codes, posns, nglyphs);
+ cairoRestore ();
}
public void copyArea (int x, int y, int width, int height, int dx, int dy)
@@ -1132,10 +1144,16 @@ public class GdkGraphics2D extends Graphics2D
public void setFont (Font f)
{
- if (f instanceof GdkFont)
- font = (GdkFont) f;
+ if (f.getPeer() instanceof GdkClasspathFontPeer)
+ font = f;
else
- font = new GdkFont (f.getAttributes ());
+ font =
+ ((ClasspathToolkit)(Toolkit.getDefaultToolkit ()))
+ .getFont (f.getName(), f.getAttributes ());
+
+ if (f != null &&
+ f.getPeer() instanceof GdkClasspathFontPeer)
+ cairoSetFont ((GdkClasspathFontPeer) f.getPeer());
}
public String toString()
diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeer.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeer.c
new file mode 100644
index 0000000..092979b
--- /dev/null
+++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeer.c
@@ -0,0 +1,160 @@
+/* gnu_java_awt_GdkFont.c
+ Copyright (C) 2003 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., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 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. */
+
+#include "gdkfont.h"
+#include "gnu_java_awt_peer_gtk_GdkClasspathFontPeer.h"
+
+struct state_table *native_font_state_table;
+
+/*
+rough sketch of the mapping between java and
+pango text objects:
+
+ Font <-> - PangoFont
+ - PangoFontDescription
+ - PangoContext
+
+ GlyphVector <-> - GList of PangoGlyphItem
+ - PangoFontDescription
+ - PangoContext
+
+ FontRenderContext <-> stays in plain java
+
+*/
+
+enum java_awt_font_style {
+ java_awt_font_PLAIN = 0,
+ java_awt_font_BOLD = 1,
+ java_awt_font_ITALIC = 2
+};
+
+enum java_awt_font_baseline {
+ java_awt_font_ROMAN_BASELINE = 0,
+ java_awt_font_CENTER_BASELINE = 1,
+ java_awt_font_HANGING_BASELINE = 2
+};
+
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkClasspathFontPeer_initStaticState
+ (JNIEnv *env, jclass clazz)
+{
+ NSA_FONT_INIT (env, clazz);
+}
+
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkClasspathFontPeer_initState
+ (JNIEnv *env, jobject self)
+{
+ struct peerfont *pfont = NULL;
+
+ gdk_threads_enter ();
+ g_assert (self != NULL);
+ pfont = (struct peerfont *) g_malloc0 (sizeof (struct peerfont));
+ g_assert (pfont != NULL);
+ NSA_SET_FONT_PTR (env, self, pfont);
+ gdk_threads_leave ();
+}
+
+
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkClasspathFontPeer_dispose
+ (JNIEnv *env, jobject self)
+{
+ struct peerfont *pfont = NULL;
+
+ gdk_threads_enter ();
+ pfont = (struct peerfont *)NSA_DEL_FONT_PTR (env, self);
+ g_assert (pfont != NULL);
+ if (pfont->ctx != NULL)
+ g_object_unref (pfont->ctx);
+ if (pfont->font != NULL)
+ g_object_unref (pfont->font);
+ if (pfont->desc != NULL)
+ pango_font_description_free (pfont->desc);
+ g_free (pfont);
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkClasspathFontPeer_setFont
+ (JNIEnv *env, jobject self, jstring family_name_str, jint style_int, jint size)
+{
+ struct peerfont *pfont = NULL;
+ PangoFontMap *map = NULL;
+ char const *family_name = NULL;
+
+ gdk_threads_enter ();
+ enum java_awt_font_style style = (enum java_awt_font_style) style_int;
+
+ g_assert (self != NULL);
+ pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, self);
+ g_assert (pfont != NULL);
+
+ pfont->desc = pango_font_description_new ();
+ g_assert (pfont->desc != NULL);
+
+ family_name = (*env)->GetStringUTFChars(env, family_name_str, 0);
+ g_assert (family_name != NULL);
+ pango_font_description_set_family (pfont->desc, family_name);
+ (*env)->ReleaseStringUTFChars(env, family_name_str, family_name);
+
+ pango_font_description_set_size (pfont->desc, size * PANGO_SCALE);
+
+ if (style & java_awt_font_BOLD)
+ pango_font_description_set_weight (pfont->desc, PANGO_WEIGHT_BOLD);
+
+ if (style & java_awt_font_ITALIC)
+ pango_font_description_set_style (pfont->desc, PANGO_STYLE_ITALIC);
+
+ /*
+ FIXME: these are possibly wrong, and should in any case
+ probably be cached between calls.
+ */
+
+ map = pango_ft2_font_map_for_display ();
+ g_assert (map != NULL);
+
+ if (pfont->ctx == NULL)
+ pfont->ctx = pango_ft2_font_map_create_context (PANGO_FT2_FONT_MAP (map));
+ g_assert (pfont->ctx != NULL);
+
+ if (pfont->font != NULL)
+ g_object_unref (pfont->font);
+
+ pfont->font = pango_font_map_load_font (map, pfont->ctx, pfont->desc);
+ g_assert (pfont->font != NULL);
+
+ gdk_threads_leave ();
+}
+
+
diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGlyphVector.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGlyphVector.c
new file mode 100644
index 0000000..052f7e9
--- /dev/null
+++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGlyphVector.c
@@ -0,0 +1,571 @@
+/* gdkglyphvector.c
+ Copyright (C) 2003 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., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 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. */
+
+#include "gdkfont.h"
+#include "gnu_java_awt_peer_gtk_GdkGlyphVector.h"
+
+struct state_table *native_glyphvector_state_table;
+
+
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_initStaticState
+ (JNIEnv *env, jclass clazz)
+{
+ NSA_GV_INIT (env, clazz);
+}
+
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_initState
+ (JNIEnv *env, jobject self, jobject font, jobject ctx)
+{
+ struct glyphvec *vec = NULL;
+ struct peerfont *pfont = NULL;
+
+ gdk_threads_enter ();
+ g_assert (font != NULL);
+ pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, font);
+ g_assert (pfont != NULL);
+ g_assert (pfont->ctx != NULL);
+ g_assert (pfont->desc != NULL);
+
+ g_assert (self != NULL);
+ vec = (struct glyphvec *) g_malloc0 (sizeof (struct glyphvec));
+ g_assert (vec != NULL);
+
+ vec->desc = pango_font_description_copy (pfont->desc);
+ g_assert (vec->desc != NULL);
+
+ vec->ctx = pfont->ctx;
+ g_object_ref (vec->ctx);
+
+ NSA_SET_GV_PTR (env, self, vec);
+ gdk_threads_leave ();
+}
+
+static void free_glyphitems (GList *list)
+{
+ GList *i = NULL;
+ PangoGlyphItem *gi = NULL;
+
+ for (i = g_list_first (list); i != NULL; i = g_list_next (i))
+ {
+ g_assert (i->data != NULL);
+ gi = (PangoGlyphItem *)i->data;
+
+ if (gi->glyphs != NULL)
+ pango_glyph_string_free (gi->glyphs);
+
+ if (gi->item != NULL)
+ g_free (gi->item);
+ }
+ g_list_free (list);
+}
+
+static void seek_glyphstring_idx (GList *list, int idx,
+ int *nidx,
+ PangoGlyphString **gs,
+ PangoFont **fnt)
+{
+ GList *i = NULL;
+ PangoGlyphItem *gi = NULL;
+
+ g_assert (list != NULL);
+ g_assert (gs != NULL);
+ g_assert (nidx != NULL);
+
+ int begin = 0;
+ for (i = g_list_first (list); i != NULL; i = g_list_next (i))
+ {
+ g_assert (i->data != NULL);
+ gi = (PangoGlyphItem *)i->data;
+
+ g_assert (gi->glyphs != NULL);
+
+ if (begin <= idx && idx < begin + gi->glyphs->num_glyphs)
+ {
+ *gs = gi->glyphs;
+ *nidx = idx - begin;
+ if (fnt && gi->item)
+ *fnt = gi->item->analysis.font;
+ return;
+ }
+ else
+ {
+ begin += gi->glyphs->num_glyphs;
+ }
+ }
+ *gs = NULL;
+ *nidx = -1;
+}
+
+static void seek_glyph_idx (GList *list, int idx,
+ PangoGlyphInfo **g,
+ PangoFont **fnt)
+{
+ PangoGlyphString *gs = NULL;
+ int nidx = -1;
+
+ g_assert (list != NULL);
+ g_assert (g != NULL);
+
+ seek_glyphstring_idx (list, idx, &nidx, &gs, fnt);
+
+ g_assert (gs != NULL);
+ g_assert (nidx != -1);
+ g_assert (nidx < gs->num_glyphs);
+ g_assert (gs->glyphs != NULL);
+
+ *g = gs->glyphs + nidx;
+}
+
+static void union_rects (PangoRectangle *r1,
+ const PangoRectangle *r2)
+{
+ PangoRectangle r;
+
+ g_assert (r1 != NULL);
+ g_assert (r2 != NULL);
+
+ /*
+ x is the left edge of the rect,
+ y is the top edge of the rect
+ */
+
+#ifndef min
+#define min(x,y) ((x) < (y) ? (x) : (y))
+#endif
+
+#ifndef max
+#define max(x,y) ((x) < (y) ? (y) : (x))
+#endif
+
+ r.x = min(r1->x, r2->x);
+
+ r.y = min(r1->y, r2->y);
+
+ r.width = max(r1->x + r1->width,
+ r2->x + r2->width) - r.x;
+
+ r.height = max(r1->y + r1->height,
+ r2->y + r2->height) - r.y;
+
+ *r1 = r;
+}
+
+static jdoubleArray rect_to_array (JNIEnv *env, const PangoRectangle *r)
+{
+ /* We often return rectangles as arrays : { x, y, w, h } */
+ jdoubleArray ret;
+ double *rp = NULL;
+ g_assert (r != NULL);
+ ret = (*env)->NewDoubleArray (env, 4);
+ rp = (*env)->GetDoubleArrayElements (env, ret, NULL);
+ g_assert (rp != NULL);
+ rp[0] = r->x / (double)PANGO_SCALE;
+ /* freetype and pango's view of space is upside down from java2d's */
+ rp[1] = (r->y / (double)PANGO_SCALE) * -1;
+ rp[2] = r->width / (double)PANGO_SCALE;
+ rp[3] = r->height / (double)PANGO_SCALE;
+ (*env)->ReleaseDoubleArrayElements (env, ret, rp, 0);
+ return ret;
+}
+
+
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_dispose
+ (JNIEnv *env, jobject self)
+{
+ struct glyphvec *vec = NULL;
+
+ gdk_threads_enter ();
+ g_assert (self != NULL);
+ vec = (struct glyphvec *)NSA_DEL_GV_PTR (env, self);
+ g_assert (vec != NULL);
+
+ if (vec->glyphitems != NULL)
+ {
+ free_glyphitems (vec->glyphitems);
+ vec->glyphitems = NULL;
+ }
+
+ if (vec->desc != NULL)
+ pango_font_description_free (vec->desc);
+
+ if (vec->ctx != NULL)
+ g_object_unref (vec->ctx);
+
+ g_free (vec);
+ gdk_threads_leave ();
+}
+
+
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_setChars
+ (JNIEnv *env, jobject self, jstring chars)
+{
+ struct glyphvec *vec = NULL;
+ gchar *str = NULL;
+ GList *items = NULL, *item = NULL;
+ PangoGlyphItem *gi;
+ PangoAttrList *attrs = NULL;
+ gint len = 0;
+
+ gdk_threads_enter ();
+ g_assert (self != NULL);
+ vec = (struct glyphvec *)NSA_GET_GV_PTR (env, self);
+ g_assert (vec != NULL);
+ g_assert (vec->desc != NULL);
+ g_assert (vec->ctx != NULL);
+
+ len = (*gdk_env)->GetStringUTFLength (env, chars);
+ str = (gchar *)(*env)->GetStringUTFChars (env, chars, NULL);
+ g_assert (str != NULL);
+
+ /* step 1: mark the text as having our FontFescription as an
+ attribute, then "itemize" the text */
+
+ attrs = pango_attr_list_new ();
+ g_assert (attrs != NULL);
+
+ PangoAttribute *da = pango_attr_font_desc_new(vec->desc);
+ g_assert (da != NULL);
+ da->start_index = 0;
+ da->end_index = len;
+
+ pango_attr_list_insert (attrs, da);
+ items = pango_itemize (vec->ctx, str, 0, len, attrs, NULL);
+ g_assert (items != NULL);
+
+ /*
+ step 2: for each item:
+ - shape the item into a glyphstring
+ - store the (item, glyphstring) pair in the vec->glyphitems list
+ */
+
+ if (vec->glyphitems != NULL)
+ {
+ free_glyphitems (vec->glyphitems);
+ vec->glyphitems = NULL;
+ }
+
+ for (item = g_list_first (items); item != NULL; item = g_list_next (item))
+ {
+ g_assert (item->data != NULL);
+
+ gi = NULL;
+ gi = g_malloc0 (sizeof(PangoGlyphItem));
+ g_assert (gi != NULL);
+
+ gi->item = (PangoItem *)item->data;
+ gi->glyphs = pango_glyph_string_new ();
+ g_assert (gi->glyphs != NULL);
+
+ pango_shape (str + gi->item->offset,
+ gi->item->length,
+ &(gi->item->analysis),
+ gi->glyphs);
+
+ vec->glyphitems = g_list_append (vec->glyphitems, gi);
+ }
+
+ /*
+ ownership of each item has been transferred to glyphitems,
+ but the list should be freed.
+ */
+
+ g_list_free (items);
+ pango_attr_list_unref (attrs);
+
+ (*env)->ReleaseStringUTFChars (env, chars, str);
+ gdk_threads_leave ();
+}
+
+
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_setGlyphCodes
+ (JNIEnv *env, jobject self, jintArray codes)
+{
+ struct glyphvec *vec = NULL;
+
+ gdk_threads_enter ();
+ g_assert (self != NULL);
+ vec = (struct glyphvec *)NSA_GET_GV_PTR (env, self);
+ g_assert (vec != NULL);
+
+ /*
+ FIXME: setting glyph codes doesn't seem particularly plausible at the
+ moment.
+ */
+
+ gdk_threads_leave ();
+
+}
+
+
+JNIEXPORT jint JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_glyphCode
+ (JNIEnv *env, jobject self, jint idx)
+{
+ struct glyphvec *vec = NULL;
+ PangoGlyphInfo *gi = NULL;
+ jint ret = 0;
+
+ gdk_threads_enter ();
+ g_assert (self != NULL);
+ vec = (struct glyphvec *)NSA_GET_GV_PTR (env, self);
+ g_assert (vec != NULL);
+ g_assert (vec->glyphitems != NULL);
+
+ seek_glyph_idx (vec->glyphitems, idx, &gi, NULL);
+ g_assert (gi != NULL);
+ ret = gi->glyph;
+ gdk_threads_leave ();
+
+ return (jint)(ret);
+}
+
+
+JNIEXPORT jint JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_numGlyphs
+ (JNIEnv *env, jobject self)
+{
+ GList *i = NULL;
+ PangoGlyphItem *gi = NULL;
+ struct glyphvec *vec = NULL;
+ jint count = 0;
+
+ gdk_threads_enter ();
+ g_assert (self != NULL);
+ vec = (struct glyphvec *)NSA_GET_GV_PTR (env, self);
+ g_assert (vec != NULL);
+
+ for (i = g_list_first (vec->glyphitems); i != NULL; i = g_list_next (i))
+ {
+ g_assert (i->data != NULL);
+ gi = (PangoGlyphItem *)i->data;
+ g_assert (gi->glyphs != NULL);
+ count += gi->glyphs->num_glyphs;
+ }
+ gdk_threads_leave ();
+
+ return count;
+}
+
+
+JNIEXPORT jint JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_glyphCharIndex
+ (JNIEnv *env, jobject self, jint idx)
+{
+ /*
+ FIXME: this is not correct, rather it assumes a (broken) 1:1
+ glyph:char model. it can be implemented in terms of bytes (also
+ broken) using pango's current interface, or perhaps in terms of
+ characters if some better byte->character conversion operator is
+ found. for the time being we leave it broken.
+ */
+ return idx;
+}
+
+
+JNIEXPORT jdoubleArray JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_allLogicalExtents
+ (JNIEnv *env, jobject self)
+{
+ struct glyphvec *vec = NULL;
+ GList *i;
+ PangoGlyphItem *gi = NULL;
+ PangoRectangle rect = {0,0,0,0};
+ PangoRectangle tmp, dummy;
+ jdoubleArray ret;
+
+ gdk_threads_enter ();
+ g_assert (self != NULL);
+ vec = (struct glyphvec *)NSA_GET_GV_PTR (env, self);
+ g_assert (vec != NULL);
+ g_assert (vec->glyphitems != NULL);
+
+ for (i = g_list_first (vec->glyphitems); i != NULL; i = g_list_next (i))
+ {
+ g_assert (i->data != NULL);
+ gi = (PangoGlyphItem *)i->data;
+ g_assert (gi->glyphs != NULL);
+
+ pango_glyph_string_extents (gi->glyphs,
+ gi->item->analysis.font,
+ &dummy,
+ &tmp);
+ union_rects (&rect, &tmp);
+ }
+
+ ret = rect_to_array (env, &rect);
+ gdk_threads_leave ();
+ return ret;
+}
+
+
+JNIEXPORT jdoubleArray JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_allInkExtents
+ (JNIEnv *env, jobject self)
+{
+ struct glyphvec *vec = NULL;
+ GList *i;
+ PangoGlyphItem *gi = NULL;
+ PangoRectangle rect = {0,0,0,0};
+ PangoRectangle tmp, dummy;
+ jdoubleArray ret;
+
+ gdk_threads_enter ();
+ g_assert (self != NULL);
+ vec = (struct glyphvec *)NSA_GET_GV_PTR (env, self);
+ g_assert (vec != NULL);
+ g_assert (vec->glyphitems != NULL);
+
+ for (i = g_list_first (vec->glyphitems); i != NULL; i = g_list_next (i))
+ {
+ g_assert (i->data != NULL);
+ gi = (PangoGlyphItem *)i->data;
+ g_assert (gi->glyphs != NULL);
+
+ pango_glyph_string_extents (gi->glyphs,
+ gi->item->analysis.font,
+ &tmp,
+ &dummy);
+ union_rects (&rect, &tmp);
+ }
+
+ ret = rect_to_array (env, &rect);
+ gdk_threads_leave ();
+ return ret;
+}
+
+JNIEXPORT jdoubleArray JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_glyphLogicalExtents
+ (JNIEnv *env, jobject self, jint idx)
+{
+ struct glyphvec *vec = NULL;
+ PangoRectangle rect = {0,0,0,0};
+ PangoRectangle dummy;
+ PangoGlyphInfo *gi = NULL;
+ PangoFont *font = NULL;
+ jdoubleArray ret;
+
+ gdk_threads_enter ();
+ g_assert (self != NULL);
+ vec = (struct glyphvec *)NSA_GET_GV_PTR (env, self);
+ g_assert (vec != NULL);
+ g_assert (vec->glyphitems != NULL);
+
+ seek_glyph_idx (vec->glyphitems, idx, &gi, &font);
+ g_assert (gi != NULL);
+ g_assert (font != NULL);
+
+ pango_font_get_glyph_extents (font, gi->glyph, &dummy, &rect);
+
+ ret = rect_to_array (env, &rect);
+ gdk_threads_leave ();
+ return ret;
+}
+
+
+JNIEXPORT jdoubleArray JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_glyphInkExtents
+ (JNIEnv *env, jobject self, jint idx)
+{
+ struct glyphvec *vec = NULL;
+ PangoRectangle rect = {0,0,0,0};
+ PangoRectangle dummy;
+ PangoGlyphInfo *gi = NULL;
+ PangoFont *font = NULL;
+ jdoubleArray ret;
+
+ gdk_threads_enter ();
+ g_assert (self != NULL);
+ vec = (struct glyphvec *)NSA_GET_GV_PTR (env, self);
+ g_assert (vec != NULL);
+ g_assert (vec->glyphitems != NULL);
+
+ seek_glyph_idx (vec->glyphitems, idx, &gi, &font);
+ g_assert (gi != NULL);
+ g_assert (font != NULL);
+
+ pango_font_get_glyph_extents (font, gi->glyph, &rect, &dummy);
+
+ ret = rect_to_array (env, &rect);
+ gdk_threads_leave ();
+ return ret;
+}
+
+JNIEXPORT jboolean JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_glyphIsHorizontal
+ (JNIEnv *env, jobject self, jint idx)
+{
+ struct glyphvec *vec = NULL;
+ PangoDirection dir;
+
+ gdk_threads_enter ();
+ g_assert (self != NULL);
+ vec = (struct glyphvec *)NSA_GET_GV_PTR (env, self);
+ g_assert (vec != NULL);
+ g_assert (vec->desc != NULL);
+ g_assert (vec->ctx != NULL);
+
+ /*
+ FIXME: this is an approximation; it's not clear to me whether
+ glyphs themselves are horizontal or vertical so much as the
+ writing system or writing context. pango thinks it's a context
+ issue, so we use that for now.
+ */
+
+ dir = pango_context_get_base_dir (vec->ctx);
+
+ gdk_threads_leave ();
+
+ return
+ ((dir == PANGO_DIRECTION_LTR) ||
+ (dir == PANGO_DIRECTION_RTL));
+}
+
+
+JNIEXPORT jboolean JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_isEqual
+ (JNIEnv *env, jobject self, jobject other)
+{
+ struct glyphvec *vec1 = NULL, *vec2 = NULL;
+ jboolean eq = 0;
+
+ gdk_threads_enter ();
+ g_assert (self != NULL);
+ vec1 = (struct glyphvec *)NSA_GET_GV_PTR (env, self);
+ vec2 = (struct glyphvec *)NSA_GET_GV_PTR (env, other);
+ g_assert (vec1 != NULL);
+ g_assert (vec2 != NULL);
+
+ /* FIXME: is there some more advantageous definition of equality for
+ glyph vectors? */
+ eq = (vec1 == vec2);
+
+ gdk_threads_leave ();
+ return eq;
+}
+
+
diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c
index 04eb2e5..08a9742 100644
--- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c
+++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c
@@ -36,6 +36,7 @@
exception statement from your version. */
#include "gtkpeer.h"
+#include "gdkfont.h"
#include "gnu_java_awt_peer_gtk_GdkGraphics2D.h"
#include <gdk/gdktypes.h>
#include <gdk/gdkprivate.h>
@@ -45,6 +46,8 @@
#include <gdk-pixbuf/gdk-pixdata.h>
#include <cairo.h>
+#include <cairo-xlib.h>
+
#include <stdio.h>
#include <stdlib.h>
@@ -198,9 +201,9 @@ init_graphics2d_as_renderable (struct graphics2d *gr)
vis = gdk_x11_visual_get_xvisual (gdk_drawable_get_visual (gr->drawable));
g_assert (vis != NULL);
- gr->surface = cairo_surface_create_for_drawable (dpy, draw, vis,
- CAIRO_FORMAT_ARGB32,
- DefaultColormap (dpy, DefaultScreen (dpy)));
+ gr->surface = cairo_xlib_surface_create (dpy, draw, vis,
+ CAIRO_FORMAT_ARGB32,
+ DefaultColormap (dpy, DefaultScreen (dpy)));
g_assert (gr->surface != NULL);
g_assert (gr->cr != NULL);
cairo_set_target_surface (gr->cr, gr->surface);
@@ -378,8 +381,8 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_gdkDrawDrawable
gc = gdk_gc_new (dst->drawable);
g_assert (gc != NULL);
- gdk_draw_drawable(dst->drawable, gc, src->drawable,
- 0, 0, x, y, width, height);
+ gdk_draw_drawable(dst->drawable, gc, src->drawable,
+ 0, 0, x, y, width, height);
g_object_unref (gc);
@@ -474,7 +477,6 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_dispose
g_object_unref (gr->drawbuf);
g_object_unref (gr->drawable);
- free (gr);
if (gr->pattern)
cairo_surface_destroy (gr->pattern);
@@ -483,6 +485,7 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_dispose
free (gr->pattern_pixels);
if (gr->debug) printf ("disposed of graphics2d\n");
+ free (gr);
gdk_threads_leave ();
}
@@ -662,6 +665,7 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_drawPixels
begin_drawing_operation (gr);
+
{
cairo_surface_t *surf = cairo_surface_create_for_image ((char *)jpixels,
CAIRO_FORMAT_ARGB32,
@@ -670,8 +674,9 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_drawPixels
cairo_show_surface (gr->cr, surf, w, h);
cairo_surface_destroy (surf);
}
+
- end_drawing_operation (gr);
+ end_drawing_operation (gr);
(*env)->ReleaseIntArrayElements (env, jarr, jpixels, 0);
@@ -723,6 +728,82 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetMatrix
update_pattern_transform (gr);
}
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetFont
+ (JNIEnv *env, jobject obj, jobject font)
+{
+ struct graphics2d *gr = NULL;
+ struct peerfont *pfont = NULL;
+ cairo_font_t *ft = NULL;
+ FT_Face face = NULL;
+
+ gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
+ g_assert (gr != NULL);
+
+ pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, font);
+ g_assert (pfont != NULL);
+
+ gdk_threads_enter ();
+
+ face = pango_ft2_font_get_face (pfont->font);
+ g_assert (face != NULL);
+
+ ft = cairo_ft_font_create_for_ft_face (face);
+ g_assert (ft != NULL);
+
+ if (gr->debug) printf ("cairo_set_font '%s'\n",
+ face->family_name);
+
+ cairo_set_font (gr->cr, ft);
+
+ cairo_scale_font (gr->cr,
+ pango_font_description_get_size (pfont->desc) /
+ (double)PANGO_SCALE);
+
+ cairo_font_destroy (ft);
+
+ gdk_threads_leave ();
+}
+
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoShowGlyphs
+ (JNIEnv *env, jobject obj, jintArray jcodes, jfloatArray jposns, jint nglyphs)
+{
+ struct graphics2d *gr = NULL;
+ cairo_glyph_t *glyphs = NULL;
+ jfloat *posns = NULL;
+ jint *codes = NULL;
+ jint i;
+
+ gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
+ g_assert (gr != NULL);
+
+ if (gr->debug) printf ("cairo_show_glyphs (%d glyphs)\n", nglyphs);
+
+ glyphs = malloc (sizeof(cairo_glyph_t) * nglyphs);
+ g_assert (glyphs);
+
+ codes = (*env)->GetIntArrayElements (env, jcodes, NULL);
+ g_assert (codes != NULL);
+
+ posns = (*env)->GetFloatArrayElements (env, jposns, NULL);
+ g_assert (posns != NULL);
+
+ for (i = 0; i < nglyphs; ++i)
+ {
+ glyphs[i].index = codes[i];
+ glyphs[i].x = (double) posns[2*i];
+ glyphs[i].y = (double) posns[2*i + 1];
+ }
+
+ (*env)->ReleaseIntArrayElements (env, jcodes, codes, 0);
+ (*env)->ReleaseFloatArrayElements (env, jposns, posns, 0);
+
+ begin_drawing_operation (gr);
+ cairo_show_glyphs (gr->cr, glyphs, nglyphs);
+ end_drawing_operation (gr);
+
+ free(glyphs);
+}
+
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetOperator
(JNIEnv *env, jobject obj, jint op)
{