Path: blob/master/src/java.desktop/share/native/libfontmanager/sunFont.c
41149 views
/*1* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425#include "stdlib.h"26#include "string.h"27#include "gdefs.h"28#include "jlong.h"29#include "jni_util.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"3536static void *theNullScalerContext = NULL;37extern void AccelGlyphCache_RemoveAllCellInfos(GlyphInfo *glyph);3839/*40* Declare library specific JNI_Onload entry if static build41*/42DEF_STATIC_JNI_OnLoad4344JNIEXPORT jlong JNICALL45Java_sun_font_NullFontScaler_getNullScalerContext46(JNIEnv *env, jclass scalerClass) {4748if (theNullScalerContext == NULL) {49theNullScalerContext = malloc(1);50}51return ptr_to_jlong(theNullScalerContext);52}5354int isNullScalerContext(void *context) {55return theNullScalerContext == context;56}5758/* Eventually we may rework it to be a singleton.59* This will require additional checks in freeLongMemory/freeIntMemory60* and on other hand malformed fonts (main source of null glyph images)61* are supposed to be collected fast.62* But perhaps it is still right thing to do.63* Even better is to eliminate the need to have this native method64* but for this it is necessary to rework Strike and drawing logic65* to be able to live with NULL pointers without performance hit.66*/67JNIEXPORT jlong JNICALL Java_sun_font_NullFontScaler_getGlyphImage68(JNIEnv *env, jobject scaler, jlong pContext, jint glyphCode) {69void *nullscaler = calloc(sizeof(GlyphInfo), 1);70return ptr_to_jlong(nullscaler);71}72737475void initLCDGammaTables();7677/* placeholder for extern variable */78static int initialisedFontIDs = 0;79FontManagerNativeIDs sunFontIDs;8081static void initFontIDs(JNIEnv *env) {8283jclass tmpClass;8485if (initialisedFontIDs) {86return;87}88CHECK_NULL(tmpClass = (*env)->FindClass(env, "sun/font/TrueTypeFont"));89CHECK_NULL(sunFontIDs.ttReadBlockMID =90(*env)->GetMethodID(env, tmpClass, "readBlock",91"(Ljava/nio/ByteBuffer;II)I"));92CHECK_NULL(sunFontIDs.ttReadBytesMID =93(*env)->GetMethodID(env, tmpClass, "readBytes", "(II)[B"));9495CHECK_NULL(tmpClass = (*env)->FindClass(env, "sun/font/Type1Font"));96CHECK_NULL(sunFontIDs.readFileMID =97(*env)->GetMethodID(env, tmpClass,98"readFile", "(Ljava/nio/ByteBuffer;)V"));99100CHECK_NULL(tmpClass =101(*env)->FindClass(env, "java/awt/geom/Point2D$Float"));102sunFontIDs.pt2DFloatClass = (jclass)(*env)->NewGlobalRef(env, tmpClass);103CHECK_NULL(sunFontIDs.pt2DFloatCtr =104(*env)->GetMethodID(env, sunFontIDs.pt2DFloatClass, "<init>","(FF)V"));105106CHECK_NULL(sunFontIDs.xFID =107(*env)->GetFieldID(env, sunFontIDs.pt2DFloatClass, "x", "F"));108CHECK_NULL(sunFontIDs.yFID =109(*env)->GetFieldID(env, sunFontIDs.pt2DFloatClass, "y", "F"));110111CHECK_NULL(tmpClass = (*env)->FindClass(env, "sun/font/StrikeMetrics"));112CHECK_NULL(sunFontIDs.strikeMetricsClass =113(jclass)(*env)->NewGlobalRef(env, tmpClass));114115CHECK_NULL(sunFontIDs.strikeMetricsCtr =116(*env)->GetMethodID(env, sunFontIDs.strikeMetricsClass,117"<init>", "(FFFFFFFFFF)V"));118119CHECK_NULL(tmpClass =120(*env)->FindClass(env, "java/awt/geom/Rectangle2D$Float"));121sunFontIDs.rect2DFloatClass = (jclass)(*env)->NewGlobalRef(env, tmpClass);122CHECK_NULL(sunFontIDs.rect2DFloatCtr =123(*env)->GetMethodID(env, sunFontIDs.rect2DFloatClass, "<init>", "()V"));124CHECK_NULL(sunFontIDs.rect2DFloatCtr4 =125(*env)->GetMethodID(env, sunFontIDs.rect2DFloatClass,126"<init>", "(FFFF)V"));127CHECK_NULL(sunFontIDs.rectF2DX =128(*env)->GetFieldID(env, sunFontIDs.rect2DFloatClass, "x", "F"));129CHECK_NULL(sunFontIDs.rectF2DY =130(*env)->GetFieldID(env, sunFontIDs.rect2DFloatClass, "y", "F"));131CHECK_NULL(sunFontIDs.rectF2DWidth =132(*env)->GetFieldID(env, sunFontIDs.rect2DFloatClass, "width", "F"));133CHECK_NULL(sunFontIDs.rectF2DHeight =134(*env)->GetFieldID(env, sunFontIDs.rect2DFloatClass, "height", "F"));135136CHECK_NULL(tmpClass = (*env)->FindClass(env, "java/awt/geom/GeneralPath"));137sunFontIDs.gpClass = (jclass)(*env)->NewGlobalRef(env, tmpClass);138CHECK_NULL(sunFontIDs.gpCtr =139(*env)->GetMethodID(env, sunFontIDs.gpClass, "<init>", "(I[BI[FI)V"));140CHECK_NULL(sunFontIDs.gpCtrEmpty =141(*env)->GetMethodID(env, sunFontIDs.gpClass, "<init>", "()V"));142143CHECK_NULL(tmpClass = (*env)->FindClass(env, "sun/font/Font2D"));144CHECK_NULL(sunFontIDs.f2dCharToGlyphMID =145(*env)->GetMethodID(env, tmpClass, "charToGlyph", "(I)I"));146CHECK_NULL(sunFontIDs.f2dCharToVariationGlyphMID =147(*env)->GetMethodID(env, tmpClass, "charToVariationGlyph", "(II)I"));148CHECK_NULL(sunFontIDs.getMapperMID =149(*env)->GetMethodID(env, tmpClass, "getMapper",150"()Lsun/font/CharToGlyphMapper;"));151CHECK_NULL(sunFontIDs.getTableBytesMID =152(*env)->GetMethodID(env, tmpClass, "getTableBytes", "(I)[B"));153CHECK_NULL(sunFontIDs.canDisplayMID =154(*env)->GetMethodID(env, tmpClass, "canDisplay", "(C)Z"));155156CHECK_NULL(tmpClass = (*env)->FindClass(env, "sun/font/CharToGlyphMapper"));157CHECK_NULL(sunFontIDs.charToGlyphMID =158(*env)->GetMethodID(env, tmpClass, "charToGlyph", "(I)I"));159160CHECK_NULL(tmpClass = (*env)->FindClass(env, "sun/font/PhysicalStrike"));161CHECK_NULL(sunFontIDs.getGlyphMetricsMID =162(*env)->GetMethodID(env, tmpClass, "getGlyphMetrics",163"(I)Ljava/awt/geom/Point2D$Float;"));164CHECK_NULL(sunFontIDs.getGlyphPointMID =165(*env)->GetMethodID(env, tmpClass, "getGlyphPoint",166"(II)Ljava/awt/geom/Point2D$Float;"));167CHECK_NULL(sunFontIDs.adjustPointMID =168(*env)->GetMethodID(env, tmpClass, "adjustPoint",169"(Ljava/awt/geom/Point2D$Float;)V"));170CHECK_NULL(sunFontIDs.pScalerContextFID =171(*env)->GetFieldID(env, tmpClass, "pScalerContext", "J"));172173CHECK_NULL(tmpClass = (*env)->FindClass(env, "sun/font/GlyphList"));174CHECK_NULL(sunFontIDs.glyphListX =175(*env)->GetFieldID(env, tmpClass, "gposx", "F"));176CHECK_NULL(sunFontIDs.glyphListY =177(*env)->GetFieldID(env, tmpClass, "gposy", "F"));178CHECK_NULL(sunFontIDs.glyphListLen =179(*env)->GetFieldID(env, tmpClass, "len", "I"));180CHECK_NULL(sunFontIDs.glyphImages =181(*env)->GetFieldID(env, tmpClass, "images", "[J"));182CHECK_NULL(sunFontIDs.glyphListUsePos =183(*env)->GetFieldID(env, tmpClass, "usePositions", "Z"));184CHECK_NULL(sunFontIDs.glyphListPos =185(*env)->GetFieldID(env, tmpClass, "positions", "[F"));186CHECK_NULL(sunFontIDs.lcdRGBOrder =187(*env)->GetFieldID(env, tmpClass, "lcdRGBOrder", "Z"));188CHECK_NULL(sunFontIDs.lcdSubPixPos =189(*env)->GetFieldID(env, tmpClass, "lcdSubPixPos", "Z"));190191initLCDGammaTables();192193initialisedFontIDs = 1;194}195196JNIEXPORT void JNICALL197Java_sun_font_SunFontManager_initIDs198(JNIEnv *env, jclass cls) {199200initFontIDs(env);201}202203JNIEXPORT FontManagerNativeIDs getSunFontIDs(JNIEnv *env) {204205initFontIDs(env);206return sunFontIDs;207}208209/*210* Class: sun_font_StrikeCache211* Method: freeIntPointer212* Signature: (I)V213*/214JNIEXPORT void JNICALL Java_sun_font_StrikeCache_freeIntPointer215(JNIEnv *env, jclass cacheClass, jint ptr) {216217/* Note this is used for freeing a glyph which was allocated218* but never placed into the glyph cache. The caller holds the219* only reference, therefore it is unnecessary to invalidate any220* accelerated glyph cache cells as we do in freeInt/LongMemory().221*/222if (ptr != 0) {223free((void*)((intptr_t)ptr));224}225}226227/*228* Class: sun_font_StrikeCache229* Method: freeLongPointer230* Signature: (J)V231*/232JNIEXPORT void JNICALL Java_sun_font_StrikeCache_freeLongPointer233(JNIEnv *env, jclass cacheClass, jlong ptr) {234235/* Note this is used for freeing a glyph which was allocated236* but never placed into the glyph cache. The caller holds the237* only reference, therefore it is unnecessary to invalidate any238* accelerated glyph cache cells as we do in freeInt/LongMemory().239*/240if (ptr != 0L) {241free(jlong_to_ptr(ptr));242}243}244245/*246* Class: sun_font_StrikeCache247* Method: freeIntMemory248* Signature: ([I)V249*/250JNIEXPORT void JNICALL Java_sun_font_StrikeCache_freeIntMemory251(JNIEnv *env, jclass cacheClass, jintArray jmemArray, jlong pContext) {252253int len = (*env)->GetArrayLength(env, jmemArray);254jint* ptrs =255(jint*)(*env)->GetPrimitiveArrayCritical(env, jmemArray, NULL);256int i;257258if (ptrs) {259for (i=0; i< len; i++) {260if (ptrs[i] != 0) {261GlyphInfo *ginfo = (GlyphInfo *)((intptr_t)ptrs[i]);262if (ginfo->cellInfo != NULL &&263ginfo->managed == MANAGED_GLYPH) {264// invalidate this glyph's accelerated cache cell265AccelGlyphCache_RemoveAllCellInfos(ginfo);266}267free(ginfo);268}269}270(*env)->ReleasePrimitiveArrayCritical(env, jmemArray, ptrs, JNI_ABORT);271}272if (!isNullScalerContext(jlong_to_ptr(pContext))) {273free(jlong_to_ptr(pContext));274}275}276277/*278* Class: sun_font_StrikeCache279* Method: freeLongMemory280* Signature: ([J)V281*/282JNIEXPORT void JNICALL Java_sun_font_StrikeCache_freeLongMemory283(JNIEnv *env, jclass cacheClass, jlongArray jmemArray, jlong pContext) {284285int len = (*env)->GetArrayLength(env, jmemArray);286jlong* ptrs =287(jlong*)(*env)->GetPrimitiveArrayCritical(env, jmemArray, NULL);288int i;289290if (ptrs) {291for (i=0; i< len; i++) {292if (ptrs[i] != 0L) {293GlyphInfo *ginfo = (GlyphInfo *) jlong_to_ptr(ptrs[i]);294if (ginfo->cellInfo != NULL &&295ginfo->managed == MANAGED_GLYPH) {296AccelGlyphCache_RemoveAllCellInfos(ginfo);297}298free((void*)ginfo);299}300}301(*env)->ReleasePrimitiveArrayCritical(env, jmemArray, ptrs, JNI_ABORT);302}303if (!isNullScalerContext(jlong_to_ptr(pContext))) {304free(jlong_to_ptr(pContext));305}306}307308JNIEXPORT void JNICALL309Java_sun_font_StrikeCache_getGlyphCacheDescription310(JNIEnv *env, jclass cls, jlongArray results) {311312jlong* nresults;313GlyphInfo *info;314size_t baseAddr;315316if ((*env)->GetArrayLength(env, results) < 13) {317return;318}319320nresults = (jlong*)(*env)->GetPrimitiveArrayCritical(env, results, NULL);321if (nresults == NULL) {322return;323}324info = (GlyphInfo*) calloc(1, sizeof(GlyphInfo));325if (info == NULL) {326(*env)->ReleasePrimitiveArrayCritical(env, results, nresults, 0);327return;328}329baseAddr = (size_t)info;330nresults[0] = sizeof(void*);331nresults[1] = sizeof(GlyphInfo);332nresults[2] = 0;333nresults[3] = (size_t)&(info->advanceY)-baseAddr;334nresults[4] = (size_t)&(info->width)-baseAddr;335nresults[5] = (size_t)&(info->height)-baseAddr;336nresults[6] = (size_t)&(info->rowBytes)-baseAddr;337nresults[7] = (size_t)&(info->topLeftX)-baseAddr;338nresults[8] = (size_t)&(info->topLeftY)-baseAddr;339nresults[9] = (size_t)&(info->image)-baseAddr;340nresults[10] = (jlong)(uintptr_t)info; /* invisible glyph */341nresults[11] = (size_t)&(info->cellInfo)-baseAddr;342nresults[12] = (size_t)&(info->managed)-baseAddr;343344(*env)->ReleasePrimitiveArrayCritical(env, results, nresults, 0);345}346347348