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