1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2007 Jonas Hurrelmann
12 * A command-line tool to convert ttf file to bitmap fonts
14 * All files in this archive are subject to the GNU General Public License.
15 * See the file COPYING in the source tree root for full license agreement.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include FT_FREETYPE_H
33 #include FT_SFNT_NAMES_H
34 #include FT_TRUETYPE_TABLES_H
38 * Set the default values used to generate a BDF font.
40 #ifndef DEFAULT_PLATFORM_ID
41 #define DEFAULT_PLATFORM_ID 3
44 #ifndef DEFAULT_ENCODING_ID
45 #define DEFAULT_ENCODING_ID 1
48 #define ABS(x) (((x) < 0) ? -(x) : (x))
50 #define VERSION "RB12"
52 * nameID macros for getting strings from the OT font.
55 BDFOTF_COPYRIGHT_STRING
= 0,
57 BDFOTF_SUBFAMILY_STRING
,
58 BDFOTF_UNIQUEID_STRING
,
59 BDFOTF_FULLNAME_STRING
,
61 BDFOTF_POSTSCRIPT_STRING
,
62 BDFOTF_TRADEMARK_STRING
,
65 * String names for the string indexes. Used for error messages.
67 static char *string_names
[] = {
74 "\"Postscript Name\"",
80 * The default platform and encoding ID's.
82 static int pid
= DEFAULT_PLATFORM_ID
;
83 static int eid
= DEFAULT_ENCODING_ID
;
87 * A flag indicating if a CMap was found or not.
89 static FT_UShort nocmap
;
91 int pct
= 0; /* display ttc table if it is not zero. */
92 unsigned long max_char
= 65535;
94 unsigned long start_char
= 0;
95 unsigned long limit_char
;
96 unsigned long firstchar
= 0;
97 unsigned long lastchar
;
98 FT_Long ttc_index
= -1;
100 short antialias
= 1; /* smooth fonts with gray levels */
103 float between_chr
= 0.0f
;
104 float between_row
= 0.0f
;
105 int hv_resolution
= 60;
108 int trim_dp
= 0; /* trim descent percent */
109 int trim_da
= 0; /* trim descnet actual */
110 int trim_ap
= 0; /* trim ascent precent */
111 int trim_aa
= 0; /* trim ascent actual */
113 struct font_header_struct
{
114 char header
[4]; /* magic number and version bytes */
115 unsigned short maxwidth
; /* max width in pixels */
116 unsigned short height
; /* height in pixels */
117 unsigned short ascent
; /* ascent (baseline) height */
118 unsigned short depth
; /* depth 0=1-bit, 1=4-bit */
119 unsigned long firstchar
; /* first character in font */
120 unsigned long defaultchar
; /* default character in font */
121 unsigned long size
; /* # characters in font */
122 unsigned long nbits
; /* # bytes imagebits data in file */ /* = bits_size */
124 FT_Long noffset
; /* # longs offset data in file */
125 FT_Long nwidth
; /* # bytes width data in file */
129 struct font_header_struct header
;
130 unsigned char *chars_data
;
131 unsigned short *offset
;
132 FT_Long
*offset_long
;
133 unsigned char *width
;
141 /* exit the program with given message */
143 panic( const char* message
)
145 fprintf( stderr
, "%s\n", message
);
150 arg_panic( const char* message
, const char* arg
)
152 fprintf( stderr
, "%s: %s\n", message
, arg
);
156 static int writebyte(FILE *fp
, unsigned char c
)
158 return putc(c
, fp
) != EOF
;
161 static int writeshort(FILE *fp
, unsigned short s
)
164 return putc(s
>>8, fp
) != EOF
;
167 static int writeint(FILE *fp
, unsigned int l
)
172 return putc(l
>>24, fp
) != EOF
;
175 static int writestr(FILE *fp
, char *str
, int count
)
177 return (int)fwrite(str
, 1, count
, fp
) == count
;
180 /* print usage information */
184 "Usage: convttf [options] [input-files]\n"
185 " convttf [options] [-o output-file] [single-input-file]\n\n"
186 " Default output-file : <font-size>-<basename>.fnt.\n"
187 " When '-ta' or '-tc' is specified in command line,\n "
188 " default output-file is: \n"
189 " <font-size>-<internal postscript-name of input-file>.fnt.\n"
191 " -s N Start output at character encodings >= N\n"
192 " -l N Limit output to character encodings <= N\n"
193 " -p N Font size N in pixel (default N=15)\n"
194 " -c N Character separation in pixel.Insert space between lines.\n"
195 " -x Trim glyphs horizontally of nearly empty space\n"
196 " (to improve spacing on V's W's, etc.)\n"
197 " -X Set the horizontal and vertical resolution (default: 60)\n"
198 " -TA N Trim vertical ascent (N percent)\n"
199 " -TD N Trim vertical descent (N percent)\n"
200 " -Ta N Trim vertical ascent (N pixels)\n"
201 " -Td N Trim vertical descent (N pixels)\n"
202 " -r N Row separation in pixel.Insert space between characters\n"
203 " -d Debug: print converted glyph images\n"
204 " -tt Display the True Type Collection tables available in the font\n"
205 " -t N Index of true type collection. It must be start from 0.(default N=0).\n"
206 " -ta Convert all fonts in ttc (ignores outfile option)\n"
208 fprintf(stderr
, "%s", help
);
212 /* remove directory prefix and file suffix from full path*/
213 char *basename(char *path
)
216 static char base
[256];
218 /* remove prepended path and extension*/
220 for (p
=path
; *p
; ++p
) {
225 for (p
=base
; *p
; ++p
) {
235 void setcharmap(FT_Face face
)
240 * Get the requested cmap.
242 for (i
= 0; i
< face
->num_charmaps
; i
++) {
243 if (face
->charmaps
[i
]->platform_id
== pid
&&
244 face
->charmaps
[i
]->encoding_id
== eid
)
248 if (i
== face
->num_charmaps
&& pid
== 3 && eid
== 1) {
250 * Make a special case when this fails with pid == 3 and eid == 1.
251 * Change to eid == 0 and try again. This captures the two possible
252 * cases for MS fonts. Some other method should be used to cycle
253 * through all the alternatives later.
255 for (i
= 0; i
< face
->num_charmaps
; i
++) {
256 if (face
->charmaps
[i
]->platform_id
== pid
&&
257 face
->charmaps
[i
]->encoding_id
== 0)
260 if (i
< face
->num_charmaps
) {
263 FT_Set_Charmap(face
, face
->charmaps
[i
]);
272 FT_Set_Charmap(face
, face
->charmaps
[i
]);
280 * A generic routine to get a name from the OT name table. This routine
281 * always looks for English language names and checks three possibilities:
282 * 1. English names with the MS Unicode encoding ID.
283 * 2. English names with the MS unknown encoding ID.
284 * 3. English names with the Apple Unicode encoding ID.
286 * The particular name ID mut be provided (e.g. nameID = 0 for copyright
287 * string, nameID = 6 for Postscript name, nameID = 1 for typeface name.
289 * If the `dash_to_space' flag is non-zero, all dashes (-) in the name will be
290 * replaced with the character passed.
292 * Returns the number of bytes added.
295 otf_get_english_string(FT_Face face
, int nameID
, int dash_to_space
,
296 char *name
, int name_size
)
301 FT_SfntName sfntName
;
305 nrec
= FT_Get_Sfnt_Name_Count(face
);
307 for (encid
= 1, j
= 0; j
< 2; j
++, encid
--) {
309 * Locate one of the MS English font names.
311 for (i
= 0; i
< nrec
; i
++) {
312 FT_Get_Sfnt_Name(face
, i
, &sfntName
);
313 if (sfntName
.platform_id
== 3 &&
314 sfntName
.encoding_id
== encid
&&
315 sfntName
.name_id
== nameID
&&
316 (sfntName
.language_id
== 0x0409 ||
317 sfntName
.language_id
== 0x0809 ||
318 sfntName
.language_id
== 0x0c09 ||
319 sfntName
.language_id
== 0x1009 ||
320 sfntName
.language_id
== 0x1409 ||
321 sfntName
.language_id
== 0x1809)) {
323 slen
= sfntName
.string_len
;
329 if (slen
>> 1 >= name_size
) {
330 fprintf(stderr
, "warning: %s string longer than buffer."
331 "Truncating to %d bytes.\n", string_names
[nameID
], name_size
);
332 slen
= name_size
<< 1;
336 * Found one of the MS English font names. The name is by
337 * definition encoded in Unicode, so copy every second byte into
338 * the `name' parameter, assuming there is enough space.
340 for (i
= 1; i
< slen
; i
+= 2) {
342 *name
++ = (s
[i
] != '-') ? s
[i
] : ' ';
343 else if (s
[i
] == '\r' || s
[i
] == '\n') {
344 if (s
[i
] == '\r' && i
+ 2 < slen
&& s
[i
+ 2] == '\n')
357 * No MS English name found, attempt to find an Apple Unicode English
360 for (i
= 0; i
< nrec
; i
++) {
361 FT_Get_Sfnt_Name(face
, i
, &sfntName
);
362 if (sfntName
.platform_id
== 0 && sfntName
.language_id
== 0 &&
363 sfntName
.name_id
== nameID
) {
365 slen
= sfntName
.string_len
;
371 if (slen
>> 1 >= name_size
) {
372 fprintf(stderr
, "warning: %s string longer than buffer."
373 "Truncating to %d bytes.\n", string_names
[nameID
], name_size
);
374 slen
= name_size
<< 1;
378 * Found the Apple Unicode English name. The name is by definition
379 * encoded in Unicode, so copy every second byte into the `name'
380 * parameter, assuming there is enough space.
382 for (i
= 1; i
< slen
; i
+= 2) {
384 *name
++ = (s
[i
] != '-') ? s
[i
] : ' ';
385 else if (s
[i
] == '\r' || s
[i
] == '\n') {
386 if (s
[i
] == '\r' && i
+ 2 < slen
&& s
[i
+ 2] == '\n')
401 int get_ttc_table(char *path
, struct ttc_table
*ttcname
)
411 /* init number of ttf in ttc */
412 ttcname
->ttc_count
= 0;
414 /* Initialize engine */
415 if ( ( error
= FT_Init_FreeType( &library
) ) != 0 )
417 panic( "Error while initializing engine" );
423 error
= FT_New_Face( library
, path
, (FT_Long
) 0, &face
);
426 arg_panic( "Could not find/open font", path
);
430 ttcname
->ttc_count
= face
->num_faces
;
431 ttcname
->ttf_name
= malloc( sizeof(char*) * ttcname
->ttc_count
);
433 for(i
= 0; i
< ttcname
->ttc_count
; i
++)
435 error
= FT_New_Face( library
, path
, i
, &face
);
436 if ( error
== FT_Err_Cannot_Open_Stream
)
437 arg_panic( "Could not find/open font", path
);
438 otf_get_english_string(face
, BDFOTF_POSTSCRIPT_STRING
, 0, xlfd
,
440 ttcname
->ttf_name
[i
] = malloc(sizeof(char) * (strlen(xlfd
) + 1 ));
441 strcpy(ttcname
->ttf_name
[i
], xlfd
);
446 void print_ttc_table(char* path
)
448 struct ttc_table ttcname
;
451 get_ttc_table(path
, &ttcname
);
452 printf("ttc header count = %ld \n\n", ttcname
.ttc_count
);
453 printf("Encoding tables available in the true type collection\n\n");
454 printf("INDEX\tPOSTSCRIPT NAME\n");
455 printf("-----------------------------------------------------\n");
456 for(i
= 0; i
< ttcname
.ttc_count
; i
++)
458 printf("%ld\t%s\n", i
, ttcname
.ttf_name
[i
]);
460 for(i
= 0; i
< ttcname
.ttc_count
; i
++)
462 free(ttcname
.ttf_name
[i
]);
465 free(ttcname
.ttf_name
);
470 FT_Long
getcharindex(FT_Face face
, FT_Long code
)
474 if (code
>= face
->num_glyphs
)
479 idx
= FT_Get_Char_Index( face
, code
);
481 if ( idx
<= 0 || idx
> face
->num_glyphs
)
487 void print_raw_glyph( FT_Face face
)
489 int pixel
,row
,col
,width
;
490 width
= face
->glyph
->metrics
.width
>> 6;
492 printf("\n---Raw-Glyph---\n");
493 for(row
=0; row
< face
->glyph
->metrics
.height
>> 6; row
++)
496 for(col
=0; col
< width
; col
++)
498 pixel
= *(face
->glyph
->bitmap
.buffer
+width
*row
+col
)/26;
499 if ( pixel
) printf("%d",pixel
); else printf(" ");
503 printf("----End-----\n");
506 int glyph_width( FT_Face face
)
508 int pitch
, h_adv
, width
;
509 unsigned spacing
= (unsigned)(between_chr
* (1<<6));/* convert to fixed point */
511 pitch
= ABS(face
->glyph
->bitmap
.pitch
);
512 h_adv
= face
->glyph
->metrics
.horiAdvance
>> 6;
513 width
= (face
->glyph
->metrics
.width
+ spacing
) >> 6;
515 if(pitch
== 0) pitch
= h_adv
;
516 if(width
< pitch
) width
= pitch
;
517 if(width
== 0) return 0;
523 void trim_glyph( FT_GlyphSlot glyph
, int *empty_first_col
,
524 int *empty_last_col
, int *width
)
527 int stride
= glyph
->bitmap
.pitch
;
529 int trim_left
= 2, trim_right
= 2;
531 const unsigned char limit
= 64u;
532 const unsigned char *image
= glyph
->bitmap
.buffer
;
535 return; /* nothing to do? */
537 for(row
=0; row
< glyph
->metrics
.height
>> 6; row
++)
539 const unsigned char *column
= image
+row
*stride
;
540 if (*column
++ < limit
&& trim_left
)
542 if (*column
>= limit
/2)
548 column
= image
+row
*stride
+end
;
549 if (*column
-- < limit
&& trim_right
)
551 if (*column
>= limit
/2)
559 (*width
) -= trim_left
+ trim_right
;
560 if (*width
< 0) *width
= 0;
562 *empty_first_col
= trim_left
;
563 *empty_last_col
= trim_right
;
566 void convttf(char* path
, char* destfile
, FT_Long face_index
)
573 int empty_first_col
, empty_last_col
;
579 unsigned char bit_shift
= 1 << depth
;
580 unsigned char pixel_per_byte
= CHAR_BIT
/ bit_shift
;
582 /* Initialize engine */
583 if ( ( error
= FT_Init_FreeType( &library
) ) != 0 )
584 panic( "Error while initializing engine" );
587 error
= FT_New_Face( library
, path
, (FT_Long
) face_index
, &face
);
588 if ( error
== FT_Err_Cannot_Open_Stream
)
589 arg_panic( "Could not find/open font\n", path
);
591 arg_panic( "Error while opening font\n", path
);
595 /* Set font header data */
596 struct font_struct export_font
;
597 export_font
.header
.header
[0] = 'R';
598 export_font
.header
.header
[1] = 'B';
599 export_font
.header
.header
[2] = '1';
600 export_font
.header
.header
[3] = '2';
601 //export_font.header.height = 0;
602 //export_font.header.ascent = 0;
604 float extra_space
= (float)(between_row
-trim_aa
-trim_da
);
605 FT_Set_Char_Size( face
, 0, pixel_size
<< 6, hv_resolution
, hv_resolution
);
606 export_font
.header
.ascent
=
607 ((face
->size
->metrics
.ascender
*(100-trim_ap
)/100) >> 6) - trim_aa
;
609 export_font
.header
.height
=
610 (((face
->size
->metrics
.ascender
*(100-trim_ap
)/100) -
611 (face
->size
->metrics
.descender
*(100-trim_dp
)/100)) >> 6) + extra_space
;
614 printf("Please wait, converting %s:\n", path
);
616 /* "face->num_glyphs" is NG.; */
617 if ( limit_char
== 0 ) limit_char
= max_char
;
618 if ( limit_char
> max_char
) limit_char
= max_char
;
620 FT_Long char_count
= 0;
624 export_font
.header
.maxwidth
= 1;
625 export_font
.header
.depth
= 1;
626 firstchar
= limit_char
;
627 lastchar
= start_char
;
629 /* calculate memory usage */
630 for(code
= start_char
; code
<= limit_char
; code
++ )
632 charindex
= getcharindex( face
, code
);
633 if ( !(charindex
) ) continue;
634 error
= FT_Load_Glyph( face
, charindex
,
635 (FT_LOAD_RENDER
| FT_LOAD_NO_BITMAP
) );
636 if ( error
) continue;
638 w
= glyph_width( face
);
639 if (w
== 0) continue;
640 empty_first_col
= empty_last_col
= 0;
642 trim_glyph( face
->glyph
, &empty_first_col
, &empty_last_col
, &w
);
644 if (export_font
.header
.maxwidth
< w
)
645 export_font
.header
.maxwidth
= w
;
649 index
+= (w
*export_font
.header
.height
+ pixel_per_byte
- 1)/pixel_per_byte
;
651 if (code
>= lastchar
)
654 if (code
<= firstchar
)
657 export_font
.header
.defaultchar
= firstchar
;
658 export_font
.header
.firstchar
= firstchar
;
659 export_font
.header
.size
= lastchar
- firstchar
+ 1;
660 export_font
.header
.nbits
= index
;
661 export_font
.header
.noffset
= export_font
.header
.size
;
662 export_font
.header
.nwidth
= export_font
.header
.size
;
664 /* check if we need to use long offsets */
665 char use_long_offset
= (export_font
.header
.nbits
>= 0xFFDB );
667 /* allocate memory */
668 export_font
.offset
= NULL
;
669 export_font
.offset_long
= NULL
;
671 export_font
.offset_long
=
672 malloc( sizeof(FT_Long
)* export_font
.header
.noffset
);
675 malloc( sizeof(unsigned short)* export_font
.header
.noffset
);
678 malloc( sizeof(unsigned char) * export_font
.header
.nwidth
);
679 export_font
.chars_data
=
680 malloc( sizeof(unsigned char) * export_font
.header
.nbits
);
682 /* for now we use the full height for each character */
683 h
= export_font
.header
.height
;
687 char char_name
[1024];
688 int converted_char_count
= 0;
689 int failed_char_count
= 0;
691 for( code
= firstchar
; code
<= lastchar
; code
++ )
693 /* Get gylph index from the char and render it */
694 charindex
= getcharindex( face
, code
);
697 if ( use_long_offset
)
698 export_font
.offset_long
[code
- firstchar
] = export_font
.offset_long
[0];
700 export_font
.offset
[code
- firstchar
] = export_font
.offset
[0];
701 export_font
.width
[code
- firstchar
] = export_font
.width
[0];
705 error
= FT_Load_Glyph( face
, charindex
,
706 (FT_LOAD_RENDER
| FT_LOAD_NO_BITMAP
) );
710 if FT_HAS_GLYPH_NAMES( face
)
711 FT_Get_Glyph_Name( face
, charindex
, char_name
, 16);
715 FT_GlyphSlot slot
= face
->glyph
;
716 FT_Bitmap
* source
= &slot
->bitmap
;
717 //print_raw_glyph( face );
718 w
= glyph_width( face
);
719 if (w
== 0) continue;
720 empty_first_col
= empty_last_col
= 0;
723 trim_glyph( face
->glyph
, &empty_first_col
, &empty_last_col
, &w
);
725 if ( use_long_offset
)
726 export_font
.offset_long
[code
- firstchar
] = index
;
728 export_font
.offset
[code
- firstchar
] = index
;
730 export_font
.width
[code
- firstchar
] = w
;
732 /* copy the glyph bitmap to a full sized glyph bitmap */
733 unsigned char* src
= source
->buffer
;
734 unsigned char* tmpbuf
= malloc(sizeof(unsigned char) * w
* h
);
735 memset(tmpbuf
, 0xff, w
*h
);
736 int start_y
= export_font
.header
.ascent
- slot
->bitmap_top
;
738 int glyph_height
= source
->rows
;
739 int stride
= source
->pitch
;
740 unsigned char* buf
= tmpbuf
;
741 unsigned char* endbuf
= tmpbuf
+ w
*h
;
744 /* insert empty pixels on the left */
745 int col_off
= w
- stride
;
746 if (col_off
> 1) col_off
/= 2;
747 if (col_off
< 0) col_off
= 0;
749 for(row
=0; row
< glyph_height
; row
++)
751 if(row
+start_y
< 0 || row
+start_y
>= h
)
753 for(col
= empty_first_col
; col
< stride
; col
++)
755 unsigned char *tsrc
, *dst
;
756 dst
= buf
+ (w
*(start_y
+row
)) + col
+ col_off
;
757 tsrc
= src
+ stride
*row
+ col
;
758 if (dst
< endbuf
&& dst
>= tmpbuf
)
762 printf("Error! row: %3d col: %3d\n", row
, col
);
766 if(error
) print_raw_glyph(face
);
772 numbits
= pixel_per_byte
;
774 for(row
=0; row
< h
; row
++)
776 for(col
=0; col
< w
; col
++)
778 unsigned int src
= *buf
++;
779 unsigned int cur_col
= (src
+ 8) / 17;
780 field
|= (cur_col
<< (bit_shift
*(pixel_per_byte
-numbits
)));
784 export_font
.chars_data
[index
++] = (unsigned char)field
;
785 numbits
= pixel_per_byte
;
792 if (numbits
!= pixel_per_byte
)
794 export_font
.chars_data
[index
++] = (unsigned char)field
;
799 /* debug: dump char */
800 printf("\n---Converted Glyph Dump---\n");
801 unsigned char bit_max
= (1 << bit_shift
) - 1;
802 if ( code
> 32 && code
< 255 ) {
805 buf
= &(export_font
.chars_data
[export_font
.offset_long
[
808 buf
= &(export_font
.chars_data
[export_font
.offset
[
810 unsigned char current_data
;
811 unsigned char font_bits
;
812 numbits
= pixel_per_byte
;
820 font_bits
= current_data
& bit_max
;
821 if (font_bits
==bit_max
)
825 if(font_bits
> bit_max
/2)
832 current_data
= *(++buf
);
833 numbits
= pixel_per_byte
;
837 current_data
>>= bit_shift
;
844 printf("---End Glyph Dump---\n");
848 converted_char_count
++;
849 done
= (100*(converted_char_count
))/char_count
;
850 printf("Converted %s %d (%d%%)\e[K\r",
851 char_name
,converted_char_count
,done
); fflush(stdout
);
854 FILE *file
= fopen(destfile
, "w");
855 printf("Writing %s\n", destfile
);
858 writestr(file
, VERSION
, 4);
859 writeshort(file
, export_font
.header
.maxwidth
);
860 writeshort(file
, export_font
.header
.height
);
861 writeshort(file
, export_font
.header
.ascent
);
862 writeshort(file
, export_font
.header
.depth
);
863 writeint(file
, export_font
.header
.firstchar
);
864 writeint(file
, export_font
.header
.defaultchar
);
865 writeint(file
, export_font
.header
.size
);
866 writeint(file
, export_font
.header
.nbits
);
867 writeint(file
, export_font
.header
.noffset
);
868 writeint(file
, export_font
.header
.nwidth
);
870 fwrite( (char*)export_font
.chars_data
, 1,
871 export_font
.header
.nbits
, file
);
872 free(export_font
.chars_data
);
875 char pad
[] = {0,0,0,0};
876 if ( use_long_offset
)
878 skip
= ((export_font
.header
.nbits
+ 3) & ~3) -
879 export_font
.header
.nbits
;
880 fwrite(pad
, 1, skip
, file
); /* pad */
881 for(i
= 0; i
< export_font
.header
.noffset
; i
++)
882 writeint(file
, export_font
.offset_long
[i
]);
886 skip
= ((export_font
.header
.nbits
+ 1) & ~1) -
887 export_font
.header
.nbits
;
888 fwrite(pad
, 1, skip
, file
); /* pad */
889 for(i
= 0; i
< export_font
.header
.noffset
; i
++)
890 writeshort(file
, export_font
.offset
[i
]);
893 for(i
= 0; i
< export_font
.header
.nwidth
; i
++)
894 writebyte(file
, export_font
.width
[i
]);
895 free(export_font
.width
);
897 if ( use_long_offset
)
898 free(export_font
.offset_long
);
900 free(export_font
.offset
);
903 FT_Done_Face( face
);
904 FT_Done_FreeType( library
);
905 printf("done (converted %d glyphs, %d errors).\e[K\n\n",
906 converted_char_count
, failed_char_count
);
910 void convttc(char* path
)
912 struct ttc_table ttcname
;
915 get_ttc_table(path
, &ttcname
);
917 if (ttcname
.ttc_count
== 0)
919 printf("This file is a not true type font.\n");
924 if (!flg_all_ttc
&& ttc_index
== -1)
927 { /* generate filename */
928 snprintf(outfile
, sizeof(outfile
),
929 "%d-%s.fnt", pixel_size
, basename(path
));
931 convttf(path
, outfile
, (FT_Long
) 0);
934 /* set face_index of ttc */
935 else if (!flg_all_ttc
)
937 print_ttc_table(path
);
940 if (ttc_index
>= 0 &&
941 ttc_index
< ttcname
.ttc_count
)
943 if (strcmp(ttcname
.ttf_name
[ttc_index
], "") != 0)
945 snprintf(outfile
, sizeof(outfile
), "%d-%s.fnt",
946 pixel_size
, ttcname
.ttf_name
[ttc_index
]);
950 snprintf(outfile
, sizeof(outfile
), "%d-%s-%ld.fnt",
951 pixel_size
, basename(path
), ttc_index
);
956 printf("illegal face index of ttc.\n");
959 convttf(path
, outfile
, ttc_index
);
961 else { /* convert all fonts */
962 print_ttc_table(path
);
963 for(i
= 0; i
< ttcname
.ttc_count
; i
++)
965 snprintf(outfile
, sizeof(outfile
), "%d-%s.fnt",
966 pixel_size
, ttcname
.ttf_name
[i
]);
967 convttf(path
, outfile
, i
);
971 for(i
= 0; i
< ttcname
.ttc_count
; i
++)
973 free(ttcname
.ttf_name
[i
]);
975 free(ttcname
.ttf_name
);
980 /* parse command line options*/
981 void getopts(int *pac
, char ***pav
)
989 limit_char
= max_char
;
992 while (ac
> 0 && av
[0][0] == '-') {
999 case ' ': /* multiple -args on av[]*/
1000 while( *p
&& *p
== ' ')
1002 if( *p
++ != '-') /* next option must have dash*/
1004 break; /* proceed to next option*/
1005 case 'o': /* set output file*/
1009 while (*p
&& *p
!= ' ')
1015 strcpy(outfile
, av
[0]);
1018 case 'l': /* set encoding limit*/
1020 limit_char
= atoi(p
);
1021 while (*p
&& *p
!= ' ')
1027 limit_char
= atoi(av
[0]);
1030 case 's': /* set encoding start*/
1032 start_char
= atol(p
);
1033 while (*p
&& *p
!= ' ')
1039 start_char
= atol(av
[0]);
1042 case 'p': /* set pixel size*/
1044 pixel_size
= atoi(p
);
1045 while (*p
&& *p
!= ' ')
1051 pixel_size
= atoi(av
[0]);
1054 case 'c': /* set spaece between characters */
1057 between_chr
= atof(p
);
1058 while (*p
&& *p
!= ' ')
1064 between_chr
= atof(av
[0]);
1070 while (*p
&& *p
!= ' ')
1075 while (*p
&& *p
!= ' ')
1080 hv_resolution
= atoi(p
);
1081 while (*p
&& *p
!= ' ')
1087 hv_resolution
= atoi(av
[0]);
1092 between_row
= atof(p
);
1093 while (*p
&& *p
!= ' ')
1099 between_row
= atof(av
[0]);
1106 while (*p
&& *p
!= ' ')
1112 trim_ap
= atoi(av
[0]);
1119 while (*p
&& *p
!= ' ')
1125 trim_dp
= atoi(av
[0]);
1132 while (*p
&& *p
!= ' ')
1138 trim_aa
= atoi(av
[0]);
1150 trim_da
= atoi(av
[0]);
1154 fprintf(stderr
, "Unknown option ignored: %s\n", p
-1);
1155 while (*p
&& *p
!= ' ')
1158 case 't': /* display ttc table */
1161 while (*p
&& *p
!= ' ')
1165 else if (*p
== 'a') {
1167 while (*p
&& *p
!= ' ')
1172 ttc_index
= atoi(p
);
1173 while (*p
&& *p
!= ' ')
1179 ttc_index
= atoi(av
[0]);
1184 fprintf(stderr
, "Unknown option ignored: %s\n", p
-1);
1185 while (*p
&& *p
!= ' ')
1195 int main(int ac
, char **av
)
1199 ++av
; --ac
; /* skip av[0]*/
1201 getopts(&ac
, &av
); /* read command line options*/
1215 if (limit_char
< start_char
)
1221 while (pct
&& ac
> 0)
1223 print_ttc_table(av
[0]);
1240 * Trie node structure.
1243 unsigned short key
; /* Key value. */
1244 unsigned short val
; /* Data for the key. */
1245 unsigned long sibs
; /* Offset of siblings from trie beginning. */
1246 unsigned long kids
; /* Offset of children from trie beginning. */
1250 * The trie used for remapping codes.
1252 static node_t
*nodes
;
1253 static unsigned long nodes_used
= 0;
1256 otf2bdf_remap(unsigned short *code
)
1258 unsigned long i
, n
, t
;
1259 unsigned short c
, codes
[2];
1262 * If no mapping table was loaded, then simply return the code.
1264 if (nodes_used
== 0)
1268 codes
[0] = (c
>> 8) & 0xff;
1269 codes
[1] = c
& 0xff;
1271 for (i
= n
= 0; i
< 2; i
++) {
1275 for (; nodes
[t
].sibs
&& nodes
[t
].key
!= codes
[i
]; t
= nodes
[t
].sibs
);
1276 if (nodes
[t
].key
!= codes
[i
])
1281 *code
= nodes
[n
].val
;