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: /**
018: * @author Ilya S. Okomin
019: * @version $Revision$
020: */package org.apache.harmony.awt.gl.font;
021:
022: import java.awt.Font;
023: import java.io.IOException;
024: import java.security.AccessController;
025: import java.security.PrivilegedAction;
026: import java.util.Hashtable;
027:
028: import org.apache.harmony.awt.internal.nls.Messages;
029:
030: public class NativeFont {
031:
032: /**
033: * List of family indexes in families array corresponding to the faces
034: * indexing.
035: */
036: public static int[] famIndices;
037: /**
038: * List of font styles of system fonts initialized using GDI
039: * corresponding to faces indexing.
040: */
041: public static int[] fontStyles;
042:
043: /**
044: * List of font types of system fonts initialized using GDI
045: * corresponding to the faces indexing.
046: */
047: public static int[] fontTypes;
048:
049: /**
050: * List of font types of system fonts initialized using GDI.
051: */
052: public static String[] faces;
053:
054: /**
055: * The number of different fonts installed onto the system.
056: */
057: public static int fontsCount;
058:
059: /**
060: * List of all families installed onto the system.
061: */
062: public static String[] families;
063:
064: /**
065: * Native method returns list of all families installed onto the system.
066: */
067: public static native String[] getFontFamiliesNames();
068:
069: /**
070: * Adds font resource from file to the system. Returns true if font was added
071: * successfully, false otherwise.
072: *
073: * @param absolutePath String that represent absolute path to the font resource.
074: */
075: public static native String embedFontNative(String absolutePath);
076:
077: /**
078: * Initialize native GDI font object and return font handle, also sets font
079: * type and unicode ranges to the font peer parameter.
080: *
081: * @param winFont Windows font peer
082: * @param name the name of the font
083: * @param style style of the font
084: * @param size font size
085: *
086: * @return native GDI font handle.
087: */
088: public static native long initializeFont(WindowsFont winFont,
089: String name, int style, int size);
090:
091: /**
092: * Returns true if native GDI font can display char, false otherwise.
093: * NullPointerException is thrown in case of GDI error.
094: *
095: * @param hndFont GDI font handle
096: * @param c specified char
097: */
098: public static native boolean canDisplayCharNative(long hndFont,
099: char c);
100:
101: /**
102: * Returns GDI font object's family name if success,
103: * otherwise null and NullPointerException is thrown.
104: *
105: * @param hndFont GDI font handle
106: */
107: public static native String getFamilyNative(long hndFont);
108:
109: /**
110: * Returns GDI font's face name.
111: * NullPointerException is thrown in case of GDI error.
112: *
113: * @param hndFont GDI font handle
114: */
115: public static native String getFontNameNative(long hndFont);
116:
117: /**
118: * Disposes native font resources.
119: *
120: * @param hndFont GDI font handle
121: * @return result of GDI library DeleteObject method
122: */
123: public static native int pFontFree(long hndFont);
124:
125: /**
126: * Returns tangent of Italic angle of given Font.
127: * NullPointerException is thrown if there is GDI error.
128: *
129: * @param hndFont GDI font handle
130: */
131: public static native float getItalicAngleNative(long hndFont);
132:
133: /**
134: * Enumerates system font face names and updates fullNames, fontStyles, fontTypes arrays.
135: * In case of exceptions in native code NullPointerException is thorwn.
136: */
137: public static native void enumSystemFonts();
138:
139: /**
140: * Returns an array of available system TrueType fonts names.
141: * In case of errors in native code returned value is null.
142: */
143: public static native String[] getFonts();
144:
145: /**
146: * Returns array of values of font metrics corresponding to the given GDI
147: * font object. null is returned and NullPointerException is thrown in case of GDI errors.
148: *
149: * @param hFont GDI font handle
150: * @param fontSize size of the font
151: * @param usesFractionalMetrics true if results calculated using fractional metrics
152: * @param fontType type of the specified font
153: */
154: public static native float[] getNativeLineMetrics(long hFont,
155: int fontSize, boolean isAntialiased,
156: boolean usesFractionalMetrics, int fontType);
157:
158: /**
159: * Returns an array of glyph precise metrics values for the specified character.
160: * null is returned and NullPointerException is thrown in case of GDI errors.
161: *
162: * @param pFnt GDI font handle
163: * @param c specified char
164: * @param fontSize size of the font
165: */
166: public static native float[] getGlyphInfoNative(long pFnt, char c,
167: int fontSize);
168:
169: /**
170: * Returns array of glyph metrics values in pixels for the specified character
171: * null is returned and NullPointerException is thrown in case of GDI errors.
172: *
173: * @param pFnt GDI font handle
174: * @param c specified char
175: */
176: public static native int[] getGlyphPxlInfoNative(long pFnt, char c);
177:
178: /**
179: * Returns an array of the glyph codes corresponding to the characters from
180: * String parameter. null is returned and NullPointerException is thrown
181: * in case of GDI errors.
182: *
183: * @param fnt GDI font handle
184: * @param str specified string
185: * @param len the length of the specified string
186: */
187: public static native int[] getGlyphCodesNative(long fnt,
188: String str, int len);
189:
190: /**
191: * Returns glyph code corresponding to the specified character. null is
192: * returned and NullPointerException is thrown in case of GDI errors.
193: *
194: * @param fnt GDI font handle
195: * @param uChar specified character
196: */
197: public static native int getGlyphCodeNative(long fnt, char uChar);
198:
199: /**
200: * Removes font resource from file with specified path from the system.
201: *
202: * @param tempFontFileName temporary font resource file path
203: * @return zero if native call fails, non-zero if success
204: */
205: public static native int RemoveFontResource(String tempFontFileName);
206:
207: /**
208: * Returns bitmap representation of the glyph image in 1 bit per pixel format
209: * for the specified Glyph object. null is
210: * returned and NullPointerException is thrown in case of GDI errors.
211: *
212: * @param glyph specified Glyph object
213: */
214: public static native byte[] NativeInitGlyphImage(Glyph glyph);
215:
216: /**
217: * Initialization of the table with LCID values key = ctry_lang, value = LCID value
218: * in Windows API format. In case of null parameters method returns required size of
219: * arrays to store results.
220: *
221: * @param shortStrings array of Strings to fill with languages from locale settings
222: * available on the system
223: * @param LCIDs array of shorts to fill with LCID values from locale settings
224: * available on the system.
225: *
226: * @return size of arrays if success, otherwise returns 0.
227: */
228: public static native int nativeInitLCIDsTable(
229: String[] shortStrings, short[] LCIDs);
230:
231: /**
232: * Returns size of polyheaders structure and set
233: * polyheaders pointer to the native array of TTPOLYGONHEADER elements.
234: *
235: * @param fnt GDI font handle
236: * @param uChar specified character
237: * @param polyheaders pointer to TTPOLYGONHEADER structure
238: * @param size size of buffer with TTPOLYGONHEADER structure
239: */
240: public static native int getGlyphOutline(long fnt, char uChar,
241: long polyheaders, int size);
242:
243: /**
244: * Returns an array of extrametrics of the font:<p>
245: * elem[0] - the average width of characters in the font (Type1 - 0.0f)<p>
246: * elem[1] - horizontal size for subscripts (Type1 - 0.7f * fontHeight)<p>
247: * elem[2] - vertical size for subscripts (Type1 - 0.65f * fontHeight)<p>
248: * elem[3] - horizontal offset for subscripts (Type1 - 0.0f)<p>
249: * elem[4] - vertical offset value for subscripts(Type1 - 0.15f * fontHeight)<p>
250: * elem[5] - horizontal size for superscripts (Type1 - 0.7f * fontHeight)<p>
251: * elem[6] - vertical size for superscripts (Type1 - 0.65f * fontHeight)<p>
252: * elem[7] - horizontal offset for superscripts (Type1 - 0.0f)<p>
253: * elem[8] - vertical offset for superscripts (Type1 - 0.45f * fontHeight)<p>
254: * For TrueType fonts metrics are taken from OS2 table, for Type1 fonts
255: * metrics are calculated using coefficients (read FontExtraMetrics comments).
256: *
257: * @param hFont GDI font handle
258: * @param fontSize font size
259: * @param fontType type of the font
260: */
261: public static native float[] getExtraMetricsNative(long hFont,
262: int fontSize, int fontType);
263:
264: /***************************************************************************
265: *
266: * GDI+ text native functions
267: *
268: ***************************************************************************/
269:
270: /**
271: * Sets antialiasing mode using GDI+ objects defined in graphics info.
272: */
273: public static native void setAntialiasing(long graphicsInfo,
274: boolean isAntialiasing);
275:
276: /**
277: * Draws string at the specified coordinates using GDI+ objects defined in graphics info.
278: * This method is applicable for drawing without affine transforms.
279: */
280: public static native int gdiPlusDrawText(long graphicsInfo,
281: String text, int length, long font, float xOffset,
282: float yOffset);
283:
284: /** GDI+ DriverStringOptions constants */
285: public static final int DriverStringOptionsCmapLookup = 1;
286: public static final int DriverStringOptionsVertical = 2;
287: public static final int DriverStringOptionsRealizedAdvance = 4;
288: public static final int DriverStringOptionsLimitSubpixel = 8;
289:
290: /**
291: * Draws transformed char according to the matrix at the specified position.
292: * @param gi GraphicsInfo pointer
293: * @param chr specified character
294: * @param font GDI font handle
295: * @param x coordinate X
296: * @param y coordinate Y
297: * @param flags drawing flags, a set of DriverStringOptions constants
298: * @param matrix transformation matrix
299: * @return GDI+ result of the char drawing.
300: */
301: public static native int gdiPlusDrawDriverChar(long gi, char chr,
302: long font, float x, float y, int flags, double[] matrix);
303:
304: /**
305: * Draws string transformed according to the matrix, each character is drawn at
306: * the specified positions.
307: *
308: * @param gi GraphicsInfo pointer
309: * @param text specified String
310: * @param length length of the specified String
311: * @param font GDI font handle
312: * @param x origin X coordinate
313: * @param y origin Y coordinate
314: * @param positions an array of positions defined for chars
315: * @param flags drawing flags, a set of DriverStringOptions constants
316: * @param matrix transformation matrix
317: * @return GDI+ result of the char drawing.
318: */
319: public static native int gdiPlusDrawDriverString(long gi,
320: String text, int length, long font, float x, float y,
321: double[] positions, int flags, double[] matrix);
322:
323: /**
324: * Draws string transformed according to the matrix, each character is drawn at
325: * the specified positions.
326: *
327: * @param gi GraphicsInfo pointer
328: * @param text specified array of chars
329: * @param length length of the specified chars array
330: * @param font GDI font handle
331: * @param positions an array of positions defined for chars
332: * @param flags drawing flags, a set of DriverStringOptions constants
333: * @param matrix transformation matrix
334: * @return GDI+ result of the char drawing.
335: */
336: public static native int gdiPlusDrawDriverChars(long gi,
337: char text[], int length, long font, double[] positions,
338: int flags, double[] matrix);
339:
340: /** Releases hdc object in GDI+ Graphics object from the GraphicsInfo. */
341: public static native void gdiPlusReleaseHDC(long gi, long hdc);
342:
343: /** Returns hdc object of the GDI+ Graphics object from the GraphicsInfo. */
344: public static native long gdiPlusGetHDC(long gi);
345:
346: /***************************************************************************/
347:
348: /**
349: * Initializes LCID table
350: */
351: public static void initLCIDsTable(Hashtable<String, Short> ht) {
352: int count = nativeInitLCIDsTable(null, null);
353:
354: if (count != 0) {
355: String[] shortStrings = new String[count];
356: short[] LCIDs = new short[count];
357:
358: nativeInitLCIDsTable(shortStrings, LCIDs);
359:
360: for (int i = 0; i < count; i++) {
361: ht
362: .put(new String(shortStrings[i]), new Short(
363: LCIDs[i]));
364: }
365: /*
366: * Because of native method nativeInitLCIDsTable returns only short
367: * strings in language_country format we have to add manually just
368: * language strings that Java locale support with LCID values (0x04**).
369: */
370: ht.put(new String("ar"), new Short((short) 0x0401)); // ar-dz //$NON-NLS-1$
371: ht.put(new String("bg"), new Short((short) 0x0402)); //$NON-NLS-1$
372: ht.put(new String("ca"), new Short((short) 0x0403)); //$NON-NLS-1$
373: ht.put(new String("zh"), new Short((short) 0x0404)); // zh-tw //$NON-NLS-1$
374: ht.put(new String("cs"), new Short((short) 0x0405)); //$NON-NLS-1$
375: ht.put(new String("da"), new Short((short) 0x0406)); //$NON-NLS-1$
376: ht.put(new String("de"), new Short((short) 0x0407)); // de-de //$NON-NLS-1$
377: ht.put(new String("el"), new Short((short) 0x0408)); //$NON-NLS-1$
378: ht.put(new String("fi"), new Short((short) 0x040b)); //$NON-NLS-1$
379: ht.put(new String("fr"), new Short((short) 0x040c)); // fr-fr //$NON-NLS-1$
380: ht.put(new String("iw"), new Short((short) 0x040d)); // "he" //$NON-NLS-1$
381: ht.put(new String("hu"), new Short((short) 0x040e)); //$NON-NLS-1$
382: ht.put(new String("is"), new Short((short) 0x040f)); //$NON-NLS-1$
383: ht.put(new String("it"), new Short((short) 0x0410)); // it-it //$NON-NLS-1$
384: ht.put(new String("ja"), new Short((short) 0x0411)); //$NON-NLS-1$
385: ht.put(new String("ko"), new Short((short) 0x0412)); //$NON-NLS-1$
386: ht.put(new String("nl"), new Short((short) 0x0413)); // nl-nl //$NON-NLS-1$
387: ht.put(new String("no"), new Short((short) 0x0414)); // no_no //$NON-NLS-1$
388: ht.put(new String("pl"), new Short((short) 0x0415)); //$NON-NLS-1$
389: ht.put(new String("pt"), new Short((short) 0x0416)); // pt-br //$NON-NLS-1$
390: ht.put(new String("rm"), new Short((short) 0x0417)); //$NON-NLS-1$
391: ht.put(new String("ro"), new Short((short) 0x0418)); //$NON-NLS-1$
392: ht.put(new String("ru"), new Short((short) 0x0419)); //$NON-NLS-1$
393: ht.put(new String("hr"), new Short((short) 0x041a)); //$NON-NLS-1$
394: ht.put(new String("sk"), new Short((short) 0x041b)); //$NON-NLS-1$
395: ht.put(new String("sq"), new Short((short) 0x041c)); //$NON-NLS-1$
396: ht.put(new String("sv"), new Short((short) 0x041d)); // sv-se //$NON-NLS-1$
397: ht.put(new String("th"), new Short((short) 0x041e)); //$NON-NLS-1$
398: ht.put(new String("tr"), new Short((short) 0x041f)); //$NON-NLS-1$
399: ht.put(new String("ur"), new Short((short) 0x0420)); //$NON-NLS-1$
400: ht.put(new String("in"), new Short((short) 0x0421)); // "id" //$NON-NLS-1$
401: ht.put(new String("uk"), new Short((short) 0x0422)); //$NON-NLS-1$
402: ht.put(new String("be"), new Short((short) 0x0423)); //$NON-NLS-1$
403: ht.put(new String("sl"), new Short((short) 0x0424)); //$NON-NLS-1$
404: ht.put(new String("et"), new Short((short) 0x0425)); //$NON-NLS-1$
405: ht.put(new String("lv"), new Short((short) 0x0426)); //$NON-NLS-1$
406: ht.put(new String("lt"), new Short((short) 0x0427)); //$NON-NLS-1$
407: ht.put(new String("fa"), new Short((short) 0x0429)); //$NON-NLS-1$
408: ht.put(new String("vi"), new Short((short) 0x042a)); //$NON-NLS-1$
409: ht.put(new String("hy"), new Short((short) 0x042b)); //$NON-NLS-1$
410: ht.put(new String("eu"), new Short((short) 0x042d)); //$NON-NLS-1$
411: ht.put(new String("sb"), new Short((short) 0x042e)); //$NON-NLS-1$
412: ht.put(new String("mk"), new Short((short) 0x042f)); //$NON-NLS-1$
413: ht.put(new String("sx"), new Short((short) 0x0430)); //$NON-NLS-1$
414: ht.put(new String("ts"), new Short((short) 0x0431)); //$NON-NLS-1$
415: ht.put(new String("tn"), new Short((short) 0x0432)); //$NON-NLS-1$
416: ht.put(new String("xh"), new Short((short) 0x0434)); //$NON-NLS-1$
417: ht.put(new String("zu"), new Short((short) 0x0435)); //$NON-NLS-1$
418: ht.put(new String("af"), new Short((short) 0x0436)); //$NON-NLS-1$
419: ht.put(new String("fo"), new Short((short) 0x0438)); //$NON-NLS-1$
420: ht.put(new String("hi"), new Short((short) 0x0439)); //$NON-NLS-1$
421: ht.put(new String("mt"), new Short((short) 0x043a)); //$NON-NLS-1$
422: ht.put(new String("gd"), new Short((short) 0x043c)); //$NON-NLS-1$
423: ht.put(new String("yi"), new Short((short) 0x043d)); //$NON-NLS-1$
424: ht.put(new String("sw"), new Short((short) 0x0441)); //$NON-NLS-1$
425: ht.put(new String("tt"), new Short((short) 0x0444)); //$NON-NLS-1$
426: ht.put(new String("ta"), new Short((short) 0x0449)); //$NON-NLS-1$
427: ht.put(new String("mr"), new Short((short) 0x044e)); //$NON-NLS-1$
428: ht.put(new String("sa"), new Short((short) 0x044f)); //$NON-NLS-1$
429: }
430: }
431:
432: /** Caches and returns the list of system font families names. */
433: public static String[] getFamilies() {
434:
435: if (families == null) {
436: families = getFontFamiliesNames();
437: }
438: return families;
439: }
440:
441: /** Fills fonts and families arrays with current system font data. */
442: public static void updateFontLists() {
443: if (families == null) {
444: families = getFontFamiliesNames();
445: }
446:
447: if (fontsCount == 0) {
448: enumSystemFonts();
449: }
450: }
451:
452: /** Returns an array of available font face names. */
453: public static String[] getAvailableFaces() {
454: updateFontLists();
455: return faces;
456: }
457:
458: /**
459: * Returns font family name that corresponds to the face name with
460: * specified index.
461: *
462: * @param faceIndex index of the font face name which family name
463: * is to be returned
464: */
465: public static String getFamily(int faceIndex) {
466: return families[famIndices[faceIndex]];
467: }
468:
469: /**
470: * Returns font family style that corresponds to the face name with
471: * specified index.
472: *
473: * @param faceIndex index of the font face name which style is to be returned
474: */
475: public static int getFontStyle(int faceIndex) {
476: return fontStyles[faceIndex];
477: }
478:
479: /**
480: * Adds new plain font with 1 pt. size from font resource file to the
481: * system if similar font wasn't into the system before. Method returns
482: * font object, corresponding to the specified resource.
483: *
484: * @param absolutePath absolute path to the font resource file
485: */
486: public static Font embedFont(String absolutePath)
487: throws IOException {
488: String familyName = embedFontNative(absolutePath);
489: if (familyName == null)
490: throw new IOException(Messages.getString("awt.299"));
491:
492: return new Font(familyName, Font.PLAIN, 1);
493: }
494:
495: /**
496: * Sets static arrays to the specified.
497: *
498: * @param types new values for the fontTypes static array
499: * @param styles new values for the fontStyles static array
500: * @param indices new values for the famIndices static array
501: * @param fFaces new values for the faces static array
502: */
503: public static void setArrays(int[] types, int[] styles,
504: int[] indices, String[] fFaces) {
505: fontsCount = styles.length;
506:
507: fontStyles = new int[fontsCount];
508: fontTypes = new int[fontsCount];
509: famIndices = new int[fontsCount];
510: faces = new String[fontsCount];
511:
512: System.arraycopy(styles, 0, fontStyles, 0, fontsCount);
513: System.arraycopy(types, 0, fontTypes, 0, fontsCount);
514: System.arraycopy(indices, 0, famIndices, 0, fontsCount);
515: System.arraycopy(fFaces, 0, faces, 0, fontsCount);
516: }
517:
518: /**
519: * Returns font type (TrueType, Type1 or UndefinedType) for the specified
520: * font face name and style.
521: *
522: * @param name face name
523: * @param style style of the font
524: *
525: * @return one of the font type constants FontManager.FONT_TYPE_T1 or
526: * FontManager.FONT_TYPE_TT.
527: */
528: public static int getFontType(String name, int style) {
529: updateFontLists();
530:
531: for (int i = 0; i < fontsCount; i++) {
532: if (fontTypes[i] == FontManager.FONT_TYPE_T1) {
533: if (name.equalsIgnoreCase(families[famIndices[i]])) {
534: return fontTypes[i];
535: }
536: }
537:
538: if (fontStyles[i] == style) {
539: if (name.equalsIgnoreCase(families[famIndices[i]])) {
540: return fontTypes[i];
541: }
542: }
543: }
544:
545: return FontManager.FONT_TYPE_TT;
546: }
547:
548: /** flag, returns true if native fontlib was loaded */
549: private static boolean isLibLoaded = false;
550:
551: static void loadLibrary() {
552: if (!isLibLoaded) {
553: AccessController.doPrivileged(new PrivilegedAction<Void>() {
554: public Void run() {
555: System.loadLibrary("fontlib"); //$NON-NLS-1$
556: return null;
557: }
558: });
559: isLibLoaded = true;
560: }
561: }
562:
563: /** load native Font library */
564: static {
565: loadLibrary();
566: updateFontLists();
567: }
568:
569: }
|