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 */
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
*
@ -94,28 +98,6 @@ inline static BOOL CheckMetrics(const AFMMETRICS *metrics)
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 *cp, *item, *value, *curpos, *endpos;
int i;
AFMMETRICS *metric;
AFMMETRICS *metric, *retval;
afm->Metrics = metric = HeapAlloc( PSDRV_Heap, 0,
afm->NumofMetrics * sizeof(AFMMETRICS) );
metric = HeapAlloc( PSDRV_Heap, 0, afm->NumofMetrics * sizeof(AFMMETRICS));
if (metric == NULL)
return FALSE;
retval = metric;
for(i = 0; i < afm->NumofMetrics; i++, metric++) {
*metric = badMetrics;
@ -145,8 +128,7 @@ static BOOL PSDRV_AFMGetCharMetrics(AFM *afm, FILE *fp)
do {
if(!fgets(line, sizeof(line), fp)) {
ERR("Unexpected EOF\n");
HeapFree(PSDRV_Heap, 0, afm->Metrics);
afm->Metrics = NULL;
HeapFree(PSDRV_Heap, 0, retval);
return FALSE;
}
cp = line + strlen(line);
@ -164,8 +146,7 @@ static BOOL PSDRV_AFMGetCharMetrics(AFM *afm, FILE *fp)
value = strpbrk(item, " \t");
if (!value) {
ERR("No whitespace found.\n");
HeapFree(PSDRV_Heap, 0, afm->Metrics);
afm->Metrics = NULL;
HeapFree(PSDRV_Heap, 0, retval);
return FALSE;
}
while(isspace(*value))
@ -173,8 +154,7 @@ static BOOL PSDRV_AFMGetCharMetrics(AFM *afm, FILE *fp)
cp = endpos = strchr(value, ';');
if (!cp) {
ERR("missing ;, failed. [%s]\n", line);
HeapFree(PSDRV_Heap, 0, afm->Metrics);
afm->Metrics = NULL;
HeapFree(PSDRV_Heap, 0, retval);
return FALSE;
}
while(isspace(*--cp))
@ -218,8 +198,7 @@ static BOOL PSDRV_AFMGetCharMetrics(AFM *afm, FILE *fp)
if (CheckMetrics(metric) == FALSE) {
ERR("Error parsing character metrics\n");
HeapFree(PSDRV_Heap, 0, afm->Metrics);
afm->Metrics = NULL;
HeapFree(PSDRV_Heap, 0, retval);
return FALSE;
}
@ -227,6 +206,10 @@ static BOOL PSDRV_AFMGetCharMetrics(AFM *afm, FILE *fp)
metric->N->sz, metric->WX, metric->B.llx, metric->B.lly,
metric->B.urx, metric->B.ury);
}
SortFontMetrics(afm, retval);
afm->Metrics = retval;
return TRUE;
}
@ -237,13 +220,13 @@ static BOOL PSDRV_AFMGetCharMetrics(AFM *afm, FILE *fp)
* PSDRV_AFMParse
*
* 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.
*
* 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;
unsigned char buf[256];
@ -252,6 +235,8 @@ static AFM *PSDRV_AFMParse(char const *file)
unsigned char *cp;
int afmfile = 0;
int c;
LPSTR font_name = NULL, full_name = NULL, family_name = NULL,
encoding_scheme = NULL;
TRACE("parsing '%s'\n", file);
@ -260,7 +245,7 @@ static AFM *PSDRV_AFMParse(char const *file)
return NULL;
}
afm = HeapAlloc(PSDRV_Heap, HEAP_ZERO_MEMORY, sizeof(AFM));
afm = HeapAlloc(PSDRV_Heap, 0, sizeof(AFM));
if(!afm) {
fclose(fp);
return NULL;
@ -297,32 +282,23 @@ static AFM *PSDRV_AFMParse(char const *file)
value++;
if(!strncmp("FontName", buf, 8)) {
afm->FontName = HEAP_strdupA(PSDRV_Heap, 0, value);
if (afm->FontName == NULL) {
fclose(fp);
FreeAFM(afm);
return NULL;
}
afm->FontName = font_name = HEAP_strdupA(PSDRV_Heap, 0, value);
if (afm->FontName == NULL)
goto cleanup_fp;
continue;
}
if(!strncmp("FullName", buf, 8)) {
afm->FullName = HEAP_strdupA(PSDRV_Heap, 0, value);
if (afm->FullName == NULL) {
fclose(fp);
FreeAFM(afm);
return NULL;
}
afm->FullName = full_name = HEAP_strdupA(PSDRV_Heap, 0, value);
if (afm->FullName == NULL)
goto cleanup_fp;
continue;
}
if(!strncmp("FamilyName", buf, 10)) {
afm->FamilyName = HEAP_strdupA(PSDRV_Heap, 0, value);
if (afm->FamilyName == NULL) {
fclose(fp);
FreeAFM(afm);
return NULL;
}
afm->FamilyName = family_name = HEAP_strdupA(PSDRV_Heap, 0, value);
if (afm->FamilyName == NULL)
goto cleanup_fp;
continue;
}
@ -399,21 +375,16 @@ static AFM *PSDRV_AFMParse(char const *file)
if(!strncmp("StartCharMetrics", buf, 16)) {
sscanf(value, "%d", &(afm->NumofMetrics) );
if (PSDRV_AFMGetCharMetrics(afm, fp) == FALSE) {
fclose(fp);
FreeAFM(afm);
return NULL;
}
if (PSDRV_AFMGetCharMetrics(afm, fp) == FALSE)
goto cleanup_fp;
continue;
}
if(!strncmp("EncodingScheme", buf, 14)) {
afm->EncodingScheme = HEAP_strdupA(PSDRV_Heap, 0, value);
if (afm->EncodingScheme == NULL) {
fclose(fp);
FreeAFM(afm);
return NULL;
}
afm->EncodingScheme = encoding_scheme =
HEAP_strdupA(PSDRV_Heap, 0, value);
if (afm->EncodingScheme == NULL)
goto cleanup_fp;
continue;
}
@ -427,21 +398,20 @@ static AFM *PSDRV_AFMParse(char const *file)
if(afm->FontName == NULL) {
WARN("%s contains no FontName.\n", file);
afm->FontName = HEAP_strdupA(PSDRV_Heap, 0, "nofont");
if (afm->FontName == NULL) {
FreeAFM(afm);
return NULL;
}
afm->FontName = font_name = HEAP_strdupA(PSDRV_Heap, 0, "nofont");
if (afm->FontName == NULL)
goto cleanup;
}
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)
afm->FamilyName = HEAP_strdupA(PSDRV_Heap, 0, afm->FontName);
if (afm->FullName == NULL || afm->FamilyName == NULL) {
FreeAFM(afm);
return NULL;
}
afm->FamilyName = family_name =
HEAP_strdupA(PSDRV_Heap, 0, afm->FontName);
if (afm->FullName == NULL || afm->FamilyName == NULL)
goto cleanup;
if(afm->Ascender == 0.0)
afm->Ascender = afm->FontBBox.ury;
@ -452,7 +422,32 @@ static AFM *PSDRV_AFMParse(char const *file)
if(afm->Weight == 0)
afm->Weight = FW_NORMAL;
CalcWindowsMetrics(afm);
if (afm->EncodingScheme != NULL &&
strcmp(afm->EncodingScheme, "AdobeStandardEncoding") == 0)
PSDRV_ReencodeCharWidths(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
* headed by head.
*/
AFM *PSDRV_FindAFMinList(FONTFAMILY *head, char *name)
const AFM *PSDRV_FindAFMinList(FONTFAMILY *head, char *name)
{
FONTFAMILY *family;
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
* 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 **insert = head;
@ -574,7 +569,7 @@ BOOL PSDRV_AddAFMtoList(FONTFAMILY **head, AFM *afm)
static void PSDRV_ReencodeCharWidths(AFM *afm)
{
int i, j;
AFMMETRICS *metric;
const AFMMETRICS *metric;
for(i = 0; i < 256; i++) {
if(isalnum(i))
@ -649,68 +644,56 @@ static int AFMMetricsByUV(const AFMMETRICS *a, const AFMMETRICS *b)
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;
while (afmle != NULL)
PSDRV_IndexGlyphList(); /* enable searching by name index */
for (i = 0; i < afm->NumofMetrics; ++i)
{
AFM *afm = afmle->afm; /* should always be valid */
INT i;
if (strcmp(afm->EncodingScheme, "FontSpecific") != 0)
UNICODEGLYPH ug, *pug;
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 */
for (i = 0; i < afm->NumofMetrics; ++i)
{
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;
}
}
WARN("Glyph '%s' in font '%s' does not have a UV\n",
ug.name->sz, afm->FullName);
metrics[i].UV = -1;
}
else /* FontSpecific encoding */
else
{
for (i = 0; i < afm->NumofMetrics; ++i)
afm->Metrics[i].UV = afm->Metrics[i].C;
metrics[i].UV = pug->UV;
}
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;
}
return TRUE;
else /* FontSpecific encoding */
{
for (i = 0; i < afm->NumofMetrics; ++i)
metrics[i].UV = metrics[i].C;
}
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
*
* Calculates several Windows-specific font metrics for each font. Relies on
* the fact that AFMs are allocated with HEAP_ZERO_MEMORY to distinguish
* TrueType fonts (when implemented), which already have these filled in.
* Calculates several Windows-specific font metrics for each font.
*
*/
static VOID CalcWindowsMetrics()
static VOID CalcWindowsMetrics(AFM *afm)
{
FONTFAMILY *family = PSDRV_AFMFontList;
while (family != NULL)
WINMETRICS wm;
INT i;
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;
while (afmle != NULL)
if (IsWinANSI(afm->Metrics[i].UV) == FALSE)
continue;
if (afm->Metrics[i].B.ury > 0)
{
WINMETRICS wm;
AFM *afm = afmle->afm; /* should always be valid */
INT i;
if (afm->WinMetrics.usUnitsPerEm != 0)
continue; /* TrueType font */
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;
USHORT ascent = (USHORT)(afm->Metrics[i].B.ury + 0.5);
if (ascent > wm.usWinAscent)
wm.usWinAscent = ascent;
}
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) {
DIR *dir;
AFM *afm;
const AFM *afm;
dir = opendir(afmdir);
if (dir) {
@ -919,13 +882,8 @@ static BOOL PSDRV_ReadAFMDir(const char* afmdir) {
TRACE("loading AFM %s\n",afmfn);
afm = PSDRV_AFMParse(afmfn);
if (afm) {
if(afm->EncodingScheme &&
!strcmp(afm->EncodingScheme,"AdobeStandardEncoding")) {
PSDRV_ReencodeCharWidths(afm);
}
if (PSDRV_AddAFMtoList(&PSDRV_AFMFontList, afm) == FALSE) {
closedir(dir);
FreeAFM(afm);
return FALSE;
}
}
@ -964,13 +922,9 @@ BOOL PSDRV_GetFontMetrics(void)
value_len = sizeof(value);
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->EncodingScheme &&
!strcmp(afm->EncodingScheme, "AdobeStandardEncoding")) {
PSDRV_ReencodeCharWidths(afm);
}
if (PSDRV_AddAFMtoList(&PSDRV_AFMFontList, afm) == FALSE) {
RegCloseKey(hkey);
return FALSE;
@ -1011,9 +965,6 @@ no_afmfiles:
no_afmdirs:
if (SortFontMetrics() == FALSE)
return FALSE;
CalcWindowsMetrics();
if (AddBuiltinAFMs() == 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)
{
PSFONT *font = &(physDev->font);
WINMETRICS *wm = &(font->afm->WinMetrics);
TEXTMETRICW *tm = &(font->tm);
LONG lfHeight_ds;
USHORT usUnitsPerEm, usWinAscent, usWinDescent;
SHORT sAscender, sDescender, sLineGap, sTypoAscender;
SHORT sTypoDescender, sTypoLineGap, sAvgCharWidth;
PSFONT *font = &(physDev->font);
const WINMETRICS *wm = &(font->afm->WinMetrics);
TEXTMETRICW *tm = &(font->tm);
LONG lfHeight_ds;
USHORT usUnitsPerEm, usWinAscent, usWinDescent;
SHORT sAscender, sDescender, sLineGap, sTypoAscender;
SHORT sTypoDescender, sTypoLineGap, sAvgCharWidth;
TRACE("'%s' %li\n", font->afm->FontName, lf->lfHeight);
@ -452,8 +452,8 @@ BOOL PSDRV_SetFont( DC *dc )
/***********************************************************************
* PSDRV_GetFontMetric
*/
static UINT PSDRV_GetFontMetric(HDC hdc, AFM *pafm, NEWTEXTMETRICEXW *pTM,
ENUMLOGFONTEXW *pLF, INT16 size)
static UINT PSDRV_GetFontMetric(HDC hdc, const AFM *pafm,
NEWTEXTMETRICEXW *pTM, ENUMLOGFONTEXW *pLF, INT16 size)
{
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)
*
*/
GLYPHNAME *PSDRV_GlyphName(LPCSTR szName)
const GLYPHNAME *PSDRV_GlyphName(LPCSTR szName)
{
INT index;

View File

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

View File

@ -19,7 +19,7 @@ typedef struct {
typedef struct {
LONG UV;
GLYPHNAME *name;
const GLYPHNAME *name;
} UNICODEGLYPH;
typedef struct {
@ -36,9 +36,9 @@ typedef struct _tagAFMMETRICS {
int C; /* character */
LONG UV;
float WX;
GLYPHNAME *N; /* name */
const GLYPHNAME *N; /* name */
AFMBBOX B;
AFMLIGS *L; /* Ligatures */
const AFMLIGS *L; /* Ligatures */
} AFMMETRICS;
typedef struct {
@ -55,10 +55,10 @@ typedef struct {
} WINMETRICS;
typedef struct _tagAFM {
char *FontName;
char *FullName;
char *FamilyName;
char *EncodingScheme;
LPCSTR FontName;
LPCSTR FullName;
LPCSTR FamilyName;
LPCSTR EncodingScheme;
LONG Weight; /* FW_NORMAL etc. */
float ItalicAngle;
BOOL IsFixedPitch;
@ -73,7 +73,7 @@ typedef struct _tagAFM {
WINMETRICS WinMetrics;
float CharWidths[256];
int NumofMetrics;
AFMMETRICS *Metrics;
const AFMMETRICS *Metrics;
} 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
@ -82,7 +82,7 @@ typedef struct _tagAFM {
fonts for each DC (dc->physDev->Fonts) */
typedef struct _tagAFMLISTENTRY {
AFM *afm;
const AFM *afm;
struct _tagAFMLISTENTRY *next;
} AFMLISTENTRY;
@ -218,7 +218,7 @@ typedef struct {
} PSCOLOR;
typedef struct {
AFM *afm;
const AFM *afm;
TEXTMETRICW tm;
INT size;
float scale;
@ -297,8 +297,8 @@ extern void PSDRV_MergeDevmodes(PSDRV_DEVMODEA *dm1, PSDRV_DEVMODEA *dm2,
extern BOOL PSDRV_GetFontMetrics(void);
extern PPD *PSDRV_ParsePPD(char *fname);
extern PRINTERINFO *PSDRV_FindPrinterInfo(LPCSTR name);
extern AFM *PSDRV_FindAFMinList(FONTFAMILY *head, char *name);
extern BOOL PSDRV_AddAFMtoList(FONTFAMILY **head, AFM *afm);
extern const AFM *PSDRV_FindAFMinList(FONTFAMILY *head, char *name);
extern BOOL PSDRV_AddAFMtoList(FONTFAMILY **head, const AFM *afm);
extern void PSDRV_FreeAFMList( FONTFAMILY *head );
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);
VOID PSDRV_DrawLine( DC *dc );
INT PSDRV_GlyphListInit();
GLYPHNAME *PSDRV_GlyphName(LPCSTR szName);
const GLYPHNAME *PSDRV_GlyphName(LPCSTR szName);
VOID PSDRV_IndexGlyphList();
BOOL PSDRV_GetTrueTypeMetrics();
const AFMMETRICS *PSDRV_UVMetrics(LONG UV, const AFM *afm);

View File

@ -39,6 +39,7 @@
#include <stdio.h>
#include "winnt.h"
#include "winerror.h"
#include "winreg.h"
#include "psdrv.h"
#include "debugtools.h"
@ -60,6 +61,16 @@ static TT_Postscript *post;
static TT_OS2 *os2;
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
@ -81,7 +92,7 @@ static const char *encoding_names[7] =
"WindowsJohab" /* TT_MS_ID_JOHAB */
};
static BOOL FindCharMap(AFM *afm)
static BOOL FindCharMap(AFM *afm, AFMSTRINGS *str)
{
FT_Int i;
FT_Error error;
@ -115,22 +126,24 @@ static BOOL FindCharMap(AFM *afm)
if (charmap->encoding_id < 7)
{
afm->EncodingScheme = HEAP_strdupA(PSDRV_Heap, 0,
str->EncodingScheme = HEAP_strdupA(PSDRV_Heap, 0,
encoding_names[charmap->encoding_id]);
if (afm->EncodingScheme == NULL)
if (str->EncodingScheme == NULL)
return FALSE;
}
else
{
afm->EncodingScheme = HeapAlloc(PSDRV_Heap, 0, /* encoding_id */
sizeof("WindowsUnknown65535")); /* is a UShort */
if (afm->EncodingScheme == NULL)
str->EncodingScheme =
HeapAlloc(PSDRV_Heap, 0, sizeof("WindowsUnknown65535"));
if (str->EncodingScheme == NULL)
return FALSE;
sprintf(afm->EncodingScheme, "%s%u", "WindowsUnknown",
sprintf(str->EncodingScheme, "%s%u", "WindowsUnknown",
charmap->encoding_id);
}
afm->EncodingScheme = str->EncodingScheme;
return TRUE;
}
@ -160,7 +173,7 @@ static BOOL NameTableString(LPSTR *sz, const FT_SfntName *name)
}
len = name->string_len / 2;
s = *sz = HeapAlloc(PSDRV_Heap, 0, len + 1);
*sz = s = HeapAlloc(PSDRV_Heap, 0, len + 1);
if (s == NULL)
return FALSE;
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.
*
*/
static BOOL ReadNameTable(AFM *afm)
static BOOL ReadNameTable(AFM *afm, AFMSTRINGS *str)
{
FT_UInt numStrings, stringIndex;
FT_SfntName name;
@ -226,20 +239,23 @@ static BOOL ReadNameTable(AFM *afm)
{
case TT_NAME_ID_FONT_FAMILY:
if (NameTableString(&(afm->FamilyName), &name) == FALSE)
if (NameTableString(&(str->FamilyName), &name) == FALSE)
return FALSE;
afm->FamilyName = str->FamilyName;
break;
case TT_NAME_ID_FULL_NAME:
if (NameTableString(&(afm->FullName), &name) == FALSE)
if (NameTableString(&(str->FullName), &name) == FALSE)
return FALSE;
afm->FullName = str->FullName;
break;
case TT_NAME_ID_PS_NAME:
if (NameTableString(&(afm->FontName), &name) == FALSE)
if (NameTableString(&(str->FontName), &name) == FALSE)
return FALSE;
afm->FontName = str->FontName;
break;
}
}
@ -247,30 +263,6 @@ static BOOL ReadNameTable(AFM *afm)
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
*
@ -335,14 +327,13 @@ static BOOL ReadMetricsTables(AFM *afm)
/*******************************************************************************
* ReadCharMetrics
*
* Reads metrics for each glyph in a TrueType font. Since FreeAFM will try to
* free afm->Metrics and afm->Encoding if they are non-NULL, don't free them
* in the event of an error.
* Reads metrics for each glyph in a TrueType font.
*
*/
static BOOL ReadCharMetrics(AFM *afm)
static AFMMETRICS *ReadCharMetrics(AFM *afm)
{
FT_ULong charcode, index;
AFMMETRICS *metrics;
/*
* 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->Metrics = HeapAlloc(PSDRV_Heap, 0, index * sizeof(AFMMETRICS));
if (afm->Metrics == NULL)
return FALSE;
metrics = HeapAlloc(PSDRV_Heap, 0, index * sizeof(AFMMETRICS));
if (metrics == NULL)
return NULL;
for (charcode = 0, index = 0; charcode <= 65536; ++charcode)
{
@ -376,14 +367,14 @@ static BOOL ReadCharMetrics(AFM *afm)
if (error != FT_Err_Ok)
{
ERR("%s returned %i\n", "FT_Load_Glyph", error);
return FALSE;
goto cleanup;
}
error = FT_Get_Glyph(face->glyph, &glyph);
if (error != FT_Err_Ok)
{
ERR("%s returned %i\n", "FT_Get_Glyph", error);
return FALSE;
goto cleanup;
}
FT_Glyph_Get_CBox(glyph, ft_glyph_bbox_unscaled, &bbox);
@ -392,26 +383,26 @@ static BOOL ReadCharMetrics(AFM *afm)
if (error != FT_Err_Ok)
{
ERR("%s returned %i\n", "FT_Get_Glyph_Name", error);
return FALSE;
goto cleanup;
}
afm->Metrics[index].N = PSDRV_GlyphName(buffer);
if (afm->Metrics[index].N == NULL)
return FALSE;
metrics[index].N = PSDRV_GlyphName(buffer);
if (metrics[index].N == NULL)
goto cleanup;;
afm->Metrics[index].C = charcode;
afm->Metrics[index].UV = charcode;
afm->Metrics[index].WX = PSUnits(face->glyph->metrics.horiAdvance);
afm->Metrics[index].B.llx = PSUnits(bbox.xMin);
afm->Metrics[index].B.lly = PSUnits(bbox.yMin);
afm->Metrics[index].B.urx = PSUnits(bbox.xMax);
afm->Metrics[index].B.ury = PSUnits(bbox.yMax);
afm->Metrics[index].L = NULL;
metrics[index].C = charcode;
metrics[index].UV = charcode;
metrics[index].WX = PSUnits(face->glyph->metrics.horiAdvance);
metrics[index].B.llx = PSUnits(bbox.xMin);
metrics[index].B.lly = PSUnits(bbox.yMin);
metrics[index].B.urx = PSUnits(bbox.xMax);
metrics[index].B.ury = PSUnits(bbox.yMax);
metrics[index].L = NULL;
TRACE("Metrics for '%s' WX = %f B = %f,%f - %f,%f\n",
afm->Metrics[index].N->sz, afm->Metrics[index].WX,
afm->Metrics[index].B.llx, afm->Metrics[index].B.lly,
afm->Metrics[index].B.urx, afm->Metrics[index].B.ury);
metrics[index].N->sz, metrics[index].WX,
metrics[index].B.llx, metrics[index].B.lly,
metrics[index].B.urx, metrics[index].B.ury);
if (charcode == 0x0048) /* 'H' */
afm->CapHeight = PSUnits(bbox.yMax);
@ -421,7 +412,12 @@ static BOOL ReadCharMetrics(AFM *afm)
++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
* 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)
{
AFMSTRINGS str = { NULL, NULL, NULL, NULL };
AFMMETRICS *metrics;
if ((face->face_flags & REQUIRED_FACE_FLAGS) != REQUIRED_FACE_FLAGS)
{
@ -441,7 +439,7 @@ static BOOL ReadTrueTypeAFM(AFM *afm)
return TRUE;
}
if (FindCharMap(afm) == FALSE)
if (FindCharMap(afm, &str) == FALSE)
return FALSE;
if (charmap == NULL)
@ -452,13 +450,22 @@ static BOOL ReadTrueTypeAFM(AFM *afm)
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;
}
if (afm->FamilyName == NULL || afm->FullName == NULL ||
afm->FontName == NULL)
if (str.FamilyName == NULL || str.FullName == NULL || str.FontName == NULL)
{
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;
}
@ -468,13 +475,30 @@ static BOOL ReadTrueTypeAFM(AFM *afm)
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;
}
/* Can't do this check until character metrics are read */
if (afm->WinMetrics.sAvgCharWidth == 0)
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;
}
@ -490,7 +514,7 @@ static BOOL ReadTrueTypeAFM(AFM *afm)
static BOOL ReadTrueTypeFile(LPCSTR filename)
{
FT_Error error;
AFM *afm;
AFM *afm;
TRACE("'%s'\n", filename);
@ -499,7 +523,6 @@ static BOOL ReadTrueTypeFile(LPCSTR filename)
return FALSE;
error = FT_New_Face(library, filename, 0, &face);
if (error != FT_Err_Ok)
{
WARN("FreeType error %i opening '%s'\n", error, filename);
@ -509,7 +532,7 @@ static BOOL ReadTrueTypeFile(LPCSTR filename)
if (ReadTrueTypeAFM(afm) == FALSE)
{
FreeAFM(afm);
HeapFree(PSDRV_Heap, 0, afm);
FT_Done_Face(face);
return FALSE;
}
@ -518,22 +541,16 @@ static BOOL ReadTrueTypeFile(LPCSTR filename)
if (error != FT_Err_Ok)
{
ERR("%s returned %i\n", "FT_Done_Face", error);
FreeAFM(afm);
HeapFree(PSDRV_Heap, 0, afm);
return FALSE;
}
if (afm->Metrics == NULL) /* last element to be set */
{
FreeAFM(afm);
HeapFree(PSDRV_Heap, 0, afm);
return TRUE;
}
if (PSDRV_AddAFMtoList(&PSDRV_AFMFontList, afm) == FALSE)
{
FreeAFM(afm);
return FALSE;
}
return TRUE;
}
@ -556,8 +573,8 @@ BOOL PSDRV_GetTrueTypeMetrics(void)
CHAR keybuf[256], namebuf[256];
INT i = 0;
FT_Error error;
HKEY hkey;
DWORD type, key_len, name_len;
HKEY hkey;
DWORD type, key_len, name_len;
error = FT_Init_FreeType(&library);
if (error != FT_Err_Ok)
@ -566,13 +583,16 @@ BOOL PSDRV_GetTrueTypeMetrics(void)
return FALSE;
}
if(RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\TrueType Font Directories",
0, KEY_READ, &hkey))
if(RegOpenKeyExA(HKEY_LOCAL_MACHINE,
"Software\\Wine\\Wine\\Config\\TrueType Font Directories",
0, KEY_READ, &hkey) != ERROR_SUCCESS)
goto no_metrics;
key_len = sizeof(keybuf);
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;
DIR *dir;
@ -626,9 +646,11 @@ BOOL PSDRV_GetTrueTypeMetrics(void)
key_len = sizeof(keybuf);
name_len = sizeof(namebuf);
}
RegCloseKey(hkey);
no_metrics:
no_metrics:
FT_Done_FreeType(library);
return TRUE;
}