1 /****************************************************************************/ 2 /* */ 3 /* The FreeType project -- a free and portable quality TrueType renderer. */ 4 /* */ 5 /* Copyright 1999 by */ 6 /* Yamano'uchi H. and W. Lemberg */ 7 /* */ 8 /* ftmetric: dump metrics and a glyph. */ 9 /* */ 10 /* NOTE: This is just a test program that is used to debug */ 11 /* the current engine. */ 12 /* */ 13 /****************************************************************************/ 14 15 #include <stdio.h> 16 #include <stdlib.h> 17 #include <string.h> 18 19 #include "common.h" 20 #include "freetype.h" 21 #include "ftxsbit.h" 22 23 /* 24 * Basically, an external program using FreeType shouldn't depend on an 25 * internal file of the FreeType library, especially not on ft_conf.h -- but 26 * to avoid another configure script which tests for the existence of the 27 * i18n stuff we include ft_conf.h here since we can be sure that our test 28 * programs use the same configuration options as the library itself. 29 */ 30 31 #include "ft_conf.h" 32 33 34 #ifdef HAVE_LIBINTL_H 35 36 #ifdef HAVE_LOCALE_H 37 #include <locale.h> 38 #endif 39 40 #include <libintl.h> 41 #include "ftxerr18.h" 42 43 #else /* !HAVE_LIBINTL */ 44 45 #define gettext( x ) ( x ) 46 47 /* We ignore error message strings with this function */ 48 49 static char* TT_ErrToString18(TT_Error error)50 TT_ErrToString18( TT_Error error ) 51 { 52 static char temp[32]; 53 54 55 sprintf( temp, "0x%04lx", error ); 56 return temp; 57 } 58 59 #endif /* !HAVE_LIBINTL */ 60 61 static void usage(char * execname)62 usage( char* execname ) 63 { 64 char* gt; 65 66 67 fprintf( stderr, "\n" ); 68 gt = gettext( "ftmetric: Simple TTF metrics/glyph dumper -- part of the FreeType project" ); 69 fprintf( stderr, "%s\n", gt ); 70 separator_line( stderr, strlen( gt ) ); 71 fprintf( stderr, gettext( 72 "Usage: %s [options below] point fontname[.ttf|.ttc]\n" 73 "\n" 74 " -B show sbit's metrics (default: none)\n" 75 " -c C use C'th font index of TrueType collection (default: 0)\n" 76 " -i index glyph index (default: 0)\n" 77 " -r R use resolution R dpi (default: 72)\n" 78 "\n" ), execname ); 79 80 exit( EXIT_FAILURE ); 81 } 82 83 84 static void Show_Metrics(TT_Big_Glyph_Metrics metrics,char * title)85 Show_Metrics( TT_Big_Glyph_Metrics metrics, 86 char* title ) 87 { 88 int show_advance = 1; 89 90 91 printf("%s: xMin %d, xMax %d, yMin %d, yMax %d", 92 title, 93 (int)(metrics.bbox.xMin / 64), 94 (int)(metrics.bbox.xMax / 64), 95 (int)(metrics.bbox.yMin / 64), 96 (int)(metrics.bbox.yMax / 64)); 97 98 99 if ( show_advance ) 100 printf( ", advance width %d", (int)(metrics.horiAdvance / 64) ); 101 102 printf("\n"); 103 return; 104 } 105 106 107 int main(int argc,char ** argv)108 main( int argc, char** argv ) 109 { 110 int i, orig_ptsize, file; 111 char filename[128 + 4]; 112 char alt_filename[128 + 4]; 113 char* execname; 114 int option; 115 116 int ptsize; 117 int num_Faces = 0; 118 int glyph_index = 0; 119 int load_flags = TTLOAD_DEFAULT; 120 121 int force_sbit = 0; 122 123 TT_Engine engine; 124 125 TT_Face face; 126 TT_Instance instance; 127 TT_Glyph glyph; 128 129 TT_Raster_Map map; 130 131 TT_Big_Glyph_Metrics metrics; 132 TT_Face_Properties properties; 133 TT_Instance_Metrics imetrics; 134 135 TT_EBLC eblc; 136 TT_SBit_Image* bitmap = NULL; 137 138 TT_Error error; 139 140 141 int res = 72; 142 143 #ifdef HAVE_LIBINTL_H 144 setlocale( LC_ALL, "" ); 145 bindtextdomain( "freetype", LOCALEDIR ); 146 textdomain( "freetype" ); 147 #endif 148 149 execname = ft_basename( argv[0] ); 150 151 while ( 1 ) 152 { 153 option = ft_getopt( argc, argv, "c:r:i:B" ); 154 155 if ( option == -1 ) 156 break; 157 158 switch ( option ) 159 { 160 case 'r': 161 res = atoi( ft_optarg ); 162 if ( res < 1 ) 163 usage( execname ); 164 break; 165 166 case 'c': 167 num_Faces = atoi( ft_optarg ); 168 if ( num_Faces < 0 ) 169 usage( execname ); 170 break; 171 172 case 'i': 173 glyph_index = atoi( ft_optarg ); 174 if ( glyph_index < 0 ) 175 usage( execname ); 176 break; 177 178 case 'B': 179 force_sbit = 1; 180 break; 181 182 default: 183 usage( execname ); 184 break; 185 } 186 } 187 188 argc -= ft_optind; 189 argv += ft_optind; 190 191 if ( argc <= 1 ) 192 usage( execname ); 193 194 if ( sscanf( argv[0], "%d", &orig_ptsize ) != 1 ) 195 orig_ptsize = 64; 196 197 file = 1; 198 199 ptsize = orig_ptsize; 200 201 i = strlen( argv[file] ); 202 while ( i > 0 && argv[file][i] != '\\' && argv[file][i] != '/' ) 203 { 204 if ( argv[file][i] == '.' ) 205 i = 0; 206 i--; 207 } 208 209 filename[128] = '\0'; 210 alt_filename[128] = '\0'; 211 212 strncpy( filename, argv[file], 128 ); 213 strncpy( alt_filename, argv[file], 128 ); 214 215 if ( i >= 0 ) 216 { 217 strncpy( filename + strlen( filename ), ".ttf", 4 ); 218 strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 ); 219 } 220 221 /* Initialize engine */ 222 223 error = TT_Init_FreeType( &engine ); 224 if ( error ) 225 { 226 fprintf( stderr, gettext( "Error while initializing engine.\n" ) ); 227 goto Failure; 228 } 229 230 error = TT_Init_SBit_Extension( engine ); 231 if ( error ) 232 { 233 fprintf( stderr, gettext( 234 "Error while initializing embedded bitmap extension.\n" ) ); 235 goto Failure; 236 } 237 238 /* Load face */ 239 240 error = TT_Open_Face( engine, filename, &face ); 241 242 if ( error == TT_Err_Could_Not_Open_File ) 243 { 244 strcpy( filename, alt_filename ); 245 error = TT_Open_Face( engine, alt_filename, &face ); 246 } 247 248 if ( error == TT_Err_Could_Not_Open_File ) 249 Panic( gettext( "Could not find or open %s.\n" ), filename ); 250 if ( error ) 251 { 252 fprintf( stderr, gettext( "Error while opening %s.\n" ), 253 filename ); 254 goto Failure; 255 } 256 257 TT_Get_Face_Properties( face, &properties ); 258 259 printf( gettext( "There are %d fonts in this collection.\n" ), 260 (int)(properties.num_Faces) ); 261 262 if ( num_Faces >= properties.num_Faces ) 263 Panic( gettext( 264 "There is no collection with index %d in this font file.\n" ), 265 num_Faces ); 266 267 TT_Close_Face( face ); 268 269 error = TT_Open_Collection( engine, filename, num_Faces, &face ); 270 271 /* get face properties and eblc */ 272 273 TT_Get_Face_Properties( face, &properties ); 274 if ( force_sbit ) 275 { 276 error = TT_Get_Face_Bitmaps( face, &eblc ); 277 if ( error == TT_Err_Table_Missing ) 278 Panic( gettext( "There is no embedded bitmap data in the font.\n" ) ); 279 if ( error ) 280 { 281 fprintf( stderr, gettext( 282 "Error while retrieving embedded bitmaps table.\n" ) ); 283 goto Failure; 284 } 285 } 286 287 /* create glyph */ 288 289 error = TT_New_Glyph( face, &glyph ); 290 if ( error ) 291 { 292 fprintf( stderr, gettext( "Could not create glyph container.\n" ) ); 293 goto Failure; 294 } 295 296 /* create instance */ 297 298 error = TT_New_Instance( face, &instance ); 299 if ( error ) 300 { 301 fprintf( stderr, gettext( "Could not create instance.\n" ) ); 302 goto Failure; 303 } 304 305 error = TT_Set_Instance_Resolutions( instance, res, res ); 306 if ( error ) 307 { 308 fprintf( stderr, gettext( "Could not set device resolutions.\n" ) ); 309 goto Failure; 310 } 311 312 error = TT_Set_Instance_CharSize( instance, ptsize*64 ); 313 if ( error ) 314 { 315 fprintf( stderr, gettext( "Could not reset instance.\n" ) ); 316 goto Failure; 317 } 318 319 TT_Get_Instance_Metrics( instance, &imetrics ); 320 321 printf( gettext( "Instance metrics: ppemX %d, ppemY %d\n" ), 322 imetrics.x_ppem, 323 imetrics.y_ppem ); 324 325 if ( force_sbit ) 326 { 327 error = TT_New_SBit_Image( &bitmap ); 328 if ( error ) 329 { 330 fprintf( stderr, gettext( 331 "Could not allocate glyph bitmap container.\n" ) ); 332 goto Failure; 333 } 334 335 error = TT_Load_Glyph_Bitmap( face, instance, glyph_index, bitmap ); 336 if ( error ) 337 { 338 fprintf( stderr, gettext( 339 "Can't load bitmap for glyph %d.\n" ), glyph_index ); 340 goto Failure; 341 } 342 343 Show_Metrics( bitmap->metrics, "SBit's metrics" ); 344 345 printf( "SBit glyph:\n" ); 346 Show_Single_Glyph( &bitmap->map ); 347 } 348 else 349 { 350 TT_Load_Glyph( instance, glyph, glyph_index, load_flags ); 351 TT_Get_Glyph_Big_Metrics( glyph, &metrics ); 352 353 map.width = ( metrics.bbox.xMax - metrics.bbox.xMin ) / 64; 354 map.rows = ( metrics.bbox.yMax - metrics.bbox.yMin ) / 64; 355 map.cols = ( map.width + 7 ) / 8; 356 map.size = map.cols * map.rows; 357 map.bitmap = malloc( map.size ); 358 map.flow = TT_Flow_Down; 359 360 memset( map.bitmap, 0, map.size ); 361 362 error = TT_Get_Glyph_Bitmap( glyph, &map, 363 -metrics.bbox.xMin, 364 -metrics.bbox.yMin ); 365 366 Show_Metrics( metrics, gettext( "Outline's metrics" ) ); 367 368 printf( gettext( "Outline glyph\n" ) ); 369 Show_Single_Glyph( &map ); 370 } 371 372 free( map.bitmap ); 373 374 if ( bitmap ) 375 TT_Done_SBit_Image( bitmap ); 376 377 TT_Done_Instance( instance ); 378 TT_Done_Glyph( glyph ); 379 TT_Done_FreeType( engine ); 380 381 exit( EXIT_SUCCESS ); /* for safety reasons */ 382 383 return 0; /* never reached */ 384 385 Failure: 386 fprintf( stderr, " " ); 387 fprintf( stderr, gettext( "FreeType error message: %s\n" ), 388 TT_ErrToString18( error ) ); 389 390 exit( EXIT_FAILURE ); 391 392 return 0; /* never reached */ 393 } 394 395 396 /* End */ 397