1 /* 2 * Copyright 2007-2008 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 #include "stdlib.h" 27 #include "malloc.h" 28 #include "string.h" 29 #include "gdefs.h" 30 #include "jlong.h" 31 #include "sunfontids.h" 32 #include "fontscalerdefs.h" 33 #include "sun_font_FontManager.h" 34 #include "sun_font_NullFontScaler.h" 35 #include "sun_font_StrikeCache.h" 36 37 static void *theNullScalerContext = NULL; 38 extern void AccelGlyphCache_RemoveAllCellInfos(GlyphInfo *glyph); 39 40 41 JNIEXPORT jlong JNICALL 42 Java_sun_font_NullFontScaler_getNullScalerContext 43 (JNIEnv *env, jclass scalerClass) { 44 45 if (theNullScalerContext == NULL) { 46 theNullScalerContext = malloc(1); 47 } 48 return ptr_to_jlong(theNullScalerContext); 49 } 50 51 int isNullScalerContext(void *context) { 52 return theNullScalerContext == context; 53 } 54 55 /* Eventually we may rework it to be a singleton. 56 * This will require additional checks in freeLongMemory/freeIntMemory 57 * and on other hand malformed fonts (main source of null glyph images) 58 * are supposed to be collected fast. 59 * But perhaps it is still right thing to do. 60 * Even better is to eliminate the need to have this native method 61 * but for this it is necessary to rework Strike and drawing logic 62 * to be able to live with NULL pointers without performance hit. 63 */ 64 JNIEXPORT jlong JNICALL Java_sun_font_NullFontScaler_getGlyphImage 65 (JNIEnv *env, jobject scaler, jlong pContext, jint glyphCode) { 66 void *nullscaler = calloc(sizeof(GlyphInfo), 1); 67 return ptr_to_jlong(nullscaler); 68 } 69 70 71 72 void initLCDGammaTables(); 73 74 /* placeholder for extern variable */ 75 FontManagerNativeIDs sunFontIDs; 76 77 JNIEXPORT void JNICALL 78 Java_sun_font_SunFontManager_initIDs 79 (JNIEnv *env, jclass cls) { 80 81 jclass tmpClass = (*env)->FindClass(env, "sun/font/TrueTypeFont"); 82 sunFontIDs.ttReadBlockMID = 83 (*env)->GetMethodID(env, tmpClass, "readBlock", 84 "(Ljava/nio/ByteBuffer;II)I"); 85 sunFontIDs.ttReadBytesMID = 86 (*env)->GetMethodID(env, tmpClass, "readBytes", "(II)[B"); 87 88 tmpClass = (*env)->FindClass(env, "sun/font/Type1Font"); 89 sunFontIDs.readFileMID = 90 (*env)->GetMethodID(env, tmpClass, 91 "readFile", "(Ljava/nio/ByteBuffer;)V"); 92 93 tmpClass = (*env)->FindClass(env, "java/awt/geom/Point2D$Float"); 94 sunFontIDs.pt2DFloatClass = (jclass)(*env)->NewGlobalRef(env, tmpClass); 95 sunFontIDs.pt2DFloatCtr = 96 (*env)->GetMethodID(env, sunFontIDs.pt2DFloatClass, "<init>","(FF)V"); 97 98 sunFontIDs.xFID = 99 (*env)->GetFieldID(env, sunFontIDs.pt2DFloatClass, "x", "F"); 100 sunFontIDs.yFID = 101 (*env)->GetFieldID(env, sunFontIDs.pt2DFloatClass, "y", "F"); 102 103 tmpClass = (*env)->FindClass(env, "sun/font/StrikeMetrics"); 104 sunFontIDs.strikeMetricsClass=(jclass)(*env)->NewGlobalRef(env, tmpClass); 105 106 sunFontIDs.strikeMetricsCtr = 107 (*env)->GetMethodID(env, sunFontIDs.strikeMetricsClass, 108 "<init>", "(FFFFFFFFFF)V"); 109 110 tmpClass = (*env)->FindClass(env, "java/awt/geom/Rectangle2D$Float"); 111 sunFontIDs.rect2DFloatClass = (jclass)(*env)->NewGlobalRef(env, tmpClass); 112 sunFontIDs.rect2DFloatCtr = 113 (*env)->GetMethodID(env, sunFontIDs.rect2DFloatClass, "<init>", "()V"); 114 sunFontIDs.rect2DFloatCtr4 = 115 (*env)->GetMethodID(env, sunFontIDs.rect2DFloatClass, 116 "<init>", "(FFFF)V"); 117 sunFontIDs.rectF2DX = 118 (*env)->GetFieldID(env, sunFontIDs.rect2DFloatClass, "x", "F"); 119 sunFontIDs.rectF2DY = 120 (*env)->GetFieldID(env, sunFontIDs.rect2DFloatClass, "y", "F"); 121 sunFontIDs.rectF2DWidth = 122 (*env)->GetFieldID(env, sunFontIDs.rect2DFloatClass, "width", "F"); 123 sunFontIDs.rectF2DHeight = 124 (*env)->GetFieldID(env, sunFontIDs.rect2DFloatClass, "height", "F"); 125 126 tmpClass = (*env)->FindClass(env, "java/awt/geom/GeneralPath"); 127 sunFontIDs.gpClass = (jclass)(*env)->NewGlobalRef(env, tmpClass); 128 sunFontIDs.gpCtr = 129 (*env)->GetMethodID(env, sunFontIDs.gpClass, "<init>", "(I[BI[FI)V"); 130 sunFontIDs.gpCtrEmpty = 131 (*env)->GetMethodID(env, sunFontIDs.gpClass, "<init>", "()V"); 132 133 tmpClass = (*env)->FindClass(env, "sun/font/Font2D"); 134 sunFontIDs.f2dCharToGlyphMID = 135 (*env)->GetMethodID(env, tmpClass, "charToGlyph", "(I)I"); 136 sunFontIDs.getMapperMID = 137 (*env)->GetMethodID(env, tmpClass, "getMapper", 138 "()Lsun/font/CharToGlyphMapper;"); 139 sunFontIDs.getTableBytesMID = 140 (*env)->GetMethodID(env, tmpClass, "getTableBytes", "(I)[B"); 141 sunFontIDs.canDisplayMID = 142 (*env)->GetMethodID(env, tmpClass, "canDisplay", "(C)Z"); 143 144 tmpClass = (*env)->FindClass(env, "sun/font/CharToGlyphMapper"); 145 sunFontIDs.charToGlyphMID = 146 (*env)->GetMethodID(env, tmpClass, "charToGlyph", "(I)I"); 147 148 tmpClass = (*env)->FindClass(env, "sun/font/PhysicalStrike"); 149 sunFontIDs.getGlyphMetricsMID = 150 (*env)->GetMethodID(env, tmpClass, "getGlyphMetrics", 151 "(I)Ljava/awt/geom/Point2D$Float;"); 152 sunFontIDs.getGlyphPointMID = 153 (*env)->GetMethodID(env, tmpClass, "getGlyphPoint", 154 "(II)Ljava/awt/geom/Point2D$Float;"); 155 sunFontIDs.adjustPointMID = 156 (*env)->GetMethodID(env, tmpClass, "adjustPoint", 157 "(Ljava/awt/geom/Point2D$Float;)V"); 158 sunFontIDs.pScalerContextFID = 159 (*env)->GetFieldID(env, tmpClass, "pScalerContext", "J"); 160 161 tmpClass = (*env)->FindClass(env, "sun/font/GlyphList"); 162 sunFontIDs.glyphListX = (*env)->GetFieldID(env, tmpClass, "x", "F"); 163 sunFontIDs.glyphListY = (*env)->GetFieldID(env, tmpClass, "y", "F"); 164 sunFontIDs.glyphListLen = (*env)->GetFieldID(env, tmpClass, "len", "I"); 165 sunFontIDs.glyphImages = 166 (*env)->GetFieldID(env, tmpClass, "images", "[J"); 167 sunFontIDs.glyphListUsePos = 168 (*env)->GetFieldID(env, tmpClass, "usePositions", "Z"); 169 sunFontIDs.glyphListPos = 170 (*env)->GetFieldID(env, tmpClass, "positions", "[F"); 171 sunFontIDs.lcdRGBOrder = 172 (*env)->GetFieldID(env, tmpClass, "lcdRGBOrder", "Z"); 173 sunFontIDs.lcdSubPixPos = 174 (*env)->GetFieldID(env, tmpClass, "lcdSubPixPos", "Z"); 175 176 initLCDGammaTables(); 177 } 178 179 JNIEXPORT FontManagerNativeIDs getSunFontIDs() { 180 return sunFontIDs; 181 } 182 183 /* 184 * Class: sun_font_StrikeCache 185 * Method: freeIntPointer 186 * Signature: (I)V 187 */ 188 JNIEXPORT void JNICALL Java_sun_font_StrikeCache_freeIntPointer 189 (JNIEnv *env, jclass cacheClass, jint ptr) { 190 191 /* Note this is used for freeing a glyph which was allocated 192 * but never placed into the glyph cache. The caller holds the 193 * only reference, therefore it is unnecessary to invalidate any 194 * accelerated glyph cache cells as we do in freeInt/LongMemory(). 195 */ 196 if (ptr != 0) { 197 free((void*)ptr); 198 } 199 } 200 201 /* 202 * Class: sun_font_StrikeCache 203 * Method: freeLongPointer 204 * Signature: (J)V 205 */ 206 JNIEXPORT void JNICALL Java_sun_font_StrikeCache_freeLongPointer 207 (JNIEnv *env, jclass cacheClass, jlong ptr) { 208 209 /* Note this is used for freeing a glyph which was allocated 210 * but never placed into the glyph cache. The caller holds the 211 * only reference, therefore it is unnecessary to invalidate any 212 * accelerated glyph cache cells as we do in freeInt/LongMemory(). 213 */ 214 if (ptr != 0L) { 215 free(jlong_to_ptr(ptr)); 216 } 217 } 218 219 /* 220 * Class: sun_font_StrikeCache 221 * Method: freeIntMemory 222 * Signature: ([I)V 223 */ 224 JNIEXPORT void JNICALL Java_sun_font_StrikeCache_freeIntMemory 225 (JNIEnv *env, jclass cacheClass, jintArray jmemArray, jlong pContext) { 226 227 int len = (*env)->GetArrayLength(env, jmemArray); 228 jint* ptrs = 229 (jint*)(*env)->GetPrimitiveArrayCritical(env, jmemArray, NULL); 230 int i; 231 232 if (ptrs) { 233 for (i=0; i< len; i++) { 234 if (ptrs[i] != 0) { 235 GlyphInfo *ginfo = (GlyphInfo *)ptrs[i]; 236 if (ginfo->cellInfo != NULL) { 237 // invalidate this glyph's accelerated cache cell 238 AccelGlyphCache_RemoveAllCellInfos(ginfo); 239 } 240 free((void*)ginfo); 241 } 242 } 243 (*env)->ReleasePrimitiveArrayCritical(env, jmemArray, ptrs, JNI_ABORT); 244 } 245 if (!isNullScalerContext(jlong_to_ptr(pContext))) { 246 free(jlong_to_ptr(pContext)); 247 } 248 } 249 250 /* 251 * Class: sun_font_StrikeCache 252 * Method: freeLongMemory 253 * Signature: ([J)V 254 */ 255 JNIEXPORT void JNICALL Java_sun_font_StrikeCache_freeLongMemory 256 (JNIEnv *env, jclass cacheClass, jlongArray jmemArray, jlong pContext) { 257 258 int len = (*env)->GetArrayLength(env, jmemArray); 259 jlong* ptrs = 260 (jlong*)(*env)->GetPrimitiveArrayCritical(env, jmemArray, NULL); 261 int i; 262 263 if (ptrs) { 264 for (i=0; i< len; i++) { 265 if (ptrs[i] != 0L) { 266 GlyphInfo *ginfo = (GlyphInfo *) jlong_to_ptr(ptrs[i]); 267 if (ginfo->cellInfo != NULL) { 268 AccelGlyphCache_RemoveAllCellInfos(ginfo); 269 } 270 free((void*)ginfo); 271 } 272 } 273 (*env)->ReleasePrimitiveArrayCritical(env, jmemArray, ptrs, JNI_ABORT); 274 } 275 if (!isNullScalerContext(jlong_to_ptr(pContext))) { 276 free(jlong_to_ptr(pContext)); 277 } 278 } 279 280 JNIEXPORT void JNICALL 281 Java_sun_font_StrikeCache_getGlyphCacheDescription 282 (JNIEnv *env, jclass cls, jlongArray results) { 283 284 jlong* nresults; 285 GlyphInfo *info; 286 size_t baseAddr; 287 288 if ((*env)->GetArrayLength(env, results) < 10) { 289 return; 290 } 291 292 nresults = (jlong*)(*env)->GetPrimitiveArrayCritical(env, results, NULL); 293 if (nresults == NULL) { 294 return; 295 } 296 info = (GlyphInfo*) calloc(1, sizeof(GlyphInfo)); 297 if (info == NULL) { 298 (*env)->ReleasePrimitiveArrayCritical(env, results, nresults, 0); 299 return; 300 } 301 baseAddr = (size_t)info; 302 nresults[0] = sizeof(void*); 303 nresults[1] = sizeof(GlyphInfo); 304 nresults[2] = 0; 305 nresults[3] = (size_t)&(info->advanceY)-baseAddr; 306 nresults[4] = (size_t)&(info->width)-baseAddr; 307 nresults[5] = (size_t)&(info->height)-baseAddr; 308 nresults[6] = (size_t)&(info->rowBytes)-baseAddr; 309 nresults[7] = (size_t)&(info->topLeftX)-baseAddr; 310 nresults[8] = (size_t)&(info->topLeftY)-baseAddr; 311 nresults[9] = (size_t)&(info->image)-baseAddr; 312 nresults[10] = (jlong)(uintptr_t)info; /* invisible glyph */ 313 (*env)->ReleasePrimitiveArrayCritical(env, results, nresults, 0); 314 } 315 316 JNIEXPORT TTLayoutTableCache* newLayoutTableCache() { 317 TTLayoutTableCache* ltc = calloc(1, sizeof(TTLayoutTableCache)); 318 if (ltc) { 319 ltc->gsub_len = -1; 320 ltc->gpos_len = -1; 321 ltc->gdef_len = -1; 322 ltc->mort_len = -1; 323 ltc->kern_len = -1; 324 } 325 return ltc; 326 } 327 328 JNIEXPORT void freeLayoutTableCache(TTLayoutTableCache* ltc) { 329 if (ltc) { 330 if (ltc->gsub) free(ltc->gsub); 331 if (ltc->gpos) free(ltc->gpos); 332 if (ltc->gdef) free(ltc->gdef); 333 if (ltc->mort) free(ltc->mort); 334 if (ltc->kern) free(ltc->kern); 335 if (ltc->kernPairs) free(ltc->kernPairs); 336 free(ltc); 337 } 338 }