jdk/src/share/classes/sun/font/FreetypeFontScaler.java
changeset 2 90ce3da70b43
child 3928 be186a33df9b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/font/FreetypeFontScaler.java	Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.font;
+
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.lang.ref.WeakReference;
+
+/* This is Freetype based implementation of FontScaler.
+ *
+ * Note that in case of runtime error it is expected that
+ * native code will release all native resources and
+ * call invalidateScaler() (that will throw FontScalerException).
+ *
+ * Note that callee is responsible for releasing native scaler context.
+ */
+class FreetypeFontScaler extends FontScaler {
+    /* constants aligned with native code */
+    private static final int TRUETYPE_FONT = 1;
+    private static final int TYPE1_FONT = 2;
+
+    static {
+        /* At the moment fontmanager library depends on freetype library
+           and therefore no need to load it explicitly here */
+        FontManagerNativeLibrary.load();
+        initIDs(FreetypeFontScaler.class);
+    }
+
+    private static native void initIDs(Class FFS);
+
+    private void invalidateScaler() throws FontScalerException {
+        nativeScaler = 0;
+        font = null;
+        throw new FontScalerException();
+    }
+
+    public FreetypeFontScaler(Font2D font, int indexInCollection,
+                     boolean supportsCJK, int filesize) {
+        int fonttype = TRUETYPE_FONT;
+        if (font instanceof Type1Font) {
+            fonttype = TYPE1_FONT;
+        }
+        nativeScaler = initNativeScaler(font,
+                                        fonttype,
+                                        indexInCollection,
+                                        supportsCJK,
+                                        filesize);
+        this.font = new WeakReference(font);
+    }
+
+    synchronized StrikeMetrics getFontMetrics(long pScalerContext)
+                     throws FontScalerException {
+        if (nativeScaler != 0L) {
+                return getFontMetricsNative(font.get(),
+                                            pScalerContext,
+                                            nativeScaler);
+        }
+        return FontManager.getNullScaler().getFontMetrics(0L);
+    }
+
+    synchronized float getGlyphAdvance(long pScalerContext, int glyphCode)
+                     throws FontScalerException {
+        if (nativeScaler != 0L) {
+            return getGlyphAdvanceNative(font.get(),
+                                         pScalerContext,
+                                         nativeScaler,
+                                         glyphCode);
+        }
+        return FontManager.getNullScaler().getGlyphAdvance(0L, glyphCode);
+    }
+
+    synchronized void getGlyphMetrics(long pScalerContext,
+                     int glyphCode, Point2D.Float metrics)
+                     throws FontScalerException {
+        if (nativeScaler != 0L) {
+            getGlyphMetricsNative(font.get(),
+                                  pScalerContext,
+                                  nativeScaler,
+                                  glyphCode,
+                                  metrics);
+            return;
+        }
+        FontManager.getNullScaler().getGlyphMetrics(0L, glyphCode, metrics);
+    }
+
+    synchronized long getGlyphImage(long pScalerContext, int glyphCode)
+                     throws FontScalerException {
+        if (nativeScaler != 0L) {
+            return getGlyphImageNative(font.get(),
+                                       pScalerContext,
+                                       nativeScaler,
+                                       glyphCode);
+        }
+        return FontManager.getNullScaler().getGlyphImage(0L, glyphCode);
+    }
+
+    synchronized Rectangle2D.Float getGlyphOutlineBounds(
+                     long pScalerContext, int glyphCode)
+                     throws FontScalerException {
+        if (nativeScaler != 0L) {
+            return getGlyphOutlineBoundsNative(font.get(),
+                                               pScalerContext,
+                                               nativeScaler,
+                                               glyphCode);
+        }
+        return FontManager.getNullScaler().getGlyphOutlineBounds(0L,glyphCode);
+    }
+
+    synchronized GeneralPath getGlyphOutline(
+                     long pScalerContext, int glyphCode, float x, float y)
+                     throws FontScalerException {
+        if (nativeScaler != 0L) {
+            return getGlyphOutlineNative(font.get(),
+                                         pScalerContext,
+                                         nativeScaler,
+                                         glyphCode,
+                                         x, y);
+        }
+        return FontManager.getNullScaler().getGlyphOutline(0L, glyphCode, x,y);
+    }
+
+    synchronized GeneralPath getGlyphVectorOutline(
+                     long pScalerContext, int[] glyphs, int numGlyphs,
+                     float x, float y) throws FontScalerException {
+        if (nativeScaler != 0L) {
+            return getGlyphVectorOutlineNative(font.get(),
+                                               pScalerContext,
+                                               nativeScaler,
+                                               glyphs,
+                                               numGlyphs,
+                                               x, y);
+        }
+        return FontManager.getNullScaler().getGlyphVectorOutline(
+                   0L, glyphs, numGlyphs, x, y);
+    }
+
+    synchronized long getLayoutTableCache() throws FontScalerException {
+        return getLayoutTableCacheNative(nativeScaler);
+    }
+
+    public synchronized void dispose() {
+        if (nativeScaler != 0L) {
+            disposeNativeScaler(nativeScaler);
+            nativeScaler = 0L;
+        }
+    }
+
+    synchronized int getNumGlyphs() throws FontScalerException {
+        if (nativeScaler != 0L) {
+            return getNumGlyphsNative(nativeScaler);
+        }
+        return FontManager.getNullScaler().getNumGlyphs();
+    }
+
+    synchronized int getMissingGlyphCode()  throws FontScalerException {
+        if (nativeScaler != 0L) {
+            return getMissingGlyphCodeNative(nativeScaler);
+        }
+        return FontManager.getNullScaler().getMissingGlyphCode();
+    }
+
+    synchronized int getGlyphCode(char charCode) throws FontScalerException {
+        if (nativeScaler != 0L) {
+            return getGlyphCodeNative(nativeScaler, charCode);
+        }
+        return FontManager.getNullScaler().getGlyphCode(charCode);
+    }
+
+    synchronized Point2D.Float getGlyphPoint(long pScalerContext,
+                                       int glyphCode, int ptNumber)
+                               throws FontScalerException {
+        if (nativeScaler != 0L) {
+            return getGlyphPointNative(font.get(), pScalerContext,
+                                      nativeScaler, glyphCode, ptNumber);
+        }
+        return FontManager.getNullScaler().getGlyphPoint(
+                   pScalerContext, glyphCode,  ptNumber);
+    }
+
+    synchronized long getUnitsPerEm() {
+        return getUnitsPerEMNative(nativeScaler);
+    }
+
+    long createScalerContext(double[] matrix, boolean fontType,
+            int aa, int fm, float boldness, float italic) {
+        if (nativeScaler != 0L) {
+            return createScalerContextNative(nativeScaler, matrix,
+                      fontType, aa, fm, boldness, italic);
+        }
+        return NullFontScaler.getNullScalerContext();
+    }
+
+    //Note: native methods can throw RuntimeException if processing fails
+    private native long initNativeScaler(Font2D font, int type,
+            int indexInCollection, boolean supportsCJK, int filesize);
+    private native StrikeMetrics getFontMetricsNative(Font2D font,
+            long pScalerContext, long pScaler);
+    private native float getGlyphAdvanceNative(Font2D font,
+            long pScalerContext, long pScaler, int glyphCode);
+    private native void getGlyphMetricsNative(Font2D font,
+            long pScalerContext, long pScaler,
+            int glyphCode, Point2D.Float metrics);
+    private native long getGlyphImageNative(Font2D font,
+            long pScalerContext, long pScaler, int glyphCode);
+    private native Rectangle2D.Float getGlyphOutlineBoundsNative(Font2D font,
+            long pScalerContext, long pScaler, int glyphCode);
+    private native GeneralPath getGlyphOutlineNative(Font2D font,
+            long pScalerContext, long pScaler,
+            int glyphCode, float x, float y);
+    private native GeneralPath getGlyphVectorOutlineNative(Font2D font,
+            long pScalerContext, long pScaler,
+            int[] glyphs, int numGlyphs, float x, float y);
+    native Point2D.Float getGlyphPointNative(Font2D font,
+            long pScalerContext, long pScaler, int glyphCode, int ptNumber);
+
+    private native long getLayoutTableCacheNative(long pScaler);
+
+    private native void disposeNativeScaler(long pScaler);
+
+    private native int getGlyphCodeNative(long pScaler, char charCode);
+    private native int getNumGlyphsNative(long pScaler);
+    private native int getMissingGlyphCodeNative(long pScaler);
+
+    private native long getUnitsPerEMNative(long pScaler);
+
+    native long createScalerContextNative(long pScaler, double[] matrix,
+            boolean fontType, int aa, int fm, float boldness, float italic);
+
+    /* Freetype scaler context does not contain any pointers that
+       has to be invalidated if native scaler is bad */
+    void invalidateScalerContext(long pScalerContext) {}
+}