Build AFM data for core PostScript fonts into WINEPS.

This commit is contained in:
Ian Pilcher 2001-05-29 22:06:10 +00:00 committed by Alexandre Julliard
parent 6bb990f7fd
commit 55d2e575af
47 changed files with 40819 additions and 3 deletions

1
configure vendored
View File

@ -7607,6 +7607,7 @@ dlls/dinput/keyboard \
dlls/dinput/mouse \
dlls/kernel/messages \
dlls/user/resources \
dlls/wineps/data \
"
for i in $extra_subdirs; do [ -d $i ] || (echo "creating $i" && mkdir $i); done

View File

@ -1140,6 +1140,7 @@ dlls/dinput/keyboard \
dlls/dinput/mouse \
dlls/kernel/messages \
dlls/user/resources \
dlls/wineps/data \
"
for i in $extra_subdirs; do [ -d $i ] || (echo "creating $i" && mkdir $i); done ])

View File

@ -9,9 +9,53 @@ IMPORTS = user32 gdi32 winspool.drv kernel32 ntdll
EXTRALIBS = @CUPSLIBS@ @FREETYPELIBS@
EXTRAINCL = @FREETYPEINCL@
FONTMETRICS = \
AvantGarde_Book \
AvantGarde_BookOblique \
AvantGarde_Demi \
AvantGarde_DemiOblique \
Bookman_Demi \
Bookman_DemiItalic \
Bookman_Light \
Bookman_LightItalic \
Courier \
Courier_Bold \
Courier_BoldOblique \
Courier_Oblique \
Helvetica \
Helvetica_Bold \
Helvetica_BoldOblique \
Helvetica_Condensed \
Helvetica_Condensed_Bold \
Helvetica_Condensed_BoldObl \
Helvetica_Condensed_Oblique \
Helvetica_Narrow \
Helvetica_Narrow_Bold \
Helvetica_Narrow_BoldOblique \
Helvetica_Narrow_Oblique \
Helvetica_Oblique \
NewCenturySchlbk_Bold \
NewCenturySchlbk_BoldItalic \
NewCenturySchlbk_Italic \
NewCenturySchlbk_Roman \
Palatino_Bold \
Palatino_BoldItalic \
Palatino_Italic \
Palatino_Roman \
Symbol \
Times_Bold \
Times_BoldItalic \
Times_Italic \
Times_Roman \
ZapfChancery_MediumItalic \
ZapfDingbats \
DATA_C_SRCS = \
data/agl.c \
$(FONTMETRICS:%=data/%.c)
C_SRCS = \
afm.c \
agl.c \
bitblt.c \
bitmap.c \
brush.c \
@ -28,11 +72,14 @@ C_SRCS = \
ppd.c \
ps.c \
text.c \
truetype.c
truetype.c \
$(DATA_C_SRCS)
RC_SRCS= \
rsrc.rc
EXTRASUBDIRS = data
@MAKE_DLL_RULES@
### Dependencies:

View File

@ -593,6 +593,17 @@ BOOL PSDRV_AddAFMtoList(FONTFAMILY **head, AFM *afm)
family->afmlist = newafmle;
return TRUE;
}
else {
tmpafmle = family->afmlist;
while (tmpafmle) {
if (!strcmp(tmpafmle->afm->FontName, afm->FontName)) {
WARN("Ignoring duplicate FontName '%s'\n", afm->FontName);
HeapFree(PSDRV_Heap, 0, newafmle);
return TRUE; /* not a fatal error */
}
tmpafmle = tmpafmle->next;
}
}
tmpafmle = family->afmlist;
while(tmpafmle->next)
@ -870,6 +881,9 @@ static VOID CalcWindowsMetrics()
afm->WinMetrics = wm;
/* See afm2c.c and mkagl.c for an explanation of this */
/* PSDRV_AFM2C(afm); */
afmle = afmle->next;
}
@ -878,6 +892,27 @@ static VOID CalcWindowsMetrics()
}
/*******************************************************************************
* AddBuiltinAFMs
*
*/
static BOOL AddBuiltinAFMs()
{
int i = 0;
while (PSDRV_BuiltinAFMs[i] != NULL)
{
if (PSDRV_AddAFMtoList(&PSDRV_AFMFontList, PSDRV_BuiltinAFMs[i])
== FALSE)
return FALSE;
++i;
}
return TRUE;
}
/***********************************************************
*
* PSDRV_GetFontMetrics
@ -973,6 +1008,8 @@ BOOL PSDRV_GetFontMetrics(void)
if (SortFontMetrics() == FALSE)
return FALSE;
CalcWindowsMetrics();
if (AddBuiltinAFMs() == FALSE)
return FALSE;
#ifdef HAVE_FREETYPE
if (PSDRV_GetTrueTypeMetrics() == FALSE)

314
dlls/wineps/afm2c.c Normal file
View File

@ -0,0 +1,314 @@
/*******************************************************************************
*
* Function to write WINEPS AFM data structures as C
*
* Copyright 2001 Ian Pilcher
*
*
* PSDRV_AFM2C(AFM *afm) writes the AFM data structure addressed by afm (and
* its subsidiary objects) as a C file which can which can then be built in to
* the driver. It creates the file in the current directory with a name of
* the form {FontName}.c, where {FontName} is the PostScript font name with
* hyphens replaced by underscores.
*
* To use this function, do the following:
*
* * Move this file to the dlls/wineps directory.
*
* * Edit dlls/wineps/Makefile (or dlls/wineps/Makefile.in) and add
* afm2c.c as a source file.
*
* * Edit dlls/wineps/afm.c and uncomment the call to PSDRV_AFM2C in
* CalcWindowsMetrics() (or wherever it gets moved). The resulting
* compiler warning can be safely ignored.
*
* IMPORTANT: For this to work, all glyph names in the AFM data being
* written *MUST* already be present in PSDRV_AGLGlyphNames in agl.c.
* See mkagl.c in this directory for information on how to generate
* updated glyph name information. Note, however, that if the glyph
* name information in agl.c is regenerated, *ALL* AFM data must also
* be recreated.
*
*/
#include <string.h>
#include <stdio.h>
#include <math.h>
#include "debugtools.h"
#include "psdrv.h"
DEFAULT_DEBUG_CHANNEL(psdrv);
inline static void cursorto(FILE *of, int np, int cp)
{
int ntp = np & 0xfffffff8;
int ctp = cp & 0xfffffff8;
while (ctp < ntp)
{
fputc('\t', of);
ctp += 8;
cp = ctp;
}
while (cp < np)
{
fputc(' ', of);
++cp;
}
}
static void writeCharWidths(FILE *of, AFM * afm)
{
int i, cp, w, row_start = 0;
fputc('\t', of); cp = 8;
for (i = 0; i < 255; ++i)
{
if (afm->CharWidths[i] == 0.0)
w = 3;
else
w = (int)log10(afm->CharWidths[i]) + 3;
if (cp + w < 40)
{
cp += fprintf(of, "%g, ", (double)(afm->CharWidths[i]));
}
else
{
cursorto(of, 40, cp);
fprintf(of, "/* CharWidths[%i] - CharWidths[%i] */\n\t",
row_start, i - 1);
cp = 8;
row_start = i;
--i;
}
}
if (afm->CharWidths[255] == 0.0)
w = 3;
else
w = (int)pow(afm->CharWidths[i], 0.1) + 3;
if (cp + w < 40)
{
cp += fprintf(of, "%g", (double)(afm->CharWidths[255]));
cursorto(of, 40, cp);
fprintf(of, "/* CharWidths[%i] - CharWidths[255] */\n },\n",
row_start);
}
else
{
cursorto(of, 40, cp);
fprintf(of, "/* CharWidths[%i] - CharWidths[254] */\n\t", row_start);
cp = 8 + fprintf(of, "%g", (double)(afm->CharWidths[255]));
cursorto(of, 40, cp);
fputs("/* CharWidths[255] */\n },\n", of);
}
}
static void writeHeader(FILE *of, AFM *afm, const char *buffer)
{
int i;
fputc('/', of);
for (i = 1; i < 80; ++i)
fputc('*', of);
fprintf(of, "\n"
" *\n"
" *\tFont metric data for %s\n"
" *\n"
" *\tCopyright 2001 Ian Pilcher\n"
" *\n"
" *\n"
" *\tThis data is derived from the Adobe Font Metrics files at"
"\n"
" *\n"
" *\t ftp://ftp.adobe.com/pub/adobe/type/win/all/afmfiles/"
"base35/\n"
" *\n"
" *\twhich are Copyright 1985-1992 Adobe Systems Incorporated."
"\n"
" *\n"
" */\n"
"\n"
"#include \"psdrv.h\"\n", afm->FullName);
}
static void writeEncoding(FILE *of, AFM *afm, const char *buffer)
{
int i;
fprintf(of, "\n\n/*\n * %s encoding vector\n */\n", afm->EncodingScheme);
fprintf(of, "\nstatic const UNICODEGLYPH ug_%s[%i] =\n{\n", buffer,
afm->Encoding->size);
for (i = 0; i < afm->Encoding->size - 1; ++i)
{
cursorto(of, 48,
fprintf(of, " { 0x%.4lx, PSDRV_AGLGlyphNames + %4i },",
afm->Encoding->glyphs[i].UV,
afm->Encoding->glyphs[i].name - PSDRV_AGLGlyphNames));
fprintf(of, "/* %s */\n", afm->Encoding->glyphs[i].name->sz);
}
cursorto(of, 48, fprintf(of, " { 0x%.4lx, PSDRV_AGLGlyphNames + %4i }",
afm->Encoding->glyphs[i].UV,
afm->Encoding->glyphs[i].name - PSDRV_AGLGlyphNames));
fprintf(of, "/* %s */\n};\n\n", afm->Encoding->glyphs[i].name->sz);
fprintf(of, "static UNICODEVECTOR enc_%s = { %i, ug_%s };\n", buffer,
afm->Encoding->size, buffer);
}
static void writeMetrics(FILE *of, AFM *afm, const char *buffer)
{
int i;
fputs("\n\n/*\n * Glyph metrics\n */\n\n", of);
fprintf(of, "static AFMMETRICS met_%s[%i] = \n{\n", buffer,
afm->NumofMetrics);
for (i = 0; i < afm->NumofMetrics - 1; ++i)
{
fputs(" {\n\t", of);
fprintf(of, "%3i, 0x%.4lx, %4g, PSDRV_AGLGlyphNames + %4i,\n\t\t",
afm->Metrics[i].C, afm->Metrics[i].UV, afm->Metrics[i].WX,
afm->Metrics[i].N - PSDRV_AGLGlyphNames);
fprintf(of, "{ %4g, %4g, %4g, %4g }, NULL\t/* %s */\n },\n",
afm->Metrics[i].B.llx, afm->Metrics[i].B.lly,
afm->Metrics[i].B.urx, afm->Metrics[i].B.ury,
afm->Metrics[i].N->sz);
}
fputs(" {\n\t", of);
fprintf(of, "%3i, 0x%.4lx, %4g, PSDRV_AGLGlyphNames + %4i,\n\t\t",
afm->Metrics[i].C, afm->Metrics[i].UV, afm->Metrics[i].WX,
afm->Metrics[i].N - PSDRV_AGLGlyphNames);
fprintf(of, "{ %4g, %4g, %4g, %4g }, NULL\t/* %s */\n }\n};\n",
afm->Metrics[i].B.llx, afm->Metrics[i].B.lly,
afm->Metrics[i].B.urx, afm->Metrics[i].B.ury,
afm->Metrics[i].N->sz);
}
static void writeAFM(FILE *of, AFM *afm, const char *buffer)
{
fputs("\n\n/*\n * Font metrics\n */\n\n", of);
fprintf(of, "AFM PSDRV_%s =\n{\n", buffer);
cursorto(of, 48, fprintf(of, " \"%s\",", afm->FontName));
fputs("/* FontName */\n", of);
cursorto(of, 48, fprintf(of, " \"%s\",", afm->FullName));
fputs("/* FullName */\n", of);
cursorto(of, 48, fprintf(of, " \"%s\",", afm->FamilyName));
fputs("/* FamilyName */\n", of);
cursorto(of, 48, fprintf(of, " \"%s\",", afm->EncodingScheme));
fputs("/* EncodingScheme */\n", of);
cursorto(of, 48, fprintf(of, " %li,", afm->Weight));
fputs("/* Weight */\n", of);
cursorto(of, 48, fprintf(of, " %g,", afm->ItalicAngle));
fputs("/* ItalicAngle */\n", of);
cursorto(of, 48, fprintf(of, " %s,",
afm->IsFixedPitch ? "TRUE" : "FALSE"));
fputs("/* IsFixedPitch */\n", of);
cursorto(of, 48, fprintf(of, " %g,", afm->UnderlinePosition));
fputs("/* UnderlinePosition */\n", of);
cursorto(of, 48, fprintf(of, " %g,", afm->UnderlineThickness));
fputs("/* UnderlineThickness */\n", of);
cursorto(of, 48, fprintf(of, " { %g, %g, %g, %g },", afm->FontBBox.llx,
afm->FontBBox.lly, afm->FontBBox.urx, afm->FontBBox.ury));
fputs("/* FontBBox */\n", of);
cursorto(of, 48, fprintf(of, " %g,", afm->CapHeight));
fputs("/* CapHeight */\n", of);
cursorto(of, 48, fprintf(of, " %g,", afm->XHeight));
fputs("/* XHeight */\n", of);
cursorto(of, 48, fprintf(of, " %g,", afm->Ascender));
fputs("/* Ascender */\n", of);
cursorto(of, 48, fprintf(of, " %g,", afm->Descender));
fputs("/* Descender */\n", of);
cursorto(of, 48, fprintf(of, " %g,", afm->FullAscender));
fputs("/* FullAscender */\n", of);
fputs(" {\n", of);
cursorto(of, 40, 7 + fprintf(of, "\t%u,",
(unsigned int)(afm->WinMetrics.usUnitsPerEm)));
fputs("/* WinMetrics.usUnitsPerEm */\n", of);
cursorto(of, 40, 7 + fprintf(of, "\t%i,",
(int)(afm->WinMetrics.sAscender)));
fputs("/* WinMetrics.sAscender */\n", of);
cursorto(of, 40, 7 + fprintf(of, "\t%i,",
(int)(afm->WinMetrics.sDescender)));
fputs("/* WinMetrics.sDescender */\n", of);
cursorto(of, 40, 7 + fprintf(of, "\t%i,",
(int)(afm->WinMetrics.sLineGap)));
fputs("/* WinMetrics.sLineGap */\n", of);
cursorto(of, 40, 7 + fprintf(of, "\t%i,",
(int)(afm->WinMetrics.sAvgCharWidth)));
fputs("/* WinMetrics.sAvgCharWidth */\n", of);
cursorto(of, 40, 7 + fprintf(of, "\t%i,",
(int)(afm->WinMetrics.sTypoAscender)));
fputs("/* WinMetrics.sTypoAscender */\n", of);
cursorto(of, 40, 7 + fprintf(of, "\t%i,",
(int)(afm->WinMetrics.sTypoDescender)));
fputs("/* WinMetrics.sTypoDescender */\n", of);
cursorto(of, 40, 7 + fprintf(of, "\t%i,",
(int)(afm->WinMetrics.sTypoLineGap)));
fputs("/* WinMetrics.sTypoLineGap */\n", of);
cursorto(of, 40, 7 + fprintf(of, "\t%u,",
(unsigned int)(afm->WinMetrics.usWinAscent)));
fputs("/* WinMetrics.usWinAscent */\n", of);
cursorto(of, 40, 7 + fprintf(of, "\t%u",
(unsigned int)(afm->WinMetrics.usWinDescent)));
fputs("/* WinMetrics.usWinDescent */\n",of);
fputs(" },\n {\n", of);
writeCharWidths(of, afm);
cursorto(of, 48, fprintf(of, " %i,", afm->NumofMetrics));
fputs("/* NumofMetrics */\n", of);
cursorto(of, 48, fprintf(of, " met_%s,", buffer));
fputs("/* Metrics */\n", of);
if (afm->Encoding == &PSDRV_AdobeGlyphList)
cursorto(of, 48, fprintf(of, " &PSDRV_AdobeGlyphList"));
else
cursorto(of, 48, fprintf(of, " &enc_%s", buffer));
fputs("/* Encoding */\n};\n", of);
}
void PSDRV_AFM2C(AFM *afm)
{
char buffer[256];
FILE *of;
int i;
strncpy(buffer, afm->FontName, sizeof(buffer) - 3);
buffer[sizeof(buffer) - 3] = '\0';
for (i = 0; i < strlen(buffer); ++i)
if (buffer[i] == '-')
buffer[i] = '_';
buffer[i] = '.'; buffer[i + 1] = 'c'; buffer[i + 2] = '\0';
MESSAGE("writing '%s'\n", buffer);
of = fopen(buffer, "w");
if (of == NULL)
{
ERR("error opening '%s' for writing\n", buffer);
return;
}
buffer[i] = '\0';
writeHeader(of, afm, buffer);
if (afm->Encoding != &PSDRV_AdobeGlyphList)
writeEncoding(of, afm, buffer);
writeMetrics(of, afm, buffer);
writeAFM(of, afm, buffer);
fclose(of);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1075
dlls/wineps/data/Courier.c Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1015
dlls/wineps/data/Helvetica.c Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1056
dlls/wineps/data/Symbol.c Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -2361,3 +2361,91 @@ static const UNICODEGLYPH encoding[1051] =
};
UNICODEVECTOR PSDRV_AdobeGlyphList = { 1051, encoding };
/*
* Built-in font metrics
*/
extern AFM PSDRV_AvantGarde_Book;
extern AFM PSDRV_AvantGarde_BookOblique;
extern AFM PSDRV_AvantGarde_Demi;
extern AFM PSDRV_AvantGarde_DemiOblique;
extern AFM PSDRV_Bookman_Demi;
extern AFM PSDRV_Bookman_DemiItalic;
extern AFM PSDRV_Bookman_Light;
extern AFM PSDRV_Bookman_LightItalic;
extern AFM PSDRV_Courier;
extern AFM PSDRV_Courier_Bold;
extern AFM PSDRV_Courier_BoldOblique;
extern AFM PSDRV_Courier_Oblique;
extern AFM PSDRV_Helvetica;
extern AFM PSDRV_Helvetica_Bold;
extern AFM PSDRV_Helvetica_BoldOblique;
extern AFM PSDRV_Helvetica_Condensed;
extern AFM PSDRV_Helvetica_Condensed_Bold;
extern AFM PSDRV_Helvetica_Condensed_BoldObl;
extern AFM PSDRV_Helvetica_Condensed_Oblique;
extern AFM PSDRV_Helvetica_Narrow;
extern AFM PSDRV_Helvetica_Narrow_Bold;
extern AFM PSDRV_Helvetica_Narrow_BoldOblique;
extern AFM PSDRV_Helvetica_Narrow_Oblique;
extern AFM PSDRV_Helvetica_Oblique;
extern AFM PSDRV_NewCenturySchlbk_Bold;
extern AFM PSDRV_NewCenturySchlbk_BoldItalic;
extern AFM PSDRV_NewCenturySchlbk_Italic;
extern AFM PSDRV_NewCenturySchlbk_Roman;
extern AFM PSDRV_Palatino_Bold;
extern AFM PSDRV_Palatino_BoldItalic;
extern AFM PSDRV_Palatino_Italic;
extern AFM PSDRV_Palatino_Roman;
extern AFM PSDRV_Symbol;
extern AFM PSDRV_Times_Bold;
extern AFM PSDRV_Times_BoldItalic;
extern AFM PSDRV_Times_Italic;
extern AFM PSDRV_Times_Roman;
extern AFM PSDRV_ZapfChancery_MediumItalic;
extern AFM PSDRV_ZapfDingbats;
AFM *const PSDRV_BuiltinAFMs[40] =
{
&PSDRV_AvantGarde_Book,
&PSDRV_AvantGarde_BookOblique,
&PSDRV_AvantGarde_Demi,
&PSDRV_AvantGarde_DemiOblique,
&PSDRV_Bookman_Demi,
&PSDRV_Bookman_DemiItalic,
&PSDRV_Bookman_Light,
&PSDRV_Bookman_LightItalic,
&PSDRV_Courier,
&PSDRV_Courier_Bold,
&PSDRV_Courier_BoldOblique,
&PSDRV_Courier_Oblique,
&PSDRV_Helvetica,
&PSDRV_Helvetica_Bold,
&PSDRV_Helvetica_BoldOblique,
&PSDRV_Helvetica_Condensed,
&PSDRV_Helvetica_Condensed_Bold,
&PSDRV_Helvetica_Condensed_BoldObl,
&PSDRV_Helvetica_Condensed_Oblique,
&PSDRV_Helvetica_Narrow,
&PSDRV_Helvetica_Narrow_Bold,
&PSDRV_Helvetica_Narrow_BoldOblique,
&PSDRV_Helvetica_Narrow_Oblique,
&PSDRV_Helvetica_Oblique,
&PSDRV_NewCenturySchlbk_Bold,
&PSDRV_NewCenturySchlbk_BoldItalic,
&PSDRV_NewCenturySchlbk_Italic,
&PSDRV_NewCenturySchlbk_Roman,
&PSDRV_Palatino_Bold,
&PSDRV_Palatino_BoldItalic,
&PSDRV_Palatino_Italic,
&PSDRV_Palatino_Roman,
&PSDRV_Symbol,
&PSDRV_Times_Bold,
&PSDRV_Times_BoldItalic,
&PSDRV_Times_Italic,
&PSDRV_Times_Roman,
&PSDRV_ZapfChancery_MediumItalic,
&PSDRV_ZapfDingbats,
NULL
};

415
dlls/wineps/mkagl.c Normal file
View File

@ -0,0 +1,415 @@
#include <sys/types.h>
#include <dirent.h>
#include <string.h>
#include <malloc.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
/*
* The array of glyph information
*/
typedef struct
{
int UV;
int index; /* in PSDRV_AGLGlyphNames */
const char *name;
const char *comment;
} GLYPHINFO;
static GLYPHINFO glyphs[1500];
static int num_glyphs = 0;
/*
* Functions to search and sort the array
*/
static int cmp_by_UV(const void *a, const void *b)
{
return ((const GLYPHINFO *)a)->UV - ((const GLYPHINFO *)b)->UV;
}
static int cmp_by_name(const void *a, const void *b)
{
return strcmp(((const GLYPHINFO *)a)->name, ((const GLYPHINFO *)b)->name);
}
inline static void sort_by_UV()
{
qsort(glyphs, num_glyphs, sizeof(GLYPHINFO), cmp_by_UV);
}
inline static void sort_by_name()
{
qsort(glyphs, num_glyphs, sizeof(GLYPHINFO), cmp_by_name);
}
inline static GLYPHINFO *search_by_name(const char *name)
{
GLYPHINFO gi;
gi.name = name;
return (GLYPHINFO *)bsearch(&gi, glyphs, num_glyphs, sizeof(GLYPHINFO),
cmp_by_name);
}
/*
* Use the 'optimal' combination of tabs and spaces to position the cursor
*/
inline static void fcpto(FILE *f, int newpos, int curpos)
{
int newtpos = newpos & ~7;
int curtpos = curpos & ~7;
while (curtpos < newtpos)
{
fputc('\t', f);
curtpos += 8;
curpos = curtpos;
}
while (curpos < newpos)
{
fputc(' ', f);
++curpos;
}
}
inline static void cpto(int newpos, int curpos)
{
fcpto(stdout, newpos, curpos);
}
/*
* Make main() look "purty"
*/
inline static void double_space(FILE *f)
{
fputc('\n', f);
}
inline static void triple_space(FILE *f)
{
fputc('\n', f); fputc('\n', f);
}
/*
* Read the Adobe Glyph List from 'glyphlist.txt'
*/
static void read_agl()
{
FILE *f = fopen("glyphlist.txt", "r");
char linebuf[256], namebuf[128], commbuf[128];
if (f == NULL)
{
fprintf(stderr, "Error opening glyphlist.txt\n");
exit(__LINE__);
}
while (fgets(linebuf, sizeof(linebuf), f) != NULL)
{
unsigned int UV;
if (linebuf[0] == '#')
continue;
sscanf(linebuf, "%X;%[^;];%[^\n]", &UV, namebuf, commbuf);
glyphs[num_glyphs].UV = (int)UV;
glyphs[num_glyphs].name = strdup(namebuf);
glyphs[num_glyphs].comment = strdup(commbuf);
if (glyphs[num_glyphs].name == NULL ||
glyphs[num_glyphs].comment == NULL)
{
fprintf(stderr, "Memory allocation failure\n");
exit(__LINE__);
}
++num_glyphs;
}
fclose(f);
if (num_glyphs != 1051)
{
fprintf(stderr, "Read %i glyphs\n", num_glyphs);
exit(__LINE__);
}
}
/*
* Read glyph names from all AFM files in current directory
*/
static void read_afms()
{
DIR *d = opendir(".");
struct dirent *de;
if (d == NULL)
{
fprintf(stderr, "Error opening current directory\n");
exit(__LINE__);
}
while ((de = readdir(d)) != NULL)
{
FILE *f;
char *cp, linebuf[256], font_family[128];
int i, num_metrics;
cp = strrchr(de->d_name, '.'); /* Does it end in */
if (cp == NULL || strcasecmp(cp, ".afm") != 0) /* .afm or .AFM? */
continue;
f = fopen(de->d_name, "r");
if (f == NULL)
{
fprintf(stderr, "Error opening %s\n", de->d_name);
exit(__LINE__);
}
while (1)
{
if (fgets(linebuf, sizeof(linebuf), f) == NULL)
{
fprintf(stderr, "FamilyName not found in %s\n", de->d_name);
exit(__LINE__);
}
if (strncmp(linebuf, "FamilyName ", 11) == 0)
break;
}
sscanf(linebuf, "FamilyName %[^\r\n]", font_family);
while (1)
{
if (fgets(linebuf, sizeof(linebuf), f) == NULL)
{
fprintf(stderr, "StartCharMetrics not found in %s\n",
de->d_name);
exit(__LINE__);
}
if (strncmp(linebuf, "StartCharMetrics ", 17) == 0)
break;
}
sscanf(linebuf, "StartCharMetrics %i", &num_metrics);
for (i = 0; i < num_metrics; ++i)
{
char namebuf[128];
if (fgets(linebuf, sizeof(linebuf), f) == NULL)
{
fprintf(stderr, "Unexpected EOF after %i glyphs in %s\n", i,
de->d_name);
exit(__LINE__);
}
cp = strchr(linebuf, 'N');
if (cp == NULL || strlen(cp) < 3)
{
fprintf(stderr, "Parse error after %i glyphs in %s\n", i,
de->d_name);
exit(__LINE__);
}
sscanf(cp, "N %s", namebuf);
if (search_by_name(namebuf) != NULL)
continue;
sprintf(linebuf, "FONT FAMILY;%s", font_family);
glyphs[num_glyphs].UV = -1;
glyphs[num_glyphs].name = strdup(namebuf);
glyphs[num_glyphs].comment = strdup(linebuf);
if (glyphs[num_glyphs].name == NULL ||
glyphs[num_glyphs].comment == NULL)
{
fprintf(stderr, "Memory allocation failure\n");
exit(__LINE__);
}
++num_glyphs;
sort_by_name();
}
fclose(f);
}
closedir(d);
}
/*
* Write opening comments, etc.
*/
static void write_header(FILE *f)
{
int i;
fputc('/', f);
for (i = 0; i < 79; ++i)
fputc('*', f);
fputs("\n"
" *\n"
" *\tAdobe Glyph List data for the Wine PostScript driver\n"
" *\n"
" *\tCopyright 2001 Ian Pilcher\n"
" *\n"
" *\n"
" *\tThis data is derived from the Adobe Glyph list at\n"
" *\n"
" *\t "
"http://partners.adobe.com/asn/developer/type/glyphlist.txt\n"
" *\n"
" *\tand the Adobe Font Metrics files at\n"
" *\n"
" *\t "
"ftp://ftp.adobe.com/pub/adobe/type/win/all/afmfiles/base35/\n"
" *\n"
" *\twhich are Copyright 1985-1998 Adobe Systems Incorporated.\n"
" *\n"
" */\n"
"\n"
"#include \"psdrv.h\"\n", f);
}
/*
* Write the array of GLYPHNAME structures (also populates indexes)
*/
static void write_glyph_names(FILE *f)
{
int i, num_names = 0, index = 0;
for (i = 0; i < num_glyphs; ++i)
if (i == 0 || strcmp(glyphs[i - 1].name, glyphs[i].name) != 0)
++num_names;
fputs( "/*\n"
" * Every glyph name in the AGL and the 39 core PostScript fonts\n"
" */\n"
"\n", f);
fprintf(f, "const INT PSDRV_AGLGlyphNamesSize = %i;\n\n", num_names);
fprintf(f, "GLYPHNAME PSDRV_AGLGlyphNames[%i] =\n{\n", num_names);
for (i = 0; i < num_glyphs - 1; ++i)
{
int cp = 0;
if (i == 0 || strcmp(glyphs[i - 1].name, glyphs[i].name) != 0)
{
cp = fprintf(f, " { -1, \"%s\" },", glyphs[i].name);
glyphs[i].index = index;
++index;
}
else
{
glyphs[i].index = index - 1;
}
fcpto(f, 36, cp);
fprintf(f, "/* %s */\n", glyphs[i].comment);
}
glyphs[i].index = index;
fcpto(f, 36, fprintf(f, " { -1, \"%s\" }", glyphs[i].name));
fprintf(f, "/* %s */\n};\n", glyphs[i].comment);
}
/*
* Write the AGL encoding vector
*/
static void write_encoding(FILE *f)
{
int i, size = 0;
for (i = 0; i < num_glyphs; ++i)
if (glyphs[i].UV != -1)
++size; /* better be 1051! */
sort_by_UV();
fputs( "/*\n"
" * The AGL encoding vector, sorted by Unicode value\n"
" */\n"
"\n", f);
fprintf(f, "static const UNICODEGLYPH encoding[%i] = \n{\n", size);
for (i = 0; i < num_glyphs - 1; ++i)
{
if (glyphs[i].UV == -1)
continue;
fprintf(f, " { 0x%.4x, PSDRV_AGLGlyphNames + %4i },\t/* %s */\n",
glyphs[i].UV, glyphs[i].index, glyphs[i].name);
}
fprintf(f, " { 0x%.4x, PSDRV_AGLGlyphNames + %4i }\t/* %s */\n};\n\n",
glyphs[i].UV, glyphs[i].index, glyphs[i].name);
fprintf(f, "UNICODEVECTOR PSDRV_AdobeGlyphList = { %i, encoding };\n",
size);
}
/*
* Do it!
*/
int main(int argc, char *argv[])
{
FILE *f;
read_agl();
read_afms();
if (argc < 2)
{
f = stdout;
}
else
{
f = fopen(argv[1], "w");
if (f == NULL)
{
fprintf(stderr, "Error opening %s for writing\n", argv[1]);
exit(__LINE__);
}
}
write_header(f);
triple_space(f);
write_glyph_names(f);
triple_space(f);
write_encoding(f);
return 0;
}

View File

@ -104,7 +104,8 @@ typedef struct _tagFONTFAMILY {
struct _tagFONTFAMILY *next; /* next family */
} FONTFAMILY;
extern FONTFAMILY *PSDRV_AFMFontList;
extern FONTFAMILY *PSDRV_AFMFontList;
extern AFM *const PSDRV_BuiltinAFMs[]; /* last element is NULL */
typedef struct _tagFONTNAME {
char *Name;