Prepare to make built-in metrics read-only

Ian Pilcher ian.pilcher at home.com
Tue Jul 24 00:48:32 CDT 2001


There's no denying that this is ugly, but it compiles without warnings,
and it seems to work.  Hopefully I'll be able to make the actual data
constant tomorrow.

Modified files:
    dlls/wineps: afm.c font.c glyphlist.c init.c psdrv.h truetype.c

Log message:
    Ian Pilcher <ian.pilcher at home.com>
    Log message: WINEPS: modify init code to handle const data types
-- 
========================================================================
Ian Pilcher                                         ian.pilcher at home.com
========================================================================
-------------- next part --------------
diff -urN ../wine-20010723cvs/dlls/wineps/afm.c ./dlls/wineps/afm.c
--- ../wine-20010723cvs/dlls/wineps/afm.c	Tue Jul 24 00:04:57 2001
+++ ./dlls/wineps/afm.c	Tue Jul 24 00:04:34 2001
@@ -31,6 +31,10 @@
 /* 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 @@
     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 @@
     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 @@
 	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 @@
 	    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 @@
 	    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 @@
 	
 	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 @@
 	      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 @@
  *	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 @@
     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 @@
         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 @@
 	        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 @@
 
 	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 @@
 
     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 @@
     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 @@
  * 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 @@
  * 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 @@
 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 @@
     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)
-	{
-	    AFM *afm = afmle->afm;  	/* should always be valid */
-	    INT i;
-	    
-	    if (strcmp(afm->EncodingScheme, "FontSpecific") != 0)
-	    {
-	    	PSDRV_IndexGlyphList();     /* enable searching by name index */
+    	PSDRV_IndexGlyphList();     	/* enable searching by name index */
 	    
-		for (i = 0; i < afm->NumofMetrics; ++i)
-		{
-		    UNICODEGLYPH    ug, *pug;
+	for (i = 0; i < afm->NumofMetrics; ++i)
+	{
+	    UNICODEGLYPH    ug, *pug;
 		    
-		    ug.name = afm->Metrics[i].N;
-		    ug.UV = -1;
+	    ug.name = metrics[i].N;
 		    
-		    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;
-		    }
-		}
+	    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);
+		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;
 	    }
+	}
+    }
+    else    	    	    	    	    /* FontSpecific encoding */
+    {
+    	for (i = 0; i < afm->NumofMetrics; ++i)
+	    metrics[i].UV = metrics[i].C;
+    }
 	    
-	    qsort(afm->Metrics, afm->NumofMetrics, sizeof(AFMMETRICS),
-	    	    (compar_callback_fn)AFMMetricsByUV);
+    qsort(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;
+    for (i = 0; i < afm->NumofMetrics; ++i) 	/* count unencoded glyphs */
+    	if (metrics[i].UV >= 0)
+	    break;
 	    
-	    afmle = afmle->next;
-	}
-	
-	family = family->next;
+    if (i != 0)
+    {
+    	TRACE("Ignoring %i unencoded glyphs\n", i);
+    	afm->NumofMetrics -= i;
+	memmove(metrics, metrics + i, afm->NumofMetrics * sizeof(*metrics));
     }
-    
-    return TRUE;
 }
 
 /*******************************************************************************
@@ -770,98 +753,78 @@
 /*******************************************************************************
  *  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)
-    {
-    	AFMLISTENTRY	*afmle = family->afmlist;
-	
-	while (afmle != NULL)
-	{
-	    WINMETRICS	wm;
-	    AFM     	*afm = afmle->afm;  	/* should always be valid */
-	    INT     	i;
+    WINMETRICS	wm;
+    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;
+    wm.usUnitsPerEm = 1000;         	    	/* for PostScript fonts */
+    wm.sTypoAscender = (SHORT)(afm->Ascender + 0.5);
+    wm.sTypoDescender = (SHORT)(afm->Descender - 0.5);
 	    
-	    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;
-		}
+    wm.sTypoLineGap = 1200 - (wm.sTypoAscender - wm.sTypoDescender);
+    if (wm.sTypoLineGap < 0)
+    	wm.sTypoLineGap = 0;
 		
-		if (afm->Metrics[i].B.lly < 0)    
-		{
-		    USHORT descent = (USHORT)(-(afm->Metrics[i].B.lly) + 0.5);
-		    
-		    if (descent > wm.usWinDescent)
-		    	wm.usWinDescent = descent;
-		}
-	    }
+    wm.usWinAscent = 0;
+    wm.usWinDescent = 0;
 	    
-	    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);
+    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.sAscender = wm.usWinAscent;
+    wm.sDescender = -(wm.usWinDescent);
 	    
-	    wm.sLineGap = 1150 - (wm.sAscender - wm.sDescender);
-	    if (wm.sLineGap < 0)
-	    	wm.sLineGap = 0;
+    wm.sLineGap = 1150 - (wm.sAscender - wm.sDescender);
+    if (wm.sLineGap < 0)
+    	wm.sLineGap = 0;
 		
-	    wm.sAvgCharWidth = PSDRV_CalcAvgCharWidth(afm);
+    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;
+    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);
 	    
-	    /* See afm2c.c and mkagl.c for an explanation of this */
-	    /*	PSDRV_AFM2C(afm);   */
+    afm->WinMetrics = wm;
 	    
-	    afmle = afmle->next;
-	}
-	
-	family = family ->next;
-    }
+    /* See afm2c.c and mkagl.c for an explanation of this */
+    /*	PSDRV_AFM2C(afm);   */
 }
 
 
@@ -898,7 +861,7 @@
 
 static BOOL PSDRV_ReadAFMDir(const char* afmdir) {
     DIR *dir;
-    AFM	*afm;
+    const AFM	*afm;
 
     dir = opendir(afmdir);
     if (dir) {
@@ -919,13 +882,8 @@
 		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 @@
     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_afmdirs:
 
-    if (SortFontMetrics() == FALSE)
-    	return FALSE;
-    CalcWindowsMetrics();
     if (AddBuiltinAFMs() == FALSE)
     	return FALSE;
 
diff -urN ../wine-20010723cvs/dlls/wineps/font.c ./dlls/wineps/font.c
--- ../wine-20010723cvs/dlls/wineps/font.c	Tue Jul 24 00:04:57 2001
+++ ./dlls/wineps/font.c	Tue Jul 24 00:04:34 2001
@@ -26,13 +26,13 @@
  
 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 @@
 /***********************************************************************
  *           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 );
diff -urN ../wine-20010723cvs/dlls/wineps/glyphlist.c ./dlls/wineps/glyphlist.c
--- ../wine-20010723cvs/dlls/wineps/glyphlist.c	Tue Jul 24 00:04:57 2001
+++ ./dlls/wineps/glyphlist.c	Tue Jul 24 00:04:34 2001
@@ -157,7 +157,7 @@
  *  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;
 
diff -urN ../wine-20010723cvs/dlls/wineps/init.c ./dlls/wineps/init.c
--- ../wine-20010723cvs/dlls/wineps/init.c	Tue Jul 24 00:04:57 2001
+++ ./dlls/wineps/init.c	Tue Jul 24 00:04:34 2001
@@ -462,7 +462,7 @@
     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];
diff -urN ../wine-20010723cvs/dlls/wineps/psdrv.h ./dlls/wineps/psdrv.h
--- ../wine-20010723cvs/dlls/wineps/psdrv.h	Tue Jul 24 00:04:57 2001
+++ ./dlls/wineps/psdrv.h	Tue Jul 24 00:04:34 2001
@@ -19,7 +19,7 @@
 
 typedef struct {
     LONG	    UV;
-    GLYPHNAME	    *name;
+    const GLYPHNAME *name;
 } UNICODEGLYPH;
 
 typedef struct {
@@ -36,9 +36,9 @@
     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 @@
 } 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 @@
     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 @@
    fonts for each DC (dc->physDev->Fonts) */
 
 typedef struct _tagAFMLISTENTRY {
-    AFM				*afm;
+    const AFM			*afm;
     struct _tagAFMLISTENTRY	*next;
 } AFMLISTENTRY;
 
@@ -218,7 +218,7 @@
 } PSCOLOR;
 
 typedef struct {
-    AFM                 *afm;
+    const AFM           *afm;
     TEXTMETRICW         tm;
     INT                 size;
     float               scale;
@@ -297,8 +297,8 @@
 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 @@
 				      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);
diff -urN ../wine-20010723cvs/dlls/wineps/truetype.c ./dlls/wineps/truetype.c
--- ../wine-20010723cvs/dlls/wineps/truetype.c	Tue Jul 24 00:04:57 2001
+++ ./dlls/wineps/truetype.c	Tue Jul 24 00:10:36 2001
@@ -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_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 @@
     "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 @@
 	
     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 @@
     }
     
     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 @@
  *  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 @@
 	{
 	    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;
 	}
     }
@@ -248,30 +264,6 @@
 }
 
 /*******************************************************************************
- *  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
  *
  *  Convert TrueType font units (relative to font em square) to PostScript
@@ -335,14 +327,13 @@
 /*******************************************************************************
  *  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 @@
     
     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 @@
 	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 @@
 	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;
-	
-	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].N = PSDRV_GlyphName(buffer);
+	if (metrics[index].N == NULL)
+	    goto cleanup;;
+	
+	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 @@
 	++index;
     }
     
-    return TRUE;
+    return metrics;
+    
+    cleanup:
+    
+    	HeapFree(PSDRV_Heap, 0, metrics);
+	return NULL;
 }
 
 /*******************************************************************************
@@ -429,11 +425,13 @@
  *
  *  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 @@
 	return TRUE;
     }
     
-    if (FindCharMap(afm) == FALSE)
+    if (FindCharMap(afm, &str) == FALSE)
     	return FALSE;
 	
     if (charmap == NULL)
@@ -452,13 +450,22 @@
     
     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 @@
 	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 ReadTrueTypeFile(LPCSTR filename)
 {
     FT_Error	error;
-    AFM     	*afm;
+    AFM  	*afm;
     
     TRACE("'%s'\n", filename);
 
@@ -499,7 +523,6 @@
     	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 @@
     
     if (ReadTrueTypeAFM(afm) == FALSE)
     {
-    	FreeAFM(afm);
+    	HeapFree(PSDRV_Heap, 0, afm);
 	FT_Done_Face(face);
 	return FALSE;
     }    
@@ -518,22 +541,16 @@
     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 @@
     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 @@
 	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 @@
 	key_len = sizeof(keybuf);
 	name_len = sizeof(namebuf);
     }
+    
     RegCloseKey(hkey);
 
-no_metrics:
+    no_metrics:
+    
     FT_Done_FreeType(library);
     return TRUE;
 }


More information about the wine-patches mailing list