aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.4.3/libjava/classpath/gnu/java/awt/peer/x/XFontPeer.java
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.4.3/libjava/classpath/gnu/java/awt/peer/x/XFontPeer.java')
-rw-r--r--gcc-4.4.3/libjava/classpath/gnu/java/awt/peer/x/XFontPeer.java770
1 files changed, 770 insertions, 0 deletions
diff --git a/gcc-4.4.3/libjava/classpath/gnu/java/awt/peer/x/XFontPeer.java b/gcc-4.4.3/libjava/classpath/gnu/java/awt/peer/x/XFontPeer.java
new file mode 100644
index 000000000..4372c965f
--- /dev/null
+++ b/gcc-4.4.3/libjava/classpath/gnu/java/awt/peer/x/XFontPeer.java
@@ -0,0 +1,770 @@
+/* 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 gnu.java.lang.CPStringBuilder;
+
+import java.awt.AWTError;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphVector;
+import java.awt.font.LineMetrics;
+import java.awt.font.TextAttribute;
+import java.awt.geom.Rectangle2D;
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.CharacterIterator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Properties;
+
+import gnu.java.awt.peer.ClasspathFontPeer;
+import gnu.x11.Display;
+import gnu.x11.Fontable;
+
+/**
+ * The bridge from AWT to X fonts.
+ *
+ * @author Roman Kennke (kennke@aicas.com)
+ */
+public class XFontPeer
+ extends ClasspathFontPeer
+{
+
+ /**
+ * The font mapping as specified in the file fonts.properties.
+ */
+ private static Properties fontProperties;
+ static
+ {
+ fontProperties = new Properties();
+ InputStream in = XFontPeer.class.getResourceAsStream("xfonts.properties");
+ try
+ {
+ fontProperties.load(in);
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * The FontMetrics implementation for XFontPeer.
+ */
+ private class XFontMetrics
+ extends FontMetrics
+ {
+ /**
+ * The ascent of the font.
+ */
+ int ascent;
+
+ /**
+ * The descent of the font.
+ */
+ int descent;
+
+ /**
+ * The maximum of the character advances.
+ */
+ private int maxAdvance;
+
+ /**
+ * The internal leading.
+ */
+ int leading;
+
+ /**
+ * Cached string metrics. This caches string metrics locally so that the
+ * server doesn't have to be asked each time.
+ */
+ private HashMap metricsCache;
+
+ /**
+ * The widths of the characters indexed by the characters themselves.
+ */
+ private int[] charWidths;
+
+ /**
+ * Creates a new XFontMetrics for the specified font.
+ *
+ * @param font the font
+ */
+ protected XFontMetrics(Font font)
+ {
+ super(font);
+ metricsCache = new HashMap();
+ Fontable.FontInfo info = getXFont().info();
+ ascent = info.font_ascent();
+ descent = info.font_descent();
+ maxAdvance = info.max_bounds().character_width();
+ leading = 0; // TODO: Not provided by X. Possible not needed.
+
+ if (info.min_byte1() == 0 && info.max_byte1() == 0)
+ readCharWidthsLinear(info);
+ else
+ readCharWidthsNonLinear(info);
+ }
+
+ /**
+ * Reads the character widths when specified in a linear fashion. That is
+ * when the min-byte1 and max-byte2 fields are both zero in the X protocol.
+ *
+ * @param info the font info reply
+ */
+ private void readCharWidthsLinear(Fontable.FontInfo info)
+ {
+ int startIndex = info.min_char_or_byte2();
+ int endIndex = info.max_char_or_byte2();
+ charWidths = new int[endIndex + 1];
+ // All the characters before startIndex are zero width.
+ for (int i = 0; i < startIndex; i++)
+ {
+ charWidths[i] = 0;
+ }
+ // All the other character info is fetched from the font info.
+ int index = startIndex;
+ Fontable.FontInfo.CharInfo[] charInfos = info.char_infos();
+ for (Fontable.FontInfo.CharInfo charInfo : charInfos)
+ {
+ charWidths[index] = charInfo.character_width();
+ index++;
+ }
+ }
+
+ private void readCharWidthsNonLinear(Fontable.FontInfo info)
+ {
+ // TODO: Implement.
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ /**
+ * Returns the ascent of the font.
+ *
+ * @return the ascent of the font
+ */
+ public int getAscent()
+ {
+ return ascent;
+ }
+
+ /**
+ * Returns the descent of the font.
+ *
+ * @return the descent of the font
+ */
+ public int getDescent()
+ {
+ return descent;
+ }
+
+ /**
+ * Returns the overall height of the font. This is the distance from
+ * baseline to baseline (usually ascent + descent + leading).
+ *
+ * @return the overall height of the font
+ */
+ public int getHeight()
+ {
+ return ascent + descent;
+ }
+
+ /**
+ * Returns the leading of the font.
+ *
+ * @return the leading of the font
+ */
+ public int getLeading()
+ {
+ return leading;
+ }
+
+ /**
+ * Returns the maximum advance for this font.
+ *
+ * @return the maximum advance for this font
+ */
+ public int getMaxAdvance()
+ {
+ return maxAdvance;
+ }
+
+ /**
+ * Determines the width of the specified character <code>c</code>.
+ *
+ * @param c the character
+ *
+ * @return the width of the character
+ */
+ public int charWidth(char c)
+ {
+ int width;
+ if (c > charWidths.length)
+ width = charWidths['?'];
+ else
+ width = charWidths[c];
+ return width;
+ }
+
+ /**
+ * Determines the overall width of the specified string.
+ *
+ * @param c the char buffer holding the string
+ * @param offset the starting offset of the string in the buffer
+ * @param length the number of characters in the string buffer
+ *
+ * @return the overall width of the specified string
+ */
+ public int charsWidth(char[] c, int offset, int length)
+ {
+ int width = 0;
+ if (c.length > 0 && length > 0)
+ {
+ String s = new String(c, offset, length);
+ width = stringWidth(s);
+ }
+ return width;
+ }
+
+ /**
+ * Determines the overall width of the specified string.
+ *
+ * @param s the string
+ *
+ * @return the overall width of the specified string
+ */
+ public int stringWidth(String s)
+ {
+ int width = 0;
+ if (s.length() > 0)
+ {
+ if (metricsCache.containsKey(s))
+ {
+ width = ((Integer) metricsCache.get(s)).intValue();
+ }
+ else
+ {
+ Fontable.TextExtentInfo extents = getXFont().text_extent(s);
+ /*
+ System.err.println("string: '" + s + "' : ");
+ System.err.println("ascent: " + extents.getAscent());
+ System.err.println("descent: " + extents.getDescent());
+ System.err.println("overall ascent: " + extents.getOverallAscent());
+ System.err.println("overall descent: " + extents.getOverallDescent());
+ System.err.println("overall width: " + extents.getOverallWidth());
+ System.err.println("overall left: " + extents.getOverallLeft());
+ System.err.println("overall right: " + extents.getOverallRight());
+ */
+ width = extents.overall_width(); // + extents.overall_left();
+ //System.err.println("String: " + s + ", width: " + width);
+ metricsCache.put(s, new Integer(width));
+ }
+ }
+ //System.err.print("stringWidth: '" + s + "': ");
+ //System.err.println(width);
+ return width;
+ }
+ }
+
+ /**
+ * The LineMetrics implementation for the XFontPeer.
+ */
+ private class XLineMetrics
+ extends LineMetrics
+ {
+
+ /**
+ * Returns the ascent of the font.
+ *
+ * @return the ascent of the font
+ */
+ public float getAscent()
+ {
+ return fontMetrics.ascent;
+ }
+
+ public int getBaselineIndex()
+ {
+ // FIXME: Implement this.
+ throw new UnsupportedOperationException();
+ }
+
+ public float[] getBaselineOffsets()
+ {
+ // FIXME: Implement this.
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Returns the descent of the font.
+ *
+ * @return the descent of the font
+ */
+ public float getDescent()
+ {
+ return fontMetrics.descent;
+ }
+
+ /**
+ * Returns the overall height of the font. This is the distance from
+ * baseline to baseline (usually ascent + descent + leading).
+ *
+ * @return the overall height of the font
+ */
+ public float getHeight()
+ {
+ return fontMetrics.ascent + fontMetrics.descent;
+ }
+
+ /**
+ * Returns the leading of the font.
+ *
+ * @return the leading of the font
+ */
+ public float getLeading()
+ {
+ return fontMetrics.leading;
+ }
+
+ public int getNumChars()
+ {
+ // FIXME: Implement this.
+ throw new UnsupportedOperationException();
+ }
+
+ public float getStrikethroughOffset()
+ {
+ return 0.F; // TODO: Provided by X??
+ }
+
+ public float getStrikethroughThickness()
+ {
+ return 1.F; // TODO: Provided by X??
+ }
+
+ public float getUnderlineOffset()
+ {
+ return 0.F; // TODO: Provided by X??
+ }
+
+ public float getUnderlineThickness()
+ {
+ return 1.F; // TODO: Provided by X??
+ }
+
+ }
+
+ /**
+ * The X font.
+ */
+ private gnu.x11.Font xfont;
+
+ private String name;
+
+ private int style;
+
+ private int size;
+
+ /**
+ * The font metrics for this font.
+ */
+ XFontMetrics fontMetrics;
+
+ /**
+ * Creates a new XFontPeer for the specified font name, style and size.
+ *
+ * @param name the font name
+ * @param style the font style (bold / italic / normal)
+ * @param size the size of the font
+ */
+ public XFontPeer(String name, int style, int size)
+ {
+ super(name, style, size);
+ this.name = name;
+ this.style = style;
+ this.size = size;
+ }
+
+ /**
+ * Creates a new XFontPeer for the specified font name and style
+ * attributes.
+ *
+ * @param name the font name
+ * @param atts the font attributes
+ */
+ public XFontPeer(String name, Map atts)
+ {
+ super(name, atts);
+ String family = name;
+ if (family == null || family.equals(""))
+ family = (String) atts.get(TextAttribute.FAMILY);
+ if (family == null)
+ family = "SansSerif";
+
+ int size = 12;
+ Float sizeFl = (Float) atts.get(TextAttribute.SIZE);
+ if (sizeFl != null)
+ size = sizeFl.intValue();
+
+ int style = 0;
+ // Detect italic attribute.
+ Float posture = (Float) atts.get(TextAttribute.POSTURE);
+ if (posture != null && !posture.equals(TextAttribute.POSTURE_REGULAR))
+ style |= Font.ITALIC;
+
+ // Detect bold attribute.
+ Float weight = (Float) atts.get(TextAttribute.WEIGHT);
+ if (weight != null && weight.compareTo(TextAttribute.WEIGHT_REGULAR) > 0)
+ style |= Font.BOLD;
+
+ this.name = name;
+ this.style = style;
+ this.size = size;
+ }
+
+ /**
+ * Initializes the font peer with the specified attributes. This method is
+ * called from both constructors.
+ *
+ * @param name the font name
+ * @param style the font style
+ * @param size the font size
+ */
+ private void init(String name, int style, int size)
+ {
+ if (name == null)
+ {
+ name = "SansSerif";
+ }
+ GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
+ GraphicsDevice dev = env.getDefaultScreenDevice();
+ if (dev instanceof XGraphicsDevice)
+ {
+ Display display = ((XGraphicsDevice) dev).getDisplay();
+ String fontDescr = encodeFont(name, style, size);
+ if (XToolkit.DEBUG)
+ System.err.println("XLFD font description: " + fontDescr);
+ xfont = new gnu.x11.Font(display, fontDescr);
+ }
+ else
+ {
+ throw new AWTError("Local GraphicsEnvironment is not XWindowGraphicsEnvironment");
+ }
+ }
+
+ public boolean canDisplay(Font font, int c)
+ {
+ // TODO: Implement this.
+ throw new UnsupportedOperationException("Not yet implemented.");
+ }
+
+ public int canDisplayUpTo(Font font, CharacterIterator i, int start, int limit)
+ {
+ // TODO: Implement this.
+ throw new UnsupportedOperationException("Not yet implemented.");
+ }
+
+ public String getSubFamilyName(Font font, Locale locale)
+ {
+ // TODO: Implement this.
+ throw new UnsupportedOperationException("Not yet implemented.");
+ }
+
+ public String getPostScriptName(Font font)
+ {
+ // TODO: Implement this.
+ throw new UnsupportedOperationException("Not yet implemented.");
+ }
+
+ public int getNumGlyphs(Font font)
+ {
+ // TODO: Implement this.
+ throw new UnsupportedOperationException("Not yet implemented.");
+ }
+
+ public int getMissingGlyphCode(Font font)
+ {
+ // TODO: Implement this.
+ throw new UnsupportedOperationException("Not yet implemented.");
+ }
+
+ public byte getBaselineFor(Font font, char c)
+ {
+ // TODO: Implement this.
+ throw new UnsupportedOperationException("Not yet implemented.");
+ }
+
+ public String getGlyphName(Font font, int glyphIndex)
+ {
+ // TODO: Implement this.
+ throw new UnsupportedOperationException("Not yet implemented.");
+ }
+
+ public GlyphVector createGlyphVector(Font font, FontRenderContext frc,
+ CharacterIterator ci)
+ {
+ // TODO: Implement this.
+ throw new UnsupportedOperationException("Not yet implemented.");
+ }
+
+ public GlyphVector createGlyphVector(Font font, FontRenderContext ctx,
+ int[] glyphCodes)
+ {
+ // TODO: Implement this.
+ throw new UnsupportedOperationException("Not yet implemented.");
+ }
+
+ public GlyphVector layoutGlyphVector(Font font, FontRenderContext frc,
+ char[] chars, int start, int limit,
+ int flags)
+ {
+ // TODO: Implement this.
+ throw new UnsupportedOperationException("Not yet implemented.");
+ }
+
+ /**
+ * Returns the font metrics for the specified font.
+ *
+ * @param font the font for which to fetch the font metrics
+ *
+ * @return the font metrics for the specified font
+ */
+ public FontMetrics getFontMetrics(Font font)
+ {
+ if (font.getPeer() != this)
+ throw new AWTError("The specified font has a different peer than this");
+
+ if (fontMetrics == null)
+ fontMetrics = new XFontMetrics(font);
+ return fontMetrics;
+ }
+
+ /**
+ * Frees the font in the X server.
+ */
+ protected void finalize()
+ {
+ if (xfont != null)
+ xfont.close();
+ }
+
+ public boolean hasUniformLineMetrics(Font font)
+ {
+ // TODO: Implement this.
+ throw new UnsupportedOperationException("Not yet implemented.");
+ }
+
+ /**
+ * Returns the line metrics for this font and the specified string and
+ * font render context.
+ */
+ public LineMetrics getLineMetrics(Font font, CharacterIterator ci, int begin,
+ int limit, FontRenderContext rc)
+ {
+ return new XLineMetrics();
+ }
+
+ public Rectangle2D getMaxCharBounds(Font font, FontRenderContext rc)
+ {
+ // TODO: Implement this.
+ throw new UnsupportedOperationException("Not yet implemented.");
+ }
+
+ public Rectangle2D getStringBounds(Font font, CharacterIterator ci,
+ int begin, int limit, FontRenderContext frc)
+ {
+ // TODO: Implement this.
+ throw new UnsupportedOperationException("Not yet implemented.");
+ }
+
+ /**
+ * Encodes a font name + style + size specification into a X logical font
+ * description (XLFD) as described here:
+ *
+ * http://www.meretrx.com/e93/docs/xlfd.html
+ *
+ * This is implemented to look up the font description in the
+ * fonts.properties of this package.
+ *
+ * @param name the font name
+ * @param atts the text attributes
+ *
+ * @return the encoded font description
+ */
+ static String encodeFont(String name, Map atts)
+ {
+ String family = name;
+ if (family == null || family.equals(""))
+ family = (String) atts.get(TextAttribute.FAMILY);
+ if (family == null)
+ family = "SansSerif";
+
+ int size = 12;
+ Float sizeFl = (Float) atts.get(TextAttribute.SIZE);
+ if (sizeFl != null)
+ size = sizeFl.intValue();
+
+ int style = 0;
+ // Detect italic attribute.
+ Float posture = (Float) atts.get(TextAttribute.POSTURE);
+ if (posture != null && !posture.equals(TextAttribute.POSTURE_REGULAR))
+ style |= Font.ITALIC;
+
+ // Detect bold attribute.
+ Float weight = (Float) atts.get(TextAttribute.WEIGHT);
+ if (weight != null && weight.compareTo(TextAttribute.WEIGHT_REGULAR) > 0)
+ style |= Font.BOLD;
+
+ return encodeFont(family, style, size);
+ }
+
+ /**
+ * Encodes a font name + style + size specification into a X logical font
+ * description (XLFD) as described here:
+ *
+ * http://www.meretrx.com/e93/docs/xlfd.html
+ *
+ * This is implemented to look up the font description in the
+ * fonts.properties of this package.
+ *
+ * @param name the font name
+ * @param style the font style
+ * @param size the font size
+ *
+ * @return the encoded font description
+ */
+ static String encodeFont(String name, int style, int size)
+ {
+ CPStringBuilder key = new CPStringBuilder();
+ 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;
+ }
+}