416089b03963562c0828328f8c82193f87673a30
[jalviewjs.git] / src / javajs / awt / Font.java
1 /* $RCSfile$
2  * $Author: hansonr $
3  * $Date: 2013-10-30 13:47:37 -0500 (Wed, 30 Oct 2013) $
4  * $Revision: 18874 $
5  *
6  * Copyright (C) 2003-2005  Miguel, Jmol Development, www.jmol.org
7  *
8  * Contact: jmol-developers@lists.sf.net
9  *
10  *  This library is free software; you can redistribute it and/or
11  *  modify it under the terms of the GNU Lesser General Public
12  *  License as published by the Free Software Foundation; either
13  *  version 2.1 of the License, or (at your option) any later version.
14  *
15  *  This library is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  *  Lesser General Public License for more details.
19  *
20  *  You should have received a copy of the GNU Lesser General Public
21  *  License along with this library; if not, write to the Free Software
22  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
23  */
24 package javajs.awt;
25
26
27 import javajs.api.FontManager;
28 import javajs.util.AU;
29
30
31 /**
32  *<p>
33  * Provides font support using a byte fid
34  * (<strong>F</strong>ont <strong>ID</strong>) as an index into font table.
35  *</p>
36  *<p>
37  * Supports standard font faces, font styles, and font sizes.
38  *</p>
39  *
40  * @author Miguel, miguel@jmol.org
41  */
42 final public class Font {
43
44   public final byte fid;
45   public final String fontFace;
46   public final String fontStyle;
47   public final float fontSizeNominal;
48   public final int idFontFace;
49   public final int idFontStyle;
50   public final float fontSize;
51   public final Object font;
52   private final Object fontMetrics;
53   private FontManager manager;
54   private int ascent;
55   private int descent;
56   private boolean isBold;
57   private boolean isItalic;
58   
59   private Font(FontManager manager, byte fid, int idFontFace,
60       int idFontStyle, float fontSize, float fontSizeNominal, Object graphics) {
61     this.manager = manager;
62     this.fid = fid;
63     this.fontFace = fontFaces[idFontFace];
64     this.fontStyle = fontStyles[idFontStyle];
65     this.idFontFace = idFontFace;
66     this.idFontStyle = idFontStyle;
67     this.fontSize = fontSize;
68     this.isBold = (idFontStyle & FONT_STYLE_BOLD) == FONT_STYLE_BOLD;
69     this.isItalic = (idFontStyle & FONT_STYLE_ITALIC) == FONT_STYLE_ITALIC;
70     this.fontSizeNominal = fontSizeNominal;
71     font = manager.newFont(fontFaces[idFontFace], isBold, isItalic,
72         fontSize);
73     fontMetrics = manager.getFontMetrics(this, graphics);
74     descent = manager.getFontDescent(fontMetrics);
75     ascent = manager.getFontAscent(fontMetrics);
76
77     //System.out.println("font3d constructed for fontsizeNominal=" + fontSizeNominal + "  and fontSize=" + fontSize);
78   }
79
80   ////////////////////////////////////////////////////////////////
81   
82   private final static int FONT_ALLOCATION_UNIT = 8;
83   private static int fontkeyCount = 1;
84   private static int[] fontkeys = new int[FONT_ALLOCATION_UNIT];
85   private static Font[] font3ds = new Font[FONT_ALLOCATION_UNIT];
86
87   public static Font getFont3D(byte fontID) {
88     return font3ds[fontID & 0xFF];
89   }
90   
91   public static synchronized Font createFont3D(int fontface, int fontstyle,
92                                        float fontsize, float fontsizeNominal,
93                                        FontManager manager, Object graphicsForMetrics) {
94     //if (graphicsForMetrics == null)
95      // return null;
96     if (fontsize > 0xFF)
97       fontsize = 0xFF;
98     int fontsizeX16 = ((int) fontsize) << 4;
99     int fontkey = ((fontface & 3) | ((fontstyle & 3) << 2) | (fontsizeX16 << 4));
100     // watch out for race condition here!
101     for (int i = fontkeyCount; --i > 0;)
102       if (fontkey == fontkeys[i]
103           && font3ds[i].fontSizeNominal == fontsizeNominal)
104         return font3ds[i];
105     int fontIndexNext = fontkeyCount++;
106     if (fontIndexNext == fontkeys.length)
107       fontkeys = AU.arrayCopyI(fontkeys, fontIndexNext + FONT_ALLOCATION_UNIT);
108       font3ds = (Font[]) AU.arrayCopyObject(font3ds, fontIndexNext + FONT_ALLOCATION_UNIT);
109     Font font3d = new Font(manager, (byte) fontIndexNext, fontface, fontstyle,
110         fontsize, fontsizeNominal, graphicsForMetrics);
111     // you must set the font3d before setting the fontkey in order
112     // to prevent a race condition with getFont3D
113     font3ds[fontIndexNext] = font3d;
114     fontkeys[fontIndexNext] = fontkey;
115     return font3d;
116   }
117
118   public final static int FONT_FACE_SANS  = 0;
119   public final static int FONT_FACE_SERIF = 1;
120   public final static int FONT_FACE_MONO  = 2;
121   
122   private final static String[] fontFaces =
123   {"SansSerif", "Serif", "Monospaced", ""};
124
125   public final static int FONT_STYLE_PLAIN      = 0;
126   public final static int FONT_STYLE_BOLD       = 1;
127   public final static int FONT_STYLE_ITALIC     = 2;
128   public final static int FONT_STYLE_BOLDITALIC = 3;
129   
130   private final static String[] fontStyles =
131   {"Plain", "Bold", "Italic", "BoldItalic"};
132   
133   public static int getFontFaceID(String fontface) {
134     return ("Monospaced".equalsIgnoreCase(fontface) ? FONT_FACE_MONO 
135         : "Serif".equalsIgnoreCase(fontface) ? FONT_FACE_SERIF 
136         : FONT_FACE_SANS);
137   }
138
139   public static int getFontStyleID(String fontstyle) {
140     for (int i = 4; --i >= 0; )
141       if (fontStyles[i].equalsIgnoreCase(fontstyle))
142        return i;
143     return -1;
144   }
145
146   public int getAscent() {
147     return ascent;
148   }
149   
150   public int getDescent() {
151     return descent;
152   }
153   
154   public int getHeight() {
155     return getAscent() + getDescent();
156   }
157
158   public Object getFontMetrics() {
159     return fontMetrics;
160   }
161   
162   public int stringWidth(String text) {
163     return manager.fontStringWidth(this, text);
164   }
165
166   public String getInfo() {
167     return  fontSizeNominal + " " + fontFace + " " + fontStyle;
168   }
169 }
170