Modify init code to handle const data types.

This commit is contained in:
Ian Pilcher 2001-07-24 20:52:19 +00:00 committed by Alexandre Julliard
parent e4ca13ea82
commit 4bc1ebb5ed
6 changed files with 311 additions and 338 deletions

View File

@ -31,6 +31,10 @@ FONTFAMILY *PSDRV_AFMFontList = NULL;
/* qsort/bsearch callback functions */ /* qsort/bsearch callback functions */
typedef int (*compar_callback_fn) (const void *, const void *); typedef int (*compar_callback_fn) (const void *, const void *);
static VOID SortFontMetrics(AFM *afm, AFMMETRICS *metrics);
static VOID CalcWindowsMetrics(AFM *afm);
static void PSDRV_ReencodeCharWidths(AFM *afm);
/******************************************************************************* /*******************************************************************************
* IsWinANSI * IsWinANSI
* *
@ -94,28 +98,6 @@ inline static BOOL CheckMetrics(const AFMMETRICS *metrics)
return TRUE; return TRUE;
} }
/*******************************************************************************
* FreeAFM
*
* Free an AFM structure and any subsidiary objects that have been allocated.
* AFM must have been allocated with HEAP_ZERO_MEMORY.
*
*/
static void FreeAFM(AFM *afm)
{
if (afm->FontName != NULL)
HeapFree(PSDRV_Heap, 0, afm->FontName);
if (afm->FullName != NULL)
HeapFree(PSDRV_Heap, 0, afm->FullName);
if (afm->FamilyName != NULL)
HeapFree(PSDRV_Heap, 0, afm->FamilyName);
if (afm->EncodingScheme != NULL)
HeapFree(PSDRV_Heap, 0, afm->EncodingScheme);
if (afm->Metrics != NULL)
HeapFree(PSDRV_Heap, 0, afm->Metrics);
HeapFree(PSDRV_Heap, 0, afm);
}
/*********************************************************** /***********************************************************
* *
@ -131,13 +113,14 @@ static BOOL PSDRV_AFMGetCharMetrics(AFM *afm, FILE *fp)
unsigned char line[256], valbuf[256]; unsigned char line[256], valbuf[256];
unsigned char *cp, *item, *value, *curpos, *endpos; unsigned char *cp, *item, *value, *curpos, *endpos;
int i; int i;
AFMMETRICS *metric; AFMMETRICS *metric, *retval;
afm->Metrics = metric = HeapAlloc( PSDRV_Heap, 0, metric = HeapAlloc( PSDRV_Heap, 0, afm->NumofMetrics * sizeof(AFMMETRICS));
afm->NumofMetrics * sizeof(AFMMETRICS) );
if (metric == NULL) if (metric == NULL)
return FALSE; return FALSE;
retval = metric;
for(i = 0; i < afm->NumofMetrics; i++, metric++) { for(i = 0; i < afm->NumofMetrics; i++, metric++) {
*metric = badMetrics; *metric = badMetrics;
@ -145,8 +128,7 @@ static BOOL PSDRV_AFMGetCharMetrics(AFM *afm, FILE *fp)
do { do {
if(!fgets(line, sizeof(line), fp)) { if(!fgets(line, sizeof(line), fp)) {
ERR("Unexpected EOF\n"); ERR("Unexpected EOF\n");
HeapFree(PSDRV_Heap, 0, afm->Metrics); HeapFree(PSDRV_Heap, 0, retval);
afm->Metrics = NULL;
return FALSE; return FALSE;
} }
cp = line + strlen(line); cp = line + strlen(line);
@ -164,8 +146,7 @@ static BOOL PSDRV_AFMGetCharMetrics(AFM *afm, FILE *fp)
value = strpbrk(item, " \t"); value = strpbrk(item, " \t");
if (!value) { if (!value) {
ERR("No whitespace found.\n"); ERR("No whitespace found.\n");
HeapFree(PSDRV_Heap, 0, afm->Metrics); HeapFree(PSDRV_Heap, 0, retval);
afm->Metrics = NULL;
return FALSE; return FALSE;
} }
while(isspace(*value)) while(isspace(*value))
@ -173,8 +154,7 @@ static BOOL PSDRV_AFMGetCharMetrics(AFM *afm, FILE *fp)
cp = endpos = strchr(value, ';'); cp = endpos = strchr(value, ';');
if (!cp) { if (!cp) {
ERR("missing ;, failed. [%s]\n", line); ERR("missing ;, failed. [%s]\n", line);
HeapFree(PSDRV_Heap, 0, afm->Metrics); HeapFree(PSDRV_Heap, 0, retval);
afm->Metrics = NULL;
return FALSE; return FALSE;
} }
while(isspace(*--cp)) while(isspace(*--cp))
@ -218,8 +198,7 @@ static BOOL PSDRV_AFMGetCharMetrics(AFM *afm, FILE *fp)
if (CheckMetrics(metric) == FALSE) { if (CheckMetrics(metric) == FALSE) {
ERR("Error parsing character metrics\n"); ERR("Error parsing character metrics\n");
HeapFree(PSDRV_Heap, 0, afm->Metrics); HeapFree(PSDRV_Heap, 0, retval);
afm->Metrics = NULL;
return FALSE; return FALSE;
} }
@ -228,6 +207,10 @@ static BOOL PSDRV_AFMGetCharMetrics(AFM *afm, FILE *fp)
metric->B.urx, metric->B.ury); metric->B.urx, metric->B.ury);
} }
SortFontMetrics(afm, retval);
afm->Metrics = retval;
return TRUE; return TRUE;
} }
@ -237,13 +220,13 @@ static BOOL PSDRV_AFMGetCharMetrics(AFM *afm, FILE *fp)
* PSDRV_AFMParse * PSDRV_AFMParse
* *
* Fills out an AFM structure and associated substructures (see psdrv.h) * Fills out an AFM structure and associated substructures (see psdrv.h)
* for a given AFM file. All memory is allocated from the process heap. * for a given AFM file. All memory is allocated from the driver heap.
* Returns a ptr to the AFM structure or NULL on error. * Returns a ptr to the AFM structure or NULL on error.
* *
* This is not complete (we don't handle kerning yet) and not efficient * This is not complete (we don't handle kerning yet) and not efficient
*/ */
static AFM *PSDRV_AFMParse(char const *file) static const AFM *PSDRV_AFMParse(char const *file)
{ {
FILE *fp; FILE *fp;
unsigned char buf[256]; unsigned char buf[256];
@ -252,6 +235,8 @@ static AFM *PSDRV_AFMParse(char const *file)
unsigned char *cp; unsigned char *cp;
int afmfile = 0; int afmfile = 0;
int c; int c;
LPSTR font_name = NULL, full_name = NULL, family_name = NULL,
encoding_scheme = NULL;
TRACE("parsing '%s'\n", file); TRACE("parsing '%s'\n", file);
@ -260,7 +245,7 @@ static AFM *PSDRV_AFMParse(char const *file)
return NULL; return NULL;
} }
afm = HeapAlloc(PSDRV_Heap, HEAP_ZERO_MEMORY, sizeof(AFM)); afm = HeapAlloc(PSDRV_Heap, 0, sizeof(AFM));
if(!afm) { if(!afm) {
fclose(fp); fclose(fp);
return NULL; return NULL;
@ -297,32 +282,23 @@ static AFM *PSDRV_AFMParse(char const *file)
value++; value++;
if(!strncmp("FontName", buf, 8)) { if(!strncmp("FontName", buf, 8)) {
afm->FontName = HEAP_strdupA(PSDRV_Heap, 0, value); afm->FontName = font_name = HEAP_strdupA(PSDRV_Heap, 0, value);
if (afm->FontName == NULL) { if (afm->FontName == NULL)
fclose(fp); goto cleanup_fp;
FreeAFM(afm);
return NULL;
}
continue; continue;
} }
if(!strncmp("FullName", buf, 8)) { if(!strncmp("FullName", buf, 8)) {
afm->FullName = HEAP_strdupA(PSDRV_Heap, 0, value); afm->FullName = full_name = HEAP_strdupA(PSDRV_Heap, 0, value);
if (afm->FullName == NULL) { if (afm->FullName == NULL)
fclose(fp); goto cleanup_fp;
FreeAFM(afm);
return NULL;
}
continue; continue;
} }
if(!strncmp("FamilyName", buf, 10)) { if(!strncmp("FamilyName", buf, 10)) {
afm->FamilyName = HEAP_strdupA(PSDRV_Heap, 0, value); afm->FamilyName = family_name = HEAP_strdupA(PSDRV_Heap, 0, value);
if (afm->FamilyName == NULL) { if (afm->FamilyName == NULL)
fclose(fp); goto cleanup_fp;
FreeAFM(afm);
return NULL;
}
continue; continue;
} }
@ -399,21 +375,16 @@ static AFM *PSDRV_AFMParse(char const *file)
if(!strncmp("StartCharMetrics", buf, 16)) { if(!strncmp("StartCharMetrics", buf, 16)) {
sscanf(value, "%d", &(afm->NumofMetrics) ); sscanf(value, "%d", &(afm->NumofMetrics) );
if (PSDRV_AFMGetCharMetrics(afm, fp) == FALSE) { if (PSDRV_AFMGetCharMetrics(afm, fp) == FALSE)
fclose(fp); goto cleanup_fp;
FreeAFM(afm);
return NULL;
}
continue; continue;
} }
if(!strncmp("EncodingScheme", buf, 14)) { if(!strncmp("EncodingScheme", buf, 14)) {
afm->EncodingScheme = HEAP_strdupA(PSDRV_Heap, 0, value); afm->EncodingScheme = encoding_scheme =
if (afm->EncodingScheme == NULL) { HEAP_strdupA(PSDRV_Heap, 0, value);
fclose(fp); if (afm->EncodingScheme == NULL)
FreeAFM(afm); goto cleanup_fp;
return NULL;
}
continue; continue;
} }
@ -427,21 +398,20 @@ static AFM *PSDRV_AFMParse(char const *file)
if(afm->FontName == NULL) { if(afm->FontName == NULL) {
WARN("%s contains no FontName.\n", file); WARN("%s contains no FontName.\n", file);
afm->FontName = HEAP_strdupA(PSDRV_Heap, 0, "nofont"); afm->FontName = font_name = HEAP_strdupA(PSDRV_Heap, 0, "nofont");
if (afm->FontName == NULL) { if (afm->FontName == NULL)
FreeAFM(afm); goto cleanup;
return NULL;
}
} }
if(afm->FullName == NULL) if(afm->FullName == NULL)
afm->FullName = HEAP_strdupA(PSDRV_Heap, 0, afm->FontName); afm->FullName = full_name = HEAP_strdupA(PSDRV_Heap, 0, afm->FontName);
if(afm->FamilyName == NULL) if(afm->FamilyName == NULL)
afm->FamilyName = HEAP_strdupA(PSDRV_Heap, 0, afm->FontName); afm->FamilyName = family_name =
if (afm->FullName == NULL || afm->FamilyName == NULL) { HEAP_strdupA(PSDRV_Heap, 0, afm->FontName);
FreeAFM(afm);
return NULL; if (afm->FullName == NULL || afm->FamilyName == NULL)
} goto cleanup;
if(afm->Ascender == 0.0) if(afm->Ascender == 0.0)
afm->Ascender = afm->FontBBox.ury; afm->Ascender = afm->FontBBox.ury;
@ -452,7 +422,32 @@ static AFM *PSDRV_AFMParse(char const *file)
if(afm->Weight == 0) if(afm->Weight == 0)
afm->Weight = FW_NORMAL; afm->Weight = FW_NORMAL;
CalcWindowsMetrics(afm);
if (afm->EncodingScheme != NULL &&
strcmp(afm->EncodingScheme, "AdobeStandardEncoding") == 0)
PSDRV_ReencodeCharWidths(afm);
return afm; return afm;
cleanup_fp:
fclose(fp);
cleanup:
if (font_name == NULL)
HeapFree(PSDRV_Heap, 0, font_name);
if (full_name == NULL)
HeapFree(PSDRV_Heap, 0, full_name);
if (family_name == NULL)
HeapFree(PSDRV_Heap, 0, family_name);
if (encoding_scheme == NULL)
HeapFree(PSDRV_Heap, 0, encoding_scheme);
HeapFree(PSDRV_Heap, 0, afm);
return NULL;
} }
/*********************************************************** /***********************************************************
@ -484,7 +479,7 @@ void PSDRV_FreeAFMList( FONTFAMILY *head )
* Returns ptr to an AFM if name (which is a PS font name) exists in list * Returns ptr to an AFM if name (which is a PS font name) exists in list
* headed by head. * headed by head.
*/ */
AFM *PSDRV_FindAFMinList(FONTFAMILY *head, char *name) const AFM *PSDRV_FindAFMinList(FONTFAMILY *head, char *name)
{ {
FONTFAMILY *family; FONTFAMILY *family;
AFMLISTENTRY *afmle; AFMLISTENTRY *afmle;
@ -505,7 +500,7 @@ AFM *PSDRV_FindAFMinList(FONTFAMILY *head, char *name)
* Adds an afm to the list whose head is pointed to by head. Creates new * Adds an afm to the list whose head is pointed to by head. Creates new
* family node if necessary and always creates a new AFMLISTENTRY. * family node if necessary and always creates a new AFMLISTENTRY.
*/ */
BOOL PSDRV_AddAFMtoList(FONTFAMILY **head, AFM *afm) BOOL PSDRV_AddAFMtoList(FONTFAMILY **head, const AFM *afm)
{ {
FONTFAMILY *family = *head; FONTFAMILY *family = *head;
FONTFAMILY **insert = head; FONTFAMILY **insert = head;
@ -574,7 +569,7 @@ BOOL PSDRV_AddAFMtoList(FONTFAMILY **head, AFM *afm)
static void PSDRV_ReencodeCharWidths(AFM *afm) static void PSDRV_ReencodeCharWidths(AFM *afm)
{ {
int i, j; int i, j;
AFMMETRICS *metric; const AFMMETRICS *metric;
for(i = 0; i < 256; i++) { for(i = 0; i < 256; i++) {
if(isalnum(i)) if(isalnum(i))
@ -649,68 +644,56 @@ static int AFMMetricsByUV(const AFMMETRICS *a, const AFMMETRICS *b)
return a->UV - b->UV; return a->UV - b->UV;
} }
static BOOL SortFontMetrics() static VOID SortFontMetrics(AFM *afm, AFMMETRICS *metrics)
{ {
FONTFAMILY *family = PSDRV_AFMFontList; INT i;
while (family != NULL) TRACE("%s\n", afm->FontName);
if (strcmp(afm->EncodingScheme, "FontSpecific") != 0)
{ {
AFMLISTENTRY *afmle = family->afmlist; PSDRV_IndexGlyphList(); /* enable searching by name index */
while (afmle != NULL) for (i = 0; i < afm->NumofMetrics; ++i)
{ {
AFM *afm = afmle->afm; /* should always be valid */ UNICODEGLYPH ug, *pug;
INT i;
if (strcmp(afm->EncodingScheme, "FontSpecific") != 0) ug.name = metrics[i].N;
pug = bsearch(&ug, PSDRV_AGLbyName, PSDRV_AGLbyNameSize,
sizeof(UNICODEGLYPH),
(compar_callback_fn)UnicodeGlyphByNameIndex);
if (pug == NULL)
{ {
PSDRV_IndexGlyphList(); /* enable searching by name index */ WARN("Glyph '%s' in font '%s' does not have a UV\n",
ug.name->sz, afm->FullName);
for (i = 0; i < afm->NumofMetrics; ++i) metrics[i].UV = -1;
{
UNICODEGLYPH ug, *pug;
ug.name = afm->Metrics[i].N;
ug.UV = -1;
pug = bsearch(&ug, PSDRV_AGLbyName, PSDRV_AGLbyNameSize,
sizeof(UNICODEGLYPH),
(compar_callback_fn)UnicodeGlyphByNameIndex);
if (pug == NULL)
{
WARN("Glyph '%s' in font '%s' does not have a UV\n",
ug.name->sz, afm->FullName);
afm->Metrics[i].UV = -1;
}
else
{
afm->Metrics[i].UV = pug->UV;
}
}
} }
else /* FontSpecific encoding */ else
{ {
for (i = 0; i < afm->NumofMetrics; ++i) metrics[i].UV = pug->UV;
afm->Metrics[i].UV = afm->Metrics[i].C;
} }
qsort(afm->Metrics, afm->NumofMetrics, sizeof(AFMMETRICS),
(compar_callback_fn)AFMMetricsByUV);
for (i = 0; i < afm->NumofMetrics; ++i)
if (afm->Metrics[i].UV >= 0)
break;
afm->NumofMetrics -= i; /* Ignore unencoded glyphs */
afm->Metrics += i;
afmle = afmle->next;
} }
}
family = family->next; else /* FontSpecific encoding */
{
for (i = 0; i < afm->NumofMetrics; ++i)
metrics[i].UV = metrics[i].C;
} }
return TRUE; qsort(metrics, afm->NumofMetrics, sizeof(AFMMETRICS),
(compar_callback_fn)AFMMetricsByUV);
for (i = 0; i < afm->NumofMetrics; ++i) /* count unencoded glyphs */
if (metrics[i].UV >= 0)
break;
if (i != 0)
{
TRACE("Ignoring %i unencoded glyphs\n", i);
afm->NumofMetrics -= i;
memmove(metrics, metrics + i, afm->NumofMetrics * sizeof(*metrics));
}
} }
/******************************************************************************* /*******************************************************************************
@ -770,98 +753,78 @@ SHORT PSDRV_CalcAvgCharWidth(const AFM *afm)
/******************************************************************************* /*******************************************************************************
* CalcWindowsMetrics * CalcWindowsMetrics
* *
* Calculates several Windows-specific font metrics for each font. Relies on * Calculates several Windows-specific font metrics for each font.
* the fact that AFMs are allocated with HEAP_ZERO_MEMORY to distinguish
* TrueType fonts (when implemented), which already have these filled in.
* *
*/ */
static VOID CalcWindowsMetrics() static VOID CalcWindowsMetrics(AFM *afm)
{ {
FONTFAMILY *family = PSDRV_AFMFontList; WINMETRICS wm;
INT i;
while (family != NULL) wm.usUnitsPerEm = 1000; /* for PostScript fonts */
wm.sTypoAscender = (SHORT)(afm->Ascender + 0.5);
wm.sTypoDescender = (SHORT)(afm->Descender - 0.5);
wm.sTypoLineGap = 1200 - (wm.sTypoAscender - wm.sTypoDescender);
if (wm.sTypoLineGap < 0)
wm.sTypoLineGap = 0;
wm.usWinAscent = 0;
wm.usWinDescent = 0;
for (i = 0; i < afm->NumofMetrics; ++i)
{ {
AFMLISTENTRY *afmle = family->afmlist; if (IsWinANSI(afm->Metrics[i].UV) == FALSE)
continue;
while (afmle != NULL) if (afm->Metrics[i].B.ury > 0)
{ {
WINMETRICS wm; USHORT ascent = (USHORT)(afm->Metrics[i].B.ury + 0.5);
AFM *afm = afmle->afm; /* should always be valid */
INT i;
if (afm->WinMetrics.usUnitsPerEm != 0) if (ascent > wm.usWinAscent)
continue; /* TrueType font */ wm.usWinAscent = ascent;
wm.usUnitsPerEm = 1000; /* for PostScript fonts */
wm.sTypoAscender = (SHORT)(afm->Ascender + 0.5);
wm.sTypoDescender = (SHORT)(afm->Descender - 0.5);
wm.sTypoLineGap = 1200 - (wm.sTypoAscender - wm.sTypoDescender);
if (wm.sTypoLineGap < 0)
wm.sTypoLineGap = 0;
wm.usWinAscent = 0;
wm.usWinDescent = 0;
for (i = 0; i < afm->NumofMetrics; ++i)
{
if (IsWinANSI(afm->Metrics[i].UV) == FALSE)
continue;
if (afm->Metrics[i].B.ury > 0)
{
USHORT ascent = (USHORT)(afm->Metrics[i].B.ury + 0.5);
if (ascent > wm.usWinAscent)
wm.usWinAscent = ascent;
}
if (afm->Metrics[i].B.lly < 0)
{
USHORT descent = (USHORT)(-(afm->Metrics[i].B.lly) + 0.5);
if (descent > wm.usWinDescent)
wm.usWinDescent = descent;
}
}
if (wm.usWinAscent == 0 && afm->FontBBox.ury > 0)
wm.usWinAscent = (USHORT)(afm->FontBBox.ury + 0.5);
if (wm.usWinDescent == 0 && afm->FontBBox.lly < 0)
wm.usWinDescent = (USHORT)(-(afm->FontBBox.lly) + 0.5);
wm.sAscender = wm.usWinAscent;
wm.sDescender = -(wm.usWinDescent);
wm.sLineGap = 1150 - (wm.sAscender - wm.sDescender);
if (wm.sLineGap < 0)
wm.sLineGap = 0;
wm.sAvgCharWidth = PSDRV_CalcAvgCharWidth(afm);
TRACE("Windows metrics for '%s':\n", afm->FullName);
TRACE("\tsAscender = %i\n", wm.sAscender);
TRACE("\tsDescender = %i\n", wm.sDescender);
TRACE("\tsLineGap = %i\n", wm.sLineGap);
TRACE("\tusUnitsPerEm = %u\n", wm.usUnitsPerEm);
TRACE("\tsTypoAscender = %i\n", wm.sTypoAscender);
TRACE("\tsTypoDescender = %i\n", wm.sTypoDescender);
TRACE("\tsTypoLineGap = %i\n", wm.sTypoLineGap);
TRACE("\tusWinAscent = %u\n", wm.usWinAscent);
TRACE("\tusWinDescent = %u\n", wm.usWinDescent);
TRACE("\tsAvgCharWidth = %i\n", wm.sAvgCharWidth);
afm->WinMetrics = wm;
/* See afm2c.c and mkagl.c for an explanation of this */
/* PSDRV_AFM2C(afm); */
afmle = afmle->next;
} }
family = family ->next; if (afm->Metrics[i].B.lly < 0)
{
USHORT descent = (USHORT)(-(afm->Metrics[i].B.lly) + 0.5);
if (descent > wm.usWinDescent)
wm.usWinDescent = descent;
}
} }
if (wm.usWinAscent == 0 && afm->FontBBox.ury > 0)
wm.usWinAscent = (USHORT)(afm->FontBBox.ury + 0.5);
if (wm.usWinDescent == 0 && afm->FontBBox.lly < 0)
wm.usWinDescent = (USHORT)(-(afm->FontBBox.lly) + 0.5);
wm.sAscender = wm.usWinAscent;
wm.sDescender = -(wm.usWinDescent);
wm.sLineGap = 1150 - (wm.sAscender - wm.sDescender);
if (wm.sLineGap < 0)
wm.sLineGap = 0;
wm.sAvgCharWidth = PSDRV_CalcAvgCharWidth(afm);
TRACE("Windows metrics for '%s':\n", afm->FullName);
TRACE("\tsAscender = %i\n", wm.sAscender);
TRACE("\tsDescender = %i\n", wm.sDescender);
TRACE("\tsLineGap = %i\n", wm.sLineGap);
TRACE("\tusUnitsPerEm = %u\n", wm.usUnitsPerEm);
TRACE("\tsTypoAscender = %i\n", wm.sTypoAscender);
TRACE("\tsTypoDescender = %i\n", wm.sTypoDescender);
TRACE("\tsTypoLineGap = %i\n", wm.sTypoLineGap);
TRACE("\tusWinAscent = %u\n", wm.usWinAscent);
TRACE("\tusWinDescent = %u\n", wm.usWinDescent);
TRACE("\tsAvgCharWidth = %i\n", wm.sAvgCharWidth);
afm->WinMetrics = wm;
/* See afm2c.c and mkagl.c for an explanation of this */
/* PSDRV_AFM2C(afm); */
} }
@ -898,7 +861,7 @@ static BOOL AddBuiltinAFMs()
static BOOL PSDRV_ReadAFMDir(const char* afmdir) { static BOOL PSDRV_ReadAFMDir(const char* afmdir) {
DIR *dir; DIR *dir;
AFM *afm; const AFM *afm;
dir = opendir(afmdir); dir = opendir(afmdir);
if (dir) { if (dir) {
@ -919,13 +882,8 @@ static BOOL PSDRV_ReadAFMDir(const char* afmdir) {
TRACE("loading AFM %s\n",afmfn); TRACE("loading AFM %s\n",afmfn);
afm = PSDRV_AFMParse(afmfn); afm = PSDRV_AFMParse(afmfn);
if (afm) { if (afm) {
if(afm->EncodingScheme &&
!strcmp(afm->EncodingScheme,"AdobeStandardEncoding")) {
PSDRV_ReencodeCharWidths(afm);
}
if (PSDRV_AddAFMtoList(&PSDRV_AFMFontList, afm) == FALSE) { if (PSDRV_AddAFMtoList(&PSDRV_AFMFontList, afm) == FALSE) {
closedir(dir); closedir(dir);
FreeAFM(afm);
return FALSE; return FALSE;
} }
} }
@ -964,13 +922,9 @@ BOOL PSDRV_GetFontMetrics(void)
value_len = sizeof(value); value_len = sizeof(value);
while(!RegEnumValueA(hkey, idx++, key, &key_len, NULL, &type, value, &value_len)) while(!RegEnumValueA(hkey, idx++, key, &key_len, NULL, &type, value, &value_len))
{ {
AFM* afm = PSDRV_AFMParse(value); const AFM* afm = PSDRV_AFMParse(value);
if (afm) { if (afm) {
if(afm->EncodingScheme &&
!strcmp(afm->EncodingScheme, "AdobeStandardEncoding")) {
PSDRV_ReencodeCharWidths(afm);
}
if (PSDRV_AddAFMtoList(&PSDRV_AFMFontList, afm) == FALSE) { if (PSDRV_AddAFMtoList(&PSDRV_AFMFontList, afm) == FALSE) {
RegCloseKey(hkey); RegCloseKey(hkey);
return FALSE; return FALSE;
@ -1011,9 +965,6 @@ no_afmfiles:
no_afmdirs: no_afmdirs:
if (SortFontMetrics() == FALSE)
return FALSE;
CalcWindowsMetrics();
if (AddBuiltinAFMs() == FALSE) if (AddBuiltinAFMs() == FALSE)
return FALSE; return FALSE;

View File

@ -26,13 +26,13 @@ inline static float round(float f)
static void ScaleFont(DC *dc, LOGFONTW *lf, PSDRV_PDEVICE *physDev) static void ScaleFont(DC *dc, LOGFONTW *lf, PSDRV_PDEVICE *physDev)
{ {
PSFONT *font = &(physDev->font); PSFONT *font = &(physDev->font);
WINMETRICS *wm = &(font->afm->WinMetrics); const WINMETRICS *wm = &(font->afm->WinMetrics);
TEXTMETRICW *tm = &(font->tm); TEXTMETRICW *tm = &(font->tm);
LONG lfHeight_ds; LONG lfHeight_ds;
USHORT usUnitsPerEm, usWinAscent, usWinDescent; USHORT usUnitsPerEm, usWinAscent, usWinDescent;
SHORT sAscender, sDescender, sLineGap, sTypoAscender; SHORT sAscender, sDescender, sLineGap, sTypoAscender;
SHORT sTypoDescender, sTypoLineGap, sAvgCharWidth; SHORT sTypoDescender, sTypoLineGap, sAvgCharWidth;
TRACE("'%s' %li\n", font->afm->FontName, lf->lfHeight); TRACE("'%s' %li\n", font->afm->FontName, lf->lfHeight);
@ -452,8 +452,8 @@ BOOL PSDRV_SetFont( DC *dc )
/*********************************************************************** /***********************************************************************
* PSDRV_GetFontMetric * PSDRV_GetFontMetric
*/ */
static UINT PSDRV_GetFontMetric(HDC hdc, AFM *pafm, NEWTEXTMETRICEXW *pTM, static UINT PSDRV_GetFontMetric(HDC hdc, const AFM *pafm,
ENUMLOGFONTEXW *pLF, INT16 size) NEWTEXTMETRICEXW *pTM, ENUMLOGFONTEXW *pLF, INT16 size)
{ {
DC *dc = DC_GetDCPtr( hdc ); DC *dc = DC_GetDCPtr( hdc );

View File

@ -157,7 +157,7 @@ static INT GlyphListSearch(LPCSTR szName, INT loIndex, INT hiIndex)
* necessary, and returns a pointer to it (NULL if unable to add it) * necessary, and returns a pointer to it (NULL if unable to add it)
* *
*/ */
GLYPHNAME *PSDRV_GlyphName(LPCSTR szName) const GLYPHNAME *PSDRV_GlyphName(LPCSTR szName)
{ {
INT index; INT index;

View File

@ -462,7 +462,7 @@ PRINTERINFO *PSDRV_FindPrinterInfo(LPCSTR name)
DWORD type = REG_BINARY, needed, res, dwPaperSize; DWORD type = REG_BINARY, needed, res, dwPaperSize;
PRINTERINFO *pi = PSDRV_PrinterList, **last = &PSDRV_PrinterList; PRINTERINFO *pi = PSDRV_PrinterList, **last = &PSDRV_PrinterList;
FONTNAME *font; FONTNAME *font;
AFM *afm; const AFM *afm;
HANDLE hPrinter; HANDLE hPrinter;
const char *ppd = NULL; const char *ppd = NULL;
char ppdFileName[256]; char ppdFileName[256];

View File

@ -19,7 +19,7 @@ typedef struct {
typedef struct { typedef struct {
LONG UV; LONG UV;
GLYPHNAME *name; const GLYPHNAME *name;
} UNICODEGLYPH; } UNICODEGLYPH;
typedef struct { typedef struct {
@ -36,9 +36,9 @@ typedef struct _tagAFMMETRICS {
int C; /* character */ int C; /* character */
LONG UV; LONG UV;
float WX; float WX;
GLYPHNAME *N; /* name */ const GLYPHNAME *N; /* name */
AFMBBOX B; AFMBBOX B;
AFMLIGS *L; /* Ligatures */ const AFMLIGS *L; /* Ligatures */
} AFMMETRICS; } AFMMETRICS;
typedef struct { typedef struct {
@ -55,10 +55,10 @@ typedef struct {
} WINMETRICS; } WINMETRICS;
typedef struct _tagAFM { typedef struct _tagAFM {
char *FontName; LPCSTR FontName;
char *FullName; LPCSTR FullName;
char *FamilyName; LPCSTR FamilyName;
char *EncodingScheme; LPCSTR EncodingScheme;
LONG Weight; /* FW_NORMAL etc. */ LONG Weight; /* FW_NORMAL etc. */
float ItalicAngle; float ItalicAngle;
BOOL IsFixedPitch; BOOL IsFixedPitch;
@ -73,7 +73,7 @@ typedef struct _tagAFM {
WINMETRICS WinMetrics; WINMETRICS WinMetrics;
float CharWidths[256]; float CharWidths[256];
int NumofMetrics; int NumofMetrics;
AFMMETRICS *Metrics; const AFMMETRICS *Metrics;
} AFM; /* CharWidths is a shortcut to the WX values of numbered glyphs */ } AFM; /* CharWidths is a shortcut to the WX values of numbered glyphs */
/* Note no 'next' in AFM. Use AFMLISTENTRY as a container. This allow more than /* Note no 'next' in AFM. Use AFMLISTENTRY as a container. This allow more than
@ -82,7 +82,7 @@ typedef struct _tagAFM {
fonts for each DC (dc->physDev->Fonts) */ fonts for each DC (dc->physDev->Fonts) */
typedef struct _tagAFMLISTENTRY { typedef struct _tagAFMLISTENTRY {
AFM *afm; const AFM *afm;
struct _tagAFMLISTENTRY *next; struct _tagAFMLISTENTRY *next;
} AFMLISTENTRY; } AFMLISTENTRY;
@ -218,7 +218,7 @@ typedef struct {
} PSCOLOR; } PSCOLOR;
typedef struct { typedef struct {
AFM *afm; const AFM *afm;
TEXTMETRICW tm; TEXTMETRICW tm;
INT size; INT size;
float scale; float scale;
@ -297,8 +297,8 @@ extern void PSDRV_MergeDevmodes(PSDRV_DEVMODEA *dm1, PSDRV_DEVMODEA *dm2,
extern BOOL PSDRV_GetFontMetrics(void); extern BOOL PSDRV_GetFontMetrics(void);
extern PPD *PSDRV_ParsePPD(char *fname); extern PPD *PSDRV_ParsePPD(char *fname);
extern PRINTERINFO *PSDRV_FindPrinterInfo(LPCSTR name); extern PRINTERINFO *PSDRV_FindPrinterInfo(LPCSTR name);
extern AFM *PSDRV_FindAFMinList(FONTFAMILY *head, char *name); extern const AFM *PSDRV_FindAFMinList(FONTFAMILY *head, char *name);
extern BOOL PSDRV_AddAFMtoList(FONTFAMILY **head, AFM *afm); extern BOOL PSDRV_AddAFMtoList(FONTFAMILY **head, const AFM *afm);
extern void PSDRV_FreeAFMList( FONTFAMILY *head ); extern void PSDRV_FreeAFMList( FONTFAMILY *head );
extern BOOL WINAPI PSDRV_Init(HINSTANCE hinst, DWORD reason, LPVOID reserved); extern BOOL WINAPI PSDRV_Init(HINSTANCE hinst, DWORD reason, LPVOID reserved);
@ -425,7 +425,7 @@ extern DWORD PSDRV_DeviceCapabilities(LPSTR lpszDriver, LPCSTR lpszDevice,
LPDEVMODEA lpdm); LPDEVMODEA lpdm);
VOID PSDRV_DrawLine( DC *dc ); VOID PSDRV_DrawLine( DC *dc );
INT PSDRV_GlyphListInit(); INT PSDRV_GlyphListInit();
GLYPHNAME *PSDRV_GlyphName(LPCSTR szName); const GLYPHNAME *PSDRV_GlyphName(LPCSTR szName);
VOID PSDRV_IndexGlyphList(); VOID PSDRV_IndexGlyphList();
BOOL PSDRV_GetTrueTypeMetrics(); BOOL PSDRV_GetTrueTypeMetrics();
const AFMMETRICS *PSDRV_UVMetrics(LONG UV, const AFM *afm); const AFMMETRICS *PSDRV_UVMetrics(LONG UV, const AFM *afm);

View File

@ -39,6 +39,7 @@
#include <stdio.h> #include <stdio.h>
#include "winnt.h" #include "winnt.h"
#include "winerror.h"
#include "winreg.h" #include "winreg.h"
#include "psdrv.h" #include "psdrv.h"
#include "debugtools.h" #include "debugtools.h"
@ -60,6 +61,16 @@ static TT_Postscript *post;
static TT_OS2 *os2; static TT_OS2 *os2;
static TT_HoriHeader *hhea; static TT_HoriHeader *hhea;
/* This is now officially a pain in the ass! */
typedef struct
{
LPSTR FontName;
LPSTR FullName;
LPSTR FamilyName;
LPSTR EncodingScheme;
} AFMSTRINGS;
/******************************************************************************* /*******************************************************************************
* *
* FindCharMap * FindCharMap
@ -81,7 +92,7 @@ static const char *encoding_names[7] =
"WindowsJohab" /* TT_MS_ID_JOHAB */ "WindowsJohab" /* TT_MS_ID_JOHAB */
}; };
static BOOL FindCharMap(AFM *afm) static BOOL FindCharMap(AFM *afm, AFMSTRINGS *str)
{ {
FT_Int i; FT_Int i;
FT_Error error; FT_Error error;
@ -115,22 +126,24 @@ static BOOL FindCharMap(AFM *afm)
if (charmap->encoding_id < 7) if (charmap->encoding_id < 7)
{ {
afm->EncodingScheme = HEAP_strdupA(PSDRV_Heap, 0, str->EncodingScheme = HEAP_strdupA(PSDRV_Heap, 0,
encoding_names[charmap->encoding_id]); encoding_names[charmap->encoding_id]);
if (afm->EncodingScheme == NULL) if (str->EncodingScheme == NULL)
return FALSE; return FALSE;
} }
else else
{ {
afm->EncodingScheme = HeapAlloc(PSDRV_Heap, 0, /* encoding_id */ str->EncodingScheme =
sizeof("WindowsUnknown65535")); /* is a UShort */ HeapAlloc(PSDRV_Heap, 0, sizeof("WindowsUnknown65535"));
if (afm->EncodingScheme == NULL) if (str->EncodingScheme == NULL)
return FALSE; return FALSE;
sprintf(afm->EncodingScheme, "%s%u", "WindowsUnknown", sprintf(str->EncodingScheme, "%s%u", "WindowsUnknown",
charmap->encoding_id); charmap->encoding_id);
} }
afm->EncodingScheme = str->EncodingScheme;
return TRUE; return TRUE;
} }
@ -160,7 +173,7 @@ static BOOL NameTableString(LPSTR *sz, const FT_SfntName *name)
} }
len = name->string_len / 2; len = name->string_len / 2;
s = *sz = HeapAlloc(PSDRV_Heap, 0, len + 1); *sz = s = HeapAlloc(PSDRV_Heap, 0, len + 1);
if (s == NULL) if (s == NULL)
return FALSE; return FALSE;
ws = (FT_UShort *)(name->string); ws = (FT_UShort *)(name->string);
@ -198,7 +211,7 @@ static BOOL NameTableString(LPSTR *sz, const FT_SfntName *name)
* returns FALSE only in the event of an unexpected error. * returns FALSE only in the event of an unexpected error.
* *
*/ */
static BOOL ReadNameTable(AFM *afm) static BOOL ReadNameTable(AFM *afm, AFMSTRINGS *str)
{ {
FT_UInt numStrings, stringIndex; FT_UInt numStrings, stringIndex;
FT_SfntName name; FT_SfntName name;
@ -226,20 +239,23 @@ static BOOL ReadNameTable(AFM *afm)
{ {
case TT_NAME_ID_FONT_FAMILY: case TT_NAME_ID_FONT_FAMILY:
if (NameTableString(&(afm->FamilyName), &name) == FALSE) if (NameTableString(&(str->FamilyName), &name) == FALSE)
return FALSE; return FALSE;
afm->FamilyName = str->FamilyName;
break; break;
case TT_NAME_ID_FULL_NAME: case TT_NAME_ID_FULL_NAME:
if (NameTableString(&(afm->FullName), &name) == FALSE) if (NameTableString(&(str->FullName), &name) == FALSE)
return FALSE; return FALSE;
afm->FullName = str->FullName;
break; break;
case TT_NAME_ID_PS_NAME: case TT_NAME_ID_PS_NAME:
if (NameTableString(&(afm->FontName), &name) == FALSE) if (NameTableString(&(str->FontName), &name) == FALSE)
return FALSE; return FALSE;
afm->FontName = str->FontName;
break; break;
} }
} }
@ -247,30 +263,6 @@ static BOOL ReadNameTable(AFM *afm)
return TRUE; return TRUE;
} }
/*******************************************************************************
* FreeAFM
*
* Frees an AFM and all subsidiary objects. For this function to work
* properly, the AFM must have been allocated with HEAP_ZERO_MEMORY, and the
* UNICODEVECTOR and it's associated array of UNICODEGLYPHs must have been
* allocated as a single object.
*/
static void FreeAFM(AFM *afm)
{
if (afm->FontName != NULL)
HeapFree(PSDRV_Heap, 0, afm->FontName);
if (afm->FullName != NULL)
HeapFree(PSDRV_Heap, 0, afm->FullName);
if (afm->FamilyName != NULL)
HeapFree(PSDRV_Heap, 0, afm->FamilyName);
if (afm->EncodingScheme != NULL)
HeapFree(PSDRV_Heap, 0, afm->EncodingScheme);
if (afm->Metrics != NULL)
HeapFree(PSDRV_Heap, 0, afm->Metrics);
HeapFree(PSDRV_Heap, 0, afm);
}
/******************************************************************************* /*******************************************************************************
* PSUnits * PSUnits
* *
@ -335,14 +327,13 @@ static BOOL ReadMetricsTables(AFM *afm)
/******************************************************************************* /*******************************************************************************
* ReadCharMetrics * ReadCharMetrics
* *
* Reads metrics for each glyph in a TrueType font. Since FreeAFM will try to * Reads metrics for each glyph in a TrueType font.
* free afm->Metrics and afm->Encoding if they are non-NULL, don't free them
* in the event of an error.
* *
*/ */
static BOOL ReadCharMetrics(AFM *afm) static AFMMETRICS *ReadCharMetrics(AFM *afm)
{ {
FT_ULong charcode, index; FT_ULong charcode, index;
AFMMETRICS *metrics;
/* /*
* There does not seem to be an easy way to get the number of characters * There does not seem to be an easy way to get the number of characters
@ -356,9 +347,9 @@ static BOOL ReadCharMetrics(AFM *afm)
afm->NumofMetrics = index; afm->NumofMetrics = index;
afm->Metrics = HeapAlloc(PSDRV_Heap, 0, index * sizeof(AFMMETRICS)); metrics = HeapAlloc(PSDRV_Heap, 0, index * sizeof(AFMMETRICS));
if (afm->Metrics == NULL) if (metrics == NULL)
return FALSE; return NULL;
for (charcode = 0, index = 0; charcode <= 65536; ++charcode) for (charcode = 0, index = 0; charcode <= 65536; ++charcode)
{ {
@ -376,14 +367,14 @@ static BOOL ReadCharMetrics(AFM *afm)
if (error != FT_Err_Ok) if (error != FT_Err_Ok)
{ {
ERR("%s returned %i\n", "FT_Load_Glyph", error); ERR("%s returned %i\n", "FT_Load_Glyph", error);
return FALSE; goto cleanup;
} }
error = FT_Get_Glyph(face->glyph, &glyph); error = FT_Get_Glyph(face->glyph, &glyph);
if (error != FT_Err_Ok) if (error != FT_Err_Ok)
{ {
ERR("%s returned %i\n", "FT_Get_Glyph", error); ERR("%s returned %i\n", "FT_Get_Glyph", error);
return FALSE; goto cleanup;
} }
FT_Glyph_Get_CBox(glyph, ft_glyph_bbox_unscaled, &bbox); FT_Glyph_Get_CBox(glyph, ft_glyph_bbox_unscaled, &bbox);
@ -392,26 +383,26 @@ static BOOL ReadCharMetrics(AFM *afm)
if (error != FT_Err_Ok) if (error != FT_Err_Ok)
{ {
ERR("%s returned %i\n", "FT_Get_Glyph_Name", error); ERR("%s returned %i\n", "FT_Get_Glyph_Name", error);
return FALSE; goto cleanup;
} }
afm->Metrics[index].N = PSDRV_GlyphName(buffer); metrics[index].N = PSDRV_GlyphName(buffer);
if (afm->Metrics[index].N == NULL) if (metrics[index].N == NULL)
return FALSE; goto cleanup;;
afm->Metrics[index].C = charcode; metrics[index].C = charcode;
afm->Metrics[index].UV = charcode; metrics[index].UV = charcode;
afm->Metrics[index].WX = PSUnits(face->glyph->metrics.horiAdvance); metrics[index].WX = PSUnits(face->glyph->metrics.horiAdvance);
afm->Metrics[index].B.llx = PSUnits(bbox.xMin); metrics[index].B.llx = PSUnits(bbox.xMin);
afm->Metrics[index].B.lly = PSUnits(bbox.yMin); metrics[index].B.lly = PSUnits(bbox.yMin);
afm->Metrics[index].B.urx = PSUnits(bbox.xMax); metrics[index].B.urx = PSUnits(bbox.xMax);
afm->Metrics[index].B.ury = PSUnits(bbox.yMax); metrics[index].B.ury = PSUnits(bbox.yMax);
afm->Metrics[index].L = NULL; metrics[index].L = NULL;
TRACE("Metrics for '%s' WX = %f B = %f,%f - %f,%f\n", TRACE("Metrics for '%s' WX = %f B = %f,%f - %f,%f\n",
afm->Metrics[index].N->sz, afm->Metrics[index].WX, metrics[index].N->sz, metrics[index].WX,
afm->Metrics[index].B.llx, afm->Metrics[index].B.lly, metrics[index].B.llx, metrics[index].B.lly,
afm->Metrics[index].B.urx, afm->Metrics[index].B.ury); metrics[index].B.urx, metrics[index].B.ury);
if (charcode == 0x0048) /* 'H' */ if (charcode == 0x0048) /* 'H' */
afm->CapHeight = PSUnits(bbox.yMax); afm->CapHeight = PSUnits(bbox.yMax);
@ -421,7 +412,12 @@ static BOOL ReadCharMetrics(AFM *afm)
++index; ++index;
} }
return TRUE; return metrics;
cleanup:
HeapFree(PSDRV_Heap, 0, metrics);
return NULL;
} }
/******************************************************************************* /*******************************************************************************
@ -429,11 +425,13 @@ static BOOL ReadCharMetrics(AFM *afm)
* *
* Fills in AFM structure for opened TrueType font file. Returns FALSE only on * Fills in AFM structure for opened TrueType font file. Returns FALSE only on
* an unexpected error (memory allocation failure or FreeType error); otherwise * an unexpected error (memory allocation failure or FreeType error); otherwise
* returns TRUE. Leaves it to the caller (ReadTrueTypeFile) to clean up. * returns TRUE.
* *
*/ */
static BOOL ReadTrueTypeAFM(AFM *afm) static BOOL ReadTrueTypeAFM(AFM *afm)
{ {
AFMSTRINGS str = { NULL, NULL, NULL, NULL };
AFMMETRICS *metrics;
if ((face->face_flags & REQUIRED_FACE_FLAGS) != REQUIRED_FACE_FLAGS) if ((face->face_flags & REQUIRED_FACE_FLAGS) != REQUIRED_FACE_FLAGS)
{ {
@ -441,7 +439,7 @@ static BOOL ReadTrueTypeAFM(AFM *afm)
return TRUE; return TRUE;
} }
if (FindCharMap(afm) == FALSE) if (FindCharMap(afm, &str) == FALSE)
return FALSE; return FALSE;
if (charmap == NULL) if (charmap == NULL)
@ -452,13 +450,22 @@ static BOOL ReadTrueTypeAFM(AFM *afm)
TRACE("Using encoding '%s'\n", afm->EncodingScheme); TRACE("Using encoding '%s'\n", afm->EncodingScheme);
if (ReadNameTable(afm) == FALSE) if (ReadNameTable(afm, &str) == FALSE)
{
if (str.FontName != NULL) HeapFree(PSDRV_Heap, 0, str.FontName);
if (str.FullName != NULL) HeapFree(PSDRV_Heap, 0, str.FullName);
if (str.FamilyName != NULL) HeapFree(PSDRV_Heap, 0, str.FamilyName);
HeapFree(PSDRV_Heap, 0, str.EncodingScheme);
return FALSE; return FALSE;
}
if (afm->FamilyName == NULL || afm->FullName == NULL || if (str.FamilyName == NULL || str.FullName == NULL || str.FontName == NULL)
afm->FontName == NULL)
{ {
WARN("Required strings missing from font\n"); WARN("Required strings missing from font\n");
if (str.FontName != NULL) HeapFree(PSDRV_Heap, 0, str.FontName);
if (str.FullName != NULL) HeapFree(PSDRV_Heap, 0, str.FullName);
if (str.FamilyName != NULL) HeapFree(PSDRV_Heap, 0, str.FamilyName);
HeapFree(PSDRV_Heap, 0, str.EncodingScheme);
return TRUE; return TRUE;
} }
@ -468,14 +475,31 @@ static BOOL ReadTrueTypeAFM(AFM *afm)
return TRUE; return TRUE;
} }
if (ReadCharMetrics(afm) == FALSE) afm->Metrics = metrics = ReadCharMetrics(afm);
if (metrics == NULL)
{
HeapFree(PSDRV_Heap, 0, str.FontName);
HeapFree(PSDRV_Heap, 0, str.FullName);
HeapFree(PSDRV_Heap, 0, str.FamilyName);
HeapFree(PSDRV_Heap, 0, str.EncodingScheme);
return FALSE; return FALSE;
}
/* Can't do this check until character metrics are read */ /* Can't do this check until character metrics are read */
if (afm->WinMetrics.sAvgCharWidth == 0) if (afm->WinMetrics.sAvgCharWidth == 0)
afm->WinMetrics.sAvgCharWidth = PSDRV_CalcAvgCharWidth(afm); afm->WinMetrics.sAvgCharWidth = PSDRV_CalcAvgCharWidth(afm);
if (PSDRV_AddAFMtoList(&PSDRV_AFMFontList, afm) == FALSE)
{
HeapFree(PSDRV_Heap, 0, str.FontName);
HeapFree(PSDRV_Heap, 0, str.FullName);
HeapFree(PSDRV_Heap, 0, str.FamilyName);
HeapFree(PSDRV_Heap, 0, str.EncodingScheme);
HeapFree(PSDRV_Heap, 0, metrics);
return FALSE;
}
return TRUE; return TRUE;
} }
@ -490,7 +514,7 @@ static BOOL ReadTrueTypeAFM(AFM *afm)
static BOOL ReadTrueTypeFile(LPCSTR filename) static BOOL ReadTrueTypeFile(LPCSTR filename)
{ {
FT_Error error; FT_Error error;
AFM *afm; AFM *afm;
TRACE("'%s'\n", filename); TRACE("'%s'\n", filename);
@ -499,7 +523,6 @@ static BOOL ReadTrueTypeFile(LPCSTR filename)
return FALSE; return FALSE;
error = FT_New_Face(library, filename, 0, &face); error = FT_New_Face(library, filename, 0, &face);
if (error != FT_Err_Ok) if (error != FT_Err_Ok)
{ {
WARN("FreeType error %i opening '%s'\n", error, filename); WARN("FreeType error %i opening '%s'\n", error, filename);
@ -509,7 +532,7 @@ static BOOL ReadTrueTypeFile(LPCSTR filename)
if (ReadTrueTypeAFM(afm) == FALSE) if (ReadTrueTypeAFM(afm) == FALSE)
{ {
FreeAFM(afm); HeapFree(PSDRV_Heap, 0, afm);
FT_Done_Face(face); FT_Done_Face(face);
return FALSE; return FALSE;
} }
@ -518,22 +541,16 @@ static BOOL ReadTrueTypeFile(LPCSTR filename)
if (error != FT_Err_Ok) if (error != FT_Err_Ok)
{ {
ERR("%s returned %i\n", "FT_Done_Face", error); ERR("%s returned %i\n", "FT_Done_Face", error);
FreeAFM(afm); HeapFree(PSDRV_Heap, 0, afm);
return FALSE; return FALSE;
} }
if (afm->Metrics == NULL) /* last element to be set */ if (afm->Metrics == NULL) /* last element to be set */
{ {
FreeAFM(afm); HeapFree(PSDRV_Heap, 0, afm);
return TRUE; return TRUE;
} }
if (PSDRV_AddAFMtoList(&PSDRV_AFMFontList, afm) == FALSE)
{
FreeAFM(afm);
return FALSE;
}
return TRUE; return TRUE;
} }
@ -556,8 +573,8 @@ BOOL PSDRV_GetTrueTypeMetrics(void)
CHAR keybuf[256], namebuf[256]; CHAR keybuf[256], namebuf[256];
INT i = 0; INT i = 0;
FT_Error error; FT_Error error;
HKEY hkey; HKEY hkey;
DWORD type, key_len, name_len; DWORD type, key_len, name_len;
error = FT_Init_FreeType(&library); error = FT_Init_FreeType(&library);
if (error != FT_Err_Ok) if (error != FT_Err_Ok)
@ -566,13 +583,16 @@ BOOL PSDRV_GetTrueTypeMetrics(void)
return FALSE; return FALSE;
} }
if(RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\TrueType Font Directories", if(RegOpenKeyExA(HKEY_LOCAL_MACHINE,
0, KEY_READ, &hkey)) "Software\\Wine\\Wine\\Config\\TrueType Font Directories",
0, KEY_READ, &hkey) != ERROR_SUCCESS)
goto no_metrics; goto no_metrics;
key_len = sizeof(keybuf); key_len = sizeof(keybuf);
name_len = sizeof(namebuf); name_len = sizeof(namebuf);
while(!RegEnumValueA(hkey, i++, keybuf, &key_len, NULL, &type, namebuf, &name_len))
while(RegEnumValueA(hkey, i++, keybuf, &key_len, NULL, &type, namebuf,
&name_len) == ERROR_SUCCESS)
{ {
struct dirent *dent; struct dirent *dent;
DIR *dir; DIR *dir;
@ -626,9 +646,11 @@ BOOL PSDRV_GetTrueTypeMetrics(void)
key_len = sizeof(keybuf); key_len = sizeof(keybuf);
name_len = sizeof(namebuf); name_len = sizeof(namebuf);
} }
RegCloseKey(hkey); RegCloseKey(hkey);
no_metrics: no_metrics:
FT_Done_FreeType(library); FT_Done_FreeType(library);
return TRUE; return TRUE;
} }