< prev index next >

src/java.desktop/share/native/libfontmanager/freetypeScaler.c

Print this page




  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 "jni.h"
  27 #include "jni_util.h"
  28 #include "jlong.h"
  29 #include "sunfontids.h"
  30 #include "sun_font_FreetypeFontScaler.h"
  31 
  32 #include<stdlib.h>



  33 #include <math.h>
  34 #include "ft2build.h"
  35 #include FT_FREETYPE_H
  36 #include FT_GLYPH_H
  37 #include FT_BBOX_H
  38 #include FT_SIZES_H
  39 #include FT_OUTLINE_H
  40 #include FT_SYNTHESIS_H
  41 #include FT_LCD_FILTER_H

  42 
  43 #include "fontscaler.h"
  44 
  45 #define  ftFixed1  (FT_Fixed) (1 << 16)
  46 #define  FloatToFTFixed(f) (FT_Fixed)((f) * (float)(ftFixed1))
  47 #define  FTFixedToFloat(x) ((x) / (float)(ftFixed1))
  48 #define  FT26Dot6ToFloat(x)  ((x) / ((float) (1<<6)))
  49 #define  FT26Dot6ToInt(x) (((int)(x)) >> 6)
  50 
  51 typedef struct {
  52     /* Important note:
  53          JNI forbids sharing same env between different threads.
  54          We are safe, because pointer is overwritten every time we get into
  55          JNI call (see setupFTContext).
  56 
  57          Pointer is used by font data reading callbacks
  58          such as ReadTTFontFileFunc.
  59 
  60          NB: We may consider switching to JNI_GetEnv. */
  61     JNIEnv* env;


 187         unsigned cacheOffset = offset - scalerInfo->fontDataOffset;
 188 
 189         memcpy(destBuffer, scalerInfo->fontData+(size_t)cacheOffset, numBytes);
 190         return numBytes;
 191     } else {
 192         /* Must fill the cache */
 193         scalerInfo->fontDataOffset = offset;
 194         scalerInfo->fontDataLength =
 195                  (offset + FILEDATACACHESIZE > scalerInfo->fileSize) ?
 196                  scalerInfo->fileSize - offset : FILEDATACACHESIZE;
 197         bBuffer = scalerInfo->directBuffer;
 198         bread = (*env)->CallIntMethod(env, scalerInfo->font2D,
 199                                       sunFontIDs.ttReadBlockMID,
 200                                       bBuffer, offset,
 201                                       scalerInfo->fontDataLength);
 202         memcpy(destBuffer, scalerInfo->fontData, numBytes);
 203         return numBytes;
 204     }
 205 }
 206 














































 207 /*
 208  * Class:     sun_font_FreetypeFontScaler
 209  * Method:    initNativeScaler
 210  * Signature: (Lsun/font/Font2D;IIZI)J
 211  */
 212 JNIEXPORT jlong JNICALL
 213 Java_sun_font_FreetypeFontScaler_initNativeScaler(
 214         JNIEnv *env, jobject scaler, jobject font2D, jint type,
 215         jint indexInCollection, jboolean supportsCJK, jint filesize) {
 216     FTScalerInfo* scalerInfo = NULL;
 217     FT_Open_Args ft_open_args;
 218     int error;
 219     jobject bBuffer;
 220     scalerInfo = (FTScalerInfo*) calloc(1, sizeof(FTScalerInfo));
 221 
 222     if (scalerInfo == NULL)
 223         return 0;
 224 
 225     scalerInfo->env = env;
 226     scalerInfo->font2D = font2D;
 227     scalerInfo->fontDataOffset = 0;
 228     scalerInfo->fontDataLength = 0;
 229     scalerInfo->fileSize = filesize;
 230 
 231     /*
 232        We can consider sharing freetype library between different
 233        scalers. However, Freetype docs suggest to use different libraries
 234        for different threads. Also, our architecture implies that single
 235        FontScaler object is shared for different sizes/transforms/styles
 236        of the same font.
 237 
 238        On other hand these methods can not be concurrently executed
 239        becaused they are "synchronized" in java.
 240     */
 241     error = FT_Init_FreeType(&scalerInfo->library);
 242     if (error) {
 243         free(scalerInfo);
 244         return 0;
 245     }

 246 
 247 #define TYPE1_FROM_JAVA        2
 248 
 249     error = 1; /* triggers memory freeing unless we clear it */
 250     if (type == TYPE1_FROM_JAVA) { /* TYPE1 */
 251         scalerInfo->fontData = (unsigned char*) malloc(filesize);
 252         scalerInfo->directBuffer = NULL;
 253         scalerInfo->fontDataLength = filesize;
 254 
 255         if (scalerInfo->fontData != NULL) {
 256             bBuffer = (*env)->NewDirectByteBuffer(env,
 257                                               scalerInfo->fontData,
 258                                               scalerInfo->fontDataLength);
 259             if (bBuffer != NULL) {
 260                 (*env)->CallVoidMethod(env, font2D,
 261                                    sunFontIDs.readFileMID, bBuffer);
 262 
 263                 error = FT_New_Memory_Face(scalerInfo->library,
 264                                    scalerInfo->fontData,
 265                                    scalerInfo->fontDataLength,




  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 "jni.h"
  27 #include "jni_util.h"
  28 #include "jlong.h"
  29 #include "sunfontids.h"
  30 #include "sun_font_FreetypeFontScaler.h"
  31 
  32 #include <stdlib.h>
  33 #if !defined(_WIN32) && !defined(__APPLE_)
  34 #include <dlfcn.h>
  35 #endif
  36 #include <math.h>
  37 #include "ft2build.h"
  38 #include FT_FREETYPE_H
  39 #include FT_GLYPH_H
  40 #include FT_BBOX_H
  41 #include FT_SIZES_H
  42 #include FT_OUTLINE_H
  43 #include FT_SYNTHESIS_H
  44 #include FT_LCD_FILTER_H
  45 #include FT_MODULE_H
  46 
  47 #include "fontscaler.h"
  48 
  49 #define  ftFixed1  (FT_Fixed) (1 << 16)
  50 #define  FloatToFTFixed(f) (FT_Fixed)((f) * (float)(ftFixed1))
  51 #define  FTFixedToFloat(x) ((x) / (float)(ftFixed1))
  52 #define  FT26Dot6ToFloat(x)  ((x) / ((float) (1<<6)))
  53 #define  FT26Dot6ToInt(x) (((int)(x)) >> 6)
  54 
  55 typedef struct {
  56     /* Important note:
  57          JNI forbids sharing same env between different threads.
  58          We are safe, because pointer is overwritten every time we get into
  59          JNI call (see setupFTContext).
  60 
  61          Pointer is used by font data reading callbacks
  62          such as ReadTTFontFileFunc.
  63 
  64          NB: We may consider switching to JNI_GetEnv. */
  65     JNIEnv* env;


 191         unsigned cacheOffset = offset - scalerInfo->fontDataOffset;
 192 
 193         memcpy(destBuffer, scalerInfo->fontData+(size_t)cacheOffset, numBytes);
 194         return numBytes;
 195     } else {
 196         /* Must fill the cache */
 197         scalerInfo->fontDataOffset = offset;
 198         scalerInfo->fontDataLength =
 199                  (offset + FILEDATACACHESIZE > scalerInfo->fileSize) ?
 200                  scalerInfo->fileSize - offset : FILEDATACACHESIZE;
 201         bBuffer = scalerInfo->directBuffer;
 202         bread = (*env)->CallIntMethod(env, scalerInfo->font2D,
 203                                       sunFontIDs.ttReadBlockMID,
 204                                       bBuffer, offset,
 205                                       scalerInfo->fontDataLength);
 206         memcpy(destBuffer, scalerInfo->fontData, numBytes);
 207         return numBytes;
 208     }
 209 }
 210 
 211 typedef FT_Error (*FT_Prop_Set_Func)(FT_Library library,
 212                                      const FT_String*  module_name,
 213                                      const FT_String*  property_name,
 214                                      const void*       value );
 215 
 216 /**
 217  * Prefer the older v35 freetype byte code interpreter.
 218  */
 219 static void setInterpreterVersion(FT_Library library) {
 220 
 221     char* props = getenv("FREETYPE_PROPERTIES");
 222     int version = 35;
 223     const char* module = "truetype";
 224     const char* property = "interpreter-version";
 225 
 226     /* If some one is setting this, don't override it */
 227     if (props != NULL && strstr(property, props)) {
 228         return;
 229     }
 230     /*
 231      * FT_Property_Set was introduced in 2.4.11.
 232      * Some older supported Linux OSes may not include it so look
 233      * this up dynamically.
 234      * And if its not available it doesn't matter, since the reason
 235      * we need it dates from 2.7.
 236      * On Windows & Mac the library is always bundled so it is safe
 237      * to use directly in those cases. 
 238      */
 239 #if defined(_WIN32) || defined(__APPLE__) 
 240     FT_Property_Set(library, module, property, (void*)(&version));
 241 #else
 242     void *lib = dlopen("libfreetype.so", RTLD_LOCAL|RTLD_LAZY);
 243     if (lib == NULL) {
 244         lib = dlopen("libfreetype.so.6", RTLD_LOCAL|RTLD_LAZY);
 245         if (lib == NULL) {
 246             return;
 247         }
 248     }
 249     FT_Prop_Set_Func func = (FT_Prop_Set_Func)dlsym(lib, "FT_Property_Set");
 250     if (func != NULL) {
 251         func(library, module, property, (void*)(&version));
 252     }
 253     dlclose(lib);
 254 #endif
 255 }
 256 
 257 /*
 258  * Class:     sun_font_FreetypeFontScaler
 259  * Method:    initNativeScaler
 260  * Signature: (Lsun/font/Font2D;IIZI)J
 261  */
 262 JNIEXPORT jlong JNICALL
 263 Java_sun_font_FreetypeFontScaler_initNativeScaler(
 264         JNIEnv *env, jobject scaler, jobject font2D, jint type,
 265         jint indexInCollection, jboolean supportsCJK, jint filesize) {
 266     FTScalerInfo* scalerInfo = NULL;
 267     FT_Open_Args ft_open_args;
 268     int error;
 269     jobject bBuffer;
 270     scalerInfo = (FTScalerInfo*) calloc(1, sizeof(FTScalerInfo));
 271 
 272     if (scalerInfo == NULL)
 273         return 0;
 274 
 275     scalerInfo->env = env;
 276     scalerInfo->font2D = font2D;
 277     scalerInfo->fontDataOffset = 0;
 278     scalerInfo->fontDataLength = 0;
 279     scalerInfo->fileSize = filesize;
 280 
 281     /*
 282        We can consider sharing freetype library between different
 283        scalers. However, Freetype docs suggest to use different libraries
 284        for different threads. Also, our architecture implies that single
 285        FontScaler object is shared for different sizes/transforms/styles
 286        of the same font.
 287 
 288        On other hand these methods can not be concurrently executed
 289        becaused they are "synchronized" in java.
 290     */
 291     error = FT_Init_FreeType(&scalerInfo->library);
 292     if (error) {
 293         free(scalerInfo);
 294         return 0;
 295     }
 296     setInterpreterVersion(scalerInfo->library);
 297 
 298 #define TYPE1_FROM_JAVA        2
 299 
 300     error = 1; /* triggers memory freeing unless we clear it */
 301     if (type == TYPE1_FROM_JAVA) { /* TYPE1 */
 302         scalerInfo->fontData = (unsigned char*) malloc(filesize);
 303         scalerInfo->directBuffer = NULL;
 304         scalerInfo->fontDataLength = filesize;
 305 
 306         if (scalerInfo->fontData != NULL) {
 307             bBuffer = (*env)->NewDirectByteBuffer(env,
 308                                               scalerInfo->fontData,
 309                                               scalerInfo->fontDataLength);
 310             if (bBuffer != NULL) {
 311                 (*env)->CallVoidMethod(env, font2D,
 312                                    sunFontIDs.readFileMID, bBuffer);
 313 
 314                 error = FT_New_Memory_Face(scalerInfo->library,
 315                                    scalerInfo->fontData,
 316                                    scalerInfo->fontDataLength,


< prev index next >