0N/A/*
3261N/A * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/A#include "stdlib.h"
0N/A#include "string.h"
0N/A#include "gdefs.h"
0N/A#include "jlong.h"
0N/A#include "sunfontids.h"
0N/A#include "fontscalerdefs.h"
0N/A#include "sun_font_FontManager.h"
0N/A#include "sun_font_NullFontScaler.h"
0N/A#include "sun_font_StrikeCache.h"
0N/A
0N/Astatic void *theNullScalerContext = NULL;
430N/Aextern void AccelGlyphCache_RemoveAllCellInfos(GlyphInfo *glyph);
430N/A
0N/A
0N/AJNIEXPORT jlong JNICALL
0N/AJava_sun_font_NullFontScaler_getNullScalerContext
0N/A (JNIEnv *env, jclass scalerClass) {
0N/A
0N/A if (theNullScalerContext == NULL) {
0N/A theNullScalerContext = malloc(1);
0N/A }
0N/A return ptr_to_jlong(theNullScalerContext);
0N/A}
0N/A
0N/Aint isNullScalerContext(void *context) {
0N/A return theNullScalerContext == context;
0N/A}
0N/A
0N/A/* Eventually we may rework it to be a singleton.
0N/A * This will require additional checks in freeLongMemory/freeIntMemory
0N/A * and on other hand malformed fonts (main source of null glyph images)
0N/A * are supposed to be collected fast.
0N/A * But perhaps it is still right thing to do.
0N/A * Even better is to eliminate the need to have this native method
0N/A * but for this it is necessary to rework Strike and drawing logic
0N/A * to be able to live with NULL pointers without performance hit.
0N/A */
0N/AJNIEXPORT jlong JNICALL Java_sun_font_NullFontScaler_getGlyphImage
0N/A (JNIEnv *env, jobject scaler, jlong pContext, jint glyphCode) {
0N/A void *nullscaler = calloc(sizeof(GlyphInfo), 1);
0N/A return ptr_to_jlong(nullscaler);
0N/A}
0N/A
0N/A
0N/A
0N/Avoid initLCDGammaTables();
0N/A
0N/A/* placeholder for extern variable */
0N/AFontManagerNativeIDs sunFontIDs;
0N/A
0N/AJNIEXPORT void JNICALL
1686N/AJava_sun_font_SunFontManager_initIDs
0N/A (JNIEnv *env, jclass cls) {
0N/A
1686N/A jclass tmpClass = (*env)->FindClass(env, "sun/font/TrueTypeFont");
0N/A sunFontIDs.ttReadBlockMID =
0N/A (*env)->GetMethodID(env, tmpClass, "readBlock",
0N/A "(Ljava/nio/ByteBuffer;II)I");
0N/A sunFontIDs.ttReadBytesMID =
0N/A (*env)->GetMethodID(env, tmpClass, "readBytes", "(II)[B");
0N/A
0N/A tmpClass = (*env)->FindClass(env, "sun/font/Type1Font");
0N/A sunFontIDs.readFileMID =
0N/A (*env)->GetMethodID(env, tmpClass,
0N/A "readFile", "(Ljava/nio/ByteBuffer;)V");
0N/A
0N/A tmpClass = (*env)->FindClass(env, "java/awt/geom/Point2D$Float");
0N/A sunFontIDs.pt2DFloatClass = (jclass)(*env)->NewGlobalRef(env, tmpClass);
0N/A sunFontIDs.pt2DFloatCtr =
0N/A (*env)->GetMethodID(env, sunFontIDs.pt2DFloatClass, "<init>","(FF)V");
0N/A
0N/A sunFontIDs.xFID =
0N/A (*env)->GetFieldID(env, sunFontIDs.pt2DFloatClass, "x", "F");
0N/A sunFontIDs.yFID =
0N/A (*env)->GetFieldID(env, sunFontIDs.pt2DFloatClass, "y", "F");
0N/A
0N/A tmpClass = (*env)->FindClass(env, "sun/font/StrikeMetrics");
0N/A sunFontIDs.strikeMetricsClass=(jclass)(*env)->NewGlobalRef(env, tmpClass);
0N/A
0N/A sunFontIDs.strikeMetricsCtr =
0N/A (*env)->GetMethodID(env, sunFontIDs.strikeMetricsClass,
0N/A "<init>", "(FFFFFFFFFF)V");
0N/A
0N/A tmpClass = (*env)->FindClass(env, "java/awt/geom/Rectangle2D$Float");
0N/A sunFontIDs.rect2DFloatClass = (jclass)(*env)->NewGlobalRef(env, tmpClass);
0N/A sunFontIDs.rect2DFloatCtr =
0N/A (*env)->GetMethodID(env, sunFontIDs.rect2DFloatClass, "<init>", "()V");
0N/A sunFontIDs.rect2DFloatCtr4 =
0N/A (*env)->GetMethodID(env, sunFontIDs.rect2DFloatClass,
0N/A "<init>", "(FFFF)V");
0N/A sunFontIDs.rectF2DX =
0N/A (*env)->GetFieldID(env, sunFontIDs.rect2DFloatClass, "x", "F");
0N/A sunFontIDs.rectF2DY =
0N/A (*env)->GetFieldID(env, sunFontIDs.rect2DFloatClass, "y", "F");
0N/A sunFontIDs.rectF2DWidth =
0N/A (*env)->GetFieldID(env, sunFontIDs.rect2DFloatClass, "width", "F");
0N/A sunFontIDs.rectF2DHeight =
0N/A (*env)->GetFieldID(env, sunFontIDs.rect2DFloatClass, "height", "F");
0N/A
0N/A tmpClass = (*env)->FindClass(env, "java/awt/geom/GeneralPath");
0N/A sunFontIDs.gpClass = (jclass)(*env)->NewGlobalRef(env, tmpClass);
0N/A sunFontIDs.gpCtr =
0N/A (*env)->GetMethodID(env, sunFontIDs.gpClass, "<init>", "(I[BI[FI)V");
0N/A sunFontIDs.gpCtrEmpty =
0N/A (*env)->GetMethodID(env, sunFontIDs.gpClass, "<init>", "()V");
0N/A
0N/A tmpClass = (*env)->FindClass(env, "sun/font/Font2D");
0N/A sunFontIDs.f2dCharToGlyphMID =
0N/A (*env)->GetMethodID(env, tmpClass, "charToGlyph", "(I)I");
0N/A sunFontIDs.getMapperMID =
0N/A (*env)->GetMethodID(env, tmpClass, "getMapper",
0N/A "()Lsun/font/CharToGlyphMapper;");
0N/A sunFontIDs.getTableBytesMID =
0N/A (*env)->GetMethodID(env, tmpClass, "getTableBytes", "(I)[B");
0N/A sunFontIDs.canDisplayMID =
0N/A (*env)->GetMethodID(env, tmpClass, "canDisplay", "(C)Z");
0N/A
0N/A tmpClass = (*env)->FindClass(env, "sun/font/CharToGlyphMapper");
0N/A sunFontIDs.charToGlyphMID =
0N/A (*env)->GetMethodID(env, tmpClass, "charToGlyph", "(I)I");
0N/A
0N/A tmpClass = (*env)->FindClass(env, "sun/font/PhysicalStrike");
0N/A sunFontIDs.getGlyphMetricsMID =
0N/A (*env)->GetMethodID(env, tmpClass, "getGlyphMetrics",
0N/A "(I)Ljava/awt/geom/Point2D$Float;");
0N/A sunFontIDs.getGlyphPointMID =
0N/A (*env)->GetMethodID(env, tmpClass, "getGlyphPoint",
0N/A "(II)Ljava/awt/geom/Point2D$Float;");
0N/A sunFontIDs.adjustPointMID =
0N/A (*env)->GetMethodID(env, tmpClass, "adjustPoint",
0N/A "(Ljava/awt/geom/Point2D$Float;)V");
0N/A sunFontIDs.pScalerContextFID =
0N/A (*env)->GetFieldID(env, tmpClass, "pScalerContext", "J");
0N/A
0N/A tmpClass = (*env)->FindClass(env, "sun/font/GlyphList");
0N/A sunFontIDs.glyphListX = (*env)->GetFieldID(env, tmpClass, "x", "F");
0N/A sunFontIDs.glyphListY = (*env)->GetFieldID(env, tmpClass, "y", "F");
0N/A sunFontIDs.glyphListLen = (*env)->GetFieldID(env, tmpClass, "len", "I");
0N/A sunFontIDs.glyphImages =
0N/A (*env)->GetFieldID(env, tmpClass, "images", "[J");
0N/A sunFontIDs.glyphListUsePos =
0N/A (*env)->GetFieldID(env, tmpClass, "usePositions", "Z");
0N/A sunFontIDs.glyphListPos =
0N/A (*env)->GetFieldID(env, tmpClass, "positions", "[F");
0N/A sunFontIDs.lcdRGBOrder =
0N/A (*env)->GetFieldID(env, tmpClass, "lcdRGBOrder", "Z");
0N/A sunFontIDs.lcdSubPixPos =
0N/A (*env)->GetFieldID(env, tmpClass, "lcdSubPixPos", "Z");
0N/A
0N/A initLCDGammaTables();
0N/A}
0N/A
0N/AJNIEXPORT FontManagerNativeIDs getSunFontIDs() {
0N/A return sunFontIDs;
0N/A}
0N/A
0N/A/*
0N/A * Class: sun_font_StrikeCache
0N/A * Method: freeIntPointer
0N/A * Signature: (I)V
0N/A */
0N/AJNIEXPORT void JNICALL Java_sun_font_StrikeCache_freeIntPointer
0N/A (JNIEnv *env, jclass cacheClass, jint ptr) {
0N/A
0N/A /* Note this is used for freeing a glyph which was allocated
0N/A * but never placed into the glyph cache. The caller holds the
0N/A * only reference, therefore it is unnecessary to invalidate any
0N/A * accelerated glyph cache cells as we do in freeInt/LongMemory().
0N/A */
0N/A if (ptr != 0) {
0N/A free((void*)ptr);
0N/A }
0N/A}
0N/A
0N/A/*
0N/A * Class: sun_font_StrikeCache
0N/A * Method: freeLongPointer
0N/A * Signature: (J)V
0N/A */
0N/AJNIEXPORT void JNICALL Java_sun_font_StrikeCache_freeLongPointer
0N/A (JNIEnv *env, jclass cacheClass, jlong ptr) {
0N/A
0N/A /* Note this is used for freeing a glyph which was allocated
0N/A * but never placed into the glyph cache. The caller holds the
0N/A * only reference, therefore it is unnecessary to invalidate any
0N/A * accelerated glyph cache cells as we do in freeInt/LongMemory().
0N/A */
0N/A if (ptr != 0L) {
0N/A free(jlong_to_ptr(ptr));
0N/A }
0N/A}
0N/A
0N/A/*
0N/A * Class: sun_font_StrikeCache
0N/A * Method: freeIntMemory
0N/A * Signature: ([I)V
0N/A */
0N/AJNIEXPORT void JNICALL Java_sun_font_StrikeCache_freeIntMemory
0N/A (JNIEnv *env, jclass cacheClass, jintArray jmemArray, jlong pContext) {
0N/A
0N/A int len = (*env)->GetArrayLength(env, jmemArray);
0N/A jint* ptrs =
0N/A (jint*)(*env)->GetPrimitiveArrayCritical(env, jmemArray, NULL);
0N/A int i;
0N/A
0N/A if (ptrs) {
0N/A for (i=0; i< len; i++) {
0N/A if (ptrs[i] != 0) {
0N/A GlyphInfo *ginfo = (GlyphInfo *)ptrs[i];
2370N/A if (ginfo->cellInfo != NULL &&
2370N/A ginfo->managed == MANAGED_GLYPH) {
0N/A // invalidate this glyph's accelerated cache cell
430N/A AccelGlyphCache_RemoveAllCellInfos(ginfo);
0N/A }
0N/A free((void*)ginfo);
0N/A }
0N/A }
0N/A (*env)->ReleasePrimitiveArrayCritical(env, jmemArray, ptrs, JNI_ABORT);
0N/A }
0N/A if (!isNullScalerContext(jlong_to_ptr(pContext))) {
0N/A free(jlong_to_ptr(pContext));
0N/A }
0N/A}
0N/A
0N/A/*
0N/A * Class: sun_font_StrikeCache
0N/A * Method: freeLongMemory
0N/A * Signature: ([J)V
0N/A */
0N/AJNIEXPORT void JNICALL Java_sun_font_StrikeCache_freeLongMemory
0N/A (JNIEnv *env, jclass cacheClass, jlongArray jmemArray, jlong pContext) {
0N/A
0N/A int len = (*env)->GetArrayLength(env, jmemArray);
0N/A jlong* ptrs =
0N/A (jlong*)(*env)->GetPrimitiveArrayCritical(env, jmemArray, NULL);
0N/A int i;
0N/A
0N/A if (ptrs) {
0N/A for (i=0; i< len; i++) {
0N/A if (ptrs[i] != 0L) {
0N/A GlyphInfo *ginfo = (GlyphInfo *) jlong_to_ptr(ptrs[i]);
2370N/A if (ginfo->cellInfo != NULL &&
2370N/A ginfo->managed == MANAGED_GLYPH) {
430N/A AccelGlyphCache_RemoveAllCellInfos(ginfo);
0N/A }
0N/A free((void*)ginfo);
0N/A }
0N/A }
0N/A (*env)->ReleasePrimitiveArrayCritical(env, jmemArray, ptrs, JNI_ABORT);
0N/A }
0N/A if (!isNullScalerContext(jlong_to_ptr(pContext))) {
0N/A free(jlong_to_ptr(pContext));
0N/A }
0N/A}
0N/A
0N/AJNIEXPORT void JNICALL
0N/AJava_sun_font_StrikeCache_getGlyphCacheDescription
0N/A (JNIEnv *env, jclass cls, jlongArray results) {
0N/A
0N/A jlong* nresults;
0N/A GlyphInfo *info;
0N/A size_t baseAddr;
0N/A
2370N/A if ((*env)->GetArrayLength(env, results) < 13) {
0N/A return;
0N/A }
0N/A
0N/A nresults = (jlong*)(*env)->GetPrimitiveArrayCritical(env, results, NULL);
0N/A if (nresults == NULL) {
0N/A return;
0N/A }
0N/A info = (GlyphInfo*) calloc(1, sizeof(GlyphInfo));
0N/A if (info == NULL) {
0N/A (*env)->ReleasePrimitiveArrayCritical(env, results, nresults, 0);
0N/A return;
0N/A }
0N/A baseAddr = (size_t)info;
0N/A nresults[0] = sizeof(void*);
0N/A nresults[1] = sizeof(GlyphInfo);
0N/A nresults[2] = 0;
0N/A nresults[3] = (size_t)&(info->advanceY)-baseAddr;
0N/A nresults[4] = (size_t)&(info->width)-baseAddr;
0N/A nresults[5] = (size_t)&(info->height)-baseAddr;
0N/A nresults[6] = (size_t)&(info->rowBytes)-baseAddr;
0N/A nresults[7] = (size_t)&(info->topLeftX)-baseAddr;
0N/A nresults[8] = (size_t)&(info->topLeftY)-baseAddr;
0N/A nresults[9] = (size_t)&(info->image)-baseAddr;
0N/A nresults[10] = (jlong)(uintptr_t)info; /* invisible glyph */
2370N/A nresults[11] = (size_t)&(info->cellInfo)-baseAddr;
2370N/A nresults[12] = (size_t)&(info->managed)-baseAddr;
2370N/A
0N/A (*env)->ReleasePrimitiveArrayCritical(env, results, nresults, 0);
0N/A}
0N/A
0N/AJNIEXPORT TTLayoutTableCache* newLayoutTableCache() {
0N/A TTLayoutTableCache* ltc = calloc(1, sizeof(TTLayoutTableCache));
0N/A if (ltc) {
5980N/A int i;
5980N/A for(i=0;i<LAYOUTCACHE_ENTRIES;i++) {
5980N/A ltc->entries[i].len = -1;
5980N/A }
0N/A }
0N/A return ltc;
0N/A}
0N/A
0N/AJNIEXPORT void freeLayoutTableCache(TTLayoutTableCache* ltc) {
0N/A if (ltc) {
5980N/A int i;
5980N/A for(i=0;i<LAYOUTCACHE_ENTRIES;i++) {
5980N/A if(ltc->entries[i].ptr) free (ltc->entries[i].ptr);
5980N/A }
0N/A if (ltc->kernPairs) free(ltc->kernPairs);
0N/A free(ltc);
0N/A }
0N/A}