001: /*
002: * @(#)GFontPeer.java 1.16 06/10/10
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027:
028: /**
029: * GFontPeer.java
030: *
031: * @author Created by Omnicore CodeGuide
032: */package sun.awt.gtk;
033:
034: import sun.awt.peer.FontPeer;
035: import java.awt.Font;
036: import java.awt.FontMetrics;
037: import java.awt.Toolkit;
038: import java.util.*;
039:
040: import sun.awt.CharsetString;
041:
042: /** The peer used for fonts in Gtk. This class extends the FontMetrics
043: class so that it is very quick to get the font metrics for a font
044: and we don't need to create a new object each time. We also maintain a cache
045: which allows multiple font objects to share the same peer if they are of the
046: same name, style and size. This reduces further the number of objects created. */
047:
048: class GFontPeer extends FontMetrics implements FontPeer {
049: private static int generatedFontCount = 0;
050: GPlatformFont gpf;
051:
052: private GFontPeer(Font font) {
053: super (font);
054: gpf = new GPlatformFont(font.getName(), font.getStyle(), font
055: .getSize());
056:
057: /* gtk init of font is done in GPlatformFont */
058:
059: }
060:
061: private GFontPeer(int gdkfont) {
062: super (null);
063: // data = gdkfont;
064: gpf = new GPlatformFont(gdkfont);
065: }
066:
067: /** Gets the FontPeer for the specified Font. This will look in a
068: cache first to prevent loading of the font for a second time. */
069:
070: synchronized static GFontPeer getFontPeer(Font font) {
071: GFontPeer peer = (GFontPeer) fontToPeerMap.get(font);
072: if (peer == null) {
073: peer = new GFontPeer(font);
074: fontToPeerMap.put(font, peer);
075: }
076: return peer;
077: }
078:
079: /** Gets the font for the specified GdkFont. This is used when installing fonts on
080: the Java components when a widget is created. We check what font the native widget uses and,
081: if one has not been explicitly set for the Java component, we set the font on the component.
082: This will examine all loaded fonts in the cache and see if there is one for gdkfont.
083: If not it will create a new font object with a unique name. */
084:
085: private synchronized static Font getFont(int gdkfont) {
086:
087: /*
088: Iterator i = fontToPeerMap.entrySet().iterator();
089: while (i.hasNext()) {
090: Map.Entry entry = (Map.Entry) i.next();
091: GFontPeer peer = (GFontPeer) entry.getValue();
092: if (areFontsTheSame(gdkfont, peer.data))
093: return (Font) entry.getKey();
094: }
095: */
096:
097: Iterator i = fontToPeerMap.entrySet().iterator();
098: while (i.hasNext()) {
099: Map.Entry entry = (Map.Entry) i.next();
100: GFontPeer peer = (GFontPeer) entry.getValue();
101: if (peer.gpf.containsGdkFont(gdkfont))
102: return (Font) entry.getKey();
103: }
104:
105: // We need to generate a new font for the GdkFont.
106:
107: GFontPeer peer = new GFontPeer(gdkfont);
108: Font font = createFont("GdkFont" + (++generatedFontCount),
109: peer, gdkfont);
110: fontToPeerMap.put(font, peer);
111: return font;
112:
113: }
114:
115: /** Tests whether two gdkfonts are the same. */
116:
117: static native boolean areFontsTheSame(int font1, int font2);
118:
119: /** Creates a font with the specified name and gdkfont. */
120:
121: private static native Font createFont(String name, GFontPeer peer,
122: int gdkfont);
123:
124: /** Loads the font and sets the ascent and descent fields. */
125:
126: private native void init(Font font, String nativeName, int size);
127:
128: /**
129: * Determines the <em>font ascent</em> of the font described by this
130: * font metric. The font ascent is the distance from the font's
131: * baseline to the top of most alphanumeric characters. Some
132: * characters in the font may extend above the font ascent line.
133: * @return the font ascent of the font.
134: * @see java.awt.FontMetrics#getMaxAscent
135: * @since JDK1.0
136: */
137: public int getAscent() {
138: return gpf.ascent;
139: // return ascent;
140: }
141:
142: /**
143: * Determines the <em>font descent</em> of the font described by this
144: * font metric. The font descent is the distance from the font's
145: * baseline to the bottom of most alphanumeric characters with
146: * descenders. Some characters in the font may extend below the font
147: * descent line.
148: * @return the font descent of the font.
149: * @see java.awt.FontMetrics#getMaxDescent
150: * @since JDK1.0
151: */
152: public int getDescent() {
153: // return descent;
154: return gpf.descent;
155: }
156:
157: /**
158: * Determines the <em>standard leading</em> of the font described by
159: * this font metric. The standard leading (interline spacing) is the
160: * logical amount of space to be reserved between the descent of one
161: * line of text and the ascent of the next line. The height metric is
162: * calculated to include this extra space.
163: * @return the standard leading of the font.
164: * @see java.awt.FontMetrics#getHeight
165: * @see java.awt.FontMetrics#getAscent
166: * @see java.awt.FontMetrics#getDescent
167: * @since JDK1.0
168: */
169: public int getLeading() {
170: return 0;
171: }
172:
173: /**
174: * Gets the maximum advance width of any character in this Font.
175: * The advance width is the amount by which the current point is
176: * moved from one character to the next in a line of text.
177: * @return the maximum advance width of any character
178: * in the font, or <code>-1</code> if the
179: * maximum advance width is not known.
180: * @since JDK1.0
181: */
182: public int getMaxAdvance() {
183: return -1;
184: }
185:
186: /**
187: * Returns the advance width of the specified character in this Font.
188: * The advance width is the amount by which the current point is
189: * moved from one character to the next in a line of text.
190: * @param ch the character to be measured
191: * @return the advance width of the specified <code>char</code>
192: * in the font described by this font metric.
193: * @see java.awt.FontMetrics#charsWidth
194: * @see java.awt.FontMetrics#stringWidth
195: * @since JDK1.0
196: */
197: public int charWidth(char ch) {
198: // Optimization for ASCII characters. Prevents creating a string and using all the
199: // char to byte converters to get the bytes.
200:
201: if (ch < 128)
202: return asciiCharWidth(ch);
203: String string = new String(new char[] { ch });
204: return stringWidth(string);
205: }
206:
207: private native int asciiCharWidth(char c);
208:
209: /**
210: * Returns the total advance width for showing the specified String
211: * in this Font.
212: * The advance width is the amount by which the current point is
213: * moved from one character to the next in a line of text.
214: * @param str the String to be measured
215: * @return the advance width of the specified string
216: * in the font described by this font metric.
217: * @see java.awt.FontMetrics#bytesWidth
218: * @see java.awt.FontMetrics#charsWidth
219: * @since JDK1.0
220: */
221: public int stringWidth(String str) {
222: int strWidth = 0;
223: CharsetString[] cs = gpf.makeMultiCharsetString(str);
224:
225: for (int i = 0; i < cs.length; i++) {
226: byte[] s = new byte[cs[i].length * 3];
227: int len;
228:
229: try {
230: len = cs[i].fontDescriptor.fontCharset.convertAny(
231: cs[i].charsetChars, cs[i].offset, cs[i].length,
232: s, 0, s.length);
233: } catch (Exception e) {
234: /* FIXME ... */
235: continue;
236: }
237:
238: int gdkfont = gpf.getGdkFont(cs[i].fontDescriptor);
239: strWidth += stringWidthNative(s, len, gdkfont);
240:
241: }
242:
243: return strWidth;
244: }
245:
246: native int stringWidthNative(byte[] str, int len, int gdkfont);
247:
248: private static native void initIDs();
249:
250: /*
251: * Try to load font properties from default locations.
252: * If font properties cannot be loaded (possibly because there is no file
253: * system present), use a set of en_US properties by default.
254: */
255: static {
256: initIDs();
257: }
258: /* The map which maps fonts to their peers. */
259:
260: private static Map fontToPeerMap = new HashMap(10);
261: /* Private data used by native code to store the GdkFont. */
262:
263: // private int data;
264: /* The ascent of this font. */
265:
266: // private int ascent;
267: /* The descent of this font. */
268:
269: // private int descent;
270: }
|