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