1 /* 2 * Copyright (c) 2008, 2012, 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. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 #import <JavaNativeFoundation/JavaNativeFoundation.h> 25 26 #import "AWTFont.h" 27 #import "CoreTextSupport.h" 28 29 #import "sun_font_CCharToGlyphMapper.h" 30 31 /* 32 * Class: sun_font_CCharToGlyphMapper 33 * Method: countGlyphs 34 * Signature: (J)I 35 */ 36 JNIEXPORT jint JNICALL 37 Java_sun_font_CCharToGlyphMapper_countGlyphs 38 (JNIEnv *env, jclass clazz, jlong awtFontPtr) 39 { 40 jint numGlyphs = 0; 41 42 JNF_COCOA_ENTER(env); 43 44 AWTFont *awtFont = (AWTFont *)jlong_to_ptr(awtFontPtr); 45 numGlyphs = [awtFont->fFont numberOfGlyphs]; 46 47 JNF_COCOA_EXIT(env); 48 49 return numGlyphs; 50 } 51 52 static inline void 53 GetGlyphsFromUnicodes(JNIEnv *env, AWTFont *awtFont, 54 jint count, UniChar *unicodes, 55 CGGlyph *cgGlyphs, jintArray glyphs) 56 { 57 jint *glyphCodeInts = (*env)->GetPrimitiveArrayCritical(env, glyphs, 0); 58 59 CTS_GetGlyphsAsIntsForCharacters(awtFont, unicodes, 60 cgGlyphs, glyphCodeInts, count); 61 62 // Do not use JNI_COMMIT, as that will not free the buffer copy 63 // when +ProtectJavaHeap is on. 64 (*env)->ReleasePrimitiveArrayCritical(env, glyphs, glyphCodeInts, 0); 65 } 66 67 static inline void 68 AllocateGlyphBuffer(JNIEnv *env, AWTFont *awtFont, 69 jint count, UniChar *unicodes, jintArray glyphs) 70 { 71 if (count < MAX_STACK_ALLOC_GLYPH_BUFFER_SIZE) { 72 CGGlyph cgGlyphs[count]; 73 GetGlyphsFromUnicodes(env, awtFont, count, unicodes, cgGlyphs, glyphs); 74 } else { 75 CGGlyph *cgGlyphs = (CGGlyph *)malloc(count * sizeof(CGGlyph)); 76 GetGlyphsFromUnicodes(env, awtFont, count, unicodes, cgGlyphs, glyphs); 77 free(cgGlyphs); 78 } 79 } 80 81 /* 82 * Class: sun_font_CCharToGlyphMapper 83 * Method: nativeCharsToGlyphs 84 * Signature: (JI[C[I)V 85 */ 86 JNIEXPORT void JNICALL 87 Java_sun_font_CCharToGlyphMapper_nativeCharsToGlyphs 88 (JNIEnv *env, jclass clazz, 89 jlong awtFontPtr, jint count, jcharArray unicodes, jintArray glyphs) 90 { 91 JNF_COCOA_ENTER(env); 92 93 AWTFont *awtFont = (AWTFont *)jlong_to_ptr(awtFontPtr); 94 95 // check the array size 96 jint len = (*env)->GetArrayLength(env, glyphs); 97 if (len < count) { 98 count = len; 99 } 100 101 jchar *unicodesAsChars = 102 (*env)->GetPrimitiveArrayCritical(env, unicodes, NULL); 103 104 AllocateGlyphBuffer(env, awtFont, count, (UniChar *)unicodesAsChars, glyphs); 105 106 (*env)->ReleasePrimitiveArrayCritical(env, unicodes, 107 unicodesAsChars, JNI_ABORT); 108 109 JNF_COCOA_EXIT(env); 110 }