001: /*
002: *
003: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
004: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
005: *
006: * This program is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU General Public License version
008: * 2 only, as published by the Free Software Foundation.
009: *
010: * This program is distributed in the hope that it will be useful, but
011: * WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * General Public License version 2 for more details (a copy is
014: * included at /legal/license.txt).
015: *
016: * You should have received a copy of the GNU General Public License
017: * version 2 along with this work; if not, write to the Free Software
018: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
019: * 02110-1301 USA
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
022: * Clara, CA 95054 or visit www.sun.com if you need additional
023: * information or have any questions.
024: */
025:
026: package sun.awt.pocketpc;
027:
028: import java.awt.*;
029: import java.util.Hashtable;
030: import sun.awt.FontDescriptor;
031: import sun.awt.PlatformFont;
032: import sun.awt.CharsetString;
033: import java.io.CharConversionException;
034: import sun.io.CharToByteConverter;
035: import sun.awt.PeerBasedToolkit;
036:
037: /**
038: * A font metrics object for a PPCServer font.
039: *
040: * @version 1.1 Dec 16, 2002
041: */
042: class PPCFontMetrics extends FontMetrics {
043: /**
044: * The widths of the first 256 characters.
045: */
046: int widths[];
047:
048: /**
049: * The standard ascent of the font. This is the logical height
050: * above the baseline for the Alphanumeric characters and should
051: * be used for determining line spacing. Note, however, that some
052: * characters in the font may extend above this height.
053: */
054: int ascent;
055:
056: /**
057: * The standard descent of the font. This is the logical height
058: * below the baseline for the Alphanumeric characters and should
059: * be used for determining line spacing. Note, however, that some
060: * characters in the font may extend below this height.
061: */
062: int descent;
063:
064: /**
065: * The standard leading for the font. This is the logical amount
066: * of space to be reserved between the descent of one line of text
067: * and the ascent of the next line. The height metric is calculated
068: * to include this extra space.
069: */
070: int leading;
071:
072: /**
073: * The standard height of a line of text in this font. This is
074: * the distance between the baseline of adjacent lines of text.
075: * It is the sum of the ascent+descent+leading. There is no
076: * guarantee that lines of text spaced at this distance will be
077: * disjoint; such lines may overlap if some characters overshoot
078: * the standard ascent and descent metrics.
079: */
080: int height;
081:
082: /**
083: * The maximum ascent for all characters in this font. No character
084: * will extend further above the baseline than this metric.
085: */
086: int maxAscent;
087:
088: /**
089: * The maximum descent for all characters in this font. No character
090: * will descend further below the baseline than this metric.
091: */
092: int maxDescent;
093:
094: /**
095: * The maximum possible height of a line of text in this font.
096: * Adjacent lines of text spaced this distance apart will be
097: * guaranteed not to overlap. Note, however, that many paragraphs
098: * that contain ordinary alphanumeric text may look too widely
099: * spaced if this metric is used to determine line spacing. The
100: * height field should be preferred unless the text in a given
101: * line contains particularly tall characters.
102: */
103: int maxHeight;
104:
105: /**
106: * The maximum advance width of any character in this font.
107: */
108: int maxAdvance;
109:
110: private static native void initIDs();
111:
112: static {
113: initIDs();
114: }
115:
116: /**
117: * Calculate the metrics from the given PPCServer and font.
118: */
119: public PPCFontMetrics(Font font) {
120: super (font);
121: init();
122: }
123:
124: /**
125: * Get leading
126: */
127: public int getLeading() {
128: return leading;
129: }
130:
131: /**
132: * Get ascent.
133: */
134: public int getAscent() {
135: return ascent;
136: }
137:
138: /**
139: * Get descent
140: */
141: public int getDescent() {
142: return descent;
143: }
144:
145: /**
146: * Get height
147: */
148: public int getHeight() {
149: return height;
150: }
151:
152: /**
153: * Get maxAscent
154: */
155: public int getMaxAscent() {
156: return maxAscent;
157: }
158:
159: /**
160: * Get maxDescent
161: */
162: public int getMaxDescent() {
163: return maxDescent;
164: }
165:
166: /**
167: * Get maxAdvance
168: */
169: public int getMaxAdvance() {
170: return maxAdvance;
171: }
172:
173: /**
174: * Return the width of the specified string in this Font.
175: */
176: public int stringWidth(String string) {
177: return charsWidth(string.toCharArray(), 0, string.length());
178: }
179:
180: /**
181: * Return the width of the specified char[] in this Font.
182: */
183: public int charsWidth(char chars[], int offset, int length) {
184: if (chars == null) {
185: throw new NullPointerException("chars[] is null");
186: }
187: if ((length < 0) || (offset < 0)
188: || (length + offset > chars.length)
189: || (length > chars.length) || (offset > chars.length)) {
190: throw new ArrayIndexOutOfBoundsException("off or len");
191: }
192: Font font = getFont();
193: PlatformFont pf = ((PlatformFont) ((PeerBasedToolkit) Toolkit
194: .getDefaultToolkit()).getFontPeer(font));
195: //PlatformFont pf = ((PlatformFont) font.getPeer());
196: if (pf.mightHaveMultiFontMetrics()) {
197: return getMFStringWidth(chars, offset, length, font, pf);
198: } else {
199: if (widths != null) {
200: int w = 0;
201: for (int i = offset; i < offset + length; i++) {
202: int ch = chars[i];
203: if (ch < 0 || ch >= widths.length) {
204: w += maxAdvance;
205: } else {
206: w += widths[ch];
207: }
208: }
209: return w;
210: } else {
211: return maxAdvance * length;
212: }
213: }
214: }
215:
216: /*
217: * get multi font string width with a multiple native font
218: */
219: private int getMFStringWidth(char string[], int offset, int length,
220: Font font, PlatformFont pf) {
221: if (length == 0) {
222: return 0;
223: }
224:
225: sun.awt.CharsetString[] css = pf.makeMultiCharsetString(string,
226: offset, length);
227:
228: byte[] csb = null;
229: int baLen = 0;
230: int w = 0;
231: for (int i = 0; i < css.length; i++) {
232: CharsetString cs = css[i];
233: if (needsConversion(font, cs.fontDescriptor)) {
234: try {
235: int l = cs.fontDescriptor.fontCharset
236: .getMaxBytesPerChar()
237: * cs.length;
238: if (l > baLen) {
239: baLen = l;
240: csb = new byte[baLen];
241: }
242: // use a new instance of the fontCharset (bug 4078870)
243: CharToByteConverter cv = (CharToByteConverter) cs.fontDescriptor.fontCharset
244: .getClass().newInstance();
245: int csbLen = cv.convert(cs.charsetChars, cs.offset,
246: cs.offset + cs.length, csb, 0, csb.length);
247:
248: w += getMFCharSegmentWidth(font, cs.fontDescriptor,
249: true, null, 0, 0, csb, csbLen);
250: } catch (InstantiationException ignored) {
251: } catch (IllegalAccessException ignored) {
252: // CharToByte converters are public and can be instantiated
253: // so no exceptions should be thrown
254: } catch (CharConversionException ignored) {
255: }
256: } else {
257: w += getMFCharSegmentWidth(font, cs.fontDescriptor,
258: false, cs.charsetChars, cs.offset, cs.length,
259: null, 0);
260: }
261: }
262: return w;
263: }
264:
265: static native boolean needsConversion(Font font, FontDescriptor des);
266:
267: // Get the width of the char segment, which is in the native charset
268: // of font.
269: private native int getMFCharSegmentWidth(Font font,
270: FontDescriptor des, boolean converted, char[] chars,
271: int offset, int charLength, byte[] bytes, int byteLength);
272:
273: /**
274: * Return the width of the specified byte[] in this Font.
275: */
276: public native int bytesWidth(byte data[], int offset, int len);
277:
278: /**
279: * Get the widths of the first 256 characters in the font.
280: */
281: public int[] getWidths() {
282: return widths;
283: }
284:
285: native void init();
286:
287: static Hashtable table = new Hashtable();
288:
289: static FontMetrics getFontMetrics(Font font) {
290: FontMetrics fm = (FontMetrics) table.get(font);
291: if (fm == null) {
292: table.put(font, fm = new PPCFontMetrics(font));
293: }
294: return fm;
295: }
296: }
|