void i_tt_dump_names(TT_Fonthandle *handle) { TT_Face_Properties props; int name_count; int i; TT_UShort platform_id, encoding_id, lang_id, name_id; TT_UShort name_len; TT_String *name; TT_Get_Face_Properties(handle->face, &props); name_count = props.num_Names; for (i = 0; i < name_count; ++i) { TT_Get_Name_ID(handle->face, i, &platform_id, &encoding_id, &lang_id, &name_id); TT_Get_Name_String(handle->face, i, &name, &name_len); printf("# %d: plat %d enc %d lang %d name %d value ", i, platform_id, encoding_id, lang_id, name_id); if (platform_id == TT_PLATFORM_APPLE_UNICODE) { printf("(unicode)\n"); } else { printf("'%s'\n", name); } } fflush(stdout); }
static void ttf_instance_setc(struct image_ttf_face_struct *face_s, struct image_ttf_faceinstance_struct *face_i, int towhat, char *where) { TT_Face_Properties prop; TT_Instance_Metrics metr; int res; int resol; if ((res=TT_Get_Face_Properties(face_s->face,&prop))) my_tt_error(where,"TT_Get_Face_Properties",res); resol=58; /* should be 72, but glyphs fit using this value */ /* (int)((72*(prop.horizontal->Ascender+ prop.horizontal->Descender)/ (float)prop.horizontal->Ascender)); */ if ((res=TT_Set_Instance_Resolutions(face_i->instance, (TT_UShort)resol, (TT_UShort)resol))) my_tt_error("Image.TTF.FaceInstance()", "TT_Set_Instance_Resolutions: ",res); if ((res=TT_Get_Instance_Metrics(face_i->instance,&metr))) my_tt_error(where,"TT_Get_Instance_Metrics",res); if ((res=TT_Set_Instance_CharSize(face_i->instance,towhat))) my_tt_error(where,"TT_Set_Instance_CharSize: ",res); face_i->baseline= DOUBLE_TO_INT(((double)(towhat/64.0+towhat/640.0)* prop.horizontal->Ascender)/ (prop.horizontal->Ascender - prop.horizontal->Descender)); face_i->height= (towhat/64 + towhat/640); face_i->trans = ~63 & (32 + DOUBLE_TO_INT(64*((towhat/64.0+towhat/640.0)* prop.horizontal->Ascender)/ (prop.horizontal->Ascender-prop.horizontal->Descender))); }
SWFFont loadSWFFontfromTTF(char *filename) { int i; TT_Engine *engine; TT_Face face; TT_Instance instance; TT_Glyph glyph; TT_Glyph_Metrics metrics; TT_Outline outline; TT_CharMap charmap; TT_Face_Properties properties; TT_UShort pid, eid; TT_Init_FreeType(engine); error = TT_Open_Face(engine, filename, &face); if(error) fprintf(stderr, "Could not open face.\n"); TT_Get_Face_Properties(face, &properties); for(i=0; i<properties->num_CharMaps; ++i) TT_Get_CharMap_ID(face, i, &pid, &eid); TT_Get_CharMap(face, charmapIndex, &charmap); TT_New_Instance(face, &instance); TT_New_Glyph(face, &glyph); for(i=0; i<whatever; ++i) { TT_Load_Glyph(instance, glyph, TT_Char_Index(charmap, i), loadFlags); TT_Get_Glyph_Outline(glyph, &outline); TT_Get_Glyph_Metrics(glyph, &metrics); } TT_Done_FreeType(engine); }
int main( int argc, char** argv ) { int i; char filename[128 + 4]; char alt_filename[128 + 4]; char* execname; char* fname; #ifdef HAVE_LIBINTL_H setlocale( LC_ALL, "" ); bindtextdomain( "freetype", LOCALEDIR ); textdomain( "freetype" ); #endif execname = argv[0]; if ( argc < 3 ) Usage( execname ); if ( sscanf( argv[1], "%d", &ptsize ) != 1 ) Usage( execname ); /* Initialize engine */ if ( (error = TT_Init_FreeType( &engine )) ) { fprintf( stderr, gettext( "Error while initializing engine.\n" ) ); goto Failure; } if ( (error = TT_Init_SBit_Extension( engine )) ) { fprintf( stderr, gettext( "Error while initializing embedded bitmap extension.\n" ) ); goto Failure; } /* Now check all files */ fname = argv[2]; i = strlen( fname ); while ( i > 0 && fname[i] != '\\' && fname[i] != '/' ) { if ( fname[i] == '.' ) i = 0; i--; } filename[128] = '\0'; alt_filename[128] = '\0'; strncpy( filename, fname, 128 ); strncpy( alt_filename, fname, 128 ); if ( i >= 0 ) { strncpy( filename + strlen( filename ), ".ttf", 4 ); strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 ); } /* Load face */ error = TT_Open_Face( engine, filename, &face ); if ( error == TT_Err_Could_Not_Open_File ) { strcpy( filename, alt_filename ); error = TT_Open_Face( engine, alt_filename, &face ); } i = strlen( filename ); fname = filename; while ( i >= 0 ) if ( filename[i] == '/' || filename[i] == '\\' ) { fname = filename + i + 1; i = -1; } else i--; if ( error ) { fprintf( stderr, gettext( "Could not find or open %s.\n" ), filename ); goto Failure; } if ( error ) { fprintf( stderr, gettext( "Error while opening %s.\n" ), filename ); goto Failure; } /* get face properties */ TT_Get_Face_Properties( face, &properties ); num_glyphs = properties.num_Glyphs; error = TT_Get_Face_Bitmaps( face, &eblc ); if ( error == TT_Err_Table_Missing ) { fprintf( stderr, gettext( "Could not find embedded bitmaps in this font.\n" ) ); goto Failure; } if ( error ) { fprintf( stderr, gettext( "Error while loading embedded bitmaps.\n" ) ); goto Failure; } /* create instance */ error = TT_New_Instance( face, &instance ); if ( error ) { fprintf( stderr, gettext( "Could not create instance.\n" ) ); goto Failure; } error = TT_Set_Instance_PixelSizes( instance, ptsize, ptsize, ptsize*3/4 ); if ( error ) { fprintf( stderr, gettext( "Could not set point size to %d.\n" ), ptsize ); goto Failure; } error = TT_New_SBit_Image( &bitmap ); if ( error ) { fprintf( stderr, gettext( "Could not allocate glyph bitmap container.\n" ) ); goto Failure; } for ( i = 3; i < argc; i++ ) { unsigned short glyph_index; /* we use %i to allow the prefixes `0x' and `0' */ if ( sscanf( argv[i], "%hi", &glyph_index ) != 1 ) Usage( execname ); error = TT_Load_Glyph_Bitmap( face, instance, glyph_index, bitmap ); if ( error == TT_Err_Invalid_Glyph_Index ) { fprintf( stderr, gettext( " no bitmap for glyph %d.\n" ), glyph_index ); continue; } if ( error ) { fprintf( stderr, gettext( "Can't load bitmap for glyph %d.\n" ), glyph_index ); goto Failure; } /* Dump the resulting bitmap */ { printf( gettext( "glyph index %d = %dx%d pixels, " ), glyph_index, bitmap->map.rows, bitmap->map.width ); printf( gettext( "advance = %ld, minBearing = [%ld,%ld]\n" ), (long)(bitmap->metrics.horiAdvance / 64), (long)(bitmap->metrics.horiBearingX / 64), (long)(bitmap->metrics.horiBearingY / 64)); Show_Single_Glyph( &bitmap->map ); } } TT_Done_SBit_Image( bitmap ); TT_Done_FreeType( engine ); exit( EXIT_SUCCESS ); /* for safety reasons */ return 0; /* never reached */ Failure: fprintf( stderr, " " ); fprintf( stderr, gettext( "FreeType error message: %s\n" ), TT_ErrToString18( error ) ); exit( EXIT_FAILURE ); return 0; /* never reached */ }
int main( int argc, char** argv ) { int i, total, mode, base, rendered_glyphs; char filename[128 + 4]; char alt_filename[128 + 4]; char* execname; long t, t0, tz0; execname = argv[0]; gray_render = 0; visual = 0; while ( argc > 1 && argv[1][0] == '-' ) { switch ( argv[1][1] ) { case 'g': gray_render = 1; break; case 'v': visual = 1; break; default: Panic( "Unknown argument '%s'!\n", argv[1] ); } argc--; argv++; } if ( argc != 2 ) { fprintf( stderr, "fttimer: simple performance timer -- part of the FreeType project\n" ); fprintf( stderr,"-----------------------------------------------------------------\n\n" ); fprintf( stderr,"Usage: %s [-g] [-v] fontname[.ttf|.ttc]\n\n", execname ); fprintf( stderr," where '-g' asks for gray-levels rendering\n" ); fprintf( stderr," '-v' displays while rendering (slower)\n" ); exit( EXIT_FAILURE ); } i = strlen( argv[1] ); while ( i > 0 && argv[1][i] != '\\' ) { if ( argv[1][i] == '.' ) i = 0; i--; } filename[128] = '\0'; alt_filename[128] = '\0'; strncpy( filename, argv[1], 128 ); strncpy( alt_filename, argv[1], 128 ); if ( i >= 0 ) { strncpy( filename + strlen( filename ), ".ttf", 4 ); strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 ); } /* Initialize engine */ if ( (error = TT_Init_FreeType( &engine )) ) Panic( "Error while initializing engine, code = 0x%x.\n", error ); /* Load face */ error = TT_Open_Face( engine, filename, &face ); if ( error == TT_Err_Could_Not_Open_File ) { strcpy( filename, alt_filename ); error = TT_Open_Face( engine, alt_filename, &face ); } if ( error == TT_Err_Could_Not_Open_File ) Panic( "Could not find/open %s.\n", filename ); else if ( error ) Panic( "Error while opening %s, error code = 0x%x.\n", filename, error ); /* get face properties and allocate preload arrays */ TT_Get_Face_Properties( face, &properties ); num_glyphs = properties.num_Glyphs; tab_glyphs = MAX_GLYPHS; if ( tab_glyphs > num_glyphs ) tab_glyphs = num_glyphs; /* create glyph */ error = TT_New_Glyph( face, &glyph ); if ( error ) Panic( "Could not create glyph container.\n" ); /* create instance */ error = TT_New_Instance( face, &instance ); if ( error ) Panic( "Could not create instance for %s.\n", filename ); error = TT_Set_Instance_CharSize( instance, 400*64 ); if ( error ) Panic( "Could not reset instance for %s.\n", filename ); if ( gray_render ) mode = Graphics_Mode_Gray; else mode = Graphics_Mode_Mono; if ( visual ) { if ( !SetGraphScreen( mode ) ) Panic( "Could not set graphics mode.\n" ); TT_Set_Raster_Gray_Palette( engine, gray_palette ); } else { /* This is the default bitmap size used */ vio_Width = 640; vio_Height = 450; } Init_Engine(); Num = 0; Fail = 0; total = num_glyphs; base = 0; rendered_glyphs = 0; t0 = 0; /* Initial time */ tz0 = Get_Time(); while ( total > 0 ) { /* First, preload 'tab_glyphs' in memory */ cur_glyph = 0; cur_point = 0; cur_contour = 0; printf( "loading %d glyphs", tab_glyphs ); for ( Num = 0; Num < tab_glyphs; Num++ ) { error = LoadTrueTypeChar( base + Num ); if ( error ) Fail++; total--; } base += tab_glyphs; if ( tab_glyphs > total ) tab_glyphs = total; printf( ", rendering... " ); /* Now, render the loaded glyphs */ t = Get_Time(); for ( Num = 0; Num < cur_glyph; Num++ ) { if ( (error = ConvertRaster( Num )) ) Fail++; else { rendered_glyphs ++; if ( visual ) { sprintf( Header, "Glyph: %5d", Num ); Display_Bitmap_On_Screen( Bit.bitmap, Bit.rows, Bit.cols ); Clear_Buffer(); } } } t = Get_Time() - t; if ( t < 0 ) t += 100L * 60 * 60; printf( " = %f s\n", (double)t / 1000 ); t0 += t; /* Now free all loaded outlines */ for ( Num = 0; Num < cur_glyph; Num++ ) TT_Done_Outline( &outlines[Num] ); } tz0 = Get_Time() - tz0; if ( visual ) RestoreScreen(); TT_Close_Face( face ); printf( "\n" ); printf( "rendered glyphs = %d\n", rendered_glyphs ); printf( "render time = %f s\n", (double)t0 / 1000 ); printf( "fails = %d\n", Fail ); printf( "average glyphs/s = %f\n", (double)rendered_glyphs / t0 * 1000 ); printf( "total timing = %f s\n", (double)tz0 / 1000 ); printf( "Fails = %d\n", Fail ); TT_Done_FreeType( engine ); exit( EXIT_SUCCESS ); /* for safety reasons */ return 0; /* never reached */ }
void TTFopen(char *filename, Font *fnt, int new_dpi, int new_ptsize, Boolean quiet) { unsigned short i, num_cmap; unsigned short cmap_plat; unsigned short cmap_enc; TT_Error error; TT_UShort script_index, language_index, feature_index; TT_UShort req_feature_index = 0xFFFF; dpi = new_dpi; ptsize = new_ptsize; if ((error = TT_Init_FreeType(&engine))) oops("Cannot initialize FreeType engine (error code = 0x%x).", error); if (fnt->PSnames) if ((error = TT_Init_Post_Extension(engine))) oops("Cannot initialize PS name support (error code = 0x%x).", error); if (fnt->rotate) if ((error = TT_Init_GSUB_Extension(engine))) oops("Cannot initialize GSUB support (error code = 0x%x).", error); /* * Load face. */ error = TT_Open_Face(engine, filename, &face); if (error) oops("Cannot open `%s'.", filename); /* * Get face properties and allocate preloaded arrays. */ TT_Get_Face_Properties(face, &properties); /* * Now we try to open the proper font in a collection. */ if (fnt->fontindex != 0) { if (properties.num_Faces == 1) warning("This isn't a TrueType collection.\n" "Parameter `Fontindex' is ignored."); else { TT_Close_Face(face); if ((error = TT_Open_Collection(engine, filename, fnt->fontindex, &face))) oops("Cannot open font %lu in TrueType Collection `%s'.", fnt->fontindex, filename); } } /* * Create instance. */ if ((error = TT_New_Instance(face, &instance))) oops("Cannot create instance for `%s' (error code = 0x%x).", filename, error); if ((error = TT_Set_Instance_Resolutions(instance, dpi, dpi))) oops("Cannot set device resolutions (error code = 0x%x)."); if ((error = TT_Set_Instance_CharSize(instance, ptsize * 64))) oops("Cannot set character size (error code = 0x%x).", error); ppem = (dpi * ptsize + 36) / 72; if (!quiet) printf("dpi = %d, ptsize = %d, ppem = %d\n\n", dpi, ptsize, ppem); matrix1.xx = (TT_Fixed)(floor(fnt->efactor * 1024) * (1<<16)/1024); matrix1.xy = (TT_Fixed)(floor(fnt->slant * 1024) * (1<<16)/1024); matrix1.yx = (TT_Fixed)0; matrix1.yy = (TT_Fixed)(1<<16); if (fnt->rotate) { matrix2.xx = 0; matrix2.yx = 1L << 16; matrix2.xy = -matrix2.yx; matrix2.yy = matrix2.xx; } if ((error = TT_Set_Instance_Transform_Flags( instance, fnt->rotate ? 1 : 0, fnt->efactor != 1.0 ? 1 : 0))) oops("Cannot set transform flags (error code = 0x%x).", error); /* * Create glyph container. */ if ((error = TT_New_Glyph(face, &glyph))) oops("Cannot create glyph container (error code = 0x%x)."); if (fnt->PSnames != Only) { num_cmap = properties.num_CharMaps; for (i = 0; i < num_cmap; i++) { if ((error = TT_Get_CharMap_ID(face, i, &cmap_plat, &cmap_enc))) oops("Cannot query cmap (error code = 0x%x).", error); if (cmap_plat == fnt->pid && cmap_enc == fnt->eid) break; } if (i == num_cmap) oops("Invalid platform and/or encoding ID."); if ((error = TT_Get_CharMap(face, i, &char_map))) oops("Cannot load cmap (error code = 0x%x).", error); } if (fnt->PSnames) { if ((error = TT_Load_PS_Names(face, &post))) oops("Cannot load TrueType PS names (error code = 0x%x).", error); } else if (cmap_plat == Microsoft_platform && cmap_enc == Microsoft_Unicode_encoding) set_encoding_scheme(encUnicode, fnt); else if (cmap_plat == Macintosh_platform && cmap_enc == Macintosh_encoding) set_encoding_scheme(encMac, fnt); else set_encoding_scheme(encFontSpecific, fnt); if (fnt->rotate) { gsub = &gsub_; error = TT_Load_GSUB_Table(face, gsub, NULL); if (!error) has_gsub = True; else if (error != TT_Err_Table_Missing) warning("Cannot load GSUB table (error code = 0x%x).", error); else warning("No GSUB data available " "for vertical glyph presentation forms."); /* we check for the `vert' feature in Chinese, Japanese, and Korean */ error = TT_GSUB_Select_Script(gsub, SCRIPT_kana, &script_index); if (error) goto check_hani; error = TT_GSUB_Select_Feature(gsub, FEATURE_vert, script_index, 0xFFFF, &feature_index); if (error) { error = TT_GSUB_Select_Language(gsub, LANGUAGE_JAN, script_index, &language_index, &req_feature_index); if (error) goto check_hani; error = TT_GSUB_Select_Feature(gsub, FEATURE_vert, script_index, language_index, &feature_index); if (error) goto check_hani; else goto Done; } else goto Done; check_hani: error = TT_GSUB_Select_Script(gsub, SCRIPT_hani, &script_index); if (error) goto check_hang; error = TT_GSUB_Select_Feature(gsub, FEATURE_vert, script_index, 0xFFFF, &feature_index); if (error) { error = TT_GSUB_Select_Language(gsub, LANGUAGE_CHN, script_index, &language_index, &req_feature_index); if (error) goto check_hang; error = TT_GSUB_Select_Feature(gsub, FEATURE_vert, script_index, language_index, &feature_index); if (error) goto check_hang; else goto Done; } else goto Done; check_hang: error = TT_GSUB_Select_Script(gsub, SCRIPT_hang, &script_index); if (error) goto Done; error = TT_GSUB_Select_Feature(gsub, FEATURE_vert, script_index, 0xFFFF, &feature_index); if (error) { error = TT_GSUB_Select_Language(gsub, LANGUAGE_KOR, script_index, &language_index, &req_feature_index); if (error) goto Done; error = TT_GSUB_Select_Feature(gsub, FEATURE_vert, script_index, language_index, &feature_index); } Done: if (error) { warning("There is no data for vertical typesetting in GSUB table."); has_gsub = False; } if (req_feature_index != 0xFFFF) TT_GSUB_Add_Feature(gsub, req_feature_index, ALL_GLYPHS); TT_GSUB_Add_Feature(gsub, feature_index, ALL_GLYPHS); in.length = 1; in.pos = 0; in.string = in_string; in.properties = NULL; out.pos = 0; out.allocated = 0; out.string = NULL; out.properties = NULL; } }
TTF_Font *TTF_OpenFont(const char *file, int ptsize) { TTF_Font *font; TT_Face_Properties properties; TT_Instance_Metrics imetrics; int i, n; TT_UShort platform, encoding; TT_Error error; font = (TTF_Font *)malloc(sizeof(*font)); if ( font == NULL ) { SDL_SetError("Out of memory"); return(NULL); } memset(font, 0, sizeof(*font)); /* Open the font and create ancillary data */ error = TT_Open_Face(engine, file, &font->face); if ( error ) { SDL_SetError("Couldn't load font file"); free(font); return(NULL); } error = TT_New_Glyph(font->face, &font->glyph); if ( error ) { SDL_SetError("Couldn't create glyph container"); TTF_CloseFont(font); return(NULL); } error = TT_New_Instance(font->face, &font->inst); if ( error ) { SDL_SetError("Couldn't create font instance"); TTF_CloseFont(font); return(NULL); } /* Set the display resolution */ error = TT_Set_Instance_Resolutions(font->inst, 72, 72); if ( error ) { SDL_SetError("Couldn't set font resolution"); TTF_CloseFont(font); return(NULL); } error = TT_Set_Instance_CharSize(font->inst, ptsize*64); if ( error ) { SDL_SetError("Couldn't set font size"); TTF_CloseFont(font); return(NULL); } /* Get a Unicode mapping for this font */ n = TT_Get_CharMap_Count(font->face); for ( i=0; i<n; ++i ) { TT_Get_CharMap_ID(font->face, i, &platform, &encoding); if ( ((platform == TT_PLATFORM_MICROSOFT) && (encoding == TT_MS_ID_UNICODE_CS)) || ((platform == TT_PLATFORM_APPLE_UNICODE) && (encoding == TT_APPLE_ID_DEFAULT)) ) { TT_Get_CharMap(font->face, i, &font->map); break; } } if ( i == n ) { SDL_SetError("Font doesn't have a Unicode mapping"); TTF_CloseFont(font); return(NULL); } /* Get the font metrics for this font */ TT_Get_Face_Properties(font->face, &properties ); TT_Get_Instance_Metrics(font->inst, &imetrics); font->pointsize = imetrics.y_ppem; font->ascent = (float)properties.horizontal->Ascender / properties.header->Units_Per_EM; font->ascent *= font->pointsize; font->descent = (float)properties.horizontal->Descender / properties.header->Units_Per_EM; font->descent *= font->pointsize; font->lineskip = (float)properties.horizontal->Line_Gap / properties.header->Units_Per_EM; font->lineskip *= font->pointsize; font->height = round(font->ascent - font->descent); /* Set the default font style */ font->style = TTF_STYLE_NORMAL; font->glyph_overhang = font->pointsize/10; /* x offset = cos(((90.0-12)/360)*2*M_PI), or 12 degree angle */ font->glyph_italics = 0.207; font->glyph_italics *= font->height; return(font); }
int main( int argc, char** argv ) { int i, orig_ptsize, file; char filename[128 + 4]; char alt_filename[128 + 4]; char* execname; int option; int ptsize; int num_Faces = 0; int glyph_index = 0; int load_flags = TTLOAD_DEFAULT; int force_sbit = 0; TT_Engine engine; TT_Face face; TT_Instance instance; TT_Glyph glyph; TT_Raster_Map map; TT_Big_Glyph_Metrics metrics; TT_Face_Properties properties; TT_Instance_Metrics imetrics; TT_EBLC eblc; TT_SBit_Image* bitmap = NULL; TT_Error error; int res = 72; #ifdef HAVE_LIBINTL_H setlocale( LC_ALL, "" ); bindtextdomain( "freetype", LOCALEDIR ); textdomain( "freetype" ); #endif execname = ft_basename( argv[0] ); while ( 1 ) { option = ft_getopt( argc, argv, "c:r:i:B" ); if ( option == -1 ) break; switch ( option ) { case 'r': res = atoi( ft_optarg ); if ( res < 1 ) usage( execname ); break; case 'c': num_Faces = atoi( ft_optarg ); if ( num_Faces < 0 ) usage( execname ); break; case 'i': glyph_index = atoi( ft_optarg ); if ( glyph_index < 0 ) usage( execname ); break; case 'B': force_sbit = 1; break; default: usage( execname ); break; } } argc -= ft_optind; argv += ft_optind; if ( argc <= 1 ) usage( execname ); if ( sscanf( argv[0], "%d", &orig_ptsize ) != 1 ) orig_ptsize = 64; file = 1; ptsize = orig_ptsize; i = strlen( argv[file] ); while ( i > 0 && argv[file][i] != '\\' && argv[file][i] != '/' ) { if ( argv[file][i] == '.' ) i = 0; i--; } filename[128] = '\0'; alt_filename[128] = '\0'; strncpy( filename, argv[file], 128 ); strncpy( alt_filename, argv[file], 128 ); if ( i >= 0 ) { strncpy( filename + strlen( filename ), ".ttf", 4 ); strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 ); } /* Initialize engine */ error = TT_Init_FreeType( &engine ); if ( error ) { fprintf( stderr, gettext( "Error while initializing engine.\n" ) ); goto Failure; } error = TT_Init_SBit_Extension( engine ); if ( error ) { fprintf( stderr, gettext( "Error while initializing embedded bitmap extension.\n" ) ); goto Failure; } /* Load face */ error = TT_Open_Face( engine, filename, &face ); if ( error == TT_Err_Could_Not_Open_File ) { strcpy( filename, alt_filename ); error = TT_Open_Face( engine, alt_filename, &face ); } if ( error == TT_Err_Could_Not_Open_File ) Panic( gettext( "Could not find or open %s.\n" ), filename ); if ( error ) { fprintf( stderr, gettext( "Error while opening %s.\n" ), filename ); goto Failure; } TT_Get_Face_Properties( face, &properties ); printf( gettext( "There are %d fonts in this collection.\n" ), (int)(properties.num_Faces) ); if ( num_Faces >= properties.num_Faces ) Panic( gettext( "There is no collection with index %d in this font file.\n" ), num_Faces ); TT_Close_Face( face ); error = TT_Open_Collection( engine, filename, num_Faces, &face ); /* get face properties and eblc */ TT_Get_Face_Properties( face, &properties ); if ( force_sbit ) { error = TT_Get_Face_Bitmaps( face, &eblc ); if ( error == TT_Err_Table_Missing ) Panic( gettext( "There is no embedded bitmap data in the font.\n" ) ); if ( error ) { fprintf( stderr, gettext( "Error while retrieving embedded bitmaps table.\n" ) ); goto Failure; } } /* create glyph */ error = TT_New_Glyph( face, &glyph ); if ( error ) { fprintf( stderr, gettext( "Could not create glyph container.\n" ) ); goto Failure; } /* create instance */ error = TT_New_Instance( face, &instance ); if ( error ) { fprintf( stderr, gettext( "Could not create instance.\n" ) ); goto Failure; } error = TT_Set_Instance_Resolutions( instance, res, res ); if ( error ) { fprintf( stderr, gettext( "Could not set device resolutions.\n" ) ); goto Failure; } error = TT_Set_Instance_CharSize( instance, ptsize*64 ); if ( error ) { fprintf( stderr, gettext( "Could not reset instance.\n" ) ); goto Failure; } TT_Get_Instance_Metrics( instance, &imetrics ); printf( gettext( "Instance metrics: ppemX %d, ppemY %d\n" ), imetrics.x_ppem, imetrics.y_ppem ); if ( force_sbit ) { error = TT_New_SBit_Image( &bitmap ); if ( error ) { fprintf( stderr, gettext( "Could not allocate glyph bitmap container.\n" ) ); goto Failure; } error = TT_Load_Glyph_Bitmap( face, instance, glyph_index, bitmap ); if ( error ) { fprintf( stderr, gettext( "Can't load bitmap for glyph %d.\n" ), glyph_index ); goto Failure; } Show_Metrics( bitmap->metrics, "SBit's metrics" ); printf( "SBit glyph:\n" ); Show_Single_Glyph( &bitmap->map ); } else { TT_Load_Glyph( instance, glyph, glyph_index, load_flags ); TT_Get_Glyph_Big_Metrics( glyph, &metrics ); map.width = ( metrics.bbox.xMax - metrics.bbox.xMin ) / 64; map.rows = ( metrics.bbox.yMax - metrics.bbox.yMin ) / 64; map.cols = ( map.width + 7 ) / 8; map.size = map.cols * map.rows; map.bitmap = malloc( map.size ); map.flow = TT_Flow_Down; memset( map.bitmap, 0, map.size ); error = TT_Get_Glyph_Bitmap( glyph, &map, -metrics.bbox.xMin, -metrics.bbox.yMin ); Show_Metrics( metrics, gettext( "Outline's metrics" ) ); printf( gettext( "Outline glyph\n" ) ); Show_Single_Glyph( &map ); } free( map.bitmap ); if ( bitmap ) TT_Done_SBit_Image( bitmap ); TT_Done_Instance( instance ); TT_Done_Glyph( glyph ); TT_Done_FreeType( engine ); exit( EXIT_SUCCESS ); /* for safety reasons */ return 0; /* never reached */ Failure: fprintf( stderr, " " ); fprintf( stderr, gettext( "FreeType error message: %s\n" ), TT_ErrToString18( error ) ); exit( EXIT_FAILURE ); return 0; /* never reached */ }
int main( int argc, char** argv ) { int i; char filename[128 + 4]; char alt_filename[128 + 4]; char* execname; char* gt; #ifdef HAVE_LIBINTL_H setlocale( LC_ALL, "" ); bindtextdomain( "freetype", LOCALEDIR ); textdomain( "freetype" ); #endif execname = argv[0]; if ( argc != 2 ) { gt = gettext( "ftdump: Simple TrueType Dumper -- part of the FreeType project" ); fprintf( stderr, "%s\n", gt ); separator_line( stderr, strlen( gt ) ); fprintf( stderr, gettext( "Usage: %s fontname[.ttf|.ttc]\n\n" ), execname ); exit( EXIT_FAILURE ); } i = strlen( argv[1] ); while ( i > 0 && argv[1][i] != '\\' ) { if ( argv[1][i] == '.' ) i = 0; i--; } filename[128] = '\0'; alt_filename[128] = '\0'; strncpy( filename, argv[1], 128 ); strncpy( alt_filename, argv[1], 128 ); if ( i >= 0 ) { strncpy( filename + strlen( filename ), ".ttf", 4 ); strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 ); } /* Initialize engine */ old_memory = 0; if ( (error = TT_Init_FreeType( &engine )) ) { fprintf( stderr, gettext( "Error while initializing engine.\n" ) ); goto Failure; } if ( (error = TT_Init_SBit_Extension( engine )) ) { fprintf( stderr, gettext( "Error while initializing embedded bitmap extension.\n" ) ); goto Failure; } if ( (error = TT_Init_GSUB_Extension( engine )) ) { fprintf( stderr, gettext( "Error while initializing GSUB extension.\n" ) ); goto Failure; } FOOTPRINT( initial_overhead ); /* Open and Load face */ error = TT_Open_Face( engine, filename, &face ); if ( error == TT_Err_Could_Not_Open_File ) { strcpy( filename, alt_filename ); error = TT_Open_Face( engine, alt_filename, &face ); } if ( error == TT_Err_Could_Not_Open_File ) Panic( gettext( "Could not find or open %s.\n" ), filename ); if ( error ) { fprintf( stderr, gettext( "Error while opening %s.\n" ), filename ); goto Failure; } FOOTPRINT( face_object ); /* get face properties and allocate preload arrays */ TT_Get_Face_Properties( face, &properties ); num_glyphs = properties.num_Glyphs; /* Now do various dumps */ if ( flag_names ) Print_Names(); if ( flag_encodings ) Print_Encodings(); if ( flag_cmap ) Print_Cmap(); if ( flag_sbits ) Print_SBits(); if ( flag_ttopen ) Print_GSUB(); #ifndef FREETYPE_DLL /* the statistics are meaningless if we use a DLL. */ if ( flag_memory ) Print_Memory(); #endif TT_Close_Face( face ); TT_Done_FreeType( engine ); exit( EXIT_SUCCESS ); /* for safety reasons */ return 0; /* never reached */ Failure: fprintf( stderr, " " ); Panic( gettext( "FreeType error message: %s\n" ), TT_ErrToString18( error ) ); return 0; /* never reached */ }
void readttf(Font *fnt, Boolean quiet, Boolean only_range) { TT_Error error; ttfinfo *ti, *Ti; long Num, index; unsigned int i, j; long k, max_k; unsigned short num_cmap; unsigned short cmap_plat, cmap_enc; int index_array[257]; static Boolean initialized = False; TT_UShort in_string[2]; TTO_GSUB_String in, out; TT_UShort script_index, language_index, feature_index; TT_UShort req_feature_index = 0xFFFF; /* * We allocate a placeholder boundary and the `.notdef' character. */ if (!only_range) { ti = newchar(fnt); ti->charcode = -1; ti->adobename = ".notdef"; ti = newchar(fnt); ti->charcode = -1; ti->adobename = "||"; /* boundary character name */ } /* * Initialize FreeType engine. */ if (!initialized) { if ((error = TT_Init_FreeType(&engine))) oops("Cannot initialize engine (error code = 0x%x).", error); if ((error = TT_Init_Kerning_Extension(engine))) oops("Cannot initialize kerning (error code = 0x%x).", error); if (fnt->PSnames) if ((error = TT_Init_Post_Extension(engine))) oops("Cannot initialize PS name support (error code = 0x%x).", error); if (fnt->rotate) if ((error = TT_Init_GSUB_Extension(engine))) oops("Cannot initialize GSUB support (error code = 0x%x).", error); /* * Load face. */ real_ttfname = TeX_search_ttf_file(&(fnt->ttfname)); if (!real_ttfname) oops("Cannot find `%s'.", fnt->ttfname); if ((error = TT_Open_Face(engine, real_ttfname, &face))) oops("Cannot open `%s'.", real_ttfname); /* * Get face properties and allocate preload arrays. */ TT_Get_Face_Properties(face, &properties); /* * Now we try to open the proper font in a collection. */ if (fnt->fontindex != 0) { if (properties.num_Faces == 1) { warning("This isn't a TrueType collection.\n" "Parameter `-f' is ignored."); fnt->fontindex = 0; fnt->fontindexparam = NULL; } else { TT_Close_Face(face); if ((error = TT_Open_Collection(engine, real_ttfname, fnt->fontindex, &face))) oops("Cannot open font %lu in TrueType Collection `%s'.", fnt->fontindex, real_ttfname); } } /* * Create instance. */ if ((error = TT_New_Instance(face, &instance))) oops("Cannot create instance for `%s' (error code = 0x%x).", real_ttfname, error); /* * We use a dummy glyph size of 10pt. */ if ((error = TT_Set_Instance_CharSize(instance, 10 * 64))) oops("Cannot set character size (error code = 0x%x).", error); matrix1.xx = (TT_Fixed)(floor(fnt->efactor * 1024) * (1L<<16)/1024); matrix1.xy = (TT_Fixed)(floor(fnt->slant * 1024) * (1L<<16)/1024); matrix1.yx = (TT_Fixed)0; matrix1.yy = (TT_Fixed)(1L<<16); if (fnt->rotate) { matrix2.xx = 0; matrix2.yx = 1L << 16; matrix2.xy = -matrix2.yx; matrix2.yy = matrix2.xx; } if ((error = TT_Set_Instance_Transform_Flags( instance, fnt->rotate ? 1 : 0, fnt->efactor != 1.0 ? 1 : 0))) oops("Cannot set transform flags (error code = 0x%x).", error); /* * Create glyph container. */ if ((error = TT_New_Glyph(face, &glyph))) oops("Cannot create glyph container (error code = 0x%x).", error); fnt->units_per_em = properties.header->Units_Per_EM; fnt->fixedpitch = properties.postscript->isFixedPitch; fnt->italicangle = properties.postscript->italicAngle / 65536.0; if (fnt->PSnames != Only) { num_cmap = properties.num_CharMaps; for (i = 0; i < num_cmap; i++) { if ((error = TT_Get_CharMap_ID(face, i, &cmap_plat, &cmap_enc))) oops("Cannot query cmap (error code = 0x%x).", error); if (cmap_plat == fnt->pid && cmap_enc == fnt->eid) break; } if (i == num_cmap) { fprintf(stderr, "%s: ERROR: Invalid platform and/or encoding ID.\n", progname); if (num_cmap == 1) fprintf(stderr, " The only valid PID/EID pair is"); else fprintf(stderr, " Valid PID/EID pairs are:\n"); for (i = 0; i < num_cmap; i++) { TT_Get_CharMap_ID(face, i, &cmap_plat, &cmap_enc); fprintf(stderr, " (%i,%i)\n", cmap_plat, cmap_enc); } fprintf(stderr, "\n"); exit(1); } if ((error = TT_Get_CharMap(face, i, &char_map))) oops("Cannot load cmap (error code = 0x%x).", error); } if (fnt->PSnames) { if ((error = TT_Load_PS_Names(face, &post))) oops("Cannot load TrueType PS names (error code = 0x%x).", error); } else if (cmap_plat == Microsoft_platform && cmap_enc == Microsoft_Unicode_encoding) set_encoding_scheme(encUnicode, fnt); else if (cmap_plat == Macintosh_platform && cmap_enc == Macintosh_encoding) set_encoding_scheme(encMac, fnt); else set_encoding_scheme(encFontSpecific, fnt); if (fnt->rotate) { gsub = &gsub_; error = TT_Load_GSUB_Table(face, gsub, NULL); if (!error) has_gsub = True; else if (error != TT_Err_Table_Missing) warning("Cannot load GSUB table (error code = 0x%x).", error); else warning("No GSUB data available " "for vertical glyph presentation forms."); /* we check for the `vert' feature in Chinese, Japanese, and Korean */ error = TT_GSUB_Select_Script(gsub, SCRIPT_kana, &script_index); if (error) goto check_hani; error = TT_GSUB_Select_Feature(gsub, FEATURE_vert, script_index, 0xFFFF, &feature_index); if (error) { error = TT_GSUB_Select_Language(gsub, LANGUAGE_JAN, script_index, &language_index, &req_feature_index); if (error) goto check_hani; error = TT_GSUB_Select_Feature(gsub, FEATURE_vert, script_index, language_index, &feature_index); if (error) goto check_hani; else goto Done; } else goto Done; check_hani: error = TT_GSUB_Select_Script(gsub, SCRIPT_hani, &script_index); if (error) goto check_hang; error = TT_GSUB_Select_Feature(gsub, FEATURE_vert, script_index, 0xFFFF, &feature_index); if (error) { error = TT_GSUB_Select_Language(gsub, LANGUAGE_CHN, script_index, &language_index, &req_feature_index); if (error) goto check_hang; error = TT_GSUB_Select_Feature(gsub, FEATURE_vert, script_index, language_index, &feature_index); if (error) goto check_hang; else goto Done; } else goto Done; check_hang: error = TT_GSUB_Select_Script(gsub, SCRIPT_hang, &script_index); if (error) goto Done; error = TT_GSUB_Select_Feature(gsub, FEATURE_vert, script_index, 0xFFFF, &feature_index); if (error) { error = TT_GSUB_Select_Language(gsub, LANGUAGE_KOR, script_index, &language_index, &req_feature_index); if (error) goto Done; error = TT_GSUB_Select_Feature(gsub, FEATURE_vert, script_index, language_index, &feature_index); } Done: if (error) { warning("There is no data for vertical typesetting in GSUB table."); has_gsub = False; } if (req_feature_index != 0xFFFF) TT_GSUB_Add_Feature(gsub, req_feature_index, ALL_GLYPHS); TT_GSUB_Add_Feature(gsub, feature_index, ALL_GLYPHS); in.length = 1; in.pos = 0; in.string = in_string; in.properties = NULL; out.pos = 0; out.allocated = 0; out.string = NULL; out.properties = NULL; } initialized = True; } if (!quiet) { if (only_range) printf("\n\n%s:\n", fnt->fullname); printf("\n"); printf("Glyph Code Glyph Name "); printf("Width llx lly urx ury\n"); printf("---------------------------------------"); printf("---------------------------------\n"); } /* * We load only glyphs with a valid cmap entry. Nevertheless, for * the default mapping, we use the first 256 glyphs addressed by * ascending code points, followed by glyphs not in the cmap. * * If we compute a range, we take the character codes given in * the fnt->sf_code array. * * If the -N flag is set, no cmap is used at all. Instead, the * first 256 glyphs (with a valid PS name) are used for the default * mapping. */ if (!only_range) for (i = 0; i < 257; i++) index_array[i] = 0; else for (i = 0; i < 256; i++) fnt->inencptrs[i] = 0; j = 0; if (fnt->PSnames == Only) max_k = properties.num_Glyphs - 1; else max_k = only_range ? 0xFF : 0x16FFFF; for (k = 0; k <= max_k; k++) { char *an; if (fnt->PSnames != Only) { if (only_range) { index = fnt->sf_code[k]; if (index < 0) continue; j = k; } else index = k; Num = TT_Char_Index(char_map, index); /* now we try to get a vertical glyph form */ if (has_gsub) { in_string[0] = Num; error = TT_GSUB_Apply_String(gsub, &in, &out); if (error && error != TTO_Err_Not_Covered) warning("Cannot get the vertical glyph form for glyph index %d.", Num); else Num = out.string[0]; } if (Num < 0) oops("Failure on cmap mapping from %s.", fnt->ttfname); if (Num == 0) continue; if (!only_range) if (Num <= 256) index_array[Num] = 1; } else { Num = k; index = 0; } error = TT_Load_Glyph(instance, glyph, Num, 0); if (!error) error = TT_Get_Glyph_Big_Metrics(glyph, &metrics); if (!error) error = TT_Get_Glyph_Outline(glyph, &outline); if (!error) { if (fnt->efactor != 1.0 || fnt->slant != 0.0 ) TT_Transform_Outline(&outline, &matrix1); if (fnt->rotate) TT_Transform_Outline(&outline, &matrix2); } if (!error) error = TT_Get_Outline_BBox(&outline, &bbox); /* we need the non- grid-fitted bbox */ if (!error) { if (fnt->PSnames) (void)TT_Get_PS_Name(face, Num, &an); else an = code_to_adobename(index); /* ignore characters not usable for typesetting with TeX */ if (strcmp(an, ".notdef") == 0) continue; if (strcmp(an, ".null") == 0) continue; if (strcmp(an, "nonmarkingreturn") == 0) continue; ti = newchar(fnt); ti->charcode = index; ti->glyphindex = Num; ti->adobename = an; ti->llx = bbox.xMin * 1000 / fnt->units_per_em; ti->lly = bbox.yMin * 1000 / fnt->units_per_em; ti->urx = bbox.xMax * 1000 / fnt->units_per_em; ti->ury = bbox.yMax * 1000 / fnt->units_per_em; /* * We must now shift the rotated character both horizontally * and vertically. The vertical amount is 25% by default. */ if (fnt->rotate) { ti->llx += (metrics.vertBearingY - bbox.xMin) * 1000 / fnt->units_per_em; ti->lly -= 1000 * fnt->y_offset; ti->urx += (metrics.vertBearingY - bbox.xMin) * 1000 / fnt->units_per_em; ti->ury -= 1000 * fnt->y_offset; } /* * We need to avoid negative heights or depths. They break accents * in math mode, among other things. */ if (ti->lly > 0) ti->lly = 0; if (ti->ury < 0) ti->ury = 0; if (fnt->rotate) ti->width = metrics.vertAdvance * 1000 / fnt->units_per_em; else ti->width = transform(metrics.horiAdvance * 1000 / fnt->units_per_em, 0, fnt->efactor, fnt->slant); if (!quiet) printf("%5ld %05lx %-25s %5d % 5d,% 5d -- % 5d,% 5d\n", Num, index, ti->adobename, ti->width, ti->llx, ti->lly, ti->urx, ti->ury); if (j < 256) { fnt->inencptrs[j] = ti; ti->incode = j; } j++; } } /* * Now we load glyphs without a cmap entry, provided some slots are * still free -- we skip this if we have to compute a range or use * PS names. */ if (!only_range && !fnt->PSnames) { for (i = 1; i <= properties.num_Glyphs; i++) { char *an; if (index_array[i] == 0) { error = TT_Load_Glyph(instance, glyph, i, 0); if (!error) error = TT_Get_Glyph_Big_Metrics(glyph, &metrics); if (!error) error = TT_Get_Glyph_Outline(glyph, &outline); if (!error) error = TT_Get_Outline_BBox(&outline, &bbox); if (!error) { an = code_to_adobename(i | 0x1000000); ti = newchar(fnt); ti->charcode = i | 0x1000000; ti->glyphindex = i; ti->adobename = an; ti->llx = bbox.xMin * 1000 / fnt->units_per_em; ti->lly = bbox.yMin * 1000 / fnt->units_per_em; ti->urx = bbox.xMax * 1000 / fnt->units_per_em; ti->ury = bbox.yMax * 1000 / fnt->units_per_em; if (ti->lly > 0) ti->lly = 0; if (ti->ury < 0) ti->ury = 0; ti->width = transform(metrics.horiAdvance*1000 / fnt->units_per_em, 0, fnt->efactor, fnt->slant); if (!quiet) printf("%5d %-25s %5d % 5d,% 5d -- % 5d,% 5d\n", i, ti->adobename, ti->width, ti->llx, ti->lly, ti->urx, ti->ury); if (j < 256) { fnt->inencptrs[j] = ti; ti->incode = j; } else break; j++; } } } } /* Finally, we construct a `Germandbls' glyph if necessary */ if (!only_range) { if (NULL == findadobe("Germandbls", fnt->charlist) && NULL != (Ti = findadobe("S", fnt->charlist))) { pcc *np, *nq; ti = newchar(fnt); ti->charcode = properties.num_Glyphs | 0x1000000; ti->glyphindex = properties.num_Glyphs; ti->adobename = "Germandbls"; ti->width = Ti->width << 1; ti->llx = Ti->llx; ti->lly = Ti->lly; ti->urx = Ti->width + Ti->urx; ti->ury = Ti->ury; ti->kerns = Ti->kerns; np = newpcc(); np->partname = "S"; nq = newpcc(); nq->partname = "S"; nq->xoffset = Ti->width; np->next = nq; ti->pccs = np; ti->constructed = True; if (!quiet) printf("* %-25s %5d % 5d,% 5d -- % 5d,% 5d\n", ti->adobename, ti->width, ti->llx, ti->lly, ti->urx, ti->ury); } } /* kerning between subfonts isn't available */ if (!only_range) readttf_kern(fnt); }
static void image_ttf_face_properties(INT32 args) { int res; TT_Face_Properties prop; pop_n_elems(args); res=TT_Get_Face_Properties(THISf->face,&prop); if (res) my_tt_error("Image.TTF.Face->properties()","",res); push_text("num_Glyphs"); push_int(prop.num_Glyphs); push_text("max_Points"); push_int(prop.max_Points); push_text("max_Contours"); push_int(prop.max_Contours); push_text("num_Faces"); push_int(prop.num_Faces); push_text("header"); if (prop.header) { push_text("Table_Version"); push_int(prop.header->Table_Version); push_text("Font_Revision"); push_int(prop.header->Font_Revision); push_text("CheckSum_Adjust"); push_int(prop.header->CheckSum_Adjust); push_text("Magic_Number"); push_int(prop.header->Magic_Number); push_text("Flags"); push_int(prop.header->Flags); push_text("Units_Per_EM"); push_int(prop.header->Units_Per_EM); push_text("Created"); push_int(prop.header->Created[0]); push_int(prop.header->Created[1]); f_aggregate(2); push_text("Modified"); push_int(prop.header->Modified[0]); push_int(prop.header->Modified[1]); f_aggregate(2); push_text("xMin"); push_int(prop.header->xMin); push_text("yMin"); push_int(prop.header->yMin); push_text("xMax"); push_int(prop.header->xMax); push_text("yMax"); push_int(prop.header->yMax); push_text("Mac_Style"); push_int(prop.header->Mac_Style); push_text("Lowest_Rec_PPEM"); push_int(prop.header->Lowest_Rec_PPEM); push_text("Font_Direction"); push_int(prop.header->Font_Direction); push_text("Index_To_Loc_Format"); push_int(prop.header->Index_To_Loc_Format); push_text("Glyph_Data_Format"); push_int(prop.header->Glyph_Data_Format); f_aggregate_mapping(17*2); } else push_int(0); push_text("horizontal"); if (prop.horizontal) { push_text("Version"); push_int(prop.horizontal->Version); push_text("Ascender"); push_int(prop.horizontal->Ascender); push_text("Descender"); push_int(prop.horizontal->Descender); push_text("Line_Gap"); push_int(prop.horizontal->Line_Gap); push_text("advance_Width_Max"); push_int(prop.horizontal->advance_Width_Max); push_text("min_Left_Side_Bearing"); push_int(prop.horizontal->min_Left_Side_Bearing); push_text("min_Right_Side_Bearing"); push_int(prop.horizontal->min_Right_Side_Bearing); push_text("xMax_Extent"); push_int(prop.horizontal->xMax_Extent); push_text("caret_Slope_Rise"); push_int(prop.horizontal->caret_Slope_Rise); push_text("caret_Slope_Run"); push_int(prop.horizontal->caret_Slope_Run); push_text("metric_Data_Format"); push_int(prop.horizontal->metric_Data_Format); push_text("number_Of_HMetrics"); push_int(prop.horizontal->number_Of_HMetrics); f_aggregate_mapping(13*2); } else push_int(0); push_text("os2"); if (prop.os2) { push_text("version"); push_int(prop.os2->version); push_text("xAvgCharWidth"); push_int(prop.os2->xAvgCharWidth); push_text("usWeightClass"); push_int(prop.os2->usWeightClass); push_text("usWidthClass"); push_int(prop.os2->usWidthClass); push_text("fsType"); push_int(prop.os2->fsType); push_text("ySubscriptXSize"); push_int(prop.os2->ySubscriptXSize); push_text("ySubscriptYSize"); push_int(prop.os2->ySubscriptYSize); push_text("ySubscriptXOffset"); push_int(prop.os2->ySubscriptXOffset); push_text("ySubscriptYOffset"); push_int(prop.os2->ySubscriptYOffset); push_text("ySuperscriptXSize"); push_int(prop.os2->ySuperscriptXSize); push_text("ySuperscriptYSize"); push_int(prop.os2->ySuperscriptYSize); push_text("ySuperscriptXOffset"); push_int(prop.os2->ySuperscriptXOffset); push_text("ySuperscriptYOffset"); push_int(prop.os2->ySuperscriptYOffset); push_text("yStrikeoutSize"); push_int(prop.os2->yStrikeoutSize); push_text("yStrikeoutPosition"); push_int(prop.os2->yStrikeoutPosition); push_text("sFamilyClass"); push_int(prop.os2->sFamilyClass); push_text("panose"); push_string(make_shared_binary_string(prop.os2->panose,10)); push_text("ulUnicodeRange1"); push_int(prop.os2->ulUnicodeRange1); push_text("ulUnicodeRange2"); push_int(prop.os2->ulUnicodeRange2); push_text("ulUnicodeRange3"); push_int(prop.os2->ulUnicodeRange3); push_text("ulUnicodeRange4"); push_int(prop.os2->ulUnicodeRange4); push_text("achVendID"); push_string(make_shared_binary_string(prop.os2->achVendID,4)); push_text("fsSelection"); push_int(prop.os2->fsSelection); push_text("usFirstCharIndex"); push_int(prop.os2->usFirstCharIndex); push_text("usLastCharIndex"); push_int(prop.os2->usLastCharIndex); push_text("sTypoAscender"); push_int(prop.os2->sTypoAscender); push_text("sTypoDescender"); push_int(prop.os2->sTypoDescender); push_text("sTypoLineGap"); push_int(prop.os2->sTypoLineGap); push_text("usWinAscent"); push_int(prop.os2->usWinAscent); push_text("usWinDescent"); push_int(prop.os2->usWinDescent); push_text("ulCodePageRange1"); push_int(prop.os2->ulCodePageRange1); push_text("ulCodePageRange2"); push_int(prop.os2->ulCodePageRange2); f_aggregate_mapping(32*2); } else push_int(0); push_text("postscript"); if (prop.postscript) { push_text("FormatType"); push_int(prop.postscript->FormatType); push_text("italicAngle"); push_int(prop.postscript->italicAngle); push_text("underlinePosition"); push_int(prop.postscript->underlinePosition); push_text("underlineThickness"); push_int(prop.postscript->underlineThickness); push_text("isFixedPitch"); push_int(prop.postscript->isFixedPitch); push_text("minMemType42"); push_int(prop.postscript->minMemType42); push_text("maxMemType42"); push_int(prop.postscript->maxMemType42); push_text("minMemType1"); push_int(prop.postscript->minMemType1); push_text("maxMemType1"); push_int(prop.postscript->maxMemType1); f_aggregate_mapping(9*2); } else push_int(0); push_text("hdmx"); if (prop.hdmx) { int i; push_text("version"); push_int(prop.hdmx->version); push_text("num_records"); push_int(prop.hdmx->num_records); push_text("records"); for (i=0; i<prop.hdmx->num_records; i++) { push_text("ppem"); push_int(prop.hdmx->records[i].ppem); push_text("max_width"); push_int(prop.hdmx->records[i].max_width); /* push_text("widths"); push_int(prop.hdmx->records[i].widths);*/ f_aggregate_mapping(2*2); } f_aggregate(prop.hdmx->num_records); f_aggregate_mapping(3*2); } else push_int(0); f_aggregate_mapping(9*2); }
TT_Fonthandle* i_tt_new(const char *fontname) { TT_Error error; TT_Fonthandle *handle; unsigned short i,n; unsigned short platform,encoding; i_tt_engine *tteng; if ((tteng = i_init_tt()) == NULL) { i_push_error(0, "Could not initialize FT1 engine"); return NULL; } i_clear_error(); mm_log((1,"i_tt_new(fontname '%s')\n",fontname)); /* allocate memory for the structure */ handle = mymalloc( sizeof(TT_Fonthandle) ); /* checked 5Nov05 tonyc */ /* load the typeface */ error = TT_Open_Face( tteng->engine, fontname, &handle->face ); if ( error ) { myfree(handle); if ( error == TT_Err_Could_Not_Open_File ) { mm_log((1, "Could not find/open %s.\n", fontname )); } else { mm_log((1, "Error while opening %s, error code = 0x%x.\n",fontname, (unsigned)error )); } i_tt_push_error(error); return NULL; } TT_Get_Face_Properties( handle->face, &(handle->properties) ); /* First, look for a Unicode charmap */ n = handle->properties.num_CharMaps; USTRCT( handle->char_map )=NULL; /* Invalidate character map */ for ( i = 0; i < n; i++ ) { TT_Get_CharMap_ID( handle->face, i, &platform, &encoding ); if ( (platform == 3 && encoding == 1 ) || (platform == 0 && encoding == 0 ) ) { mm_log((2,"i_tt_new - found char map platform %u encoding %u\n", platform, encoding)); TT_Get_CharMap( handle->face, i, &(handle->char_map) ); break; } } if (!USTRCT(handle->char_map) && n != 0) { /* just use the first one */ TT_Get_CharMap( handle->face, 0, &(handle->char_map)); } /* Zero the pointsizes - and ordering */ for(i=0;i<TT_CHC;i++) { USTRCT(handle->instanceh[i].instance)=NULL; handle->instanceh[i].order=i; handle->instanceh[i].ptsize=0; handle->instanceh[i].smooth=-1; } #ifdef FTXPOST handle->loaded_names = 0; #endif mm_log((1,"i_tt_new <- %p\n",handle)); return handle; }
/* =item i_tt_face_name(handle, name_buf, name_buf_size) Retrieve's the font's postscript name. This is complicated by the need to handle encodings and so on. =cut */ size_t i_tt_face_name(TT_Fonthandle *handle, char *name_buf, size_t name_buf_size) { TT_Face_Properties props; int name_count; int i; TT_UShort platform_id, encoding_id, lang_id, name_id; TT_UShort name_len; TT_String *name; int want_index = -1; /* an acceptable but not perfect name */ int score = 0; i_clear_error(); TT_Get_Face_Properties(handle->face, &props); name_count = props.num_Names; for (i = 0; i < name_count; ++i) { TT_Get_Name_ID(handle->face, i, &platform_id, &encoding_id, &lang_id, &name_id); TT_Get_Name_String(handle->face, i, &name, &name_len); if (platform_id != TT_PLATFORM_APPLE_UNICODE && name_len && name_id == TT_NAME_ID_PS_NAME) { int might_want_index = -1; int might_score = 0; if ((platform_id == TT_PLATFORM_MACINTOSH && encoding_id == TT_MAC_ID_ROMAN) || (platform_id == TT_PLATFORM_MICROSOFT && encoding_id == TT_MS_LANGID_ENGLISH_UNITED_STATES)) { /* exactly what we want */ want_index = i; break; } if (platform_id == TT_PLATFORM_MICROSOFT && (encoding_id & 0xFF) == TT_MS_LANGID_ENGLISH_GENERAL) { /* any english is good */ might_want_index = i; might_score = 9; } /* there might be something in between */ else { /* anything non-unicode is better than nothing */ might_want_index = i; might_score = 1; } if (might_score > score) { score = might_score; want_index = might_want_index; } } } if (want_index != -1) { TT_Get_Name_String(handle->face, want_index, &name, &name_len); strncpy(name_buf, name, name_buf_size); name_buf[name_buf_size-1] = '\0'; return strlen(name) + 1; } else { i_push_error(0, "no face name present"); return 0; } }