summaryrefslogtreecommitdiff
path: root/mkfontscale.c
diff options
context:
space:
mode:
authorKaleb Keithley <kaleb@freedesktop.org>2003-11-26 22:49:10 +0000
committerKaleb Keithley <kaleb@freedesktop.org>2003-11-26 22:49:10 +0000
commitf420965b8e48aff65f0c181cb36cbd9410e88b1b (patch)
tree2765cce0a55cdbdd1a94e016469bdf8d086728c6 /mkfontscale.c
parent632e8a138dd16efe41384a4335ec46530da4a04b (diff)
merge latest (4.3.99.16) from XFree86 (vendor) branch
Diffstat (limited to 'mkfontscale.c')
-rw-r--r--mkfontscale.c877
1 files changed, 665 insertions, 212 deletions
diff --git a/mkfontscale.c b/mkfontscale.c
index 95db6e4..3036752 100644
--- a/mkfontscale.c
+++ b/mkfontscale.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2002 by Juliusz Chroboczek
+ Copyright (c) 2002-2003 by Juliusz Chroboczek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -19,7 +19,7 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
-/* $XFree86: xc/programs/mkfontscale/mkfontscale.c,v 1.4 2003/02/13 03:04:07 dawes Exp $ */
+/* $XFree86: xc/programs/mkfontscale/mkfontscale.c,v 1.17 2003/11/21 05:22:08 dawes Exp $ */
#include <stdio.h>
#include <stdlib.h>
@@ -27,54 +27,84 @@
#include <sys/types.h>
#include <dirent.h>
+#include <unistd.h>
+#include <errno.h>
#include <X11/fonts/fontenc.h>
-#include <freetype/freetype.h>
-#include <freetype/ftsnames.h>
-#include <freetype/tttables.h>
-#include <freetype/ttnameid.h>
-#include <freetype/t1tables.h>
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_SFNT_NAMES_H
+#include FT_TRUETYPE_TABLES_H
+#include FT_TRUETYPE_IDS_H
+#include FT_TYPE1_TABLES_H
+#include FT_BDF_H
+#include FT_TRUETYPE_TABLES_H
-#define CODE_IGNORED(c) ((c) < 0x20 || \
- ((c) >= 0x7F && (c) <= 0xA0) || \
- (c) == 0xAD)
-
#include "list.h"
+#include "hash.h"
#include "data.h"
+#include "ident.h"
+
+#define NPREFIX 1024
+
+#ifndef MAXFONTFILENAMELEN
+#define MAXFONTFILENAMELEN 1024
+#endif
+#ifndef MAXFONTNAMELEN
+#define MAXFONTNAMELEN 1024
+#endif
char *encodings_array[] =
{ "iso8859-1", "iso8859-2", "iso8859-3", "iso8859-4", "iso8859-5",
"iso8859-6", "iso8859-7", "iso8859-8", "iso8859-9", "iso8859-10",
"iso8859-11", "iso8859-12", "iso8859-13", "iso8859-14", "iso8859-15",
- "koi8-r", "koi8-u", "koi8-e",
- "adobe-standard", "adobe-symbol", "ibm-cp437", "microsoft-cp1252",
+ "koi8-r", "koi8-u", "koi8-ru", "koi8-e", "koi8-uni",
+ "tis620-2",
+ "adobe-standard", "adobe-symbol",
+ "ibm-cp437", "microsoft-cp1252",
/* But not "adobe-dingbats", as it uses generic glyph names. */
"jisx0201.1976-0", "jisx0208.1983-0", "jisx0208.1990-0",
- "jisx0212.1190-0", "big5-0", "gb2312.1980-0",
+ "jisx0212.1990-0", "big5-0", "gb2312.1980-0",
"ksc5601.1987-0", "ksc5601.1992-3"};
char *extra_encodings_array[] =
{ "iso10646-1", "adobe-fontspecific", "microsoft-symbol" };
ListPtr encodings, extra_encodings;
+char *outfilename;
#define countof(_a) (sizeof(_a)/sizeof((_a)[0]))
-int doDirectory(char*);
+static int doDirectory(char*, int, ListPtr);
static int checkEncoding(FT_Face face, char *encoding_name);
static int checkExtraEncoding(FT_Face face, char *encoding_name, int found);
static int find_cmap(int type, int pid, int eid, FT_Face face);
static char* notice_foundry(char *notice);
static char* vendor_foundry(signed char *vendor);
+static int readFontScale(HashTablePtr entries, char *dirname);
+ListPtr makeXLFD(char *filename, FT_Face face, int);
+static int readEncodings(ListPtr encodings, char *dirname);
static FT_Library ft_library;
static float bigEncodingFuzz = 0.02;
+static int relative;
+static int doScalable;
+static int doBitmaps;
+static int onlyEncodings;
+static ListPtr encodingsToDo;
+static int reencodeLegacy;
+static char *encodingPrefix;
+static char *exclusionSuffix;
+
static void
usage(void)
{
fprintf(stderr,
- "mkfontscale [ -e encoding ] [ -f fuzz ] [ directory ]\n");
+ "mkfontscale [ -b ] [ -s ] [ -o filename ] [-x suffix ]\n"
+ " [ -a encoding ] [ -f fuzz ] [ -l ] "
+ " [ -e directory ] [ -p prefix ] [ -n ] [ -r ] \n"
+ " [ directory ]...\n");
}
int
@@ -82,12 +112,33 @@ main(int argc, char **argv)
{
int argn;
FT_Error ftrc;
+ int rc, ll = 0;
+ char prefix[NPREFIX];
+
+ encodingPrefix = NULL;
+ exclusionSuffix = NULL;
+
+ if(getcwd(prefix, NPREFIX - 1) == NULL) {
+ perror("Couldn't get cwd");
+ exit(1);
+ }
+ if(prefix[strlen(prefix) - 1] != '/')
+ strcat(prefix, "/");
+ encodingPrefix = dsprintf("%s", prefix);
+
+ outfilename = NULL;
encodings = makeList(encodings_array, countof(encodings_array), NULL, 0);
extra_encodings = makeList(extra_encodings_array,
countof(extra_encodings_array),
NULL, 0);
+ doBitmaps = 0;
+ doScalable = 1;
+ onlyEncodings = 0;
+ relative = 0;
+ reencodeLegacy = 1;
+ encodingsToDo = NULL;
argn = 1;
while(argn < argc) {
@@ -96,38 +147,100 @@ main(int argc, char **argv)
if(argv[argn][1] == '-') {
argn++;
break;
- } else if(argv[argn][1] == 'e') {
+ } else if (strcmp(argv[argn], "-x") == 0) {
+ if(argn >= argc - 1) {
+ usage();
+ exit(1);
+ }
+ exclusionSuffix = argv[argn + 1];
+ argn += 2;
+ } else if(strcmp(argv[argn], "-a") == 0) {
if(argn >= argc - 1) {
usage();
exit(1);
}
makeList(&argv[argn + 1], 1, encodings, 0);
argn += 2;
- } else if(argv[argn][1] == 'f') {
+ } else if(strcmp(argv[argn], "-p") == 0) {
+ if(argn >= argc - 1) {
+ usage();
+ exit(1);
+ }
+ if(strlen(argv[argn + 1]) > NPREFIX - 1) {
+ usage();
+ exit(1);
+ }
+ free(encodingPrefix);
+ encodingPrefix = dsprintf("%s", argv[argn + 1]);
+ argn += 2;
+ } else if(strcmp(argv[argn], "-e") == 0) {
+ if(argn >= argc - 1) {
+ usage();
+ exit(1);
+ }
+ rc = readEncodings(encodingsToDo, argv[argn + 1]);
+ if(rc < 0)
+ exit(1);
+ argn += 2;
+ } else if(strcmp(argv[argn], "-b") == 0) {
+ doBitmaps = 1;
+ argn++;
+ } else if(strcmp(argv[argn], "-s") == 0) {
+ doScalable = 0;
+ argn++;
+ } else if(strcmp(argv[argn], "-n") == 0) {
+ onlyEncodings = 1;
+ argn++;
+ } else if(strcmp(argv[argn], "-r") == 0) {
+ relative = 1;
+ argn++;
+ } else if(strcmp(argv[argn], "-l") == 0) {
+ reencodeLegacy = !reencodeLegacy;
+ argn++;
+ } else if(strcmp(argv[argn], "-o") == 0) {
+ if(argn >= argc - 1) {
+ usage();
+ exit(1);
+ }
+ outfilename = argv[argn + 1];
+ argn += 2;
+ } else if(strcmp(argv[argn], "-f") == 0) {
if(argn >= argc - 1) {
usage();
exit(1);
}
bigEncodingFuzz = atof(argv[argn + 1]) / 100.0;
argn += 2;
- } else {
+ } else if (strcmp(argv[argn], "-r") == 0) { /* ignore for now */
+ argn++;
+ } else if (strcmp(argv[argn], "-n") == 0) {
+ argn++;
+ } else {
usage();
exit(1);
}
}
+ if(outfilename == NULL) {
+ if(doBitmaps)
+ outfilename = "fonts.dir";
+ else
+ outfilename = "fonts.scale";
+ }
+
ftrc = FT_Init_FreeType(&ft_library);
if(ftrc) {
fprintf(stderr, "Could not initialise FreeType library: %d\n", ftrc);
exit(1);
}
-
+
+ ll = listLength(encodingsToDo);
if (argn == argc)
- doDirectory(".");
+ doDirectory(".", ll, encodingsToDo);
else
while(argn < argc) {
- doDirectory(argv[argn]);
+ doDirectory(argv[argn], ll, encodingsToDo);
argn++;
}
return 0;
@@ -261,11 +374,40 @@ os2Width(int width)
return "ultraexpanded";
}
+static char *widths[] = {
+ "ultracondensed", "extracondensed", "condensed", "semicondensed",
+ "normal", "semiexpanded", "expanded", "extraexpanded", "ultraexpanded"
+};
+
+#define NUMWIDTHS (sizeof(widths) / sizeof(widths[0]))
+
+static char*
+nameWidth(char *name)
+{
+ char buf[500];
+ int i;
+ int n = strlen(name);
+
+ if(n >= 499) return NULL;
+ for(i = 0; i < n; i++)
+ buf[i] = tolower(name[i]);
+ buf[i] = '\0';
+
+ for(i = 0; i < NUMWIDTHS; i++)
+ if(strstr(buf, widths[i]))
+ return widths[i];
+ return NULL;
+}
+
static char*
t1Weight(char *weight)
{
if(!weight)
return NULL;
+ if(strcmp(weight, "Thin") == 0)
+ return "thin";
+ if(strcmp(weight, "Light") == 0)
+ return "light";
if(strcmp(weight, "Regular") == 0)
return "medium";
if(strcmp(weight, "Normal") == 0)
@@ -282,23 +424,14 @@ t1Weight(char *weight)
return "semibold";
else if(strcmp(weight, "Bold") == 0)
return "bold";
+ else if(strcmp(weight, "Black") == 0)
+ return "black";
else {
fprintf(stderr, "Unknown Type 1 weight \"%s\"\n", weight);
return NULL;
}
}
-static char*
-strcat_reliable(char *a, char *b)
-{
- char *c = malloc(strlen(a) + strlen(b) + 1);
- if(c == NULL)
- return NULL;
- strcpy(c, a);
- strcat(c, b);
- return c;
-}
-
static int
unsafe(char c)
{
@@ -339,33 +472,301 @@ safe(char* s)
return t;
}
-int
-doDirectory(char *dirname_given)
+ListPtr
+makeXLFD(char *filename, FT_Face face, int isBitmap)
{
- char *dirname, *fontscale_name, *filename;
- FILE *fontscale;
- DIR *dirp;
- struct dirent *entry;
- FT_Error ftrc;
- FT_Face face;
+ ListPtr xlfd = NULL;
+ char *foundry, *family, *weight, *slant, *sWidth, *adstyle,
+ *spacing, *full_name;
TT_Header *head;
TT_HoriHeader *hhea;
TT_OS2 *os2;
TT_Postscript *post;
PS_FontInfoRec *t1info, t1info_rec;
- char *foundry, *family, *weight, *slant, *sWidth, *adstyle,
- *spacing, *full_name;
- ListPtr encoding, entries = NULL;
- int i, found, rc;
+ int rc;
+
+ foundry = NULL;
+ family = NULL;
+ weight = NULL;
+ slant = NULL;
+ sWidth = NULL;
+ adstyle = NULL;
+ spacing = NULL;
+ full_name = NULL;
+
+ head = FT_Get_Sfnt_Table(face, ft_sfnt_head);
+ hhea = FT_Get_Sfnt_Table(face, ft_sfnt_hhea);
+ os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2);
+ post = FT_Get_Sfnt_Table(face, ft_sfnt_post);
+
+ rc = FT_Get_PS_Font_Info(face, &t1info_rec);
+ if(rc == 0)
+ t1info = &t1info_rec;
+ else
+ t1info = NULL;
+
+ if(!family)
+ family = getName(face, TT_NAME_ID_FONT_FAMILY);
+ if(!family)
+ family = getName(face, TT_NAME_ID_FULL_NAME);
+ if(!family)
+ family = getName(face, TT_NAME_ID_PS_NAME);
+
+ if(!full_name)
+ full_name = getName(face, TT_NAME_ID_FULL_NAME);
+ if(!full_name)
+ full_name = getName(face, TT_NAME_ID_PS_NAME);
+
+ if(os2 && os2->version != 0xFFFF) {
+ if(!weight)
+ weight = os2Weight(os2->usWeightClass);
+ if(!sWidth)
+ sWidth = os2Width(os2->usWidthClass);
+ if(!foundry)
+ foundry = vendor_foundry(os2->achVendID);
+ if(!slant)
+ slant = os2->fsSelection & 1 ? "i" : "r";
+ }
+
+ if(post) {
+ if(!spacing) {
+ if(post->isFixedPitch) {
+ if(hhea->min_Left_Side_Bearing >= 0 &&
+ hhea->xMax_Extent <= hhea->advance_Width_Max) {
+ spacing = "c";
+ } else {
+ spacing = "m";
+ }
+ } else {
+ spacing = "p";
+ }
+ }
+ }
+
+ if(t1info) {
+ if(!family)
+ family = t1info->family_name;
+ if(!family)
+ family = t1info->full_name;
+ if(!full_name)
+ full_name = t1info->full_name;
+ if(!foundry)
+ foundry = notice_foundry(t1info->notice);
+ if(!weight)
+ weight = t1Weight(t1info->weight);
+ if(!spacing)
+ spacing = t1info->is_fixed_pitch ? "m" : "p";
+ if(!slant) {
+ /* Bitstream fonts have positive italic angle. */
+ slant =
+ t1info->italic_angle <= -4 || t1info->italic_angle >= 4 ?
+ "i" : "r";
+ }
+ }
+
+ if(!full_name) {
+ fprintf(stderr, "Couldn't determine full name for %s\n", filename);
+ full_name = filename;
+ }
+
+ if(head) {
+ if(!slant)
+ slant = head->Mac_Style & 2 ? "i" : "r";
+ if(!weight)
+ weight = head->Mac_Style & 1 ? "bold" : "medium";
+ }
+
+ if(!slant) {
+ fprintf(stderr, "Couldn't determine slant for %s\n", filename);
+ slant = "r";
+ }
+
+ if(!weight) {
+ fprintf(stderr, "Couldn't determine weight for %s\n", filename);
+ weight = "medium";
+ }
+
+ if(!foundry) {
+ char *notice;
+ notice = getName(face, TT_NAME_ID_TRADEMARK);
+ if(notice) {
+ foundry = notice_foundry(notice);
+ }
+ if(!foundry) {
+ notice = getName(face, TT_NAME_ID_MANUFACTURER);
+ if(notice) {
+ foundry = notice_foundry(notice);
+ }
+ }
+ }
+
+ if(strcmp(slant, "i") == 0) {
+ if(strstr(full_name, "Oblique"))
+ slant = "o";
+ if(strstr(full_name, "Slanted"))
+ slant = "o";
+ }
+
+ if(!sWidth)
+ sWidth = nameWidth(full_name);
+
+ if(!foundry) foundry = "misc";
+ if(!family) {
+ fprintf(stderr, "Couldn't get family name for %s\n", filename);
+ family = filename;
+ }
+
+ if(!weight) weight = "medium";
+ if(!slant) slant = "r";
+ if(!sWidth) sWidth = "normal";
+ if(!adstyle) adstyle = "";
+ if(!spacing) spacing = "p";
+
+ /* Yes, it's a memory leak. */
+ foundry = safe(foundry);
+ family = safe(family);
+
+ if(!isBitmap) {
+ xlfd = listConsF(xlfd,
+ "-%s-%s-%s-%s-%s-%s-0-0-0-0-%s-0",
+ foundry, family,
+ weight, slant, sWidth, adstyle, spacing);
+ } else {
+ int i, w, h, xres, yres;
+ for(i = 0; i < face->num_fixed_sizes; i++) {
+ w = face->available_sizes[i].width;
+ h = face->available_sizes[i].height;
+ xres = 75;
+ yres = (double)h / w * xres;
+ xlfd = listConsF(xlfd,
+ "-%s-%s-%s-%s-%s-%s-%d-%d-%d-%d-%s-%d",
+ foundry, family,
+ weight, slant, sWidth, adstyle,
+ h, (int)(h / (double)yres * 72.27 * 10 + 0.5),
+ xres, yres,
+ spacing, 60);
+ }
+ }
+ return xlfd;
+}
+
+static int
+readFontScale(HashTablePtr entries, char *dirname)
+{
+ int n = strlen(dirname);
+ char *filename;
+ FILE *in;
+ int rc, count, i;
+ char file[MAXFONTFILENAMELEN], font[MAXFONTNAMELEN];
+ char format[100];
+
+ snprintf(format, 100, "%%%ds %%%d[^\n]\n",
+ MAXFONTFILENAMELEN, MAXFONTNAMELEN);
+
+ if(dirname[n - 1] == '/')
+ filename = dsprintf("%sfonts.scale", dirname);
+ else
+ filename = dsprintf("%s/fonts.scale", dirname);
+ if(filename == NULL)
+ return -1;
+
+ in = fopen(filename, "r");
+ free(filename);
+ if(in == NULL) {
+ if(errno != ENOENT)
+ perror("open(fonts.scale)");
+ return -1;
+ }
+
+ rc = fscanf(in, "%d\n", &count);
+ if(rc != 1) {
+ fprintf(stderr, "Invalid fonts.scale in %s.\n", dirname);
+ fclose(in);
+ return -1;
+ }
+
+ for(i = 0; i < count; i++) {
+ rc = fscanf(in, format, file, font);
+ if(rc != 2)
+ break;
+ putHash(entries, font, file, 100);
+ }
+ fclose(in);
+ return 1;
+}
+
+static int
+filePrio(char *filename)
+{
+ int n = strlen(filename);
+ if(n < 4)
+ return 0;
+ if(strcmp(filename + n - 4, ".otf") == 0)
+ return 4;
+ if(strcmp(filename + n - 4, ".OTF") == 0)
+ return 4;
+ if(strcmp(filename + n - 4, ".ttf") == 0)
+ return 3;
+ if(strcmp(filename + n - 4, ".TTF") == 0)
+ return 3;
+ if(strcmp(filename + n - 3, ".gz") == 0)
+ return 2;
+ if(strcmp(filename + n - 2, ".Z") == 0)
+ return 1;
+ return 0;
+}
+
+static int
+doDirectory(char *dirname_given, int numEncodings, ListPtr encodingsToDo)
+{
+ char *dirname, *fontscale_name, *filename, *encdir;
+ FILE *fontscale, *encfile;
+ DIR *dirp;
+ struct dirent *entry;
+ FT_Error ftrc;
+ FT_Face face;
+ ListPtr encoding, xlfd, lp;
+ HashTablePtr entries;
+ HashBucketPtr *array;
+ int i, n, found, rc;
+ int isBitmap=0,xl=0;
+
+ if (exclusionSuffix)
+ xl = strlen (exclusionSuffix);
i = strlen(dirname_given);
if(i == 0)
- dirname = strcat_reliable(".", "/");
+ dirname = dsprintf("./");
else if(dirname_given[i - 1] != '/')
- dirname = strcat_reliable(dirname_given, "/");
+ dirname = dsprintf("%s/", dirname_given);
else
- dirname = strcat_reliable(dirname_given, "");
- fontscale_name = strcat_reliable(dirname, "fonts.scale");
+ dirname = dsprintf("%s", dirname_given);
+
+ if(dirname == NULL) {
+ perror("dirname");
+ exit(1);
+ }
+
+ if (onlyEncodings)
+ goto encodings;
+
+ entries = makeHashTable();
+ if(doBitmaps && !doScalable) {
+ readFontScale(entries, dirname);
+ }
+
+ if(strcmp(outfilename, "-") == 0)
+ fontscale_name = NULL;
+ else {
+ if(outfilename[0] == '/')
+ fontscale_name = dsprintf("%s", outfilename);
+ else
+ fontscale_name = dsprintf("%s%s", dirname, outfilename);
+ if(fontscale_name == NULL) {
+ perror("fontscale_name");
+ exit(1);
+ }
+ }
dirp = opendir(dirname);
if(dirp == NULL) {
@@ -374,195 +775,189 @@ doDirectory(char *dirname_given)
return 0;
}
- fontscale = fopen(fontscale_name, "w");
+ if(fontscale_name == NULL)
+ fontscale = stdout;
+ else
+ fontscale = fopen(fontscale_name, "w");
+
if(fontscale == NULL) {
fprintf(stderr, "%s: ", fontscale_name);
perror("fopen(w)");
return 0;
}
-
- for(;;) {
- entry = readdir(dirp);
- if(entry == NULL)
- break;
- filename = strcat_reliable(dirname, entry->d_name);
- ftrc = FT_New_Face(ft_library, filename, 0, &face);
- if(ftrc)
- continue;
- if((face->face_flags & FT_FACE_FLAG_SCALABLE) == 0)
- continue;
+ while((entry = readdir(dirp)) != NULL) {
+ int have_face = 0;
+ char *xlfd_name = NULL;
+ xlfd = NULL;
- found = 0;
+ if (xl) {
+ int dl = strlen (entry->d_name);
+ if (strcmp (entry->d_name + dl - xl, exclusionSuffix) == 0)
+ continue;
+ }
- foundry = NULL;
- family = NULL;
- weight = NULL;
- slant = NULL;
- sWidth = NULL;
- adstyle = NULL;
- spacing = NULL;
- full_name = NULL;
-
- head = FT_Get_Sfnt_Table(face, ft_sfnt_head);
- hhea = FT_Get_Sfnt_Table(face, ft_sfnt_hhea);
- os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2);
- post = FT_Get_Sfnt_Table(face, ft_sfnt_post);
-
- rc = FT_Get_PS_Font_Info(face, &t1info_rec);
- if(rc == 0)
- t1info = &t1info_rec;
+ filename = dsprintf("%s%s", dirname, entry->d_name);
+
+ if(doBitmaps)
+ rc = bitmapIdentify(filename, &xlfd_name);
else
- t1info = NULL;
+ rc = 0;
+
+ if(rc < 0)
+ goto done;
+
+ if(rc == 0) {
+ ftrc = FT_New_Face(ft_library, filename, 0, &face);
+ if(ftrc)
+ goto done;
+ have_face = 1;
+
+ isBitmap = ((face->face_flags & FT_FACE_FLAG_SCALABLE) == 0);
+
+ if(!isBitmap) {
+ /* Workaround for bitmap-only TTF fonts */
+ if(face->num_fixed_sizes > 0) {
+ TT_MaxProfile *maxp;
+ maxp = FT_Get_Sfnt_Table(face, ft_sfnt_maxp);
+ if(maxp != NULL && maxp->maxContours == 0)
+ isBitmap = 1;
+ }
+ }
- if(!family)
- family = getName(face, TT_NAME_ID_FONT_FAMILY);
- if(!family)
- family = getName(face, TT_NAME_ID_FULL_NAME);
- if(!family)
- family = getName(face, TT_NAME_ID_PS_NAME);
-
- if(!full_name)
- full_name = getName(face, TT_NAME_ID_FULL_NAME);
- if(!full_name)
- full_name = getName(face, TT_NAME_ID_PS_NAME);
-
- if(os2 && os2->version != 0xFFFF) {
- if(!weight)
- weight = os2Weight(os2->usWeightClass);
- if(!sWidth)
- sWidth = os2Width(os2->usWidthClass);
- if(!foundry)
- foundry = vendor_foundry(os2->achVendID);
- if(!slant)
- slant = os2->fsSelection & 1 ? "i" : "r";
- }
+ if(isBitmap) {
+ if(!doBitmaps)
+ goto done;
+ } else {
+ if(!doScalable)
+ goto done;
+ }
- if(post) {
- if(!spacing) {
- if(post->isFixedPitch) {
- if(hhea->min_Left_Side_Bearing >= 0 &&
- hhea->xMax_Extent <= hhea->advance_Width_Max) {
- spacing = "c";
- } else {
- spacing = "m";
- }
- } else {
- spacing = "p";
+ if(isBitmap) {
+ BDF_PropertyRec prop;
+ rc = FT_Get_BDF_Property(face, "FONT", &prop);
+ if(rc == 0 && prop.type == BDF_PROPERTY_TYPE_ATOM) {
+ xlfd_name = malloc(strlen(prop.u.atom) + 1);
+ if(xlfd_name == NULL)
+ goto done;
+ strcpy(xlfd_name, prop.u.atom);
}
}
}
-
- if(t1info) {
- if(!family)
- family = t1info->family_name;
- if(!family)
- family = t1info->full_name;
- if(!full_name)
- full_name = t1info->full_name;
- if(!foundry)
- foundry = notice_foundry(t1info->notice);
- if(!weight)
- weight = t1Weight(t1info->weight);
- if(!spacing)
- spacing = t1info->is_fixed_pitch ? "m" : "p";
- if(!slant) {
- /* Bitstream fonts have positive italic angle. */
- slant =
- t1info->italic_angle <= -4 || t1info->italic_angle >= 4 ?
- "i" : "r";
+
+ if(xlfd_name) {
+ /* We know it's a bitmap font, and we know its XLFD */
+ int n = strlen(xlfd_name);
+ if(reencodeLegacy &&
+ n >= 12 && strcasecmp(xlfd_name + n - 11, "-iso10646-1") == 0) {
+ char *s;
+
+ s = malloc(n - 10);
+ memcpy(s, xlfd_name, n - 11);
+ s[n - 11] = '\0';
+ xlfd = listCons(s, xlfd);
+ } else {
+ /* Not a reencodable font -- skip all the rest of the loop body */
+ putHash(entries, xlfd_name, entry->d_name, filePrio(entry->d_name));
+ goto done;
}
}
- if(head) {
- if(!slant)
- slant = head->Mac_Style & 2 ? "i" : "r";
- if(!weight)
- weight = head->Mac_Style & 1 ? "bold" : "medium";
+ if(!have_face) {
+ ftrc = FT_New_Face(ft_library, filename, 0, &face);
+ if(ftrc)
+ goto done;
+ have_face = 1;
+ isBitmap = ((face->face_flags & FT_FACE_FLAG_SCALABLE) == 0);
+
+ if(!isBitmap) {
+ if(face->num_fixed_sizes > 0) {
+ TT_MaxProfile *maxp;
+ maxp = FT_Get_Sfnt_Table(face, ft_sfnt_maxp);
+ if(maxp != NULL && maxp->maxContours == 0)
+ isBitmap = 1;
+ }
+ }
}
- if(!slant) {
- fprintf(stderr, "Couldn't determine slant for %s\n", filename);
- slant = "r";
- }
+ if(xlfd == NULL)
+ xlfd = makeXLFD(entry->d_name, face, isBitmap);
- if(!weight) {
- fprintf(stderr, "Couldn't determine weight for %s\n", filename);
- weight = "medium";
- }
+ found = 0;
- if(!foundry) {
- char *notice;
- notice = getName(face, TT_NAME_ID_TRADEMARK);
- if(notice) {
- foundry = notice_foundry(notice);
+ for(lp = xlfd; lp; lp = lp->next) {
+ char buf[MAXFONTNAMELEN];
+ for(encoding = encodings; encoding; encoding = encoding->next) {
+ if(checkEncoding(face, encoding->value)) {
+ found = 1;
+ snprintf(buf, MAXFONTNAMELEN, "%s-%s",
+ lp->value, encoding->value);
+ putHash(entries, buf, entry->d_name, filePrio(entry->d_name));
+ }
}
- if(!foundry) {
- notice = getName(face, TT_NAME_ID_MANUFACTURER);
- if(notice) {
- foundry = notice_foundry(notice);
+ for(encoding = extra_encodings; encoding;
+ encoding = encoding->next) {
+ if(checkExtraEncoding(face, encoding->value, found)) {
+ /* Do not set found! */
+ snprintf(buf, MAXFONTNAMELEN, "%s-%s",
+ lp->value, encoding->value);
+ putHash(entries, buf, entry->d_name, filePrio(entry->d_name));
}
}
}
-
- if(strcmp(slant, "i") == 0) {
- if(strstr(full_name, "Oblique"))
- slant = "o";
- if(strstr(full_name, "Slanted"))
- slant = "o";
+ done:
+ if(have_face) {
+ FT_Done_Face(face);
+ have_face = 0;
}
+ deepDestroyList(xlfd);
+ xlfd = NULL;
+ free(filename);
+ }
- if(!foundry) foundry = "misc";
- if(!family) {
- fprintf(stderr, "Couldn't get family name for %s\n", filename);
- family = entry->d_name;
- }
+ closedir(dirp);
+ n = hashElements(entries);
+ fprintf(fontscale, "%d\n", n);
+ array = hashArray(entries, 1);
+ for(i = 0; i < n; i++)
+ fprintf(fontscale, "%s %s\n", array[i]->value, array[i]->key);
+ destroyHashArray(array);
+ entries = NULL;
+ if(fontscale_name) {
+ fclose(fontscale);
+ free(fontscale_name);
+ }
- if(!weight) weight = "medium";
- if(!slant) slant = "r";
- if(!sWidth) sWidth = "normal";
- if(!adstyle) adstyle = "";
- if(!spacing) spacing = "p";
-
- /* Yes, it's a memory leak. */
- foundry = safe(foundry);
- family = safe(family);
-
- for(encoding = encodings; encoding; encoding = encoding->next)
- if(checkEncoding(face, encoding->value)) {
- found = 1;
- entries = listConsF(entries,
- "%s -%s-%s-%s-%s-%s-%s-0-0-0-0-%s-0-%s",
- entry->d_name,
- foundry, family,
- weight, slant, sWidth, adstyle, spacing,
- encoding->value);
- }
- for(encoding = extra_encodings; encoding; encoding = encoding->next)
- if(checkExtraEncoding(face, encoding->value, found)) {
- /* Do not set found! */
- entries = listConsF(entries,
- "%s -%s-%s-%s-%s-%s-%s-0-0-0-0-%s-0-%s",
- entry->d_name,
- foundry, family,
- weight, slant, sWidth, adstyle, spacing,
- encoding->value);
- }
- free(filename);
+ encodings:
+ encdir = dsprintf("%s%s", dirname, "encodings.dir");
+
+ if(encdir == NULL) {
+ perror("encodings");
+ exit(1);
}
- entries = reverseList(entries);
- fprintf(fontscale, "%d\n", listLength(entries));
- while(entries) {
- fprintf(fontscale, "%s\n", entries->value);
- entries = entries->next;
+ unlink(encdir);
+
+ if (numEncodings) {
+ encfile = fopen(encdir, "w");
+ if(encfile == NULL) {
+ perror("open(encodings.dir)");
+ exit(1);
+ }
+ fprintf(encfile, "%d\n", numEncodings);
+ for(lp = encodingsToDo; lp; lp = lp->next) {
+ fprintf(encfile, "%s\n", lp->value);
+ }
+ fclose (encfile);
}
- deepDestroyList(entries);
- fclose(fontscale);
- free(fontscale_name);
+
free(dirname);
return 1;
}
+#define CODE_IGNORED(c) ((c) < 0x20 || \
+ ((c) >= 0x7F && (c) <= 0xA0) || \
+ (c) == 0xAD || (c) == 0xF71B)
+
static int
checkEncoding(FT_Face face, char *encoding_name)
{
@@ -576,14 +971,16 @@ checkEncoding(FT_Face face, char *encoding_name)
return 0;
/* An encoding is ``small'' if one of the following is true:
- - it uses PostScript glyph names;
- it is linear and has no more than 256 codepoints; or
- it is a matrix encoding and has no more than one column.
- For small encodings, we require perfect coverage except for
- CODE_IGNORED and KOI-8 linedrawing glyphs.
+ For small encodings using Unicode indices, we require perfect
+ coverage except for CODE_IGNORED and KOI-8 IBM-PC compatibility.
- For large encodings, we require coverage up to bigEncodingFuzz. */
+ For large encodings, we require coverage up to bigEncodingFuzz.
+
+ For encodings using PS names (currently Adobe Standard and
+ Adobe Symbol only), we require perfect coverage. */
if(FT_Has_PS_Glyph_Names(face)) {
@@ -646,8 +1043,8 @@ checkEncoding(FT_Face face, char *encoding_name)
return 1;
} else {
int estimate = encoding->size - encoding->first;
- /* For the KOI8 encodings, ignore the lack of
- linedrawing characters */
+ /* For the KOI8 encodings, we ignore the lack of
+ linedrawing and pseudo-math characters */
if(strncmp(encoding->name, "koi8-", 5) == 0)
koi8 = 1;
else
@@ -655,7 +1052,7 @@ checkEncoding(FT_Face face, char *encoding_name)
for(i = encoding->first; i < encoding->size; i++) {
c = FontEncRecode(i, mapping);
if(CODE_IGNORED(c) ||
- (koi8 && i >= 0x80 && i < 0xA0)) {
+ (koi8 && ((c >= 0x2200 && c < 0x2600) || c == 0x00b2))) {
continue;
} else {
if(FT_Get_Char_Index(face, c) == 0) {
@@ -742,7 +1139,7 @@ checkExtraEncoding(FT_Face face, char *encoding_name, int found)
if(strcasecmp(encoding_name, "iso10646-1") == 0) {
if(find_cmap(FONT_ENCODING_UNICODE, -1, -1, face)) {
int found = 0;
- /* Export as Unicode if there are at least 15 BMP
+ /* Export as Unicode if there are at least 15 BMP
characters that are not a space or ignored. */
for(c = 0x21; c < 0x10000; c++) {
if(CODE_IGNORED(c))
@@ -809,3 +1206,59 @@ vendor_foundry(signed char *vendor)
return vendor_foundries[i][1];
return NULL;
}
+
+static int
+readEncodings(ListPtr encodings, char *dirname)
+{
+ char *fullname;
+ DIR *dirp;
+ struct dirent *file;
+ char **names, **name;
+
+ if(strlen(dirname) > 1 && dirname[strlen(dirname) - 1] == '/')
+ dirname[strlen(dirname) - 1] = '\0';
+
+ dirp = opendir(dirname);
+ if(dirp == NULL) {
+ perror("opendir");
+ return -1;
+ }
+
+ while((file = readdir(dirp)) != NULL) {
+ fullname = dsprintf("%s/%s", dirname, file->d_name);
+ if(fullname == NULL) {
+ fprintf(stderr, "Couldn't allocate fullname\n");
+ closedir(dirp);
+ return -1;
+ }
+
+ names = FontEncIdentify(fullname);
+ if(!names)
+ continue;
+
+ for(name = names; *name; name++) {
+ if(fullname[0] != '/' && !relative) {
+ char *n;
+ n = dsprintf("%s%s", encodingPrefix, fullname);
+ if(n == NULL) {
+ fprintf(stderr, "Couldn't allocate name\n");
+ closedir(dirp);
+ return -1;
+ }
+ encodingsToDo = listConsF(encodingsToDo, "%s %s", *name, n);
+ free(n);
+ } else {
+ encodingsToDo =
+ listConsF(encodingsToDo, "%s %s", *name, fullname);
+ }
+ if(encodingsToDo == NULL) {
+ fprintf(stderr, "Couldn't allocate encodings\n");
+ closedir(dirp);
+ return -1;
+ }
+ }
+ free(names); /* only the spine */
+ }
+ closedir(dirp);
+ return 0;
+}