1 /* 2 * Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Sun designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Sun in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 22 * CA 95054 USA or visit www.sun.com if you need additional information or 23 * have any questions. 24 */ 25 26 package sun.font; 27 28 import java.awt.geom.GeneralPath; 29 import java.awt.geom.Point2D; 30 import java.awt.geom.Rectangle2D; 31 import java.lang.ref.WeakReference; 32 33 /* This is Freetype based implementation of FontScaler. 34 * 35 * Note that in case of runtime error it is expected that 36 * native code will release all native resources and 37 * call invalidateScaler() (that will throw FontScalerException). 38 * 39 * Note that callee is responsible for releasing native scaler context. 40 */ 41 class FreetypeFontScaler extends FontScaler { 42 /* constants aligned with native code */ 43 private static final int TRUETYPE_FONT = 1; 44 private static final int TYPE1_FONT = 2; 45 46 static { 47 /* At the moment fontmanager library depends on freetype library 48 and therefore no need to load it explicitly here */ 49 FontManagerNativeLibrary.load(); 50 initIDs(FreetypeFontScaler.class); 51 } 52 53 private static native void initIDs(Class FFS); 54 55 private void invalidateScaler() throws FontScalerException { 56 nativeScaler = 0; 57 font = null; 58 throw new FontScalerException(); 59 } 60 61 public FreetypeFontScaler(Font2D font, int indexInCollection, 62 boolean supportsCJK, int filesize) { 63 int fonttype = TRUETYPE_FONT; 64 if (font instanceof Type1Font) { 65 fonttype = TYPE1_FONT; 66 } 67 nativeScaler = initNativeScaler(font, 68 fonttype, 69 indexInCollection, 70 supportsCJK, 71 filesize); 72 this.font = new WeakReference(font); 73 } 74 75 synchronized StrikeMetrics getFontMetrics(long pScalerContext) 76 throws FontScalerException { 77 if (nativeScaler != 0L) { 78 return getFontMetricsNative(font.get(), 79 pScalerContext, 80 nativeScaler); 81 } 82 return FontManager.getNullScaler().getFontMetrics(0L); 83 } 84 85 synchronized float getGlyphAdvance(long pScalerContext, int glyphCode) 86 throws FontScalerException { 87 if (nativeScaler != 0L) { 88 return getGlyphAdvanceNative(font.get(), 89 pScalerContext, 90 nativeScaler, 91 glyphCode); 92 } 93 return FontManager.getNullScaler().getGlyphAdvance(0L, glyphCode); 94 } 95 96 synchronized void getGlyphMetrics(long pScalerContext, 97 int glyphCode, Point2D.Float metrics) 98 throws FontScalerException { 99 if (nativeScaler != 0L) { 100 getGlyphMetricsNative(font.get(), 101 pScalerContext, 102 nativeScaler, 103 glyphCode, 104 metrics); 105 return; 106 } 107 FontManager.getNullScaler().getGlyphMetrics(0L, glyphCode, metrics); 108 } 109 110 synchronized long getGlyphImage(long pScalerContext, int glyphCode) 111 throws FontScalerException { 112 if (nativeScaler != 0L) { 113 return getGlyphImageNative(font.get(), 114 pScalerContext, 115 nativeScaler, 116 glyphCode); 117 } 118 return FontManager.getNullScaler().getGlyphImage(0L, glyphCode); 119 } 120 121 synchronized Rectangle2D.Float getGlyphOutlineBounds( 122 long pScalerContext, int glyphCode) 123 throws FontScalerException { 124 if (nativeScaler != 0L) { 125 return getGlyphOutlineBoundsNative(font.get(), 126 pScalerContext, 127 nativeScaler, 128 glyphCode); 129 } 130 return FontManager.getNullScaler().getGlyphOutlineBounds(0L,glyphCode); 131 } 132 133 synchronized GeneralPath getGlyphOutline( 134 long pScalerContext, int glyphCode, float x, float y) 135 throws FontScalerException { 136 if (nativeScaler != 0L) { 137 return getGlyphOutlineNative(font.get(), 138 pScalerContext, 139 nativeScaler, 140 glyphCode, 141 x, y); 142 } 143 return FontManager.getNullScaler().getGlyphOutline(0L, glyphCode, x,y); 144 } 145 146 synchronized GeneralPath getGlyphVectorOutline( 147 long pScalerContext, int[] glyphs, int numGlyphs, 148 float x, float y) throws FontScalerException { 149 if (nativeScaler != 0L) { 150 return getGlyphVectorOutlineNative(font.get(), 151 pScalerContext, 152 nativeScaler, 153 glyphs, 154 numGlyphs, 155 x, y); 156 } 157 return FontManager.getNullScaler().getGlyphVectorOutline( 158 0L, glyphs, numGlyphs, x, y); 159 } 160 161 synchronized long getLayoutTableCache() throws FontScalerException { 162 return getLayoutTableCacheNative(nativeScaler); 163 } 164 165 public synchronized void dispose() { 166 if (nativeScaler != 0L) { 167 disposeNativeScaler(nativeScaler); 168 nativeScaler = 0L; 169 } 170 } 171 172 synchronized int getNumGlyphs() throws FontScalerException { 173 if (nativeScaler != 0L) { 174 return getNumGlyphsNative(nativeScaler); 175 } 176 return FontManager.getNullScaler().getNumGlyphs(); 177 } 178 179 synchronized int getMissingGlyphCode() throws FontScalerException { 180 if (nativeScaler != 0L) { 181 return getMissingGlyphCodeNative(nativeScaler); 182 } 183 return FontManager.getNullScaler().getMissingGlyphCode(); 184 } 185 186 synchronized int getGlyphCode(char charCode) throws FontScalerException { 187 if (nativeScaler != 0L) { 188 return getGlyphCodeNative(nativeScaler, charCode); 189 } 190 return FontManager.getNullScaler().getGlyphCode(charCode); 191 } 192 193 synchronized Point2D.Float getGlyphPoint(long pScalerContext, 194 int glyphCode, int ptNumber) 195 throws FontScalerException { 196 if (nativeScaler != 0L) { 197 return getGlyphPointNative(font.get(), pScalerContext, 198 nativeScaler, glyphCode, ptNumber); 199 } 200 return FontManager.getNullScaler().getGlyphPoint( 201 pScalerContext, glyphCode, ptNumber); 202 } 203 204 synchronized long getUnitsPerEm() { 205 return getUnitsPerEMNative(nativeScaler); 206 } 207 208 long createScalerContext(double[] matrix, boolean fontType, 209 int aa, int fm, float boldness, float italic) { 210 if (nativeScaler != 0L) { 211 return createScalerContextNative(nativeScaler, matrix, 212 fontType, aa, fm, boldness, italic); 213 } 214 return NullFontScaler.getNullScalerContext(); 215 } 216 217 //Note: native methods can throw RuntimeException if processing fails 218 private native long initNativeScaler(Font2D font, int type, 219 int indexInCollection, boolean supportsCJK, int filesize); 220 private native StrikeMetrics getFontMetricsNative(Font2D font, 221 long pScalerContext, long pScaler); 222 private native float getGlyphAdvanceNative(Font2D font, 223 long pScalerContext, long pScaler, int glyphCode); 224 private native void getGlyphMetricsNative(Font2D font, 225 long pScalerContext, long pScaler, 226 int glyphCode, Point2D.Float metrics); 227 private native long getGlyphImageNative(Font2D font, 228 long pScalerContext, long pScaler, int glyphCode); 229 private native Rectangle2D.Float getGlyphOutlineBoundsNative(Font2D font, 230 long pScalerContext, long pScaler, int glyphCode); 231 private native GeneralPath getGlyphOutlineNative(Font2D font, 232 long pScalerContext, long pScaler, 233 int glyphCode, float x, float y); 234 private native GeneralPath getGlyphVectorOutlineNative(Font2D font, 235 long pScalerContext, long pScaler, 236 int[] glyphs, int numGlyphs, float x, float y); 237 native Point2D.Float getGlyphPointNative(Font2D font, 238 long pScalerContext, long pScaler, int glyphCode, int ptNumber); 239 240 private native long getLayoutTableCacheNative(long pScaler); 241 242 private native void disposeNativeScaler(long pScaler); 243 244 private native int getGlyphCodeNative(long pScaler, char charCode); 245 private native int getNumGlyphsNative(long pScaler); 246 private native int getMissingGlyphCodeNative(long pScaler); 247 248 private native long getUnitsPerEMNative(long pScaler); 249 250 native long createScalerContextNative(long pScaler, double[] matrix, 251 boolean fontType, int aa, int fm, float boldness, float italic); 252 253 /* Freetype scaler context does not contain any pointers that 254 has to be invalidated if native scaler is bad */ 255 void invalidateScalerContext(long pScalerContext) {} 256 }