2
Copyright (c) 2002-2003 by Juliusz Chroboczek
4
Permission is hereby granted, free of charge, to any person obtaining a copy
5
of this software and associated documentation files (the "Software"), to deal
6
in the Software without restriction, including without limitation the rights
7
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
copies of the Software, and to permit persons to whom the Software is
9
furnished to do so, subject to the following conditions:
11
The above copyright notice and this permission notice shall be included in
12
all copies or substantial portions of the Software.
14
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
/* $XdotOrg: xc/programs/mkfontscale/mkfontscale.c,v 1.2 2004/04/23 19:54:36 eich Exp $ */
23
/* $XFree86: xc/programs/mkfontscale/mkfontscale.c,v 1.21 2003/12/10 02:58:07 dawes Exp $ */
29
#include <sys/types.h>
35
#include <X11/fonts/fontenc.h>
37
#include FT_FREETYPE_H
38
#include FT_SFNT_NAMES_H
39
#include FT_TRUETYPE_TABLES_H
40
#include FT_TRUETYPE_IDS_H
41
#include FT_TYPE1_TABLES_H
43
#include FT_TRUETYPE_TABLES_H
58
#ifndef MAXFONTFILENAMELEN
59
#define MAXFONTFILENAMELEN 1024
61
#ifndef MAXFONTNAMELEN
62
#define MAXFONTNAMELEN 1024
65
char *encodings_array[] =
67
"iso8859-1", "iso8859-2", "iso8859-3", "iso8859-4", "iso8859-5",
68
"iso8859-6", "iso8859-6.8", "iso8859-6.8x", "iso8859-6.16",
69
"iso8859-7", "iso8859-8", "iso8859-9", "iso8859-10",
70
"iso8859-11", "iso8859-12", "iso8859-13", "iso8859-14",
71
"iso8859-15", "iso8859-16",
72
"ansi-1251", "koi8-r", "koi8-u", "koi8-ru", "koi8-e", "koi8-uni",
74
"sun.unicode.india-0", "suneu-greek",
75
"adobe-standard", "adobe-symbol",
76
"ibm-cp437", "ibm-cp850", "ibm-cp852", "ibm-cp866", "microsoft-cp1252",
77
/* But not "adobe-dingbats", as it uses generic glyph names. */
78
"cns11643-1", "cns11643-2", "cns11643-3",
79
"jisx0201.1976-0", "jisx0208.1983-0", "jisx0208.1990-0",
80
"jisx0212.1990-0", "big5-0", "big5.eten-0", "big5hkscs-0",
81
"gb2312.1980-0", "gb18030.2000-0", "gb18030.2000-1",
82
"ksc5601.1987-0", "ksc5601.1992-3"};
84
char *extra_encodings_array[] =
85
{ "iso10646-1", "adobe-fontspecific", "microsoft-symbol" };
87
ListPtr encodings, extra_encodings;
90
#define countof(_a) (sizeof(_a)/sizeof((_a)[0]))
92
static int doDirectory(char*, int, ListPtr);
93
static int checkEncoding(FT_Face face, char *encoding_name);
94
static int checkExtraEncoding(FT_Face face, char *encoding_name, int found);
95
static int find_cmap(int type, int pid, int eid, FT_Face face);
96
static char* notice_foundry(char *notice);
97
static char* vendor_foundry(signed char *vendor);
98
static int readFontScale(HashTablePtr entries, char *dirname);
99
ListPtr makeXLFD(char *filename, FT_Face face, int);
100
static int readEncodings(ListPtr encodings, char *dirname);
102
static FT_Library ft_library;
103
static float bigEncodingFuzz = 0.02;
106
static int doScalable;
107
static int doBitmaps;
108
static int doISO10646_1_encoding;
109
static int onlyEncodings;
110
static ListPtr encodingsToDo;
111
static int reencodeLegacy;
112
static char *encodingPrefix;
113
static char *exclusionSuffix;
119
"mkfontscale [ -b ] [ -s ] [ -o filename ] [-x suffix ]\n"
120
" [ -a encoding ] [ -f fuzz ] [ -l ] "
121
" [ -e directory ] [ -p prefix ] [ -n ] [ -r ] \n"
122
" [-u] [-U] [ directory ]...\n");
126
main(int argc, char **argv)
131
char prefix[NPREFIX];
133
encodingPrefix = NULL;
134
exclusionSuffix = NULL;
136
if(getcwd(prefix, NPREFIX - 1) == NULL) {
137
perror("Couldn't get cwd");
140
if(prefix[strlen(prefix) - 1] != '/')
142
encodingPrefix = dsprintf("%s", prefix);
146
encodings = makeList(encodings_array, countof(encodings_array), NULL, 0);
148
extra_encodings = makeList(extra_encodings_array,
149
countof(extra_encodings_array),
152
doISO10646_1_encoding = 1;
157
encodingsToDo = NULL;
161
if(argv[argn][0] == '\0' || argv[argn][0] != '-')
163
if(argv[argn][1] == '-') {
166
} else if (strcmp(argv[argn], "-x") == 0) {
167
if(argn >= argc - 1) {
171
exclusionSuffix = argv[argn + 1];
173
} else if(strcmp(argv[argn], "-a") == 0) {
174
if(argn >= argc - 1) {
178
makeList(&argv[argn + 1], 1, encodings, 0);
180
} else if(strcmp(argv[argn], "-p") == 0) {
181
if(argn >= argc - 1) {
185
if(strlen(argv[argn + 1]) > NPREFIX - 1) {
189
free(encodingPrefix);
190
encodingPrefix = dsprintf("%s", argv[argn + 1]);
192
} else if(strcmp(argv[argn], "-e") == 0) {
193
if(argn >= argc - 1) {
197
rc = readEncodings(encodingsToDo, argv[argn + 1]);
201
} else if(strcmp(argv[argn], "-b") == 0) {
204
} else if(strcmp(argv[argn], "-u") == 0) {
205
doISO10646_1_encoding = 0;
207
} else if(strcmp(argv[argn], "-U") == 0) {
208
doISO10646_1_encoding = 1;
210
} else if(strcmp(argv[argn], "-s") == 0) {
213
} else if(strcmp(argv[argn], "-n") == 0) {
216
} else if(strcmp(argv[argn], "-r") == 0) {
219
} else if(strcmp(argv[argn], "-l") == 0) {
220
reencodeLegacy = !reencodeLegacy;
222
} else if(strcmp(argv[argn], "-o") == 0) {
223
if(argn >= argc - 1) {
227
outfilename = argv[argn + 1];
229
} else if(strcmp(argv[argn], "-f") == 0) {
230
if(argn >= argc - 1) {
234
bigEncodingFuzz = atof(argv[argn + 1]) / 100.0;
236
} else if (strcmp(argv[argn], "-r") == 0) { /* ignore for now */
238
} else if (strcmp(argv[argn], "-n") == 0) {
246
if(outfilename == NULL) {
248
outfilename = "fonts.dir";
250
outfilename = "fonts.scale";
253
ftrc = FT_Init_FreeType(&ft_library);
255
fprintf(stderr, "Could not initialise FreeType library: %d\n", ftrc);
259
ll = listLength(encodingsToDo);
262
doDirectory(".", ll, encodingsToDo);
265
doDirectory(argv[argn], ll, encodingsToDo);
272
getNameHelper(FT_Face face, int nid, int pid, int eid,
273
FT_SfntName *name_return)
278
n = FT_Get_Sfnt_Name_Count(face);
282
for(i = 0; i < n; i++) {
283
if(FT_Get_Sfnt_Name(face, i, &name))
285
if(name.name_id == nid &&
286
name.platform_id == pid &&
287
(eid < 0 || name.encoding_id == eid)) {
288
switch(name.platform_id) {
289
case TT_PLATFORM_APPLE_UNICODE:
290
case TT_PLATFORM_MACINTOSH:
291
if(name.language_id != TT_MAC_LANGID_ENGLISH)
294
case TT_PLATFORM_MICROSOFT:
295
if(name.language_id != TT_MS_LANGID_ENGLISH_UNITED_STATES &&
296
name.language_id != TT_MS_LANGID_ENGLISH_UNITED_KINGDOM)
302
if(name.string_len > 0) {
312
getName(FT_Face face, int nid)
318
if(getNameHelper(face, nid,
319
TT_PLATFORM_MICROSOFT, TT_MS_ID_UNICODE_CS, &name) ||
320
getNameHelper(face, nid,
321
TT_PLATFORM_APPLE_UNICODE, -1, &name)) {
322
string = malloc(name.string_len / 2 + 1);
324
fprintf(stderr, "Couldn't allocate name\n");
327
for(i = 0; i < name.string_len / 2; i++) {
328
if(name.string[2 * i] != 0)
331
string[i] = name.string[2 * i + 1];
337
/* Pretend that Apple Roman is ISO 8859-1. */
338
if(getNameHelper(face, nid, TT_PLATFORM_MACINTOSH, TT_MAC_ID_ROMAN,
340
string = malloc(name.string_len + 1);
342
fprintf(stderr, "Couldn't allocate name\n");
345
memcpy(string, name.string, name.string_len);
346
string[name.string_len] = '\0';
354
os2Weight(int weight)
358
else if(weight < 250)
360
else if(weight < 350)
362
else if(weight < 450)
363
return "medium"; /* officially "normal" */
364
else if(weight < 550)
366
else if(weight < 650)
368
else if(weight < 750)
370
else if(weight < 850)
380
return "ultracondensed";
382
return "extracondensed";
386
return "semicondensed";
390
return "semiexpanded";
394
return "extraexpanded";
396
return "ultraexpanded";
399
static char *widths[] = {
400
"ultracondensed", "extracondensed", "condensed", "semicondensed",
401
"normal", "semiexpanded", "expanded", "extraexpanded", "ultraexpanded"
404
#define NUMWIDTHS (sizeof(widths) / sizeof(widths[0]))
407
nameWidth(char *name)
411
int n = strlen(name);
413
if(n >= 499) return NULL;
414
for(i = 0; i < n; i++)
415
buf[i] = tolower(name[i]);
418
for(i = 0; i < NUMWIDTHS; i++)
419
if(strstr(buf, widths[i]))
425
t1Weight(char *weight)
429
if(strcmp(weight, "Thin") == 0)
431
if(strcmp(weight, "Light") == 0)
433
if(strcmp(weight, "Regular") == 0)
435
if(strcmp(weight, "Normal") == 0)
437
if(strcmp(weight, "Medium") == 0)
439
if(strcmp(weight, "Book") == 0)
441
if(strcmp(weight, "Roman") == 0) /* Some URW++ fonts do that! */
443
if(strcmp(weight, "Demi") == 0)
445
if(strcmp(weight, "DemiBold") == 0)
447
else if(strcmp(weight, "Bold") == 0)
449
else if(strcmp(weight, "Black") == 0)
452
fprintf(stderr, "Unknown Type 1 weight \"%s\"\n", weight);
461
c < 0x20 || c > 0x7E ||
462
c == '[' || c == ']' || c == '(' || c == ')' || c == '\\' || c == '-';
468
int i, len, safe_flag = 1;
472
while(s[i] != '\0') {
478
if(safe_flag) return s;
483
perror("Couldn't allocate string");
487
for(i = 0; i < len; i++) {
498
makeXLFD(char *filename, FT_Face face, int isBitmap)
501
char *foundry, *family, *weight, *slant, *sWidth, *adstyle,
502
*spacing, *full_name;
507
PS_FontInfoRec *t1info, t1info_rec;
519
head = FT_Get_Sfnt_Table(face, ft_sfnt_head);
520
hhea = FT_Get_Sfnt_Table(face, ft_sfnt_hhea);
521
os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2);
522
post = FT_Get_Sfnt_Table(face, ft_sfnt_post);
524
rc = FT_Get_PS_Font_Info(face, &t1info_rec);
526
t1info = &t1info_rec;
531
family = getName(face, TT_NAME_ID_FONT_FAMILY);
533
family = getName(face, TT_NAME_ID_FULL_NAME);
535
family = getName(face, TT_NAME_ID_PS_NAME);
538
full_name = getName(face, TT_NAME_ID_FULL_NAME);
540
full_name = getName(face, TT_NAME_ID_PS_NAME);
542
if(os2 && os2->version != 0xFFFF) {
544
weight = os2Weight(os2->usWeightClass);
546
sWidth = os2Width(os2->usWidthClass);
548
foundry = vendor_foundry(os2->achVendID);
550
slant = os2->fsSelection & 1 ? "i" : "r";
555
if(post->isFixedPitch) {
556
if(hhea->min_Left_Side_Bearing >= 0 &&
557
hhea->xMax_Extent <= hhea->advance_Width_Max) {
570
family = t1info->family_name;
572
family = t1info->full_name;
574
full_name = t1info->full_name;
576
foundry = notice_foundry(t1info->notice);
578
weight = t1Weight(t1info->weight);
580
spacing = t1info->is_fixed_pitch ? "m" : "p";
582
/* Bitstream fonts have positive italic angle. */
584
t1info->italic_angle <= -4 || t1info->italic_angle >= 4 ?
590
fprintf(stderr, "Couldn't determine full name for %s\n", filename);
591
full_name = filename;
596
slant = head->Mac_Style & 2 ? "i" : "r";
598
weight = head->Mac_Style & 1 ? "bold" : "medium";
602
fprintf(stderr, "Couldn't determine slant for %s\n", filename);
607
fprintf(stderr, "Couldn't determine weight for %s\n", filename);
613
notice = getName(face, TT_NAME_ID_TRADEMARK);
615
foundry = notice_foundry(notice);
618
notice = getName(face, TT_NAME_ID_MANUFACTURER);
620
foundry = notice_foundry(notice);
625
if(strcmp(slant, "i") == 0) {
626
if(strstr(full_name, "Oblique"))
628
if(strstr(full_name, "Slanted"))
633
sWidth = nameWidth(full_name);
635
if(!foundry) foundry = "misc";
637
fprintf(stderr, "Couldn't get family name for %s\n", filename);
641
if(!weight) weight = "medium";
642
if(!slant) slant = "r";
643
if(!sWidth) sWidth = "normal";
644
if(!adstyle) adstyle = "";
645
if(!spacing) spacing = "p";
647
/* Yes, it's a memory leak. */
648
foundry = safe(foundry);
649
family = safe(family);
652
xlfd = listConsF(xlfd,
653
"-%s-%s-%s-%s-%s-%s-0-0-0-0-%s-0",
655
weight, slant, sWidth, adstyle, spacing);
657
int i, w, h, xres, yres;
658
for(i = 0; i < face->num_fixed_sizes; i++) {
659
w = face->available_sizes[i].width;
660
h = face->available_sizes[i].height;
662
yres = (double)h / w * xres;
663
xlfd = listConsF(xlfd,
664
"-%s-%s-%s-%s-%s-%s-%d-%d-%d-%d-%s-%d",
666
weight, slant, sWidth, adstyle,
667
h, (int)(h / (double)yres * 72.27 * 10 + 0.5),
676
readFontScale(HashTablePtr entries, char *dirname)
678
int n = strlen(dirname);
682
char file[MAXFONTFILENAMELEN], font[MAXFONTNAMELEN];
685
snprintf(format, 100, "%%%ds %%%d[^\n]\n",
686
MAXFONTFILENAMELEN, MAXFONTNAMELEN);
688
if(dirname[n - 1] == '/')
689
filename = dsprintf("%sfonts.scale", dirname);
691
filename = dsprintf("%s/fonts.scale", dirname);
695
in = fopen(filename, "r");
699
perror("open(fonts.scale)");
703
rc = fscanf(in, "%d\n", &count);
705
fprintf(stderr, "Invalid fonts.scale in %s.\n", dirname);
710
for(i = 0; i < count; i++) {
711
rc = fscanf(in, format, file, font);
714
putHash(entries, font, file, 100);
721
filePrio(char *filename)
723
int n = strlen(filename);
726
if(strcmp(filename + n - 4, ".otf") == 0)
728
if(strcmp(filename + n - 4, ".OTF") == 0)
730
if(strcmp(filename + n - 4, ".ttf") == 0)
732
if(strcmp(filename + n - 4, ".TTF") == 0)
734
if(strcmp(filename + n - 3, ".gz") == 0)
736
if(strcmp(filename + n - 2, ".Z") == 0)
742
doDirectory(char *dirname_given, int numEncodings, ListPtr encodingsToDo)
744
char *dirname, *fontscale_name, *filename, *encdir;
745
FILE *fontscale, *encfile;
747
struct dirent *entry;
750
ListPtr encoding, xlfd, lp;
751
HashTablePtr entries;
752
HashBucketPtr *array;
757
xl = strlen (exclusionSuffix);
759
i = strlen(dirname_given);
761
dirname = dsprintf("./");
762
else if(dirname_given[i - 1] != '/')
763
dirname = dsprintf("%s/", dirname_given);
765
dirname = dsprintf("%s", dirname_given);
767
if(dirname == NULL) {
775
entries = makeHashTable();
776
if(doBitmaps && !doScalable) {
777
readFontScale(entries, dirname);
780
if(strcmp(outfilename, "-") == 0)
781
fontscale_name = NULL;
783
if(outfilename[0] == '/')
784
fontscale_name = dsprintf("%s", outfilename);
786
fontscale_name = dsprintf("%s%s", dirname, outfilename);
787
if(fontscale_name == NULL) {
788
perror("fontscale_name");
793
dirp = opendir(dirname);
795
fprintf(stderr, "%s: ", dirname);
800
if(fontscale_name == NULL)
803
fontscale = fopen(fontscale_name, "w");
805
if(fontscale == NULL) {
806
fprintf(stderr, "%s: ", fontscale_name);
811
while((entry = readdir(dirp)) != NULL) {
813
char *xlfd_name = NULL;
817
int dl = strlen (entry->d_name);
818
if (strcmp (entry->d_name + dl - xl, exclusionSuffix) == 0)
822
filename = dsprintf("%s%s", dirname, entry->d_name);
825
rc = bitmapIdentify(filename, &xlfd_name);
833
ftrc = FT_New_Face(ft_library, filename, 0, &face);
838
isBitmap = ((face->face_flags & FT_FACE_FLAG_SCALABLE) == 0);
841
/* Workaround for bitmap-only TTF fonts */
842
if(face->num_fixed_sizes > 0) {
844
maxp = FT_Get_Sfnt_Table(face, ft_sfnt_maxp);
845
if(maxp != NULL && maxp->maxContours == 0)
859
BDF_PropertyRec prop;
860
rc = FT_Get_BDF_Property(face, "FONT", &prop);
861
if(rc == 0 && prop.type == BDF_PROPERTY_TYPE_ATOM) {
862
xlfd_name = malloc(strlen(prop.u.atom) + 1);
863
if(xlfd_name == NULL)
865
strcpy(xlfd_name, prop.u.atom);
871
/* We know it's a bitmap font, and we know its XLFD */
872
int n = strlen(xlfd_name);
874
n >= 12 && strcasecmp(xlfd_name + n - 11, "-iso10646-1") == 0) {
878
memcpy(s, xlfd_name, n - 11);
880
xlfd = listCons(s, xlfd);
882
/* Not a reencodable font -- skip all the rest of the loop body */
883
putHash(entries, xlfd_name, entry->d_name, filePrio(entry->d_name));
889
ftrc = FT_New_Face(ft_library, filename, 0, &face);
893
isBitmap = ((face->face_flags & FT_FACE_FLAG_SCALABLE) == 0);
896
if(face->num_fixed_sizes > 0) {
898
maxp = FT_Get_Sfnt_Table(face, ft_sfnt_maxp);
899
if(maxp != NULL && maxp->maxContours == 0)
906
xlfd = makeXLFD(entry->d_name, face, isBitmap);
910
for(lp = xlfd; lp; lp = lp->next) {
911
char buf[MAXFONTNAMELEN];
912
for(encoding = encodings; encoding; encoding = encoding->next) {
913
if(checkEncoding(face, encoding->value)) {
915
snprintf(buf, MAXFONTNAMELEN, "%s-%s",
916
lp->value, encoding->value);
917
putHash(entries, buf, entry->d_name, filePrio(entry->d_name));
920
for(encoding = extra_encodings; encoding;
921
encoding = encoding->next) {
922
if(checkExtraEncoding(face, encoding->value, found)) {
923
/* Do not set found! */
924
snprintf(buf, MAXFONTNAMELEN, "%s-%s",
925
lp->value, encoding->value);
926
putHash(entries, buf, entry->d_name, filePrio(entry->d_name));
935
deepDestroyList(xlfd);
941
n = hashElements(entries);
942
fprintf(fontscale, "%d\n", n);
943
array = hashArray(entries, 1);
944
for(i = 0; i < n; i++)
945
fprintf(fontscale, "%s %s\n", array[i]->value, array[i]->key);
946
destroyHashArray(array);
950
free(fontscale_name);
954
encdir = dsprintf("%s%s", dirname, "encodings.dir");
963
encfile = fopen(encdir, "w");
964
if(encfile == NULL) {
965
perror("open(encodings.dir)");
968
fprintf(encfile, "%d\n", numEncodings);
969
for(lp = encodingsToDo; lp; lp = lp->next) {
970
fprintf(encfile, "%s\n", lp->value);
979
#define CODE_IGNORED(c) ((c) < 0x20 || \
980
((c) >= 0x7F && (c) <= 0xA0) || \
981
(c) == 0xAD || (c) == 0xF71B)
984
checkEncoding(FT_Face face, char *encoding_name)
991
encoding = FontEncFind(encoding_name, NULL);
995
/* An encoding is ``small'' if one of the following is true:
996
- it is linear and has no more than 256 codepoints; or
997
- it is a matrix encoding and has no more than one column.
999
For small encodings using Unicode indices, we require perfect
1000
coverage except for CODE_IGNORED and KOI-8 IBM-PC compatibility.
1002
For large encodings, we require coverage up to bigEncodingFuzz.
1004
For encodings using PS names (currently Adobe Standard and
1005
Adobe Symbol only), we require perfect coverage. */
1008
if(FT_Has_PS_Glyph_Names(face)) {
1009
for(mapping = encoding->mappings; mapping; mapping = mapping->next) {
1010
if(mapping->type == FONT_ENCODING_POSTSCRIPT) {
1011
if(encoding->row_size > 0) {
1012
for(i = encoding->first; i < encoding->size; i++) {
1013
for(j = encoding->first_col;
1014
j < encoding->row_size;
1016
n = FontEncName((i<<8) | j, mapping);
1017
if(n && FT_Get_Name_Index(face, n) == 0) {
1024
for(i = encoding->first; i < encoding->size; i++) {
1025
n = FontEncName(i, mapping);
1026
if(n && FT_Get_Name_Index(face, n) == 0) {
1036
for(mapping = encoding->mappings; mapping; mapping = mapping->next) {
1037
if(find_cmap(mapping->type, mapping->pid, mapping->eid, face)) {
1038
int total = 0, failed = 0;
1039
if(encoding->row_size > 0) {
1041
(encoding->size - encoding->first) *
1042
(encoding->row_size - encoding->first_col);
1043
for(i = encoding->first; i < encoding->size; i++) {
1044
for(j = encoding->first_col;
1045
j < encoding->row_size;
1047
c = FontEncRecode((i<<8) | j, mapping);
1048
if(CODE_IGNORED(c)) {
1051
if(FT_Get_Char_Index(face, c) == 0) {
1055
if((encoding->size <= 1 && failed > 0) ||
1056
((float)failed >= bigEncodingFuzz * estimate)) {
1062
if((float)failed >= total * bigEncodingFuzz)
1067
int estimate = encoding->size - encoding->first;
1068
/* For the KOI8 encodings, we ignore the lack of
1069
linedrawing and pseudo-math characters */
1070
if(strncmp(encoding->name, "koi8-", 5) == 0)
1074
for(i = encoding->first; i < encoding->size; i++) {
1075
c = FontEncRecode(i, mapping);
1076
if(CODE_IGNORED(c) ||
1077
(koi8 && ((c >= 0x2200 && c < 0x2600) || c == 0x00b2))) {
1080
if(FT_Get_Char_Index(face, c) == 0) {
1084
if((encoding->size <= 256 && failed > 0) ||
1085
((float)failed >= bigEncodingFuzz * estimate)) {
1090
if((float)failed >= total * bigEncodingFuzz)
1101
find_cmap(int type, int pid, int eid, FT_Face face)
1104
FT_CharMap cmap = NULL;
1106
n = face->num_charmaps;
1109
case FONT_ENCODING_TRUETYPE: /* specific cmap */
1110
for(i=0; i<n; i++) {
1111
cmap = face->charmaps[i];
1112
if(cmap->platform_id == pid && cmap->encoding_id == eid) {
1113
rc = FT_Set_Charmap(face, cmap);
1119
case FONT_ENCODING_UNICODE: /* any Unicode cmap */
1120
/* prefer Microsoft Unicode */
1121
for(i=0; i<n; i++) {
1122
cmap = face->charmaps[i];
1123
if(cmap->platform_id == TT_PLATFORM_MICROSOFT &&
1124
cmap->encoding_id == TT_MS_ID_UNICODE_CS) {
1125
rc = FT_Set_Charmap(face, cmap);
1131
/* Try Apple Unicode */
1132
for(i=0; i<n; i++) {
1133
cmap = face->charmaps[i];
1134
if(cmap->platform_id == TT_PLATFORM_APPLE_UNICODE) {
1135
rc = FT_Set_Charmap(face, cmap);
1141
for(i=0; i<n; i++) {
1142
cmap = face->charmaps[i];
1143
if(cmap->platform_id == TT_PLATFORM_ISO) {
1144
rc = FT_Set_Charmap(face, cmap);
1157
checkExtraEncoding(FT_Face face, char *encoding_name, int found)
1161
if(strcasecmp(encoding_name, "iso10646-1") == 0) {
1162
if(doISO10646_1_encoding && find_cmap(FONT_ENCODING_UNICODE, -1, -1, face)) {
1164
/* Export as Unicode if there are at least 15 BMP
1165
characters that are not a space or ignored. */
1166
for(c = 0x21; c < 0x10000; c++) {
1169
if(FT_Get_Char_Index(face, c) > 0)
1177
} else if(strcasecmp(encoding_name, "microsoft-symbol") == 0) {
1178
if(find_cmap(FONT_ENCODING_TRUETYPE,
1179
TT_PLATFORM_MICROSOFT, TT_MS_ID_SYMBOL_CS,
1184
} else if(strcasecmp(encoding_name, "adobe-fontspecific") == 0) {
1186
if(FT_Has_PS_Glyph_Names(face))
1193
fprintf(stderr, "Unknown extra encoding %s\n", encoding_name);
1199
notice_foundry(char *notice)
1202
for(i = 0; i < countof(notice_foundries); i++)
1203
if(notice && strstr(notice, notice_foundries[i][0]))
1204
return notice_foundries[i][1];
1209
vendor_match(signed char *vendor, char *vendor_string)
1211
/* vendor is not necessarily NUL-terminated. */
1213
len = strlen(vendor_string);
1214
if(memcmp(vendor, vendor_string, len) != 0)
1216
for(i = len; i < 4; i++)
1217
if(vendor[i] != ' ' && vendor[i] != '\0')
1223
vendor_foundry(signed char *vendor)
1226
for(i = 0; i < countof(vendor_foundries); i++)
1227
if(vendor_match(vendor, vendor_foundries[i][0]))
1228
return vendor_foundries[i][1];
1233
readEncodings(ListPtr encodings, char *dirname)
1237
struct dirent *file;
1238
char **names, **name;
1240
if(strlen(dirname) > 1 && dirname[strlen(dirname) - 1] == '/')
1241
dirname[strlen(dirname) - 1] = '\0';
1243
dirp = opendir(dirname);
1249
while((file = readdir(dirp)) != NULL) {
1250
fullname = dsprintf("%s/%s", dirname, file->d_name);
1251
if(fullname == NULL) {
1252
fprintf(stderr, "Couldn't allocate fullname\n");
1257
names = FontEncIdentify(fullname);
1261
for(name = names; *name; name++) {
1262
if(fullname[0] != '/' && !relative) {
1264
n = dsprintf("%s%s", encodingPrefix, fullname);
1266
fprintf(stderr, "Couldn't allocate name\n");
1270
encodingsToDo = listConsF(encodingsToDo, "%s %s", *name, n);
1274
listConsF(encodingsToDo, "%s %s", *name, fullname);
1276
if(encodingsToDo == NULL) {
1277
fprintf(stderr, "Couldn't allocate encodings\n");
1282
free(names); /* only the spine */