1 /* 2 * Copyright (c) 2007, 2014, Oracle and/or its affiliates. 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * 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 FontScaler.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 FontScaler.getNullScaler(). 94 getGlyphAdvance(0L, glyphCode); 95 } 96 97 synchronized void getGlyphMetrics(long pScalerContext, 98 int glyphCode, Point2D.Float metrics) 99 throws FontScalerException { 100 if (nativeScaler != 0L) { 101 getGlyphMetricsNative(font.get(), 102 pScalerContext, 103 nativeScaler, 104 glyphCode, 105 metrics); 106 return; 107 } 108 FontScaler.getNullScaler(). 109 getGlyphMetrics(0L, glyphCode, metrics); 110 } 111 112 synchronized long getGlyphImage(long pScalerContext, int glyphCode) 113 throws FontScalerException { 114 if (nativeScaler != 0L) { 115 return getGlyphImageNative(font.get(), 116 pScalerContext, 117 nativeScaler, 118 glyphCode); 119 } 120 return FontScaler.getNullScaler(). 121 getGlyphImage(0L, glyphCode); 122 } 123 124 synchronized Rectangle2D.Float getGlyphOutlineBounds( 125 long pScalerContext, int glyphCode) 126 throws FontScalerException { 127 if (nativeScaler != 0L) { 128 return getGlyphOutlineBoundsNative(font.get(), 129 pScalerContext, 130 nativeScaler, 131 glyphCode); 132 } 133 return FontScaler.getNullScaler(). 134 getGlyphOutlineBounds(0L,glyphCode); 135 } 136 137 synchronized GeneralPath getGlyphOutline( 138 long pScalerContext, int glyphCode, float x, float y) 139 throws FontScalerException { 140 if (nativeScaler != 0L) { 141 return getGlyphOutlineNative(font.get(), 142 pScalerContext, 143 nativeScaler, 144 glyphCode, 145 x, y); 146 } 147 return FontScaler.getNullScaler(). 148 getGlyphOutline(0L, glyphCode, x,y); 149 } 150 151 synchronized GeneralPath getGlyphVectorOutline( 152 long pScalerContext, int[] glyphs, int numGlyphs, 153 float x, float y) throws FontScalerException { 154 if (nativeScaler != 0L) { 155 return getGlyphVectorOutlineNative(font.get(), 156 pScalerContext, 157 nativeScaler, 158 glyphs, 159 numGlyphs, 160 x, y); 161 } 162 return FontScaler 163 .getNullScaler().getGlyphVectorOutline(0L, glyphs, numGlyphs, x, y); 164 } 165 166 synchronized long getLayoutTableCache() throws FontScalerException { 167 return getLayoutTableCacheNative(nativeScaler); 168 } 169 170 public synchronized void dispose() { 171 if (nativeScaler != 0L) { 172 disposeNativeScaler(font.get(), nativeScaler); 173 nativeScaler = 0L; 174 } 175 } 176 177 synchronized int getNumGlyphs() throws FontScalerException { 178 if (nativeScaler != 0L) { 179 return getNumGlyphsNative(nativeScaler); 180 } 181 return FontScaler.getNullScaler().getNumGlyphs(); 182 } 183 184 synchronized int getMissingGlyphCode() throws FontScalerException { 185 if (nativeScaler != 0L) { 186 return getMissingGlyphCodeNative(nativeScaler); 187 } 188 return FontScaler.getNullScaler().getMissingGlyphCode(); 189 } 190 191 synchronized int getGlyphCode(char charCode) throws FontScalerException { 192 if (nativeScaler != 0L) { 193 return getGlyphCodeNative(font.get(), nativeScaler, charCode); 194 } 195 return FontScaler.getNullScaler().getGlyphCode(charCode); 196 } 197 198 synchronized Point2D.Float getGlyphPoint(long pScalerContext, 199 int glyphCode, int ptNumber) 200 throws FontScalerException { 201 if (nativeScaler != 0L) { 202 return getGlyphPointNative(font.get(), pScalerContext, 203 nativeScaler, glyphCode, ptNumber); 204 } 205 return FontScaler.getNullScaler().getGlyphPoint( 206 pScalerContext, glyphCode, ptNumber); 207 } 208 209 synchronized long getUnitsPerEm() { 210 return getUnitsPerEMNative(nativeScaler); 211 } 212 213 long createScalerContext(double[] matrix, 214 int aa, int fm, float boldness, float italic, 215 boolean disableHinting) { 216 if (nativeScaler != 0L) { 217 return createScalerContextNative(nativeScaler, matrix, 218 aa, fm, boldness, italic); 219 } 220 return NullFontScaler.getNullScalerContext(); 221 } 222 223 //Note: native methods can throw RuntimeException if processing fails 224 private native long initNativeScaler(Font2D font, int type, 225 int indexInCollection, boolean supportsCJK, int filesize); 226 private native StrikeMetrics getFontMetricsNative(Font2D font, 227 long pScalerContext, long pScaler); 228 private native float getGlyphAdvanceNative(Font2D font, 229 long pScalerContext, long pScaler, int glyphCode); 230 private native void getGlyphMetricsNative(Font2D font, 231 long pScalerContext, long pScaler, 232 int glyphCode, Point2D.Float metrics); 233 private native long getGlyphImageNative(Font2D font, 234 long pScalerContext, long pScaler, int glyphCode); 235 private native Rectangle2D.Float getGlyphOutlineBoundsNative(Font2D font, 236 long pScalerContext, long pScaler, int glyphCode); 237 private native GeneralPath getGlyphOutlineNative(Font2D font, 238 long pScalerContext, long pScaler, 239 int glyphCode, float x, float y); 240 private native GeneralPath getGlyphVectorOutlineNative(Font2D font, 241 long pScalerContext, long pScaler, 242 int[] glyphs, int numGlyphs, float x, float y); 243 native Point2D.Float getGlyphPointNative(Font2D font, 244 long pScalerContext, long pScaler, int glyphCode, int ptNumber); 245 246 private native long getLayoutTableCacheNative(long pScaler); 247 248 private native void disposeNativeScaler(Font2D font2D, long pScaler); 249 250 private native int getGlyphCodeNative(Font2D font, long pScaler, char charCode); 251 private native int getNumGlyphsNative(long pScaler); 252 private native int getMissingGlyphCodeNative(long pScaler); 253 254 private native long getUnitsPerEMNative(long pScaler); 255 256 native long createScalerContextNative(long pScaler, double[] matrix, 257 int aa, int fm, float boldness, float italic); 258 259 /* Freetype scaler context does not contain any pointers that 260 has to be invalidated if native scaler is bad */ 261 void invalidateScalerContext(long pScalerContext) {} 262 }