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