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 ****************************************************************************/
21 #define BITMAP_WORDS(x) (((x)+15)/16) /* image size in words*/
26 #include FT_FREETYPE_H
36 #include FT_SFNT_NAMES_H
37 #include FT_TRUETYPE_TABLES_H
41 * Set the default values used to generate a BDF font.
43 #ifndef DEFAULT_PLATFORM_ID
44 #define DEFAULT_PLATFORM_ID 3
47 #ifndef DEFAULT_ENCODING_ID
48 #define DEFAULT_ENCODING_ID 1
51 #define log_level_nolog 0
52 #define log_level_warnning 1
53 #define log_level_header 2
54 #define log_level_description1 3
55 #define log_level_description2 4
58 #define log_level log_level_nolog
61 #define MIN(a,b) ((a)<(b) ? (a) : (b))
62 #define MAX(a,b) ((a)>(b) ? (a) : (b))
65 * nameID macros for getting strings from the OT font.
68 BDFOTF_COPYRIGHT_STRING
= 0,
70 BDFOTF_SUBFAMILY_STRING
,
71 BDFOTF_UNIQUEID_STRING
,
72 BDFOTF_FULLNAME_STRING
,
74 BDFOTF_POSTSCRIPT_STRING
,
75 BDFOTF_TRADEMARK_STRING
,
78 * String names for the string indexes. Used for error messages.
80 static char *string_names
[] = {
87 "\"Postscript Name\"",
93 * The default platform and encoding ID's.
95 static int pid
= DEFAULT_PLATFORM_ID
;
96 static int eid
= DEFAULT_ENCODING_ID
;
100 * A flag indicating if a CMap was found or not.
102 static FT_UShort nocmap
;
104 #define MAX_CHAR 65535
105 int pct
= 0; /* display ttc table if it is not zero. */
107 unsigned long start_char
= 0;
108 unsigned long limit_char
;
109 unsigned long firstchar
= 0;
110 unsigned long lastchar
;
111 FT_Long ttc_index
= -1;
114 short antialias
= 1; /* smooth fonts with gray levels */
120 struct font_header_struct
{
121 char header
[4]; /* magic number and version bytes */
122 unsigned short maxwidth
; /* max width in pixels */
123 unsigned short height
; /* height in pixels */
124 unsigned short ascent
; /* ascent (baseline) height */
125 unsigned short depth
; /* depth 0=1-bit, 1=4-bit */
126 unsigned long firstchar
; /* first character in font */
127 unsigned long defaultchar
; /* default character in font */
128 unsigned long size
; /* # characters in font */
129 unsigned long nbits
; /* # bytes imagebits data in file */
131 FT_Long noffset
; /* # longs offset data in file */
132 FT_Long nwidth
; /* # bytes width data in file */
140 /* exit the program with given message */
142 panic( const char* message
)
144 fprintf( stderr
, "%s\n", message
);
148 /* print usage information */
152 "Usage: convttf [options] [input-files]\n"
153 " convttf [options] [-o output-file] [single-input-file]\n\n"
154 " Default output-filename : \n"
155 " 'input-files name removed extension'_'font-size'.fnt.\n"
156 " but default output-filename become \n "
157 " 'internal postscript-name of input-file'_'font-size'.fnt.\n"
158 " if '-ta' or '-tc' options are described.\n"
160 " -s N Start output at character encodings >= N\n"
161 " -l N Limit output to character encodings <= N\n"
162 " -p N Character height N in pixel (default N=15)\n"
163 " -c N Character separation in pixel.Insert space between lines. (default N=1)\n"
164 " -r N Row separation in pixel.Insert space between characters\n"
165 " -tt Display the True Type Collection tables available in the font\n"
166 " -t N Index of true type collection. It must be start from 0.(default N=0).\n"
167 " -ta Convert all fonts in ttc\n"
168 " \"-o output-file\" specified is ignored when \"-ta\" is specified.\n"
170 fprintf(stderr
, help
);
174 /* remove directory prefix and file suffix from full path*/
175 char *basename(char *path
)
178 static char base
[256];
180 /* remove prepended path and extension*/
182 for (p
=path
; *p
; ++p
) {
187 for (p
=base
; *p
; ++p
) {
197 void setcharmap(FT_Face face
)
202 * Get the requested cmap.
204 for (i
= 0; i
< face
->num_charmaps
; i
++) {
205 if (face
->charmaps
[i
]->platform_id
== pid
&&
206 face
->charmaps
[i
]->encoding_id
== eid
)
210 if (i
== face
->num_charmaps
&& pid
== 3 && eid
== 1) {
212 * Make a special case when this fails with pid == 3 and eid == 1.
213 * Change to eid == 0 and try again. This captures the two possible
214 * cases for MS fonts. Some other method should be used to cycle
215 * through all the alternatives later.
217 for (i
= 0; i
< face
->num_charmaps
; i
++) {
218 if (face
->charmaps
[i
]->platform_id
== pid
&&
219 face
->charmaps
[i
]->encoding_id
== 0)
222 if (i
< face
->num_charmaps
) {
225 FT_Set_Charmap(face
, face
->charmaps
[i
]);
234 FT_Set_Charmap(face
, face
->charmaps
[i
]);
242 * A generic routine to get a name from the OT name table. This routine
243 * always looks for English language names and checks three possibilities:
244 * 1. English names with the MS Unicode encoding ID.
245 * 2. English names with the MS unknown encoding ID.
246 * 3. English names with the Apple Unicode encoding ID.
248 * The particular name ID mut be provided (e.g. nameID = 0 for copyright
249 * string, nameID = 6 for Postscript name, nameID = 1 for typeface name.
251 * If the `dash_to_space' flag is non-zero, all dashes (-) in the name will be
252 * replaced with the character passed.
254 * Returns the number of bytes added.
257 otf_get_english_string(FT_Face face
, int nameID
, int dash_to_space
,
258 char *name
, int name_size
)
263 FT_SfntName sfntName
;
267 nrec
= FT_Get_Sfnt_Name_Count(face
);
269 for (encid
= 1, j
= 0; j
< 2; j
++, encid
--) {
271 * Locate one of the MS English font names.
273 for (i
= 0; i
< nrec
; i
++) {
274 FT_Get_Sfnt_Name(face
, i
, &sfntName
);
275 if (sfntName
.platform_id
== 3 &&
276 sfntName
.encoding_id
== encid
&&
277 sfntName
.name_id
== nameID
&&
278 (sfntName
.language_id
== 0x0409 ||
279 sfntName
.language_id
== 0x0809 ||
280 sfntName
.language_id
== 0x0c09 ||
281 sfntName
.language_id
== 0x1009 ||
282 sfntName
.language_id
== 0x1409 ||
283 sfntName
.language_id
== 0x1809)) {
285 slen
= sfntName
.string_len
;
291 if (slen
>> 1 >= name_size
) {
292 fprintf(stderr
, "warning: %s string longer than buffer. "
293 "Truncating to %d bytes.\n", string_names
[nameID
],
295 slen
= name_size
<< 1;
299 * Found one of the MS English font names. The name is by
300 * definition encoded in Unicode, so copy every second byte into
301 * the `name' parameter, assuming there is enough space.
303 for (i
= 1; i
< slen
; i
+= 2) {
305 *name
++ = (s
[i
] != '-') ? s
[i
] : ' ';
306 else if (s
[i
] == '\r' || s
[i
] == '\n') {
307 if (s
[i
] == '\r' && i
+ 2 < slen
&& s
[i
+ 2] == '\n')
320 * No MS English name found, attempt to find an Apple Unicode English
323 for (i
= 0; i
< nrec
; i
++) {
324 FT_Get_Sfnt_Name(face
, i
, &sfntName
);
325 if (sfntName
.platform_id
== 0 && sfntName
.language_id
== 0 &&
326 sfntName
.name_id
== nameID
) {
328 slen
= sfntName
.string_len
;
334 if (slen
>> 1 >= name_size
) {
335 fprintf(stderr
, "warning: %s string longer than buffer. "
336 "Truncating to %d bytes.\n", string_names
[nameID
], name_size
);
337 slen
= name_size
<< 1;
341 * Found the Apple Unicode English name. The name is by definition
342 * encoded in Unicode, so copy every second byte into the `name'
343 * parameter, assuming there is enough space.
345 for (i
= 1; i
< slen
; i
+= 2) {
347 *name
++ = (s
[i
] != '-') ? s
[i
] : ' ';
348 else if (s
[i
] == '\r' || s
[i
] == '\n') {
349 if (s
[i
] == '\r' && i
+ 2 < slen
&& s
[i
+ 2] == '\n')
364 int get_ttc_table(char *path
, struct ttc_table
*ttcname
)
374 /* init number of ttf in ttc */
375 ttcname
->ttc_count
= 0;
377 /* Initialize engine */
378 if ( ( error
= FT_Init_FreeType( &library
) ) != 0 )
380 panic( "Error while initializing engine" );
386 error
= FT_New_Face( library
, path
, (FT_Long
) 0, &face
);
387 if ( error
== FT_Err_Cannot_Open_Stream
)
389 panic( "Could not find/open font resource" );
393 ttcname
->ttc_count
= face
->num_faces
;
394 ttcname
->ttf_name
= malloc( sizeof(char*) * ttcname
->ttc_count
);
396 for(i
= 0; i
< ttcname
->ttc_count
; i
++)
398 error
= FT_New_Face( library
, path
, i
, &face
);
399 if ( error
== FT_Err_Cannot_Open_Stream
)
400 panic( "Could not find/open font resource\n" );
401 otf_get_english_string(face
, BDFOTF_POSTSCRIPT_STRING
, 0, xlfd
,
403 ttcname
->ttf_name
[i
] = malloc(sizeof(char) * (strlen(xlfd
) + 1 ));
404 strcpy(ttcname
->ttf_name
[i
], xlfd
);
409 void print_ttc_table(char* path
)
411 struct ttc_table ttcname
;
414 get_ttc_table(path
, &ttcname
);
415 printf("ttc header count = %ld \n\n", ttcname
.ttc_count
);
416 printf("Encoding tables available in the true type collection\n\n");
417 printf("INDEX\tPOSTSCRIPT NAME\n");
418 printf("-----------------------------------------------------\n");
419 for(i
= 0; i
< ttcname
.ttc_count
; i
++)
421 printf("%ld\t%s\n", i
, ttcname
.ttf_name
[i
]);
423 for(i
= 0; i
< ttcname
.ttc_count
; i
++)
425 free(ttcname
.ttf_name
[i
]);
428 free(ttcname
.ttf_name
);
433 FT_Long
getcharindex(FT_Face face
, FT_Long code
)
437 if (code
>= face
->num_glyphs
)
442 idx
= FT_Get_Char_Index( face
, code
);
444 if ( idx
<= 0 || idx
> face
->num_glyphs
)
450 int calculate_output_glyph_data(FT_GlyphSlot glyph
, int *start_x
)
453 ow
= glyph
->bitmap
.pitch
;
455 ow
= glyph
->metrics
.horiAdvance
>> 6;
456 ow1
= glyph
->metrics
.width
>> 6;
460 osx
= glyph
->metrics
.horiBearingX
>> 6;
462 ow
+= osx
+ between_chr
;
465 osx
+= between_chr
>> 1;
470 void convttf(char* path
, FT_Long face_index
)
482 FT_Long glyph_index
[MAX_CHAR
] = {0};
483 FT_Size_RequestRec req
= {
484 FT_SIZE_REQUEST_TYPE_REAL_DIM
,
486 ((pixel_size
- between_row
) << 10),
491 int empty_glyphs
[256] = {0};
492 int glyph_buffer_size
= 0;
493 unsigned char *glyph_buffer
= NULL
;
497 #if log_level > log_level_nolog
500 strcpy(logfile
, basename(path
));
502 sprintf(log_suf
, "_%d.log", pixel_size
);
503 strcat(logfile
, log_suf
);
504 if ((pTmplog
= fopen(logfile
, "w")) == 0) {
505 fprintf(stderr
, "unable to open temporary file '%s'.\n",
511 printf("log_file is %s\n\n", logfile
);
515 /* Initialize engine */
516 if ( ( error
= FT_Init_FreeType( &library
) ) != 0 )
517 panic( "Error while initializing engine" );
520 error
= FT_New_Face( library
, path
, (FT_Long
) face_index
, &face
);
521 if ( error
== FT_Err_Cannot_Open_Stream
)
522 panic( "Could not find/open font resource" );
524 panic( "Error while opening font resource" );
529 error
= FT_Request_Size( face
, &req
);
531 panic( "Could not reset instance" );
533 printf("Please wait, converting %s to %s:\n",path
,outfile
);
535 if ( limit_char
== 0 ) limit_char
= MAX_CHAR
;
536 if ( limit_char
> MAX_CHAR
) limit_char
= MAX_CHAR
;
538 FT_Long char_count
= 0;
540 /* Set font header data */
541 struct font_header_struct export_font
;
542 export_font
.header
[0] = 'R';
543 export_font
.header
[1] = 'B';
544 export_font
.header
[2] = '1';
545 export_font
.header
[3] = '2';
547 export_font
.maxwidth
= 0;
548 h
= min_start_y
= ((face
->size
->metrics
.ascender
549 - face
->size
->metrics
.descender
+ 63) >> 6);
552 export_font
.ascent
= (face
->size
->metrics
.ascender
+ 63) >> 6;
553 export_font
.depth
= depth
;
554 firstchar
= limit_char
;
555 lastchar
= limit_char
;
556 default_char
= limit_char
;
557 #if log_level >= log_level_header
558 fprintf(pTmplog
, "limit_char=%ld\n", limit_char
);
559 fprintf(pTmplog
, "face->size->metrics.ascender>>6=%ld\n",
560 face
->size
->metrics
.ascender
>>6);
561 fprintf(pTmplog
, "face->size->metrics.descender>>6=%ld\n",
562 face
->size
->metrics
.descender
>>6);
567 /* decide common height, first_char and last_char, char_count */
568 FT_Long tmp_count
= 0;
569 printf("calculating height...\n"); fflush(stdout
);
571 error
= FT_Load_Glyph( face
, 0, (FT_LOAD_NO_BITMAP
) );
574 FT_Long glyph_height
= face
->glyph
->metrics
.height
>> 6;
575 FT_Long start_y
= export_font
.ascent
- face
->glyph
->bitmap_top
;
576 FT_Long end_y
= start_y
+ glyph_height
;
579 if (end_y
> max_end_y
) max_end_y
= end_y
;
580 if (start_y
< min_start_y
) min_start_y
= start_y
;
585 for(code
= start_char
; code
<= limit_char
; code
++ )
589 /* combining diacritical marks */
593 /* combining diacritical marks supplement */
597 /* combining diacritical marks for symbols */
601 /* high surrogates */
609 /* combining half marks */
614 /* Is there glyph of this code in this ttf? */
615 charindex
= getcharindex( face
, code
);
616 if ( !(charindex
) ) goto check_default
;
618 printf("\t%3d%% \e[K\r", (int) (tmp_count
++
619 * 100 / face
->num_glyphs
) );
622 error
= FT_Load_Glyph( face
, charindex
, (FT_LOAD_RENDER
|
623 FT_LOAD_NO_BITMAP
) );
624 if ( error
) goto check_default
;
626 /* Is this glyph available? */
627 if (!(w
= calculate_output_glyph_data(face
->glyph
, NULL
)))
630 /* count this font */
631 glyph_index
[code
] = charindex
;
635 FT_Long glyph_height
= face
->glyph
->metrics
.height
>> 6;
636 FT_Long start_y
= export_font
.ascent
- face
->glyph
->bitmap_top
;
637 FT_Long end_y
= start_y
+ glyph_height
;
639 #if log_level >= log_level_description1
640 fprintf(pTmplog
, "code=%ld\n", code
);
644 #if log_level >= log_level_description2
645 fprintf(pTmplog
, "\t glyph_height =%ld \n",
646 (face
->glyph
->metrics
.height
) >> 6);
647 fprintf(pTmplog
, "\t horiBearingY =%ld \n",
648 (face
->glyph
->metrics
.horiBearingY
>>6) );
649 fprintf(pTmplog
, "\t vertBearingY =%ld \n",
650 (face
->glyph
->metrics
.vertBearingY
>>6));
651 fprintf(pTmplog
, "\t vertAdvance =%ld \n",
652 (face
->glyph
->metrics
.vertAdvance
>>6));
653 fprintf(pTmplog
, "\t start_y =%ld \n", start_y
);
654 fprintf(pTmplog
, "\t height =%ld \n",
655 (face
->glyph
->metrics
.height
>> 6));
656 fprintf(pTmplog
, "\t end_y =%ld \n", end_y
);
658 if (face
->glyph
->bitmap_top
!= (face
->glyph
->metrics
.horiBearingY
>>6))
659 fprintf(pTmplog
, "\t bitmap_top =%d \n",
660 face
->glyph
->bitmap_top
);
661 if (face
->glyph
->bitmap
.rows
!= glyph_height
)
662 fprintf(pTmplog
, "\t bitmap.rows =%d \n",
663 face
->glyph
->bitmap
.rows
);
667 if (code
< firstchar
) firstchar
= code
;
669 if (end_y
> max_end_y
) max_end_y
= end_y
;
670 if (start_y
< min_start_y
) min_start_y
= start_y
;
673 if (firstchar
< limit_char
&& default_char
== limit_char
)
676 min_start_y
= MAX(min_start_y
, 0);
677 max_end_y
= MIN(max_end_y
, h
);
678 h
= (max_end_y
- min_start_y
);
679 req
.type
= FT_SIZE_REQUEST_TYPE_SCALES
;
680 req
.height
= req
.width
= face
->size
->metrics
.x_scale
681 * (pixel_size
- between_row
) / h
;
682 min_start_y
= min_start_y
* (pixel_size
- between_row
) / h
;
683 h
= export_font
.height
= pixel_size
;
684 if (default_char
== limit_char
)
685 default_char
= --firstchar
;
686 error
= FT_Request_Size( face
, &req
);
688 panic( "Could not reset instance" );
689 export_font
.ascent
= face
->size
->metrics
.ascender
>> 6;
691 export_font
.height
= h
;
692 int extra_top
= between_row
>> 1; /* about half of between_row */
693 printf("\t done.\t\n");
694 printf("\t%ld glyphs are encoded in this source file according to a source"
695 " font property.\n", face
->num_glyphs
);
696 printf("\t%ld characters can be converted.\n", char_count
);
697 printf("\tfirst character = %ld\n", firstchar
);
698 printf("\tlast character = %ld\n", lastchar
);
699 printf("\tdefault character = %d\n", default_char
);
700 printf("\tline height = %d\n\n", h
);
703 #if log_level >= log_level_header
704 fprintf(pTmplog
, "requested size=%.2f\n", req
.height
/ 64.0);
705 fprintf(pTmplog
, "max_end_y=%ld\n", max_end_y
);
706 fprintf(pTmplog
, "min_start_y=%ld\n", min_start_y
);
707 fprintf(pTmplog
, "ascender - descender = %ld \n",
708 (face
->size
->metrics
.ascender
- face
->size
->metrics
.descender
)>>6);
709 fprintf(pTmplog
, "h = %ld \n", (FT_Long
) h
);
712 export_font
.size
= lastchar
- firstchar
+ 1;
713 export_font
.noffset
= export_font
.size
;
714 export_font
.nwidth
= export_font
.size
;
715 export_font
.defaultchar
= default_char
;
716 export_font
.firstchar
= firstchar
;
717 uint32_t offsets
[export_font
.size
];
718 uint8_t widths
[export_font
.size
];
719 memset(offsets
, 0, sizeof(offsets
));
720 memset(widths
, 0, sizeof(widths
));
723 fprintf(stderr
,"converting font...\n"); fflush(stdout
);
724 for( code
= firstchar
; code
<= lastchar
; code
++)
726 printf("\t%3d%% \e[K\r", (int)((code
- firstchar
+ 1)
727 * 100 / export_font
.size
));
729 offsets
[code
- firstchar
] = offsets
[default_char
];
730 widths
[code
- firstchar
] = widths
[default_char
];
731 if (!(charindex
= glyph_index
[code
])
732 && (!got_default
|| code
!= default_char
))
734 error
= FT_Load_Glyph( face
, charindex
,
735 FT_LOAD_RENDER
|FT_LOAD_NO_BITMAP
);
738 if FT_HAS_GLYPH_NAMES(face
)
739 FT_Get_Glyph_Name(face
, charindex
, char_name
, 16);
743 FT_Bitmap
*source
= &face
->glyph
->bitmap
;
745 if (!(w
= calculate_output_glyph_data(face
->glyph
, &start_x
)))
748 export_font
.maxwidth
= MAX(w
, export_font
.maxwidth
);
749 unsigned char* src
= source
->buffer
;
750 unsigned char tmpbuf
[w
* h
];
751 memset(tmpbuf
, 0xff, w
* h
);
752 FT_Long start_y
= export_font
.ascent
- face
->glyph
->bitmap_top
;
753 FT_Long glyph_height
= face
->glyph
->metrics
.height
>> 6;
754 FT_Long glyph_width
= face
->glyph
->metrics
.width
>> 6;
755 unsigned char *buf
= tmpbuf
;
756 int offset
= extra_top
+ (start_y
- min_start_y
);
761 src
+= -offset
* glyph_width
;
762 int max_col
= MIN(glyph_width
, w
- start_x
);
763 int max_row
= MIN(h
- MAX(offset
, 0), glyph_height
+ MIN(offset
, 0));
764 unsigned char *endbuf
= buf
+ w
* max_row
;
767 for(; buf
< endbuf
; buf
+= w
, src
+= glyph_width
)
768 for(col
=0; col
< max_col
; col
++)
769 buf
[col
+ start_x
]= 0xff - src
[col
];
773 if (!empty_glyphs
[w
])
775 int glyph_size
= (w
* h
+ 1) / 2;
776 empty_glyphs
[w
] = index
;
777 if (glyph_buffer_size
< index
+ glyph_size
)
778 if (!(glyph_buffer
= realloc(glyph_buffer
,
779 glyph_buffer_size
+= (glyph_size
* 2 + 1023) & ~1023)))
780 panic("Failed to allocate memory for glyphs");
781 memset(&glyph_buffer
[index
], 0xff, glyph_size
);
784 offsets
[code
- firstchar
] = empty_glyphs
[w
];
785 widths
[code
- firstchar
] = w
;
788 offsets
[code
- firstchar
] = index
;
789 widths
[code
- firstchar
] = w
;
793 int glyph_size
= (w
* h
+ 1) / 2;
794 if (glyph_buffer_size
< index
+ glyph_size
)
795 if (!(glyph_buffer
= realloc(glyph_buffer
, glyph_buffer_size
796 += (glyph_size
* 2 + 1023) & ~1023)))
797 panic("Failed to allocate memory for glyphs");
798 for (i
= 0; i
< w
* h
; i
++)
801 unsigned char pixel
= ((unsigned)(*buf
++) + 8) / 17;
802 field
|= pixel
<< (subcol
<< 2);
805 glyph_buffer
[index
++] = field
;
811 glyph_buffer
[index
++] = field
;
813 printf("\t done.\t\n");
814 export_font
.nbits
= index
;
816 FILE *file
= fopen(outfile
, "w");
817 n
= fwrite(&export_font
, 1, sizeof(struct font_header_struct
), file
);
818 /* This prevents valgrind from triggering on the write from uninitialized
821 memset(glyph_buffer
+ index
, 0, glyph_buffer_size
- index
);
822 n
= fwrite(glyph_buffer
, 1, (index
+ 3) & ~3, file
);
823 int offsets_size
= export_font
.noffset
* 4;
824 if ( index
< 0xFFDB )
826 uint16_t * short_offsets
= (uint16_t *)offsets
;
828 for (i
= 0; i
< export_font
.noffset
; i
++)
829 short_offsets
[i
] = offsets
[i
];
832 n
= fwrite(offsets
, 1, offsets_size
, file
);
833 n
= fwrite(widths
, 1, export_font
.nwidth
, file
);
835 #if log_level > log_level_nolog
840 void convttc(char* path
)
842 struct ttc_table ttcname
;
845 get_ttc_table(path
, &ttcname
);
847 if (ttcname
.ttc_count
== 0)
849 printf("This file is a not true type font.\n");
859 printf("path: %s\n", path
);
860 sprintf(outfile
, "%d-%s.fnt", pixel_size
, basename(path
));
862 convttf(path
, (FT_Long
) 0);
865 /* set face_index of ttc */
866 else if (!flg_all_ttc
)
868 print_ttc_table(path
);
871 if (ttc_index
>= 0 &&
872 ttc_index
< ttcname
.ttc_count
)
874 if (strcmp(ttcname
.ttf_name
[ttc_index
], "") != 0)
876 sprintf(outfile
, "%d-%s.fnt", pixel_size
,
877 ttcname
.ttf_name
[ttc_index
]);
881 sprintf(outfile
, "%d-%s-%ld.fnt",
882 pixel_size
,basename(path
),ttc_index
);
887 printf("illegal face index of ttc.\n");
890 convttf(path
, ttc_index
);
892 else { /* convert all fonts */
893 print_ttc_table(path
);
894 for(i
= 0; i
< ttcname
.ttc_count
; i
++)
897 sprintf(outfile
, "%d-%s.fnt", pixel_size
, ttcname
.ttf_name
[i
]);
901 for(i
= 0; i
< ttcname
.ttc_count
; i
++)
903 free(ttcname
.ttf_name
[i
]);
905 free(ttcname
.ttf_name
);
910 /* parse command line options*/
911 void getopts(int *pac
, char ***pav
)
919 limit_char
= MAX_CHAR
;
922 while (ac
> 0 && av
[0][0] == '-') {
929 case ' ': /* multiple -args on av[]*/
930 while( *p
&& *p
== ' ')
932 if( *p
++ != '-') /* next option must have dash*/
934 break; /* proceed to next option*/
935 case 'o':case 'O': /* set output file*/
939 while (*p
&& *p
!= ' ')
945 strcpy(outfile
, av
[0]);
948 case 'l':case 'L': /* set encoding limit*/
950 limit_char
= atoi(p
);
951 while (*p
&& *p
!= ' ')
957 limit_char
= atoi(av
[0]);
960 case 's':case 'S': /* set encoding start*/
962 start_char
= atol(p
);
963 while (*p
&& *p
!= ' ')
969 start_char
= atol(av
[0]);
972 case 'p':case 'P': /* set pixel size*/
974 pixel_size
= atoi(p
);
975 while (*p
&& *p
!= ' ')
981 pixel_size
= atoi(av
[0]);
984 case 'c':case 'C': /* set spaece between characters */
986 between_chr
= atoi(p
);
987 while (*p
&& *p
!= ' ')
993 between_chr
= atoi(av
[0]);
996 case 'r':case 'R': /* set spaece between rows */
998 between_row
= atoi(p
);
999 while (*p
&& *p
!= ' ')
1005 between_row
= atoi(av
[0]);
1008 case 't':case 'T': /* display ttc table */
1009 if (*p
== 't' || *p
== 'T') {
1011 while (*p
&& *p
!= ' ')
1015 else if (*p
== 'a' || *p
== 'A') {
1017 while (*p
&& *p
!= ' ')
1022 ttc_index
= atoi(p
);
1023 while (*p
&& *p
!= ' ')
1029 ttc_index
= atoi(av
[0]);
1034 fprintf(stderr
, "Unknown option ignored: %c\r\n", *(p
-1));
1043 int main(int ac
, char **av
)
1047 ++av
; --ac
; /* skip av[0]*/
1049 getopts(&ac
, &av
); /* read command line options*/
1063 if (limit_char
< start_char
)
1069 while (pct
&& ac
> 0)
1071 print_ttc_table(av
[0]);
1088 * Trie node structure.
1091 unsigned short key
; /* Key value. */
1092 unsigned short val
; /* Data for the key. */
1093 unsigned long sibs
; /* Offset of siblings from trie beginning. */
1094 unsigned long kids
; /* Offset of children from trie beginning. */
1098 * The trie used for remapping codes.
1100 static node_t
*nodes
;
1101 static unsigned long nodes_used
= 0;
1104 otf2bdf_remap(unsigned short *code
)
1106 unsigned long i
, n
, t
;
1107 unsigned short c
, codes
[2];
1110 * If no mapping table was loaded, then simply return the code.
1112 if (nodes_used
== 0)
1116 codes
[0] = (c
>> 8) & 0xff;
1117 codes
[1] = c
& 0xff;
1119 for (i
= n
= 0; i
< 2; i
++) {
1123 for (; nodes
[t
].sibs
&& nodes
[t
].key
!= codes
[i
]; t
= nodes
[t
].sibs
);
1124 if (nodes
[t
].key
!= codes
[i
])
1129 *code
= nodes
[n
].val
;