001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.harmony.awt.gl.font.fontlib;
018:
019: import java.awt.font.FontRenderContext;
020: import java.awt.font.LineMetrics;
021: import java.awt.geom.AffineTransform;
022: import java.awt.geom.Rectangle2D;
023: import java.util.Hashtable;
024:
025: import org.apache.harmony.awt.gl.font.FontExtraMetrics;
026: import org.apache.harmony.awt.gl.font.FontManager;
027: import org.apache.harmony.awt.gl.font.FontPeerImpl;
028: import org.apache.harmony.awt.gl.font.Glyph;
029: import org.apache.harmony.awt.gl.font.LineMetricsImpl;
030:
031: final public class FLFontPeer extends FontPeerImpl {
032: private static final boolean USE_CONSTANT_METRICS = false;
033: private static final Hashtable<String, FontPeerNativeHandler> handlersTable = new Hashtable<String, FontPeerNativeHandler>();
034: private static final Hashtable<Integer, FLGlyph> glyphTable = new Hashtable<Integer, FLGlyph>();
035:
036: private static long getHandler(String name, int style) {
037: String hash = name.concat(String.valueOf(style));
038:
039: FontPeerNativeHandler handl = handlersTable.get(hash);
040:
041: if (handl == null) {
042: handl = new FontPeerNativeHandler(name, style);
043:
044: handlersTable.put(hash, handl);
045: }
046:
047: handl.incriment();
048:
049: return handl.getHandl();
050: }
051:
052: private static void releaseHandler(String name, int style) {
053: handlersTable.get(name.concat(String.valueOf(style)))
054: .decriment();
055: }
056:
057: private static final class FontPeerNativeHandler {
058: private long pFont;
059: private char count = 0;
060: private String name;
061: private int style;
062:
063: FontPeerNativeHandler(String name, int style) {
064: this .name = name;
065: this .style = style;
066: }
067:
068: void incriment() {
069: if (count == 0) {
070: pFont = initFLFontPeer(name, style);
071:
072: //System.out.println("pFont = " + pFont + "name = " + name + ", style = " + style);
073: }
074:
075: if (pFont == 0) {
076: throw new NullPointerException();
077: }
078:
079: count++;
080: }
081:
082: void decriment() {
083: count--;
084:
085: if (count == 0) {
086: //System.out.println("native dispose " + pFont);
087:
088: dispose(pFont);
089: }
090: }
091:
092: long getHandl() {
093: return pFont;
094: }
095:
096: }
097:
098: private int missingGlyphCode = -1;
099:
100: private Glyph defGlyph;
101:
102: public FLFontPeer(String name, int style, int size) {
103: super ();
104: // if (true) throw new NullPointerException();
105: this .size = size;
106: this .style = style;
107: this .name = name;
108:
109: pFont = getHandler(name, style);
110:
111: getLineMetrics();
112:
113: /* if (pFont != 0){
114: this.numGlyphs = LinuxNativeFont.getNumGlyphsNative(pFont);
115: this.italicAngle = LinuxNativeFont.getItalicAngleNative(pFont, this.fontType);
116: }
117:
118: this.nlm = new LinuxLineMetrics(this, null, " "); //$NON-NLS-1$
119:
120: this.ascent = nlm.getLogicalAscent();
121: this.descent = nlm.getLogicalDescent();
122: this.height = nlm.getHeight();
123: this.leading = nlm.getLogicalLeading();
124: this.maxAdvance = nlm.getLogicalMaxCharWidth();
125:
126: if (this.fontType == FontManager.FONT_TYPE_T1){
127: this.defaultChar = 1;
128: } else {
129: this.defaultChar = 0;
130: }
131:
132: this.maxCharBounds = new Rectangle2D.Float(0, -nlm.getAscent(), nlm.getMaxCharWidth(), this.height);
133:
134: */
135:
136: maxCharBounds = new Rectangle2D.Float(0, -nlm.getAscent(), nlm
137: .getMaxCharWidth(), nlm.getHeight());
138:
139: //if (pFont == 0) throw new NullPointerException();
140:
141: //System.out.println("create font size " + size + " style " + style + " name " + name + " pFont " + pFont);
142: }
143:
144: @Override
145: public FontExtraMetrics getExtraMetrics() {
146: // TODO Auto-generated method stub
147: return null;
148: }
149:
150: @Override
151: public LineMetrics getLineMetrics(String str,
152: FontRenderContext frc, AffineTransform at) {
153: /*
154: * metrics[0] - ascent<p>
155: * metrics[1] - descent<p>
156: * metrics[2] - external leading<p>
157: * metrics[3] - underline thickness<p>
158: * -metrics[4] - underline offset<p>
159: * metrics[5] - strikethrough thickness<p>
160: * -metrics[6] - strikethrough offset<p>
161: * metrics[7] - maximum char width<p>*/
162:
163: /*System.out.println("LineMetrics length " + metrics.length + " Font " + pFont);
164: for (int i = 0; i < metrics.length; i ++) {
165: System.out.println(metrics[i]);
166: }//*/
167:
168: /**
169: * Creates LineMetricsImpl object from specified parameters. If baseline data parameter
170: * is null than {0, (-ascent+descent)/2, -ascent} values are used for baseline offsets.
171: *
172: * @param _numChars number of chars
173: * @param _baseLineIndex index of the baseline offset
174: * @param _baselineOffsets an array of baseline offsets
175: * @param _underlineThickness underline thickness
176: * @param _underlineOffset underline offset
177: * @param _strikethroughThickness strikethrough thickness
178: * @param _strikethroughOffset strinkethrough offset
179: * @param _leading leading of the font
180: * @param _height font height
181: * @param _ascent ascent of the font
182: * @param _descent descent of the font
183: * @param _maxCharWidth max char width
184: *
185: public LineMetricsImpl(int _numChars, int _baseLineIndex,
186: float[] _baselineOffsets, float _underlineThickness,
187: float _underlineOffset, float _strikethroughThickness,
188: float _strikethroughOffset, float _leading, float _height,
189: float _ascent, float _descent, float _maxCharWidth) {*/
190:
191: // System.out.println("LineMetricsImpl");
192:
193: LineMetricsImpl lm;
194: if (USE_CONSTANT_METRICS) {
195: float height = size;
196: float ascent = canDisplay('H') ? getGlyph('H').getHeight()
197: : (height * 3) / 4;
198: float descent = canDisplay('p') ? (float) getGlyph('p')
199: .getGlyphMetrics().getBounds2D().getMaxY()
200: : height / 4;
201:
202: lm = new LineMetricsImpl(
203: str.length(), //_numChars number of chars
204: 0, //_baseLineIndex index of the baseline offset
205: new float[] { 0, (-ascent + descent) / 2, -ascent }, //_baselineOffsets an array of baseline offsets
206: ascent / 13, //_underlineThickness underline thickness
207: -descent / 2, //_underlineOffset underline offset
208: ascent / 13, //_strikethroughThickness strikethrough thickness
209: ascent / 2, //_strikethroughOffset strinkethrough offset
210: height - ascent - descent, //_leading leading of the font
211: height, //_height font height
212: ascent, //_ascent ascent of the font
213: descent, //_descent descent of the font
214: canDisplay('W') ? getGlyph('W').getWidth()
215: : getGlyph(' ').getWidth()); //_maxCharWidth max char width
216:
217: } else {
218: float[] metrics = getLineMetrics(pFont);
219: lm = new LineMetricsImpl(str.length(), //_numChars number of chars
220: 0, //_baseLineIndex index of the baseline offset
221: new float[] { 0,
222: (-metrics[0] + metrics[1]) * size / 2,
223: -metrics[0] * size }, //_baselineOffsets an array of baseline offsets
224: metrics[3] * size, //_underlineThickness underline thickness
225: metrics[4] * size, //_underlineOffset underline offset
226: metrics[5] * size, //_strikethroughThickness strikethrough thickness
227: metrics[6] * size, //_strikethroughOffset strinkethrough offset
228: metrics[2] * size, //_leading leading of the font
229: (metrics[0] + metrics[1] + metrics[2]) * size, //_height font height
230: metrics[0] * size, //_ascent ascent of the font
231: metrics[1] * size, //_descent descent of the font
232: metrics[7] * size); //_maxCharWidth max char width
233: }
234:
235: if ((at != null) && (!at.isIdentity())) {
236: lm.scale((float) at.getScaleX(), (float) at.getScaleY());
237: }
238:
239: return lm;
240: }
241:
242: @Override
243: public String getPSName() {
244: psName = getPSName(pFont);
245: return psName;
246: }
247:
248: @Override
249: public int getMissingGlyphCode() {
250: if (missingGlyphCode == -1) {
251: missingGlyphCode = getMissingGlyphCode(pFont);
252: }
253: return missingGlyphCode;
254: }
255:
256: @Override
257: public Glyph getGlyph(char ch) {
258: Integer id = new Integer((size << 8) + ch);
259:
260: if (!glyphTable.containsKey(id)) {
261: //System.out.println("size = " + size + ", char " + ch + ", id = " + id);
262: glyphTable.put(id, new FLGlyph(ch, pFont, size));
263: }
264:
265: return glyphTable.get(id);
266: }
267:
268: @Override
269: public void dispose() {
270: ((FLFontManager) FontManager.getInstance())
271: .removeFontFromHash(this );
272:
273: //System.out.println("dispose " + pFont);
274:
275: releaseHandler(name, style);
276:
277: //dispose(pFont);
278: }
279:
280: @Override
281: public Glyph getDefaultGlyph() {
282: if (defGlyph == null) {
283: defGlyph = getGlyph((char) 0);
284: }
285: return defGlyph;
286: }
287:
288: @Override
289: public boolean canDisplay(char c) {
290: return canDisplay(c, pFont);
291: }
292:
293: @Override
294: public char getUnicodeByIndex(int glyphCode) {
295: return getUnicodeByIndex(glyphCode, pFont);
296: }
297:
298: private static native long initFLFontPeer(String family, int style);
299:
300: private static native float[] getLineMetrics(long fontPeerPointer);
301:
302: private static native String getPSName(long fontPeerPointer);
303:
304: private static native int getMissingGlyphCode(long fontPeerPointer);
305:
306: private static native void dispose(long fontPeerPointer);
307:
308: private static native boolean canDisplay(char c,
309: long fontPeerPointer);
310:
311: private static native char getUnicodeByIndex(int glyphCode,
312: long fontPeerPointer);
313: }
|