1 /* ClasspathFontPeer.java -- Font peer used by GNU Classpath.
2 Copyright (C) 2003, 2004 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., 59 Temple Place, Suite 330, 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. */
39 package gnu
.java
.awt
.peer
;
42 import java
.awt
.peer
.*;
43 import java
.awt
.font
.*;
44 import java
.awt
.geom
.*;
47 import gnu
.java
.awt
.*;
51 * A peer for fonts that are used inside Classpath. The purpose of
52 * this interface is to abstract from platform-specific font handling
53 * in the Classpath implementation of java.awt.Font and related
56 * <p><b>State kept by the peer:</b> a peer is generated for each Font
57 * object in the default implementation. If you wish to share peers between
58 * fonts, you will need to subclass both ClasspathFontPeer and
59 * {@link ClasspathToolKit}.</p>
61 * <p><b>Thread Safety:</b> Methods of this interface may be called
62 * from arbitrary threads at any time. Implementations of the
63 * <code>ClasspathFontPeer</code> interface are required to perform
64 * the necessary synchronization.</p>
66 * @see java.awt.Font#getPeer
67 * @see java.awt.Toolkit#getFontPeer
69 * @author Sascha Brawer (brawer@dandelis.ch)
70 * @author Graydon Hoare (graydon@redhat.com)
72 public abstract class ClasspathFontPeer
76 /*************************************************************************/
83 * The 3 names of this font. all fonts have 3 names, some of which
86 * logical -- name the font was constructed from
87 * family -- a designer or brand name (Helvetica)
88 * face -- specific instance of a design (Helvetica Regular)
90 * @see isLogicalFontName
93 protected String logicalName
;
94 protected String familyName
;
95 protected String faceName
;
98 * The font style, which is a combination (by OR-ing) of the font style
99 * constants PLAIN, BOLD and ITALIC, in this class.
104 * The font point size. A point is 1/72 of an inch.
106 protected float size
;
109 * The affine transformation the font is currently subject to.
111 protected AffineTransform transform
;
113 protected static ClasspathToolkit
tk()
115 return (ClasspathToolkit
)(Toolkit
.getDefaultToolkit ());
119 * Confusingly, a Logical Font is a concept unrelated to
120 * a Font's Logical Name.
122 * A Logical Font is one of 6 built-in, abstract font types
123 * which must be supported by any java environment: SansSerif,
124 * Serif, Monospaced, Dialog, and DialogInput.
126 * A Font's Logical Name is the name the font was constructed
127 * from. This might be the name of a Logical Font, or it might
128 * be the name of a Font Face.
131 protected static boolean isLogicalFontName(String name
)
133 String uname
= name
.toUpperCase ();
134 return (uname
.equals ("SANSSERIF") ||
135 uname
.equals ("SERIF") ||
136 uname
.equals ("MONOSPACED") ||
137 uname
.equals ("DIALOG") ||
138 uname
.equals ("DIALOGINPUT"));
141 protected static String
logicalFontNameToFaceName (String name
)
143 String uname
= name
.toUpperCase ();
144 if (uname
.equals("SANSSERIF"))
146 else if (uname
.equals ("SERIF"))
148 else if (uname
.equals ("MONOSPACED"))
150 else if (uname
.equals ("DIALOG"))
152 else if (uname
.equals ("DIALOGINPUT"))
158 protected static String
faceNameToFamilyName (String name
)
163 public static void copyStyleToAttrs (int style
, Map attrs
)
165 if ((style
& Font
.BOLD
) == Font
.BOLD
)
166 attrs
.put (TextAttribute
.WEIGHT
, TextAttribute
.WEIGHT_BOLD
);
168 attrs
.put (TextAttribute
.WEIGHT
, TextAttribute
.WEIGHT_REGULAR
);
170 if ((style
& Font
.ITALIC
) == Font
.ITALIC
)
171 attrs
.put (TextAttribute
.POSTURE
, TextAttribute
.POSTURE_OBLIQUE
);
173 attrs
.put (TextAttribute
.POSTURE
, TextAttribute
.POSTURE_REGULAR
);
176 protected static void copyFamilyToAttrs (String fam
, Map attrs
)
179 attrs
.put (TextAttribute
.FAMILY
, fam
);
182 public static void copySizeToAttrs (float size
, Map attrs
)
184 attrs
.put (TextAttribute
.SIZE
, new Float (size
));
187 protected static void copyTransformToAttrs (AffineTransform trans
, Map attrs
)
190 attrs
.put(TextAttribute
.TRANSFORM
, new TransformAttribute (trans
));
194 protected void setStandardAttributes (String name
, String family
, int style
,
195 float size
, AffineTransform trans
)
197 this.logicalName
= name
;
199 if (isLogicalFontName (name
))
200 this.faceName
= logicalFontNameToFaceName (name
);
202 this.faceName
= name
;
205 this.familyName
= family
;
207 this.familyName
= faceNameToFamilyName (faceName
);
211 this.transform
= trans
;
215 protected void setStandardAttributes (String name
, Map attribs
)
217 String family
= this.familyName
;
218 AffineTransform trans
= this.transform
;
219 float size
= this.size
;
220 int style
= this.style
;
222 if (attribs
.containsKey (TextAttribute
.FAMILY
))
223 family
= (String
) attribs
.get (TextAttribute
.FAMILY
);
228 if (attribs
.containsKey (TextAttribute
.WEIGHT
))
230 Float weight
= (Float
) attribs
.get (TextAttribute
.WEIGHT
);
231 if (weight
.floatValue () >= TextAttribute
.WEIGHT_BOLD
.floatValue ())
235 if (attribs
.containsKey (TextAttribute
.POSTURE
))
237 Float posture
= (Float
) attribs
.get (TextAttribute
.POSTURE
);
238 if (posture
.floatValue () >= TextAttribute
.POSTURE_OBLIQUE
.floatValue ())
239 style
+= Font
.ITALIC
;
242 if (attribs
.containsKey (TextAttribute
.SIZE
))
244 Float sz
= (Float
) attribs
.get (TextAttribute
.SIZE
);
245 size
= sz
.floatValue ();
247 // Pango doesn't accept 0 as a font size.
254 if (attribs
.containsKey (TextAttribute
.TRANSFORM
))
256 TransformAttribute ta
= (TransformAttribute
)
257 attribs
.get(TextAttribute
.TRANSFORM
);
258 trans
= ta
.getTransform ();
261 setStandardAttributes (name
, family
, style
, size
, trans
);
264 protected void getStandardAttributes (Map attrs
)
266 copyFamilyToAttrs (this.familyName
, attrs
);
267 copySizeToAttrs (this.size
, attrs
);
268 copyStyleToAttrs (this.style
, attrs
);
269 copyTransformToAttrs (this.transform
, attrs
);
273 /* Begin public API */
275 public ClasspathFontPeer (String name
, Map attrs
)
277 setStandardAttributes (name
, attrs
);
280 public ClasspathFontPeer (String name
, int style
, int size
)
282 setStandardAttributes (name
, (String
)null, style
,
283 (float)size
, (AffineTransform
)null);
287 * Implementation of {@link Font#getName}
289 * @param font the font this peer is being called from. This may be
290 * useful if you are sharing peers between Font objects. Otherwise it may
294 public String
getName (Font font
)
300 * Implementation of {@link Font#getFamily()}
302 * @param font the font this peer is being called from. This may be
303 * useful if you are sharing peers between Font objects. Otherwise it may
307 public String
getFamily (Font font
)
313 * Implementation of {@link Font#getFamily(Locale)}
315 * @param font the font this peer is being called from. This may be
316 * useful if you are sharing peers between Font objects. Otherwise it may
320 public String
getFamily (Font font
, Locale lc
)
326 * Implementation of {@link Font#getFontName()}
328 * @param font the font this peer is being called from. This may be
329 * useful if you are sharing peers between Font objects. Otherwise it may
333 public String
getFontName (Font font
)
339 * Implementation of {@link Font#getFontName(Locale)}
341 * @param font the font this peer is being called from. This may be
342 * useful if you are sharing peers between Font objects. Otherwise it may
346 public String
getFontName (Font font
, Locale lc
)
352 * Implementation of {@link Font#getSize}
354 * @param font the font this peer is being called from. This may be
355 * useful if you are sharing peers between Font objects. Otherwise it may
359 public float getSize (Font font
)
365 * Implementation of {@link Font#isPlain}
367 * @param font the font this peer is being called from. This may be
368 * useful if you are sharing peers between Font objects. Otherwise it may
372 public boolean isPlain (Font font
)
374 return style
== Font
.PLAIN
;
378 * Implementation of {@link Font#isBold}
380 * @param font the font this peer is being called from. This may be
381 * useful if you are sharing peers between Font objects. Otherwise it may
385 public boolean isBold (Font font
)
387 return ((style
& Font
.BOLD
) == Font
.BOLD
);
391 * Implementation of {@link Font#isItalic}
393 * @param font the font this peer is being called from. This may be
394 * useful if you are sharing peers between Font objects. Otherwise it may
398 public boolean isItalic (Font font
)
400 return ((style
& Font
.ITALIC
) == Font
.ITALIC
);
404 * Implementation of {@link Font#deriveFont(int, float)}
406 * @param font the font this peer is being called from. This may be
407 * useful if you are sharing peers between Font objects. Otherwise it may
411 public Font
deriveFont (Font font
, int style
, float size
)
413 Map attrs
= new HashMap ();
414 getStandardAttributes (attrs
);
415 copyStyleToAttrs (style
, attrs
);
416 copySizeToAttrs (size
, attrs
);
417 return tk().getFont (logicalName
, attrs
);
421 * Implementation of {@link Font#deriveFont(float)}
423 * @param font the font this peer is being called from. This may be
424 * useful if you are sharing peers between Font objects. Otherwise it may
428 public Font
deriveFont (Font font
, float size
)
430 Map attrs
= new HashMap ();
431 getStandardAttributes (attrs
);
432 copySizeToAttrs (size
, attrs
);
433 return tk().getFont (logicalName
, attrs
);
437 * Implementation of {@link Font#deriveFont(int)}
439 * @param font the font this peer is being called from. This may be
440 * useful if you are sharing peers between Font objects. Otherwise it may
444 public Font
deriveFont (Font font
, int style
)
446 Map attrs
= new HashMap ();
447 getStandardAttributes (attrs
);
448 copyStyleToAttrs (style
, attrs
);
449 return tk().getFont (logicalName
, attrs
);
453 * Implementation of {@link Font#deriveFont(int, AffineTransform)}
455 * @param font the font this peer is being called from. This may be
456 * useful if you are sharing peers between Font objects. Otherwise it may
460 public Font
deriveFont (Font font
, int style
, AffineTransform t
)
462 Map attrs
= new HashMap ();
463 getStandardAttributes (attrs
);
464 copyStyleToAttrs (style
, attrs
);
465 copyTransformToAttrs (t
, attrs
);
466 return tk().getFont (logicalName
, attrs
);
470 * Implementation of {@link Font#deriveFont(AffineTransform)}
472 * @param font the font this peer is being called from. This may be
473 * useful if you are sharing peers between Font objects. Otherwise it may
477 public Font
deriveFont (Font font
, AffineTransform t
)
479 Map attrs
= new HashMap ();
480 getStandardAttributes (attrs
);
481 copyTransformToAttrs (t
, attrs
);
482 return tk().getFont (logicalName
, attrs
);
486 * Implementation of {@link Font#deriveFont(Map)}
488 * @param font the font this peer is being called from. This may be
489 * useful if you are sharing peers between Font objects. Otherwise it may
493 public Font
deriveFont (Font font
, Map attrs
)
495 return tk().getFont (logicalName
, attrs
);
499 * Implementation of {@link Font#getAttributes()}
501 * @param font the font this peer is being called from. This may be
502 * useful if you are sharing peers between Font objects. Otherwise it may
506 public Map
getAttributes (Font font
)
508 HashMap h
= new HashMap ();
509 getStandardAttributes (h
);
514 * Implementation of {@link Font#getAvailableAttributes()}
516 * @param font the font this peer is being called from. This may be
517 * useful if you are sharing peers between Font objects. Otherwise it may
521 public AttributedCharacterIterator
.Attribute
[] getAvailableAttributes(Font font
)
523 AttributedCharacterIterator
.Attribute a
[] =
524 new AttributedCharacterIterator
.Attribute
[5];
525 a
[0] = TextAttribute
.FAMILY
;
526 a
[1] = TextAttribute
.SIZE
;
527 a
[2] = TextAttribute
.POSTURE
;
528 a
[3] = TextAttribute
.WEIGHT
;
529 a
[4] = TextAttribute
.TRANSFORM
;
534 * Implementation of {@link Font#getTransform()}
536 * @param font the font this peer is being called from. This may be
537 * useful if you are sharing peers between Font objects. Otherwise it may
541 public AffineTransform
getTransform (Font font
)
543 if (transform
== null)
544 transform
= new AffineTransform ();
549 * Implementation of {@link Font#isTransformed()}
551 * @param font the font this peer is being called from. This may be
552 * useful if you are sharing peers between Font objects. Otherwise it may
556 public boolean isTransformed (Font font
)
558 return ! transform
.isIdentity ();
562 * Implementation of {@link Font#getItalicAngle()}
564 * @param font the font this peer is being called from. This may be
565 * useful if you are sharing peers between Font objects. Otherwise it may
569 public float getItalicAngle (Font font
)
571 if ((style
& Font
.ITALIC
) == Font
.ITALIC
)
572 return TextAttribute
.POSTURE_OBLIQUE
.floatValue ();
574 return TextAttribute
.POSTURE_REGULAR
.floatValue ();
579 * Implementation of {@link Font#getStyle()}
581 * @param font the font this peer is being called from. This may be
582 * useful if you are sharing peers between Font objects. Otherwise it may
586 public int getStyle (Font font
)
594 /* Remaining methods are abstract */
597 * Implementation of {@link Font#canDisplay(char)}
599 * @param font the font this peer is being called from. This may be
600 * useful if you are sharing peers between Font objects. Otherwise it may
604 public abstract boolean canDisplay (Font font
, char c
);
607 * Implementation of {@link Font#canDisplay(String)},
608 * {@link Font#canDisplay(char [], int, int)}, and
609 * {@link Font#canDisplay(CharacterIterator, int, int)}.
611 * @param font the font this peer is being called from. This may be
612 * useful if you are sharing peers between Font objects. Otherwise it may
616 public abstract int canDisplayUpTo (Font font
, CharacterIterator i
, int start
, int limit
);
620 * Returns the name of this font face inside the family, for example
621 * <i>“Light”</i>.
623 * <p>This method is currently not used by {@link Font}. However,
624 * this name would be needed by any serious desktop publishing
627 * @param font the font whose sub-family name is requested.
629 * @param locale the locale for which to localize the name. If
630 * <code>locale</code> is <code>null</code>, the returned name is
631 * localized to the user’s default locale.
633 * @return the name of the face inside its family, or
634 * <code>null</code> if the font does not provide a sub-family name.
637 public abstract String
getSubFamilyName (Font font
, Locale locale
);
641 * Implementation of {@link Font#getPSName()}
643 * @param font the font this peer is being called from. This may be
644 * useful if you are sharing peers between Font objects. Otherwise it may
648 public abstract String
getPostScriptName (Font font
);
652 * Implementation of {@link Font#getNumGlyphs()}
654 * @param font the font this peer is being called from. This may be
655 * useful if you are sharing peers between Font objects. Otherwise it may
659 public abstract int getNumGlyphs (Font font
);
663 * Implementation of {@link Font#getMissingGlyphCode()}
665 * @param font the font this peer is being called from. This may be
666 * useful if you are sharing peers between Font objects. Otherwise it may
670 public abstract int getMissingGlyphCode (Font font
);
674 * Implementation of {@link Font#getBaselineFor(char)}
676 * @param font the font this peer is being called from. This may be
677 * useful if you are sharing peers between Font objects. Otherwise it may
681 public abstract byte getBaselineFor (Font font
, char c
);
685 * Returns a name for the specified glyph. This is useful for
686 * generating PostScript or PDF files that embed some glyphs of a
687 * font. If the implementation follows glyph naming conventions
688 * specified by Adobe, search engines can extract the original text
689 * from the generated PostScript and PDF files.
691 * <p>This method is currently not used by GNU Classpath. However,
692 * it would be very useful for someone wishing to write a good
693 * PostScript or PDF stream provider for the
694 * <code>javax.print</code> package.
696 * <p><b>Names are not unique:</b> Under some rare circumstances,
697 * the same name can be returned for different glyphs. It is
698 * therefore recommended that printer drivers check whether the same
699 * name has already been returned for antoher glyph, and make the
700 * name unique by adding the string ".alt" followed by the glyph
703 * <p>This situation would occur for an OpenType or TrueType font
704 * that has a <code>post</code> table of format 3 and provides a
705 * mapping from glyph IDs to Unicode sequences through a
706 * <code>Zapf</code> table. If the same sequence of Unicode
707 * codepoints leads to different glyphs (depending on contextual
708 * position, for example, or on typographic sophistication level),
709 * the same name would get synthesized for those glyphs. To avoid
710 * this, the font peer would have to go through the names of all
711 * glyphs, which would make this operation very inefficient with
714 * @param font the font containing the glyph whose name is
717 * @param glyphIndex the glyph whose name the caller wants to
720 * @return the glyph name, or <code>null</code> if a font does not
721 * provide glyph names.
724 public abstract String
getGlyphName (Font font
, int glyphIndex
);
728 * Implementation of {@link
729 * Font#createGlyphVector(FontRenderContext, String)}, {@link
730 * Font#createGlyphVector(FontRenderContext, char[])}, and {@link
731 * Font#createGlyphVector(FontRenderContext, CharacterIterator)}.
733 * @param font the font object that the created GlyphVector will return
734 * when it gets asked for its font. This argument is needed because the
735 * public API of {@link GlyphVector} works with {@link java.awt.Font},
736 * not with font peers.
739 public abstract GlyphVector
createGlyphVector (Font font
,
740 FontRenderContext frc
,
741 CharacterIterator ci
);
745 * Implementation of {@link Font#createGlyphVector(FontRenderContext,
748 * @param font the font object that the created GlyphVector will return
749 * when it gets asked for its font. This argument is needed because the
750 * public API of {@link GlyphVector} works with {@link java.awt.Font},
751 * not with font peers.
754 public abstract GlyphVector
createGlyphVector (Font font
,
755 FontRenderContext ctx
,
760 * Implementation of {@link Font#layoutGlyphVector(FontRenderContext,
761 * char[], int, int, int)}.
763 * @param font the font object that the created GlyphVector will return
764 * when it gets asked for its font. This argument is needed because the
765 * public API of {@link GlyphVector} works with {@link java.awt.Font},
766 * not with font peers.
769 public abstract GlyphVector
layoutGlyphVector (Font font
,
770 FontRenderContext frc
,
771 char[] chars
, int start
,
772 int limit
, int flags
);
776 * Implementation of {@link Font#getFontMetrics()}
778 * @param font the font this peer is being called from. This may be
779 * useful if you are sharing peers between Font objects. Otherwise it may
783 public abstract FontMetrics
getFontMetrics (Font font
);
787 * Implementation of {@link Font#hasUniformLineMetrics()}
789 * @param font the font this peer is being called from. This may be
790 * useful if you are sharing peers between Font objects. Otherwise it may
794 public abstract boolean hasUniformLineMetrics (Font font
);
798 * Implementation of {@link Font#getLineMetrics(CharacterIterator, int,
799 * int, FontRenderContext)}
801 * @param font the font this peer is being called from. This may be
802 * useful if you are sharing peers between Font objects. Otherwise it may
806 public abstract LineMetrics
getLineMetrics (Font font
,
807 CharacterIterator ci
,
808 int begin
, int limit
,
809 FontRenderContext rc
);
812 * Implementation of {@link Font#getMaxCharBounds(FontRenderContext)}
814 * @param font the font this peer is being called from. This may be
815 * useful if you are sharing peers between Font objects. Otherwise it may
819 public abstract Rectangle2D
getMaxCharBounds (Font font
,
820 FontRenderContext rc
);
823 * Implementation of {@link Font#getStringBounds(CharacterIterator, int,
824 * int, FontRenderContext)}
826 * @param font the font this peer is being called from. This may be
827 * useful if you are sharing peers between Font objects. Otherwise it may
831 public abstract Rectangle2D
getStringBounds (Font font
,
832 CharacterIterator ci
,
833 int begin
, int limit
,
834 FontRenderContext frc
);