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
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
28 #include "wine/debug.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(psdrv
);
32 /* ptr to fonts for which we have afm files */
33 FONTFAMILY
*PSDRV_AFMFontList
= NULL
;
36 /***********************************************************
40 * Frees the family and afmlistentry structures in list head
42 void PSDRV_FreeAFMList( FONTFAMILY
*head
)
44 AFMLISTENTRY
*afmle
, *nexta
;
45 FONTFAMILY
*family
, *nextf
;
47 for(nextf
= family
= head
; nextf
; family
= nextf
) {
48 for(nexta
= afmle
= family
->afmlist
; nexta
; afmle
= nexta
) {
50 HeapFree( PSDRV_Heap
, 0, afmle
);
53 HeapFree( PSDRV_Heap
, 0, family
);
59 /***********************************************************
62 * Returns ptr to an AFM if name (which is a PS font name) exists in list
65 const AFM
*PSDRV_FindAFMinList(FONTFAMILY
*head
, LPCSTR name
)
70 for(family
= head
; family
; family
= family
->next
) {
71 for(afmle
= family
->afmlist
; afmle
; afmle
= afmle
->next
) {
72 if(!strcmp(afmle
->afm
->FontName
, name
))
79 /***********************************************************
83 * Adds an afm to the list whose head is pointed to by head. Creates new
84 * family node if necessary and always creates a new AFMLISTENTRY.
86 * Returns FALSE for memory allocation error; returns TRUE, but sets *p_added
87 * to FALSE, for duplicate.
89 BOOL
PSDRV_AddAFMtoList(FONTFAMILY
**head
, const AFM
*afm
, BOOL
*p_added
)
91 FONTFAMILY
*family
= *head
;
92 FONTFAMILY
**insert
= head
;
93 AFMLISTENTRY
*tmpafmle
, *newafmle
;
95 newafmle
= HeapAlloc(PSDRV_Heap
, HEAP_ZERO_MEMORY
,
103 if(!wcscmp(family
->FamilyName
, afm
->FamilyName
))
105 insert
= &(family
->next
);
106 family
= family
->next
;
110 family
= HeapAlloc(PSDRV_Heap
, HEAP_ZERO_MEMORY
,
112 if (family
== NULL
) {
113 HeapFree(PSDRV_Heap
, 0, newafmle
);
117 if (!(family
->FamilyName
= HeapAlloc(PSDRV_Heap
, 0, (wcslen(afm
->FamilyName
)+1)*sizeof(WCHAR
) ))) {
118 HeapFree(PSDRV_Heap
, 0, family
);
119 HeapFree(PSDRV_Heap
, 0, newafmle
);
122 wcscpy( family
->FamilyName
, afm
->FamilyName
);
123 family
->afmlist
= newafmle
;
128 tmpafmle
= family
->afmlist
;
130 if (!strcmp(tmpafmle
->afm
->FontName
, afm
->FontName
)) {
131 WARN("Ignoring duplicate FontName '%s'\n", afm
->FontName
);
132 HeapFree(PSDRV_Heap
, 0, newafmle
);
134 return TRUE
; /* not a fatal error */
136 tmpafmle
= tmpafmle
->next
;
140 tmpafmle
= family
->afmlist
;
141 while(tmpafmle
->next
)
142 tmpafmle
= tmpafmle
->next
;
144 tmpafmle
->next
= newafmle
;
151 /***********************************************************
156 static void PSDRV_DumpFontList(void)
161 for(family
= PSDRV_AFMFontList
; family
; family
= family
->next
) {
162 TRACE("Family %s\n", debugstr_w(family
->FamilyName
));
163 for(afmle
= family
->afmlist
; afmle
; afmle
= afmle
->next
)
169 TRACE("\tFontName '%s' (%i glyphs) - %s encoding:\n",
170 afmle
->afm
->FontName
, afmle
->afm
->NumofMetrics
,
171 debugstr_w(afmle
->afm
->EncodingScheme
));
173 /* Uncomment to regenerate font data; see afm2c.c */
175 /* PSDRV_AFM2C(afmle->afm); */
178 for (i
= 0; i
< afmle
->afm
->NumofMetrics
; ++i
)
180 TRACE("\t\tU+%.4lX; C %i; N '%s'\n", afmle
->afm
->Metrics
[i
].UV
,
181 afmle
->afm
->Metrics
[i
].C
, afmle
->afm
->Metrics
[i
].N
->sz
);
189 /******************************************************************************
192 * Find the AFMMETRICS for a given UV. Returns NULL if the font does not
193 * have a glyph for the given UV.
195 static int __cdecl
MetricsByUV(const void *a
, const void *b
)
197 return (int)(((const AFMMETRICS
*)a
)->UV
- ((const AFMMETRICS
*)b
)->UV
);
200 static const AFMMETRICS
*PSDRV_UVMetrics(LONG UV
, const AFM
*afm
)
205 * Ugly work-around for symbol fonts. Wine is sending characters which
206 * belong in the Unicode private use range (U+F020 - U+F0FF) as ASCII
207 * characters (U+0020 - U+00FF).
210 if ((afm
->Metrics
->UV
& 0xff00) == 0xf000 && UV
< 0x100)
214 return bsearch(&key
, afm
->Metrics
, afm
->NumofMetrics
, sizeof(AFMMETRICS
), MetricsByUV
);
217 /*******************************************************************************
218 * PSDRV_CalcAvgCharWidth
220 * Calculate WinMetrics.sAvgCharWidth for a Type 1 font. Can also be used on
221 * TrueType fonts, if font designer set OS/2:xAvgCharWidth to zero.
223 * Tries to use formula in TrueType specification; falls back to simple mean
224 * if any lowercase latin letter (or space) is not present.
226 static inline SHORT
MeanCharWidth(const AFM
*afm
)
231 for (i
= 0; i
< afm
->NumofMetrics
; ++i
)
232 w
+= afm
->Metrics
[i
].WX
;
234 w
/= afm
->NumofMetrics
;
236 return (SHORT
)(w
+ 0.5);
239 static const struct { LONG UV
; int weight
; } UVweight
[] =
241 { 0x0061, 64 }, { 0x0062, 14 }, { 0x0063, 27 }, { 0x0064, 35 },
242 { 0x0065, 100 }, { 0x0066, 20 }, { 0x0067, 14 }, { 0x0068, 42 },
243 { 0x0069, 63 }, { 0x006a, 3 }, { 0x006b, 6 }, { 0x006c, 35 },
244 { 0x006d, 20 }, { 0x006e, 56 }, { 0x006f, 56 }, { 0x0070, 17 },
245 { 0x0071, 4 }, { 0x0072, 49 }, { 0x0073, 56 }, { 0x0074, 71 },
246 { 0x0075, 31 }, { 0x0076, 10 }, { 0x0077, 18 }, { 0x0078, 3 },
247 { 0x0079, 18 }, { 0x007a, 2 }, { 0x0020, 166 }
250 SHORT
PSDRV_CalcAvgCharWidth(const AFM
*afm
)
255 for (i
= 0; i
< ARRAY_SIZE(UVweight
); ++i
)
257 const AFMMETRICS
*afmm
;
259 afmm
= PSDRV_UVMetrics(UVweight
[i
].UV
, afm
);
261 return MeanCharWidth(afm
);
263 w
+= afmm
->WX
* (float)(UVweight
[i
].weight
);
268 return (SHORT
)(w
+ 0.5);
272 /*******************************************************************************
277 static BOOL
AddBuiltinAFMs(void)
279 const AFM
*const *afm
= PSDRV_BuiltinAFMs
;
285 if (PSDRV_AddAFMtoList(&PSDRV_AFMFontList
, *afm
, &added
) == FALSE
)
289 TRACE("Ignoring built-in font %s\n", (*afm
)->FontName
);
298 /***********************************************************
300 * PSDRV_GetFontMetrics
302 * Parses all afm files listed in the
303 * HKEY_CURRENT_USER\\Software\\Wine\\Fonts registry key.
304 * Adds built-in data last, so it can be overridden by
305 * user-supplied AFM or TTF files.
307 * If this function fails, PSDRV_Init will destroy PSDRV_Heap, so don't worry
308 * about freeing all the memory that's been allocated.
311 BOOL
PSDRV_GetFontMetrics(void)
313 if (PSDRV_GlyphListInit() != 0)
316 if (PSDRV_GetType1Metrics() == FALSE
)
319 if (AddBuiltinAFMs() == FALSE
)
322 PSDRV_IndexGlyphList(); /* Enable fast searching of glyph names */
324 PSDRV_DumpFontList();