1 /* XFontPeer2.java -- A Java based TTF font peer for X
2 Copyright (C) 2006 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
38 package gnu.java.awt.peer.x;
41 import java.awt.FontMetrics;
42 import java.awt.font.FontRenderContext;
43 import java.awt.font.GlyphVector;
44 import java.awt.font.LineMetrics;
45 import java.awt.font.TextAttribute;
46 import java.awt.geom.AffineTransform;
47 import java.awt.geom.Point2D;
48 import java.awt.geom.Rectangle2D;
50 import java.io.FileInputStream;
51 import java.io.IOException;
52 import java.io.InputStream;
53 import java.nio.ByteBuffer;
54 import java.nio.channels.FileChannel;
55 import java.text.CharacterIterator;
56 import java.text.StringCharacterIterator;
57 import java.util.Locale;
59 import java.util.Properties;
61 import gnu.java.awt.font.FontDelegate;
62 import gnu.java.awt.font.FontFactory;
63 import gnu.java.awt.peer.ClasspathFontPeer;
65 public class XFontPeer2
66 extends ClasspathFontPeer
70 * The font mapping as specified in the file fonts.properties.
72 private static Properties fontProperties;
75 fontProperties = new Properties();
76 InputStream in = XFontPeer2.class.getResourceAsStream("fonts.properties");
79 fontProperties.load(in);
87 private class XLineMetrics
92 private GlyphVector glyphVector;
93 // private CharacterIterator characterIterator;
96 private FontRenderContext fontRenderContext;
97 XLineMetrics(Font f, CharacterIterator ci, int b, int l,
101 // characterIterator = ci;
104 fontRenderContext = rc;
105 glyphVector = fontDelegate.createGlyphVector(font, fontRenderContext,
109 public float getAscent()
111 return fontDelegate.getAscent(font.getSize(), fontRenderContext.getTransform(),
112 fontRenderContext.isAntiAliased(),
113 fontRenderContext.usesFractionalMetrics(), true);
116 public int getBaselineIndex()
118 // FIXME: Implement this.
119 throw new UnsupportedOperationException("Not yet implemented");
122 public float[] getBaselineOffsets()
124 // FIXME: Implement this.
125 throw new UnsupportedOperationException("Not yet implemented");
128 public float getDescent()
130 return (int) fontDelegate.getDescent(font.getSize(), IDENDITY, false,
134 public float getHeight()
136 return (float) glyphVector.getLogicalBounds().getHeight();
139 public float getLeading()
141 return getHeight() - getAscent() - getDescent();
144 public int getNumChars()
146 // FIXME: Implement this.
147 throw new UnsupportedOperationException("Not yet implemented");
150 public float getStrikethroughOffset()
155 public float getStrikethroughThickness()
160 public float getUnderlineOffset()
165 public float getUnderlineThickness()
172 private class XFontMetrics
176 * A cached point instance, to be used in #charWidth().
178 private Point2D cachedPoint = new Point2D.Double();
185 public int getAscent()
187 return (int) fontDelegate.getAscent(getFont().getSize(), IDENDITY,
188 false, false, false);
191 public int getDescent()
193 return (int) fontDelegate.getDescent(getFont().getSize(), IDENDITY,
194 false, false, false);
197 public int getHeight()
199 GlyphVector gv = fontDelegate.createGlyphVector(getFont(),
200 new FontRenderContext(IDENDITY, false, false),
201 new StringCharacterIterator("m"));
202 Rectangle2D b = gv.getVisualBounds();
203 return (int) b.getHeight();
206 public int charWidth(char c)
208 int code = fontDelegate.getGlyphIndex(c);
209 Point2D advance = cachedPoint;
210 fontDelegate.getAdvance(code, font.getSize2D(), IDENDITY,
211 false, false, true, advance);
212 return (int) advance.getX();
215 public int charsWidth(char[] chars, int offs, int len)
217 return stringWidth(new String(chars, offs, len));
220 public int stringWidth(String s)
222 GlyphVector gv = fontDelegate.createGlyphVector(getFont(),
223 new FontRenderContext(IDENDITY, false, false),
224 new StringCharacterIterator(s));
225 Rectangle2D b = gv.getVisualBounds();
226 return (int) b.getWidth();
231 * The indendity transform, to be used in several methods.
233 private static final AffineTransform IDENDITY = new AffineTransform();
235 private FontDelegate fontDelegate;
237 XFontPeer2(String name, int style, int size)
239 super(name, style, size);
242 File fontfile = new File("/usr/share/fonts/truetype/freefont/FreeSans.ttf");
243 FileInputStream in = new FileInputStream(fontfile);
244 FileChannel ch = in.getChannel();
245 ByteBuffer buffer = ch.map(FileChannel.MapMode.READ_ONLY, 0,
247 fontDelegate = FontFactory.createFonts(buffer)[0];
251 ex.printStackTrace();
255 XFontPeer2(String name, Map atts)
260 File fontfile = new File("/usr/share/fonts/truetype/freefont/FreeSans.ttf");
261 FileInputStream in = new FileInputStream(fontfile);
262 FileChannel ch = in.getChannel();
263 ByteBuffer buffer = ch.map(FileChannel.MapMode.READ_ONLY, 0,
265 fontDelegate = FontFactory.createFonts(buffer)[0];
269 ex.printStackTrace();
273 public boolean canDisplay(Font font, int c)
275 // FIXME: Implement this.
276 throw new UnsupportedOperationException("Not yet implemented");
279 public int canDisplayUpTo(Font font, CharacterIterator i, int start, int limit)
281 // FIXME: Implement this.
282 throw new UnsupportedOperationException("Not yet implemented");
285 public String getSubFamilyName(Font font, Locale locale)
287 // FIXME: Implement this.
288 throw new UnsupportedOperationException("Not yet implemented");
291 public String getPostScriptName(Font font)
293 // FIXME: Implement this.
294 throw new UnsupportedOperationException("Not yet implemented");
297 public int getNumGlyphs(Font font)
299 // FIXME: Implement this.
300 throw new UnsupportedOperationException("Not yet implemented");
303 public int getMissingGlyphCode(Font font)
305 // FIXME: Implement this.
306 throw new UnsupportedOperationException("Not yet implemented");
309 public byte getBaselineFor(Font font, char c)
311 // FIXME: Implement this.
312 throw new UnsupportedOperationException("Not yet implemented");
315 public String getGlyphName(Font font, int glyphIndex)
317 // FIXME: Implement this.
318 throw new UnsupportedOperationException("Not yet implemented");
321 public GlyphVector createGlyphVector(Font font, FontRenderContext frc, CharacterIterator ci)
323 return fontDelegate.createGlyphVector(font, frc, ci);
326 public GlyphVector createGlyphVector(Font font, FontRenderContext ctx, int[] glyphCodes)
328 // FIXME: Implement this.
329 throw new UnsupportedOperationException("Not yet implemented");
332 public GlyphVector layoutGlyphVector(Font font, FontRenderContext frc, char[] chars, int start, int limit, int flags)
334 StringCharacterIterator i = new StringCharacterIterator(new String(chars), start, limit, 0);
335 return fontDelegate.createGlyphVector(font, frc, i);
338 public FontMetrics getFontMetrics(Font font)
340 return new XFontMetrics(font);
343 public boolean hasUniformLineMetrics(Font font)
345 // FIXME: Implement this.
346 throw new UnsupportedOperationException("Not yet implemented");
349 public LineMetrics getLineMetrics(Font font, CharacterIterator ci, int begin, int limit, FontRenderContext rc)
351 return new XLineMetrics(font, ci, begin, limit, rc);
354 public Rectangle2D getMaxCharBounds(Font font, FontRenderContext rc)
356 // FIXME: Implement this.
357 throw new UnsupportedOperationException("Not yet implemented");
361 * Encodes a font name + style + size specification into a X logical font
362 * description (XLFD) as described here:
364 * http://www.meretrx.com/e93/docs/xlfd.html
366 * This is implemented to look up the font description in the
367 * fonts.properties of this package.
369 * @param name the font name
370 * @param atts the text attributes
372 * @return the encoded font description
374 static String encodeFont(String name, Map atts)
376 String family = name;
377 if (family == null || family.equals(""))
378 family = (String) atts.get(TextAttribute.FAMILY);
380 family = "SansSerif";
383 Float sizeFl = (Float) atts.get(TextAttribute.SIZE);
385 size = sizeFl.intValue();
388 // Detect italic attribute.
389 Float posture = (Float) atts.get(TextAttribute.POSTURE);
390 if (posture != null && !posture.equals(TextAttribute.POSTURE_REGULAR))
391 style |= Font.ITALIC;
393 // Detect bold attribute.
394 Float weight = (Float) atts.get(TextAttribute.WEIGHT);
395 if (weight != null && weight.compareTo(TextAttribute.WEIGHT_REGULAR) > 0)
398 return encodeFont(name, style, size);
402 * Encodes a font name + style + size specification into a X logical font
403 * description (XLFD) as described here:
405 * http://www.meretrx.com/e93/docs/xlfd.html
407 * This is implemented to look up the font description in the
408 * fonts.properties of this package.
410 * @param name the font name
411 * @param style the font style
412 * @param size the font size
414 * @return the encoded font description
416 static String encodeFont(String name, int style, int size)
418 StringBuilder key = new StringBuilder();
419 key.append(validName(name));
427 key.append("italic");
429 case (Font.BOLD | Font.ITALIC):
430 key.append("bolditalic");
438 String protoType = fontProperties.getProperty(key.toString());
440 return protoType.replaceFirst("%d", String.valueOf(s * 10));
444 * Checks the specified font name for a valid font name. If the font name
445 * is not known, then this returns 'sansserif' as fallback.
447 * @param name the font name to check
449 * @return a valid font name
451 static String validName(String name)
454 if (name.equalsIgnoreCase("sansserif")
455 || name.equalsIgnoreCase("serif")
456 || name.equalsIgnoreCase("monospaced")
457 || name.equalsIgnoreCase("dialog")
458 || name.equalsIgnoreCase("dialoginput"))
460 retVal = name.toLowerCase();
464 retVal = "sansserif";