contrib/OWB: add correct SDL dependency, fix compilers used
[AROS-Contrib.git] / freetype1 / test / ftdump.c
blob655aab4038182e4b479e2549c470495c19df7b08
1 /****************************************************************************/
2 /* */
3 /* The FreeType project -- a free and portable quality TrueType renderer. */
4 /* */
5 /* Copyright 1996-1999 by */
6 /* D. Turner, R.Wilhelm, and W. Lemberg */
7 /* */
8 /* ftdump: Simple TrueType font file resource profiler. */
9 /* */
10 /* This program dumps various properties of a given font file. */
11 /* */
12 /* */
13 /* */
14 /* NOTE: This is just a test program that is used to show off and */
15 /* debug the current engine. */
16 /* */
17 /****************************************************************************/
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
23 #include "common.h" /* for Panic() etc. */
24 #include "freetype.h"
25 #include "ftxcmap.h"
26 #include "ftxopen.h" /* TrueType Open support */
27 #include "ftxsbit.h" /* embedded bitmap support */
30 * The following comment should be ignored. The "ttobjs.h" file does
31 * already include ft_conf.h.
33 * ------------------------------------------------------------------
35 * IGNORE> Basically, an external program using FreeType shouldn't depend on an
36 * IGNORE> internal file of the FreeType library, especially not on ft_conf.h -- but
37 * IGNORE> to avoid another configure script which tests for the existence of the
38 * IGNORE> i18n stuff we include ft_conf.h here since we can be sure that our test
39 * IGNORE> programs use the same configuration options as the library itself.
42 #include "ttobjs.h" /* We're going to access internal tables directly */
44 #ifdef HAVE_LIBINTL_H
46 #ifdef HAVE_LOCALE_H
47 #include <locale.h>
48 #endif
50 #include "ftxerr18.h"
51 #include <libintl.h>
52 #else
53 #define gettext( x ) ( x )
54 #endif
57 TT_Error error;
59 TT_Engine engine;
60 TT_Face face;
61 TT_Instance instance;
62 TT_Glyph glyph;
64 TT_Instance_Metrics imetrics;
65 TT_Outline outline;
66 TT_Glyph_Metrics metrics;
68 TT_Face_Properties properties;
70 int num_glyphs;
71 int ptsize;
73 int Fail;
74 int Num;
76 int flag_memory = 1;
77 int flag_names = 1;
78 int flag_encodings = 1;
79 int flag_cmap = 1;
80 int flag_sbits = 1;
81 int flag_ttopen = 1;
83 #ifdef FREETYPE_DLL
85 /* If the library is linked as a DLL, TTMemory_Allocated() */
86 /* (which is not exported) cannot be accessed. */
87 /* In this case, some compilers report an error because */
88 /* they try to link against a non-existing symbol. */
89 /* */
90 /* We thus avoid the external reference on these compilers. */
92 #define TTMemory_Allocated 0L
94 #else
95 extern long TTMemory_Allocated;
96 #endif
98 long org_memory, old_memory, cur_memory;
100 const char* Apple_Encodings[33] =
102 "Roman", "Japanese", "Chinese", "Korean", "Arabic", "Hebrew",
103 "Greek", "Russian", "RSymbol", "Devanagari", "Gurmukhi",
104 "Gujarati", "Oriya", "Bengali", "Tamil", "Telugu", "Kannada",
105 "Malayalam", "Sinhalese", "Burmese", "Khmer", "Tai", "Laotian",
106 "Georgian", "Armenian", "Maldivian/Simplif. Chinese", "Tibetan",
107 "Mongolian", "Geez", "Slavic", "Vietnamese", "Sindhi", "Uninterpreted"
110 struct
112 long initial_overhead;
113 long face_object;
114 long glyph_object;
115 long first_instance;
116 long second_instance;
118 } memory_footprint;
121 /* We ignore error message strings with this function */
123 #ifndef HAVE_LIBINTL_H
124 static char*
125 TT_ErrToString18( TT_Error error )
127 static char temp[32];
130 sprintf( temp, "0x%04lx", error );
131 return temp;
133 #endif
136 void
137 Save_Memory( long* var )
139 *var = TTMemory_Allocated - old_memory;
140 old_memory += *var;
143 #define FOOTPRINT( field ) Save_Memory( &memory_footprint.##field )
146 static void
147 Print_Mem( long val, char* string )
149 printf( "%6ld Bytes (%4ld kByte): %s\n",
150 val,
151 ( val + 1023L ) / 1024,
152 string );
155 #define PRINT_MEM( field, string ) \
156 Print_Mem( memory_footprint.##field, string )
159 /* Print the memory footprint */
161 void
162 Print_Memory( void )
164 /* create glyph */
165 error = TT_New_Glyph( face, &glyph );
166 if ( error )
168 fprintf( stderr, gettext( "Could not create glyph container.\n" ) );
169 goto Failure;
172 FOOTPRINT( glyph_object );
174 /* create instance */
175 error = TT_New_Instance( face, &instance );
176 if ( error )
178 fprintf( stderr, gettext( "Could not create instance.\n" ) );
179 goto Failure;
182 FOOTPRINT( first_instance );
184 error = TT_New_Instance( face, &instance );
185 if ( error )
187 fprintf( stderr, gettext( "Could not create second instance.\n" ) );
188 goto Failure;
191 FOOTPRINT( second_instance );
193 printf( gettext( "Memory footprint statistics:\n" ) );
194 separator_line( stdout, 78 );
196 /* NOTE: In our current implementation, the face's execution */
197 /* context object is created lazily with the first */
198 /* instance. However, all later instances share the */
199 /* the same context. */
201 PRINT_MEM( face_object, gettext( "face object" ) );
202 PRINT_MEM( glyph_object, gettext( "glyph object" ) );
203 PRINT_MEM( second_instance, gettext( "instance object" ) );
205 Print_Mem( memory_footprint.first_instance -
206 memory_footprint.second_instance,
207 gettext( "exec. context object" ) );
209 separator_line( stdout, 78 );
211 Print_Mem( memory_footprint.face_object +
212 memory_footprint.glyph_object +
213 memory_footprint.first_instance,
214 gettext( "total memory usage" ) );
216 printf( "\n" );
218 return;
220 Failure:
221 fprintf( stderr, " " );
222 Panic( gettext( "FreeType error message: %s\n" ),
223 TT_ErrToString18( error ) );
227 static char name_buffer[257];
228 static int name_len = 0;
231 static char*
232 LookUp_Name( int index )
234 unsigned short i, n;
236 unsigned short platform, encoding, language, id;
237 char* string;
238 unsigned short string_len;
240 int j, found;
243 n = properties.num_Names;
245 for ( i = 0; i < n; i++ )
247 TT_Get_Name_ID( face, i, &platform, &encoding, &language, &id );
248 TT_Get_Name_String( face, i, &string, &string_len );
250 if ( id == index )
253 /* The following code was inspired from Mark Leisher's */
254 /* ttf2bdf package */
256 found = 0;
258 /* Try to find a Microsoft English name */
260 if ( platform == 3 )
261 for ( j = 1; j >= 0; j-- )
262 if ( encoding == j ) /* Microsoft ? */
263 if ( (language & 0x3FF) == 0x009 ) /* English language */
265 found = 1;
266 break;
269 if ( !found && platform == 0 && language == 0 )
270 found = 1;
272 /* Found a Unicode Name. */
274 if ( found )
276 if ( string_len > 512 )
277 string_len = 512;
279 name_len = 0;
281 for ( i = 1; i < string_len; i += 2 )
282 name_buffer[name_len++] = string[i];
284 name_buffer[name_len] = '\0';
286 return name_buffer;
291 /* Not found */
292 return NULL;
296 static void
297 Print_Names( void )
299 printf( gettext( "font name table entries\n" ) );
300 separator_line( stdout, 78 );
302 if ( LookUp_Name( 4 ) )
303 printf( "%s - ", name_buffer );
305 if ( LookUp_Name( 5 ) )
306 printf( "%s\n\n", name_buffer );
308 if ( LookUp_Name( 6 ) )
309 printf( gettext( "PostScript name: %s\n\n" ), name_buffer );
311 if ( LookUp_Name( 0 ) )
312 printf( "%s\n\n", name_buffer );
314 if ( LookUp_Name( 7 ) )
315 printf( name_buffer );
317 printf( "\n" );
318 separator_line( stdout, 78 );
322 static void
323 Print_Encodings( void )
325 unsigned short n, i;
326 unsigned short platform, encoding;
327 char* platStr, *encoStr;
329 char tempStr[128];
332 printf( gettext( "character map encodings\n" ) );
333 separator_line( stdout, 78 );
335 n = properties.num_CharMaps;
336 if ( n == 0 )
338 printf( gettext(
339 "The file doesn't seem to have any encoding table.\n" ) );
340 return;
343 printf( gettext( "There are %hu encodings:\n\n" ), n );
345 for ( i = 0; i < n; i++ )
347 TT_Get_CharMap_ID( face, i, &platform, &encoding );
348 printf( gettext( "encoding %2u: " ), i );
350 platStr = encoStr = NULL;
352 switch ( platform )
354 case TT_PLATFORM_APPLE_UNICODE:
355 platStr = "Apple Unicode";
356 switch ( encoding )
358 case TT_APPLE_ID_DEFAULT:
359 encoStr = "";
360 break;
362 case TT_APPLE_ID_UNICODE_1_1:
363 encoStr = "(v.1.1)";
364 break;
366 case TT_APPLE_ID_ISO_10646:
367 encoStr = "(ISO 10646-1:1993)";
368 break;
370 case TT_APPLE_ID_UNICODE_2_0:
371 encoStr = "(v.2.0)";
372 break;
374 default:
375 sprintf( tempStr, gettext( "Unknown value %hu" ), encoding );
376 encoStr = tempStr;
378 break;
380 case TT_PLATFORM_MACINTOSH:
381 platStr = "Apple";
382 if ( encoding > 32 )
384 sprintf( tempStr, gettext( "Unknown value %hu" ), encoding );
385 encoStr = tempStr;
387 else
388 encoStr = (char*)Apple_Encodings[encoding];
389 break;
391 case TT_PLATFORM_ISO:
392 platStr = "Iso";
393 switch ( encoding )
395 case TT_ISO_ID_7BIT_ASCII:
396 platStr = "Ascii";
397 encoStr = "7-bit";
398 break;
400 case TT_ISO_ID_10646:
401 encoStr = "10646";
402 break;
404 case TT_ISO_ID_8859_1:
405 encoStr = "8859-1";
406 break;
408 default:
409 sprintf( tempStr, "%hu", encoding );
410 encoStr = tempStr;
412 break;
414 case TT_PLATFORM_MICROSOFT:
415 platStr = "Windows";
416 switch ( encoding )
418 case TT_MS_ID_SYMBOL_CS:
419 encoStr = "Symbol";
420 break;
422 case TT_MS_ID_UNICODE_CS:
423 encoStr = "Unicode";
424 break;
426 case TT_MS_ID_SJIS:
427 encoStr = "Shift-JIS";
428 break;
430 case TT_MS_ID_GB2312:
431 encoStr = "GB2312";
432 break;
434 case TT_MS_ID_BIG_5:
435 encoStr = "Big 5";
436 break;
438 case TT_MS_ID_WANSUNG:
439 encoStr = "WanSung";
440 break;
442 case TT_MS_ID_JOHAB:
443 encoStr = "Johab";
444 break;
446 default:
447 sprintf( tempStr, gettext( "Unknown value %hu" ), encoding );
448 encoStr = tempStr;
450 break;
452 default:
453 sprintf( tempStr, "%hu - %hu", platform, encoding );
454 platStr = gettext( "Unknown" );
455 encoStr = tempStr;
458 printf( "%s %s\n", platStr, encoStr );
461 printf( "\n" );
462 separator_line( stdout, 78 );
466 static void
467 Print_Cmap( void )
469 TT_CharMap charmap;
470 TT_UShort glyph_index;
471 TT_Long char_index;
472 unsigned short n, i;
473 unsigned short platform, encoding;
476 printf( gettext( "ftxcmap test\n" ) );
477 separator_line( stdout, 78 );
479 n = properties.num_CharMaps;
480 if ( n == 0 )
482 printf( gettext(
483 "The file doesn't seem to have any encoding table.\n" ) );
484 return;
487 printf( gettext( "There are %hu encodings:\n\n" ), n );
489 for ( i = 0; i < n; i++ )
492 TT_Get_CharMap_ID( face, i, &platform, &encoding );
493 printf( gettext( "encoding %2u:\n" ), i );
495 TT_Get_CharMap( face, i, &charmap);
497 char_index = TT_CharMap_First( charmap, &glyph_index );
498 printf( gettext( "first: glyph index %hu, character code 0x%lx\n" ),
499 glyph_index, char_index );
501 char_index = TT_CharMap_Next( charmap, char_index, &glyph_index );
502 printf( gettext( "next: glyph index %hu, character code 0x%lx\n" ),
503 glyph_index, char_index );
505 char_index = TT_CharMap_Last( charmap, &glyph_index );
506 printf( gettext( "last: glyph index %hu, character code 0x%lx\n" ),
507 glyph_index, char_index );
510 printf( "\n" );
511 separator_line( stdout, 78 );
515 static void
516 Print_SBits( void )
518 TT_EBLC eblc;
519 TT_Error error;
522 error = TT_Get_Face_Bitmaps( face, &eblc );
523 if ( error == TT_Err_Table_Missing )
524 return;
525 if ( error )
527 fprintf( stderr, gettext(
528 "Error while retrieving embedded bitmaps table.\n" ) );
529 goto Failure;
532 printf( gettext( "embedded bitmap table\n" ) );
533 separator_line( stdout, 78 );
535 printf( gettext( " version of embedded bitmap table: 0x%lx\n" ),
536 eblc.version );
537 printf( gettext( " number of embedded bitmap strikes: %lu\n" ),
538 eblc.num_strikes );
541 TT_SBit_Strike* strike = eblc.strikes;
542 int count = 0;
545 for ( ; count < eblc.num_strikes; count++, strike++ )
547 printf( gettext( " bitmap strike %hu/%lu: " ),
548 count + 1, eblc.num_strikes );
550 printf( gettext( "%hux%hu pixels, %hu-bit depth, glyphs [%hu..%hu]\n" ),
551 strike->x_ppem, strike->y_ppem, strike->bit_depth,
552 strike->start_glyph, strike->end_glyph );
554 TT_SBit_Range* range = strike->sbit_ranges;
555 TT_SBit_Range* limit = range + strike->num_ranges;
558 for ( ; range < limit; range++ )
559 printf( gettext( " range format (%hu:%hu) glyphs %hu..%hu\n" ),
560 range->index_format,
561 range->image_format,
562 range->first_glyph,
563 range->last_glyph );
567 printf( "\n" );
568 separator_line( stdout, 78 );
570 return;
572 Failure:
573 fprintf( stderr, " " );
574 Panic( gettext( "FreeType error message: %s\n" ),
575 TT_ErrToString18( error ) );
579 #define TAG2STRING( t, s ) s[0] = (char)(t >> 24), \
580 s[1] = (char)(t >> 16), \
581 s[2] = (char)(t >> 8), \
582 s[3] = (char)(t )
585 static void
586 Print_GSUB( void )
588 TTO_GSUBHeader gsub;
589 TT_Error error;
591 TT_UShort i;
592 TTO_Feature f;
593 TTO_Lookup* lo;
595 TT_ULong *script_tag_list, *stl;
596 TT_ULong *language_tag_list, *ltl;
597 TT_ULong *feature_tag_list, *ftl;
599 TT_UShort script_index, language_index,
600 feature_index, req_feature_index;
602 char script_tag[4], language_tag[4], feature_tag[4];
605 error = TT_Load_GSUB_Table( face, &gsub, NULL );
606 if ( error == TT_Err_Table_Missing )
607 return;
608 if ( error )
610 fprintf( stderr, gettext( "Error while loading GSUB table.\n" ) );
611 goto Failure;
614 printf( gettext( "GSUB table\n" ) );
615 separator_line( stdout, 78 );
617 error = TT_GSUB_Query_Scripts( &gsub, &script_tag_list );
618 if ( error )
620 fprintf( stderr, gettext(
621 "Error while querying GSUB script list.\n" ) );
622 goto Failure;
625 stl = script_tag_list;
626 for ( ; *stl; stl++ )
628 TAG2STRING( *stl, script_tag );
630 error = TT_GSUB_Select_Script( &gsub, *stl, &script_index );
631 if ( error )
633 fprintf( stderr, gettext(
634 "Error while selecting GSUB script `%4.4s'.\n" ),
635 script_tag );
636 goto Failure;
639 printf( gettext( " script `%4.4s' (index %hu):\n" ),
640 script_tag, script_index );
642 error = TT_GSUB_Query_Features( &gsub, script_index, 0xFFFF,
643 &feature_tag_list );
644 if ( error )
646 fprintf( stderr, gettext(
647 "Error while querying GSUB default language system for script `%4.4s'.\n" ),
648 script_tag );
649 goto Failure;
652 printf( gettext( " default language system:\n" ) );
654 ftl = feature_tag_list;
655 for ( ; *ftl; ftl++ )
657 TAG2STRING( *ftl, feature_tag );
659 error = TT_GSUB_Select_Feature( &gsub, *ftl,
660 script_index, 0xFFFF,
661 &feature_index );
662 if ( error )
664 fprintf( stderr, gettext(
665 "Error while selecting GSUB feature `%4.4s'\n"
666 "for default language system of script `%4.4s'.\n" ),
667 feature_tag, script_tag );
668 goto Failure;
671 printf( gettext( " feature `%4.4s' (index %hu; lookup " ),
672 feature_tag, feature_index );
674 f = gsub.FeatureList.FeatureRecord[feature_index].Feature;
676 for ( i = 0; i < f.LookupListCount - 1; i++ )
677 printf( "%hu, ", f.LookupListIndex[i] );
678 printf( "%hu)\n", f.LookupListIndex[i] );
680 free( feature_tag_list );
682 error = TT_GSUB_Query_Languages( &gsub, script_index,
683 &language_tag_list );
684 if ( error )
686 fprintf( stderr, gettext(
687 "Error while querying GSUB language list for script `%4.4s'.\n" ),
688 script_tag );
689 goto Failure;
692 ltl = language_tag_list;
693 for ( ; *ltl; ltl++ )
695 TAG2STRING( *ltl, language_tag );
697 error = TT_GSUB_Select_Language( &gsub, *ltl,
698 script_index,
699 &language_index,
700 &req_feature_index );
701 if ( error )
703 fprintf( stderr, gettext(
704 "Error while selecting GSUB language `%4.4s' for script `%4.4s'.\n" ),
705 language_tag, script_tag );
706 goto Failure;
709 printf( gettext( " language `%4.4s' (index %hu):\n" ),
710 language_tag, language_index );
712 if ( req_feature_index != 0xFFFF )
714 printf( gettext( " required feature index %hu (lookup " ),
715 req_feature_index );
717 f = gsub.FeatureList.FeatureRecord[req_feature_index].Feature;
719 for ( i = 0; i < f.LookupListCount - 1; i++ )
720 printf( "%hu, ", f.LookupListIndex[i] );
721 printf( "%hu)\n", f.LookupListIndex[i] );
724 error = TT_GSUB_Query_Features( &gsub, script_index, language_index,
725 &feature_tag_list );
726 if ( error )
728 fprintf( stderr, gettext(
729 "Error while querying GSUB feature list\n"
730 "for script `%4.4s', language `%4.4s'.\n" ),
731 script_tag, language_tag );
732 goto Failure;
735 ftl = feature_tag_list;
736 for ( ; *ftl; ftl++ )
738 TAG2STRING( *ftl, feature_tag );
740 error = TT_GSUB_Select_Feature( &gsub, *ftl,
741 script_index, language_index,
742 &feature_index );
743 if ( error )
745 fprintf( stderr, gettext(
746 "Error while selecting GSUB feature `%4.4s'\n"
747 "for script `%4.4s', language `%4.4s'.\n" ),
748 feature_tag, script_tag, language_tag );
749 goto Failure;
752 printf( gettext( " feature `%4.4s' (index %hu; lookup " ),
753 feature_tag, feature_index );
755 f = gsub.FeatureList.FeatureRecord[feature_index].Feature;
757 for ( i = 0; i < f.LookupListCount - 1; i++ )
758 printf( "%hu, ", f.LookupListIndex[i] );
759 printf( "%hu)\n", f.LookupListIndex[i] );
761 free( feature_tag_list );
763 free( language_tag_list );
765 free( script_tag_list );
767 printf( "\n" );
769 lo = gsub.LookupList.Lookup;
771 printf( gettext( "Lookups:\n\n" ) );
773 for ( i = 0; i < gsub.LookupList.LookupCount; i++ )
774 printf( gettext( " %hu: type %hu, flag 0x%x\n" ),
775 i, lo[i].LookupType, lo[i].LookupFlag );
777 printf( "\n" );
778 separator_line( stdout, 78 );
780 return;
782 Failure:
783 fprintf( stderr, " " );
784 Panic( gettext( "FreeType error message: %s\n" ),
785 TT_ErrToString18( error ) );
790 main( int argc, char** argv )
792 int i;
793 char filename[128 + 4];
794 char alt_filename[128 + 4];
795 char* execname;
796 char* gt;
799 #ifdef HAVE_LIBINTL_H
800 setlocale( LC_ALL, "" );
801 bindtextdomain( "freetype", LOCALEDIR );
802 textdomain( "freetype" );
803 #endif
805 execname = argv[0];
807 if ( argc != 2 )
809 gt = gettext( "ftdump: Simple TrueType Dumper -- part of the FreeType project" );
810 fprintf( stderr, "%s\n", gt );
811 separator_line( stderr, strlen( gt ) );
813 fprintf( stderr, gettext( "Usage: %s fontname[.ttf|.ttc]\n\n" ),
814 execname );
816 exit( EXIT_FAILURE );
819 i = strlen( argv[1] );
820 while ( i > 0 && argv[1][i] != '\\' )
822 if ( argv[1][i] == '.' )
823 i = 0;
824 i--;
827 filename[128] = '\0';
828 alt_filename[128] = '\0';
830 strncpy( filename, argv[1], 128 );
831 strncpy( alt_filename, argv[1], 128 );
833 if ( i >= 0 )
835 strncpy( filename + strlen( filename ), ".ttf", 4 );
836 strncpy( alt_filename + strlen( alt_filename ), ".ttc", 4 );
839 /* Initialize engine */
841 old_memory = 0;
843 if ( (error = TT_Init_FreeType( &engine )) )
845 fprintf( stderr, gettext( "Error while initializing engine.\n" ) );
846 goto Failure;
849 if ( (error = TT_Init_SBit_Extension( engine )) )
851 fprintf( stderr, gettext(
852 "Error while initializing embedded bitmap extension.\n" ) );
853 goto Failure;
856 if ( (error = TT_Init_GSUB_Extension( engine )) )
858 fprintf( stderr, gettext(
859 "Error while initializing GSUB extension.\n" ) );
860 goto Failure;
863 FOOTPRINT( initial_overhead );
865 /* Open and Load face */
867 error = TT_Open_Face( engine, filename, &face );
868 if ( error == TT_Err_Could_Not_Open_File )
870 strcpy( filename, alt_filename );
871 error = TT_Open_Face( engine, alt_filename, &face );
874 if ( error == TT_Err_Could_Not_Open_File )
875 Panic( gettext( "Could not find or open %s.\n" ), filename );
876 if ( error )
878 fprintf( stderr, gettext( "Error while opening %s.\n" ), filename );
879 goto Failure;
882 FOOTPRINT( face_object );
884 /* get face properties and allocate preload arrays */
886 TT_Get_Face_Properties( face, &properties );
887 num_glyphs = properties.num_Glyphs;
889 /* Now do various dumps */
891 if ( flag_names )
892 Print_Names();
894 if ( flag_encodings )
895 Print_Encodings();
897 if ( flag_cmap )
898 Print_Cmap();
900 if ( flag_sbits )
901 Print_SBits();
903 if ( flag_ttopen )
904 Print_GSUB();
906 #ifndef FREETYPE_DLL /* the statistics are meaningless if we use a DLL. */
907 if ( flag_memory )
908 Print_Memory();
909 #endif
911 TT_Close_Face( face );
913 TT_Done_FreeType( engine );
915 exit( EXIT_SUCCESS ); /* for safety reasons */
917 return 0; /* never reached */
919 Failure:
920 fprintf( stderr, " " );
921 Panic( gettext( "FreeType error message: %s\n" ),
922 TT_ErrToString18( error ) );
924 return 0; /* never reached */
928 /* End */