2 * Font metric functions common to Type 1 (AFM) and TrueType font files.
3 * Functions specific to Type 1 and TrueType fonts are in type1afm.c and
4 * truetype.c respectively.
6 * Copyright 1998 Huw D M Davies
7 * Copyright 2001 Ian Pilcher
16 #include "debugtools.h"
18 DEFAULT_DEBUG_CHANNEL(psdrv);
20 /* ptr to fonts for which we have afm files */
21 FONTFAMILY *PSDRV_AFMFontList = NULL;
24 /***********************************************************
28 * Frees the family and afmlistentry structures in list head
30 void PSDRV_FreeAFMList( FONTFAMILY *head )
32 AFMLISTENTRY *afmle, *nexta;
33 FONTFAMILY *family, *nextf;
35 for(nextf = family = head; nextf; family = nextf) {
36 for(nexta = afmle = family->afmlist; nexta; afmle = nexta) {
38 HeapFree( PSDRV_Heap, 0, afmle );
41 HeapFree( PSDRV_Heap, 0, family );
47 /***********************************************************
50 * Returns ptr to an AFM if name (which is a PS font name) exists in list
53 const AFM *PSDRV_FindAFMinList(FONTFAMILY *head, LPCSTR name)
58 for(family = head; family; family = family->next) {
59 for(afmle = family->afmlist; afmle; afmle = afmle->next) {
60 if(!strcmp(afmle->afm->FontName, name))
67 /***********************************************************
71 * Adds an afm to the list whose head is pointed to by head. Creates new
72 * family node if necessary and always creates a new AFMLISTENTRY.
74 * Returns FALSE for memory allocation error; returns TRUE, but sets *p_added
75 * to FALSE, for duplicate.
77 BOOL PSDRV_AddAFMtoList(FONTFAMILY **head, const AFM *afm, BOOL *p_added)
79 FONTFAMILY *family = *head;
80 FONTFAMILY **insert = head;
81 AFMLISTENTRY *tmpafmle, *newafmle;
83 newafmle = HeapAlloc(PSDRV_Heap, HEAP_ZERO_MEMORY,
91 if(!strcmp(family->FamilyName, afm->FamilyName))
93 insert = &(family->next);
94 family = family->next;
98 family = HeapAlloc(PSDRV_Heap, HEAP_ZERO_MEMORY,
100 if (family == NULL) {
101 HeapFree(PSDRV_Heap, 0, newafmle);
105 if (!(family->FamilyName = HeapAlloc(PSDRV_Heap, 0, strlen(afm->FamilyName)+1 ))) {
106 HeapFree(PSDRV_Heap, 0, family);
107 HeapFree(PSDRV_Heap, 0, newafmle);
110 strcpy( family->FamilyName, afm->FamilyName );
111 family->afmlist = newafmle;
116 tmpafmle = family->afmlist;
118 if (!strcmp(tmpafmle->afm->FontName, afm->FontName)) {
119 WARN("Ignoring duplicate FontName '%s'\n", afm->FontName);
120 HeapFree(PSDRV_Heap, 0, newafmle);
122 return TRUE; /* not a fatal error */
124 tmpafmle = tmpafmle->next;
128 tmpafmle = family->afmlist;
129 while(tmpafmle->next)
130 tmpafmle = tmpafmle->next;
132 tmpafmle->next = newafmle;
139 /***********************************************************
144 static void PSDRV_DumpFontList(void)
149 for(family = PSDRV_AFMFontList; family; family = family->next) {
150 TRACE("Family '%s'\n", family->FamilyName);
151 for(afmle = family->afmlist; afmle; afmle = afmle->next)
155 TRACE("\tFontName '%s' (%i glyphs) - '%s' encoding:\n",
156 afmle->afm->FontName, afmle->afm->NumofMetrics,
157 afmle->afm->EncodingScheme);
159 /* Uncomment to regenerate font data; see afm2c.c */
161 /* PSDRV_AFM2C(afmle->afm); */
163 for (i = 0; i < afmle->afm->NumofMetrics; ++i)
165 TRACE("\t\tU+%.4lX; C %i; N '%s'\n", afmle->afm->Metrics[i].UV,
166 afmle->afm->Metrics[i].C, afmle->afm->Metrics[i].N->sz);
174 /*******************************************************************************
175 * PSDRV_CalcAvgCharWidth
177 * Calculate WinMetrics.sAvgCharWidth for a Type 1 font. Can also be used on
178 * TrueType fonts, if font designer set OS/2:xAvgCharWidth to zero.
180 * Tries to use formula in TrueType specification; falls back to simple mean
181 * if any lowercase latin letter (or space) is not present.
183 inline static SHORT MeanCharWidth(const AFM *afm)
188 for (i = 0; i < afm->NumofMetrics; ++i)
189 w += afm->Metrics[i].WX;
191 w /= afm->NumofMetrics;
193 return (SHORT)(w + 0.5);
196 static const struct { LONG UV; int weight; } UVweight[27] =
198 { 0x0061, 64 }, { 0x0062, 14 }, { 0x0063, 27 }, { 0x0064, 35 },
199 { 0x0065, 100 }, { 0x0066, 20 }, { 0x0067, 14 }, { 0x0068, 42 },
200 { 0x0069, 63 }, { 0x006a, 3 }, { 0x006b, 6 }, { 0x006c, 35 },
201 { 0x006d, 20 }, { 0x006e, 56 }, { 0x006f, 56 }, { 0x0070, 17 },
202 { 0x0071, 4 }, { 0x0072, 49 }, { 0x0073, 56 }, { 0x0074, 71 },
203 { 0x0075, 31 }, { 0x0076, 10 }, { 0x0077, 18 }, { 0x0078, 3 },
204 { 0x0079, 18 }, { 0x007a, 2 }, { 0x0020, 166 }
207 SHORT PSDRV_CalcAvgCharWidth(const AFM *afm)
212 for (i = 0; i < 27; ++i)
214 const AFMMETRICS *afmm;
216 afmm = PSDRV_UVMetrics(UVweight[i].UV, afm);
217 if (afmm->UV != UVweight[i].UV) /* UVMetrics returns first glyph */
218 return MeanCharWidth(afm); /* in font if UV is missing */
220 w += afmm->WX * (float)(UVweight[i].weight);
225 return (SHORT)(w + 0.5);
229 /*******************************************************************************
234 static BOOL AddBuiltinAFMs()
236 const AFM *const *afm = PSDRV_BuiltinAFMs;
242 if (PSDRV_AddAFMtoList(&PSDRV_AFMFontList, *afm, &added) == FALSE)
246 TRACE("Ignoring built-in font %s\n", (*afm)->FontName);
255 /***********************************************************
257 * PSDRV_GetFontMetrics
259 * Parses all afm files listed in [afmdirs] and [TrueType Font Directories]
260 * sections of Wine configuration file. Adds built-in data last, so it can
261 * be overridden by user-supplied AFM or TTF files.
263 * If this function fails, PSDRV_Init will destroy PSDRV_Heap, so don't worry
264 * about freeing all the memory that's been allocated.
267 BOOL PSDRV_GetFontMetrics(void)
269 if (PSDRV_GlyphListInit() != 0)
272 if (PSDRV_GetType1Metrics() == FALSE)
276 if (PSDRV_GetTrueTypeMetrics() == FALSE)
280 if (AddBuiltinAFMs() == FALSE)
283 PSDRV_IndexGlyphList(); /* Enable fast searching of glyph names */
285 PSDRV_DumpFontList();