crypt32: Add tests for encoding/decoding CMSG_CMS_SIGNER_INFO.
[wine] / dlls / gdi32 / freetype.c
1 /*
2  * FreeType font engine interface
3  *
4  * Copyright 2001 Huw D M Davies for CodeWeavers.
5  * Copyright 2006 Dmitry Timoshkov for CodeWeavers.
6  *
7  * This file contains the WineEng* functions.
8  *
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.
13  *
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.
18  *
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
22  */
23
24 #include "config.h"
25 #include "wine/port.h"
26
27 #include <stdarg.h>
28 #include <stdlib.h>
29 #ifdef HAVE_SYS_STAT_H
30 # include <sys/stat.h>
31 #endif
32 #ifdef HAVE_SYS_MMAN_H
33 # include <sys/mman.h>
34 #endif
35 #include <string.h>
36 #include <dirent.h>
37 #include <stdio.h>
38 #include <assert.h>
39
40 #ifdef HAVE_CARBON_CARBON_H
41 #define LoadResource __carbon_LoadResource
42 #define CompareString __carbon_CompareString
43 #define GetCurrentThread __carbon_GetCurrentThread
44 #define GetCurrentProcess __carbon_GetCurrentProcess
45 #define AnimatePalette __carbon_AnimatePalette
46 #define EqualRgn __carbon_EqualRgn
47 #define FillRgn __carbon_FillRgn
48 #define FrameRgn __carbon_FrameRgn
49 #define GetPixel __carbon_GetPixel
50 #define InvertRgn __carbon_InvertRgn
51 #define LineTo __carbon_LineTo
52 #define OffsetRgn __carbon_OffsetRgn
53 #define PaintRgn __carbon_PaintRgn
54 #define Polygon __carbon_Polygon
55 #define ResizePalette __carbon_ResizePalette
56 #define SetRectRgn __carbon_SetRectRgn
57 #include <Carbon/Carbon.h>
58 #undef LoadResource
59 #undef CompareString
60 #undef GetCurrentThread
61 #undef _CDECL
62 #undef DPRINTF
63 #undef GetCurrentProcess
64 #undef AnimatePalette
65 #undef EqualRgn
66 #undef FillRgn
67 #undef FrameRgn
68 #undef GetPixel
69 #undef InvertRgn
70 #undef LineTo
71 #undef OffsetRgn
72 #undef PaintRgn
73 #undef Polygon
74 #undef ResizePalette
75 #undef SetRectRgn
76 #endif /* HAVE_CARBON_CARBON_H */
77
78 #include "windef.h"
79 #include "winbase.h"
80 #include "winternl.h"
81 #include "winerror.h"
82 #include "winreg.h"
83 #include "wingdi.h"
84 #include "gdi_private.h"
85 #include "wine/unicode.h"
86 #include "wine/debug.h"
87 #include "wine/list.h"
88
89 WINE_DEFAULT_DEBUG_CHANNEL(font);
90
91 #ifdef HAVE_FREETYPE
92
93 #ifdef HAVE_FT2BUILD_H
94 #include <ft2build.h>
95 #endif
96 #ifdef HAVE_FREETYPE_FREETYPE_H
97 #include <freetype/freetype.h>
98 #endif
99 #ifdef HAVE_FREETYPE_FTGLYPH_H
100 #include <freetype/ftglyph.h>
101 #endif
102 #ifdef HAVE_FREETYPE_TTTABLES_H
103 #include <freetype/tttables.h>
104 #endif
105 #ifdef HAVE_FREETYPE_FTTYPES_H
106 #include <freetype/fttypes.h>
107 #endif
108 #ifdef HAVE_FREETYPE_FTSNAMES_H
109 #include <freetype/ftsnames.h>
110 #else
111 # ifdef HAVE_FREETYPE_FTNAMES_H
112 # include <freetype/ftnames.h>
113 # endif
114 #endif
115 #ifdef HAVE_FREETYPE_TTNAMEID_H
116 #include <freetype/ttnameid.h>
117 #endif
118 #ifdef HAVE_FREETYPE_FTOUTLN_H
119 #include <freetype/ftoutln.h>
120 #endif
121 #ifdef HAVE_FREETYPE_INTERNAL_SFNT_H
122 #include <freetype/internal/sfnt.h>
123 #endif
124 #ifdef HAVE_FREETYPE_FTTRIGON_H
125 #include <freetype/fttrigon.h>
126 #endif
127 #ifdef HAVE_FREETYPE_FTWINFNT_H
128 #include <freetype/ftwinfnt.h>
129 #endif
130 #ifdef HAVE_FREETYPE_FTMODAPI_H
131 #include <freetype/ftmodapi.h>
132 #endif
133
134 #ifndef HAVE_FT_TRUETYPEENGINETYPE
135 typedef enum
136 {
137     FT_TRUETYPE_ENGINE_TYPE_NONE = 0,
138     FT_TRUETYPE_ENGINE_TYPE_UNPATENTED,
139     FT_TRUETYPE_ENGINE_TYPE_PATENTED
140 } FT_TrueTypeEngineType;
141 #endif
142
143 static FT_Library library = 0;
144 typedef struct
145 {
146     FT_Int major;
147     FT_Int minor;
148     FT_Int patch;
149 } FT_Version_t;
150 static FT_Version_t FT_Version;
151 static DWORD FT_SimpleVersion;
152
153 static void *ft_handle = NULL;
154
155 #define MAKE_FUNCPTR(f) static typeof(f) * p##f = NULL
156 MAKE_FUNCPTR(FT_Vector_Unit);
157 MAKE_FUNCPTR(FT_Done_Face);
158 MAKE_FUNCPTR(FT_Get_Char_Index);
159 MAKE_FUNCPTR(FT_Get_Module);
160 MAKE_FUNCPTR(FT_Get_Sfnt_Name);
161 MAKE_FUNCPTR(FT_Get_Sfnt_Name_Count);
162 MAKE_FUNCPTR(FT_Get_Sfnt_Table);
163 MAKE_FUNCPTR(FT_Init_FreeType);
164 MAKE_FUNCPTR(FT_Load_Glyph);
165 MAKE_FUNCPTR(FT_Matrix_Multiply);
166 MAKE_FUNCPTR(FT_MulFix);
167 MAKE_FUNCPTR(FT_New_Face);
168 MAKE_FUNCPTR(FT_New_Memory_Face);
169 MAKE_FUNCPTR(FT_Outline_Get_Bitmap);
170 MAKE_FUNCPTR(FT_Outline_Transform);
171 MAKE_FUNCPTR(FT_Outline_Translate);
172 MAKE_FUNCPTR(FT_Select_Charmap);
173 MAKE_FUNCPTR(FT_Set_Charmap);
174 MAKE_FUNCPTR(FT_Set_Pixel_Sizes);
175 MAKE_FUNCPTR(FT_Vector_Transform);
176 static void (*pFT_Library_Version)(FT_Library,FT_Int*,FT_Int*,FT_Int*);
177 static FT_Error (*pFT_Load_Sfnt_Table)(FT_Face,FT_ULong,FT_Long,FT_Byte*,FT_ULong*);
178 static FT_ULong (*pFT_Get_First_Char)(FT_Face,FT_UInt*);
179 static FT_ULong (*pFT_Get_Next_Char)(FT_Face,FT_ULong,FT_UInt*);
180 static FT_TrueTypeEngineType (*pFT_Get_TrueType_Engine_Type)(FT_Library);
181 #ifdef HAVE_FREETYPE_FTWINFNT_H
182 MAKE_FUNCPTR(FT_Get_WinFNT_Header);
183 #endif
184
185 #ifdef SONAME_LIBFONTCONFIG
186 #include <fontconfig/fontconfig.h>
187 MAKE_FUNCPTR(FcConfigGetCurrent);
188 MAKE_FUNCPTR(FcFontList);
189 MAKE_FUNCPTR(FcFontSetDestroy);
190 MAKE_FUNCPTR(FcInit);
191 MAKE_FUNCPTR(FcObjectSetAdd);
192 MAKE_FUNCPTR(FcObjectSetCreate);
193 MAKE_FUNCPTR(FcObjectSetDestroy);
194 MAKE_FUNCPTR(FcPatternCreate);
195 MAKE_FUNCPTR(FcPatternDestroy);
196 MAKE_FUNCPTR(FcPatternGetBool);
197 MAKE_FUNCPTR(FcPatternGetString);
198 #endif
199
200 #undef MAKE_FUNCPTR
201
202 #ifndef FT_MAKE_TAG
203 #define FT_MAKE_TAG( ch0, ch1, ch2, ch3 ) \
204         ( ((DWORD)(BYTE)(ch0) << 24) | ((DWORD)(BYTE)(ch1) << 16) | \
205           ((DWORD)(BYTE)(ch2) << 8) | (DWORD)(BYTE)(ch3) )
206 #endif
207
208 #ifndef ft_encoding_none
209 #define FT_ENCODING_NONE ft_encoding_none
210 #endif
211 #ifndef ft_encoding_ms_symbol
212 #define FT_ENCODING_MS_SYMBOL ft_encoding_symbol
213 #endif
214 #ifndef ft_encoding_unicode
215 #define FT_ENCODING_UNICODE ft_encoding_unicode
216 #endif
217 #ifndef ft_encoding_apple_roman
218 #define FT_ENCODING_APPLE_ROMAN ft_encoding_apple_roman
219 #endif
220
221 #ifdef WORDS_BIGENDIAN
222 #define GET_BE_WORD(x) (x)
223 #else
224 #define GET_BE_WORD(x) RtlUshortByteSwap(x)
225 #endif
226
227 /* This is basically a copy of FT_Bitmap_Size with an extra element added */
228 typedef struct {
229     FT_Short height;
230     FT_Short width;
231     FT_Pos size;
232     FT_Pos x_ppem;
233     FT_Pos y_ppem;
234     FT_Short internal_leading;
235 } Bitmap_Size;
236
237 /* FT_Bitmap_Size gained 3 new elements between FreeType 2.1.4 and 2.1.5
238    So to let this compile on older versions of FreeType we'll define the
239    new structure here. */
240 typedef struct {
241     FT_Short height, width;
242     FT_Pos size, x_ppem, y_ppem;
243 } My_FT_Bitmap_Size;
244
245 struct enum_data
246 {
247     ENUMLOGFONTEXW elf;
248     NEWTEXTMETRICEXW ntm;
249     DWORD type;
250 };
251
252 typedef struct tagFace {
253     struct list entry;
254     WCHAR *StyleName;
255     char *file;
256     void *font_data_ptr;
257     DWORD font_data_size;
258     FT_Long face_index;
259     FONTSIGNATURE fs;
260     FONTSIGNATURE fs_links;
261     DWORD ntmFlags;
262     FT_Fixed font_version;
263     BOOL scalable;
264     Bitmap_Size size;     /* set if face is a bitmap */
265     BOOL external; /* TRUE if we should manually add this font to the registry */
266     struct tagFamily *family;
267     /* Cached data for Enum */
268     struct enum_data *cached_enum_data;
269 } Face;
270
271 typedef struct tagFamily {
272     struct list entry;
273     const WCHAR *FamilyName;
274     struct list faces;
275 } Family;
276
277 typedef struct {
278     GLYPHMETRICS gm;
279     INT adv; /* These three hold to widths of the unrotated chars */
280     INT lsb;
281     INT bbx;
282     BOOL init;
283 } GM;
284
285 typedef struct {
286     FLOAT eM11, eM12;
287     FLOAT eM21, eM22;
288 } FMAT2;
289
290 typedef struct {
291     DWORD hash;
292     LOGFONTW lf;
293     FMAT2 matrix;
294     BOOL can_use_bitmap;
295 } FONT_DESC;
296
297 typedef struct tagHFONTLIST {
298     struct list entry;
299     HFONT hfont;
300 } HFONTLIST;
301
302 typedef struct {
303     struct list entry;
304     Face *face;
305     GdiFont *font;
306 } CHILD_FONT;
307
308 struct tagGdiFont {
309     struct list entry;
310     GM **gm;
311     DWORD gmsize;
312     struct list hfontlist;
313     OUTLINETEXTMETRICW *potm;
314     DWORD total_kern_pairs;
315     KERNINGPAIR *kern_pairs;
316     struct list child_fonts;
317
318     /* the following members can be accessed without locking, they are never modified after creation */
319     FT_Face ft_face;
320     struct font_mapping *mapping;
321     LPWSTR name;
322     int charset;
323     int codepage;
324     BOOL fake_italic;
325     BOOL fake_bold;
326     BYTE underline;
327     BYTE strikeout;
328     INT orientation;
329     FONT_DESC font_desc;
330     LONG aveWidth, ppem;
331     double scale_y;
332     SHORT yMax;
333     SHORT yMin;
334     DWORD ntmFlags;
335     FONTSIGNATURE fs;
336     GdiFont *base_font;
337     VOID *GSUB_Table;
338     DWORD cache_num;
339 };
340
341 typedef struct {
342     struct list entry;
343     const WCHAR *font_name;
344     struct list links;
345 } SYSTEM_LINKS;
346
347 #define GM_BLOCK_SIZE 128
348 #define FONT_GM(font,idx) (&(font)->gm[(idx) / GM_BLOCK_SIZE][(idx) % GM_BLOCK_SIZE])
349
350 static struct list gdi_font_list = LIST_INIT(gdi_font_list);
351 static struct list unused_gdi_font_list = LIST_INIT(unused_gdi_font_list);
352 #define UNUSED_CACHE_SIZE 10
353 static struct list child_font_list = LIST_INIT(child_font_list);
354 static struct list system_links = LIST_INIT(system_links);
355
356 static struct list font_subst_list = LIST_INIT(font_subst_list);
357
358 static struct list font_list = LIST_INIT(font_list);
359
360 static const WCHAR defSerif[] = {'T','i','m','e','s',' ','N','e','w',' ','R','o','m','a','n','\0'};
361 static const WCHAR defSans[] = {'A','r','i','a','l','\0'};
362 static const WCHAR defFixed[] = {'C','o','u','r','i','e','r',' ','N','e','w','\0'};
363
364 static const WCHAR fontsW[] = {'\\','f','o','n','t','s','\0'};
365 static const WCHAR win9x_font_reg_key[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
366                                            'W','i','n','d','o','w','s','\\',
367                                            'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
368                                            'F','o','n','t','s','\0'};
369
370 static const WCHAR winnt_font_reg_key[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
371                                            'W','i','n','d','o','w','s',' ','N','T','\\',
372                                            'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
373                                            'F','o','n','t','s','\0'};
374
375 static const WCHAR system_fonts_reg_key[] = {'S','o','f','t','w','a','r','e','\\','F','o','n','t','s','\0'};
376 static const WCHAR FixedSys_Value[] = {'F','I','X','E','D','F','O','N','.','F','O','N','\0'};
377 static const WCHAR System_Value[] = {'F','O','N','T','S','.','F','O','N','\0'};
378 static const WCHAR OEMFont_Value[] = {'O','E','M','F','O','N','T','.','F','O','N','\0'};
379
380 static const WCHAR * const SystemFontValues[4] = {
381     System_Value,
382     OEMFont_Value,
383     FixedSys_Value,
384     NULL
385 };
386
387 static const WCHAR external_fonts_reg_key[] = {'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\',
388                                                'F','o','n','t','s','\\','E','x','t','e','r','n','a','l',' ','F','o','n','t','s','\0'};
389
390 static const WCHAR ArabicW[] = {'A','r','a','b','i','c','\0'};
391 static const WCHAR BalticW[] = {'B','a','l','t','i','c','\0'};
392 static const WCHAR CHINESE_BIG5W[] = {'C','H','I','N','E','S','E','_','B','I','G','5','\0'};
393 static const WCHAR CHINESE_GB2312W[] = {'C','H','I','N','E','S','E','_','G','B','2','3','1','2','\0'};
394 static const WCHAR Central_EuropeanW[] = {'C','e','n','t','r','a','l',' ',
395                                     'E','u','r','o','p','e','a','n','\0'};
396 static const WCHAR CyrillicW[] = {'C','y','r','i','l','l','i','c','\0'};
397 static const WCHAR GreekW[] = {'G','r','e','e','k','\0'};
398 static const WCHAR HangulW[] = {'H','a','n','g','u','l','\0'};
399 static const WCHAR Hangul_Johab_W[] = {'H','a','n','g','u','l','(','J','o','h','a','b',')','\0'};
400 static const WCHAR HebrewW[] = {'H','e','b','r','e','w','\0'};
401 static const WCHAR JapaneseW[] = {'J','a','p','a','n','e','s','e','\0'};
402 static const WCHAR SymbolW[] = {'S','y','m','b','o','l','\0'};
403 static const WCHAR ThaiW[] = {'T','h','a','i','\0'};
404 static const WCHAR TurkishW[] = {'T','u','r','k','i','s','h','\0'};
405 static const WCHAR VietnameseW[] = {'V','i','e','t','n','a','m','e','s','e','\0'};
406 static const WCHAR WesternW[] = {'W','e','s','t','e','r','n','\0'};
407 static const WCHAR OEM_DOSW[] = {'O','E','M','/','D','O','S','\0'};
408
409 static const WCHAR * const ElfScriptsW[32] = { /* these are in the order of the fsCsb[0] bits */
410     WesternW, /*00*/
411     Central_EuropeanW,
412     CyrillicW,
413     GreekW,
414     TurkishW,
415     HebrewW,
416     ArabicW,
417     BalticW,
418     VietnameseW, /*08*/
419     NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*15*/
420     ThaiW,
421     JapaneseW,
422     CHINESE_GB2312W,
423     HangulW,
424     CHINESE_BIG5W,
425     Hangul_Johab_W,
426     NULL, NULL, /*23*/
427     NULL, NULL, NULL, NULL, NULL, NULL, NULL,
428     SymbolW /*31*/
429 };
430
431 typedef struct {
432     WCHAR *name;
433     INT charset;
434 } NameCs;
435
436 typedef struct tagFontSubst {
437     struct list entry;
438     NameCs from;
439     NameCs to;
440 } FontSubst;
441
442 struct font_mapping
443 {
444     struct list entry;
445     int         refcount;
446     dev_t       dev;
447     ino_t       ino;
448     void       *data;
449     size_t      size;
450 };
451
452 static struct list mappings_list = LIST_INIT( mappings_list );
453
454 static BOOL have_installed_roman_font = FALSE; /* CreateFontInstance will fail if this is still FALSE */
455
456 static CRITICAL_SECTION freetype_cs;
457 static CRITICAL_SECTION_DEBUG critsect_debug =
458 {
459     0, 0, &freetype_cs,
460     { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
461       0, 0, { (DWORD_PTR)(__FILE__ ": freetype_cs") }
462 };
463 static CRITICAL_SECTION freetype_cs = { &critsect_debug, -1, 0, 0, 0, 0 };
464
465 static const WCHAR font_mutex_nameW[] = {'_','_','W','I','N','E','_','F','O','N','T','_','M','U','T','E','X','_','_','\0'};
466
467 static const WCHAR szDefaultFallbackLink[] = {'M','i','c','r','o','s','o','f','t',' ','S','a','n','s',' ','S','e','r','i','f',0};
468 static BOOL use_default_fallback = FALSE;
469
470 static BOOL get_glyph_index_linked(GdiFont *font, UINT c, GdiFont **linked_font, FT_UInt *glyph);
471
472 /****************************************
473  *   Notes on .fon files
474  *
475  * The fonts System, FixedSys and Terminal are special.  There are typically multiple
476  * versions installed for different resolutions and codepages.  Windows stores which one to use
477  * in HKEY_CURRENT_CONFIG\\Software\\Fonts.
478  *    Key            Meaning
479  *  FIXEDFON.FON    FixedSys
480  *  FONTS.FON       System
481  *  OEMFONT.FON     Terminal
482  *  LogPixels       Current dpi set by the display control panel applet
483  *                  (HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion\\FontDPI
484  *                  also has a LogPixels value that appears to mirror this)
485  *
486  * On my system these values have data: vgafix.fon, vgasys.fon, vga850.fon and 96 respectively
487  * (vgaoem.fon would be your oemfont.fon if you have a US setup).
488  * If the resolution is changed to be >= 109dpi then the fonts goto 8514fix, 8514sys and 8514oem
489  * (not sure what's happening to the oem codepage here). 109 is nicely halfway between 96 and 120dpi,
490  * so that makes sense.
491  *
492  * Additionally Windows also loads the fonts listed in the [386enh] section of system.ini (this doesn't appear
493  * to be mapped into the registry on Windows 2000 at least).
494  * I have
495  * woafont=app850.fon
496  * ega80woa.fon=ega80850.fon
497  * ega40woa.fon=ega40850.fon
498  * cga80woa.fon=cga80850.fon
499  * cga40woa.fon=cga40850.fon
500  */
501
502 /* These are all structures needed for the GSUB table */
503
504 #define GSUB_TAG MS_MAKE_TAG('G', 'S', 'U', 'B')
505 #define TATEGAKI_LOWER_BOUND  0x02F1
506
507 typedef struct {
508     DWORD version;
509     WORD ScriptList;
510     WORD FeatureList;
511     WORD LookupList;
512 } GSUB_Header;
513
514 typedef struct {
515     CHAR ScriptTag[4];
516     WORD Script;
517 } GSUB_ScriptRecord;
518
519 typedef struct {
520     WORD ScriptCount;
521     GSUB_ScriptRecord ScriptRecord[1];
522 } GSUB_ScriptList;
523
524 typedef struct {
525     CHAR LangSysTag[4];
526     WORD LangSys;
527 } GSUB_LangSysRecord;
528
529 typedef struct {
530     WORD DefaultLangSys;
531     WORD LangSysCount;
532     GSUB_LangSysRecord LangSysRecord[1];
533 } GSUB_Script;
534
535 typedef struct {
536     WORD LookupOrder; /* Reserved */
537     WORD ReqFeatureIndex;
538     WORD FeatureCount;
539     WORD FeatureIndex[1];
540 } GSUB_LangSys;
541
542 typedef struct {
543     CHAR FeatureTag[4];
544     WORD Feature;
545 } GSUB_FeatureRecord;
546
547 typedef struct {
548     WORD FeatureCount;
549     GSUB_FeatureRecord FeatureRecord[1];
550 } GSUB_FeatureList;
551
552 typedef struct {
553     WORD FeatureParams; /* Reserved */
554     WORD LookupCount;
555     WORD LookupListIndex[1];
556 } GSUB_Feature;
557
558 typedef struct {
559     WORD LookupCount;
560     WORD Lookup[1];
561 } GSUB_LookupList;
562
563 typedef struct {
564     WORD LookupType;
565     WORD LookupFlag;
566     WORD SubTableCount;
567     WORD SubTable[1];
568 } GSUB_LookupTable;
569
570 typedef struct {
571     WORD CoverageFormat;
572     WORD GlyphCount;
573     WORD GlyphArray[1];
574 } GSUB_CoverageFormat1;
575
576 typedef struct {
577     WORD Start;
578     WORD End;
579     WORD StartCoverageIndex;
580 } GSUB_RangeRecord;
581
582 typedef struct {
583     WORD CoverageFormat;
584     WORD RangeCount;
585     GSUB_RangeRecord RangeRecord[1];
586 } GSUB_CoverageFormat2;
587
588 typedef struct {
589     WORD SubstFormat; /* = 1 */
590     WORD Coverage;
591     WORD DeltaGlyphID;
592 } GSUB_SingleSubstFormat1;
593
594 typedef struct {
595     WORD SubstFormat; /* = 2 */
596     WORD Coverage;
597     WORD GlyphCount;
598     WORD Substitute[1];
599 }GSUB_SingleSubstFormat2;
600
601 #ifdef HAVE_CARBON_CARBON_H
602 static char *find_cache_dir(void)
603 {
604     FSRef ref;
605     OSErr err;
606     static char cached_path[MAX_PATH];
607     static const char *wine = "/Wine", *fonts = "/Fonts";
608
609     if(*cached_path) return cached_path;
610
611     err = FSFindFolder(kUserDomain, kCachedDataFolderType, kCreateFolder, &ref);
612     if(err != noErr)
613     {
614         WARN("can't create cached data folder\n");
615         return NULL;
616     }
617     err = FSRefMakePath(&ref, (unsigned char*)cached_path, sizeof(cached_path));
618     if(err != noErr)
619     {
620         WARN("can't create cached data path\n");
621         *cached_path = '\0';
622         return NULL;
623     }
624     if(strlen(cached_path) + strlen(wine) + strlen(fonts) + 1 > sizeof(cached_path))
625     {
626         ERR("Could not create full path\n");
627         *cached_path = '\0';
628         return NULL;
629     }
630     strcat(cached_path, wine);
631
632     if(mkdir(cached_path, 0700) == -1 && errno != EEXIST)
633     {
634         WARN("Couldn't mkdir %s\n", cached_path);
635         *cached_path = '\0';
636         return NULL;
637     }
638     strcat(cached_path, fonts);
639     if(mkdir(cached_path, 0700) == -1 && errno != EEXIST)
640     {
641         WARN("Couldn't mkdir %s\n", cached_path);
642         *cached_path = '\0';
643         return NULL;
644     }
645     return cached_path;
646 }
647
648 /******************************************************************
649  *            expand_mac_font
650  *
651  * Extracts individual TrueType font files from a Mac suitcase font
652  * and saves them into the user's caches directory (see
653  * find_cache_dir()).
654  * Returns a NULL terminated array of filenames.
655  *
656  * We do this because they are apps that try to read ttf files
657  * themselves and they don't like Mac suitcase files.
658  */
659 static char **expand_mac_font(const char *path)
660 {
661     FSRef ref;
662     SInt16 res_ref;
663     OSStatus s;
664     unsigned int idx;
665     const char *out_dir;
666     const char *filename;
667     int output_len;
668     struct {
669         char **array;
670         unsigned int size, max_size;
671     } ret;
672
673     TRACE("path %s\n", path);
674
675     s = FSPathMakeRef((unsigned char*)path, &ref, FALSE);
676     if(s != noErr)
677     {
678         WARN("failed to get ref\n");
679         return NULL;
680     }
681
682     s = FSOpenResourceFile(&ref, 0, NULL, fsRdPerm, &res_ref);
683     if(s != noErr)
684     {
685         TRACE("no data fork, so trying resource fork\n");
686         res_ref = FSOpenResFile(&ref, fsRdPerm);
687         if(res_ref == -1)
688         {
689             TRACE("unable to open resource fork\n");
690             return NULL;
691         }
692     }
693
694     ret.size = 0;
695     ret.max_size = 10;
696     ret.array = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ret.max_size * sizeof(*ret.array));
697     if(!ret.array)
698     {
699         CloseResFile(res_ref);
700         return NULL;
701     }
702
703     out_dir = find_cache_dir();
704
705     filename = strrchr(path, '/');
706     if(!filename) filename = path;
707     else filename++;
708
709     /* output filename has the form out_dir/filename_%04x.ttf */
710     output_len = strlen(out_dir) + 1 + strlen(filename) + 5 + 5;
711
712     UseResFile(res_ref);
713     idx = 1;
714     while(1)
715     {
716         FamRec *fam_rec;
717         unsigned short *num_faces_ptr, num_faces, face;
718         AsscEntry *assoc;
719         Handle fond;
720         ResType fond_res = FT_MAKE_TAG('F','O','N','D');
721
722         fond = Get1IndResource(fond_res, idx);
723         if(!fond) break;
724         TRACE("got fond resource %d\n", idx);
725         HLock(fond);
726
727         fam_rec = *(FamRec**)fond;
728         num_faces_ptr = (unsigned short *)(fam_rec + 1);
729         num_faces = GET_BE_WORD(*num_faces_ptr);
730         num_faces++;
731         assoc = (AsscEntry*)(num_faces_ptr + 1);
732         TRACE("num faces %04x\n", num_faces);
733         for(face = 0; face < num_faces; face++, assoc++)
734         {
735             Handle sfnt;
736             ResType sfnt_res = FT_MAKE_TAG('s','f','n','t');
737             unsigned short size, font_id;
738             char *output;
739
740             size = GET_BE_WORD(assoc->fontSize);
741             font_id = GET_BE_WORD(assoc->fontID);
742             if(size != 0)
743             {
744                 TRACE("skipping id %04x because it's not scalable (fixed size %d)\n", font_id, size);
745                 continue;
746             }
747
748             TRACE("trying to load sfnt id %04x\n", font_id);
749             sfnt = GetResource(sfnt_res, font_id);
750             if(!sfnt)
751             {
752                 TRACE("can't get sfnt resource %04x\n", font_id);
753                 continue;
754             }
755
756             output = HeapAlloc(GetProcessHeap(), 0, output_len);
757             if(output)
758             {
759                 int fd;
760
761                 sprintf(output, "%s/%s_%04x.ttf", out_dir, filename, font_id);
762
763                 fd = open(output, O_CREAT | O_EXCL | O_WRONLY, 0600);
764                 if(fd != -1 || errno == EEXIST)
765                 {
766                     if(fd != -1)
767                     {
768                         unsigned char *sfnt_data;
769
770                         HLock(sfnt);
771                         sfnt_data = *(unsigned char**)sfnt;
772                         write(fd, sfnt_data, GetHandleSize(sfnt));
773                         HUnlock(sfnt);
774                         close(fd);
775                     }
776                     if(ret.size >= ret.max_size - 1) /* Always want the last element to be NULL */
777                     {
778                         ret.max_size *= 2;
779                         ret.array = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ret.array, ret.max_size * sizeof(*ret.array));
780                     }
781                     ret.array[ret.size++] = output;
782                 }
783                 else
784                 {
785                     WARN("unable to create %s\n", output);
786                     HeapFree(GetProcessHeap(), 0, output);
787                 }
788             }
789             ReleaseResource(sfnt);
790         }
791         HUnlock(fond);
792         ReleaseResource(fond);
793         idx++;
794     }
795     CloseResFile(res_ref);
796
797     return ret.array;
798 }
799
800 #endif /* HAVE_CARBON_CARBON_H */
801
802 static inline BOOL is_win9x(void)
803 {
804     return GetVersion() & 0x80000000;
805 }
806 /* 
807    This function builds an FT_Fixed from a double. It fails if the absolute
808    value of the float number is greater than 32768.
809 */
810 static inline FT_Fixed FT_FixedFromFloat(double f)
811 {
812         return f * 0x10000;
813 }
814
815 /* 
816    This function builds an FT_Fixed from a FIXED. It simply put f.value 
817    in the highest 16 bits and f.fract in the lowest 16 bits of the FT_Fixed.
818 */
819 static inline FT_Fixed FT_FixedFromFIXED(FIXED f)
820 {
821         return (FT_Fixed)((long)f.value << 16 | (unsigned long)f.fract);
822 }
823
824
825 static Face *find_face_from_filename(const WCHAR *file_name, const WCHAR *face_name)
826 {
827     Family *family;
828     Face *face;
829     const char *file;
830     DWORD len = WideCharToMultiByte(CP_UNIXCP, 0, file_name, -1, NULL, 0, NULL, NULL);
831     char *file_nameA = HeapAlloc(GetProcessHeap(), 0, len);
832
833     WideCharToMultiByte(CP_UNIXCP, 0, file_name, -1, file_nameA, len, NULL, NULL);
834     TRACE("looking for file %s name %s\n", debugstr_a(file_nameA), debugstr_w(face_name));
835
836     LIST_FOR_EACH_ENTRY(family, &font_list, Family, entry)
837     {
838         if(face_name && strcmpiW(face_name, family->FamilyName))
839             continue;
840         LIST_FOR_EACH_ENTRY(face, &family->faces, Face, entry)
841         {
842             if (!face->file)
843                 continue;
844             file = strrchr(face->file, '/');
845             if(!file)
846                 file = face->file;
847             else
848                 file++;
849             if(!strcasecmp(file, file_nameA))
850             {
851                 HeapFree(GetProcessHeap(), 0, file_nameA);
852                 return face;
853             }
854         }
855     }
856     HeapFree(GetProcessHeap(), 0, file_nameA);
857     return NULL;
858 }
859
860 static Family *find_family_from_name(const WCHAR *name)
861 {
862     Family *family;
863
864     LIST_FOR_EACH_ENTRY(family, &font_list, Family, entry)
865     {
866         if(!strcmpiW(family->FamilyName, name))
867             return family;
868     }
869
870     return NULL;
871 }
872
873 static void DumpSubstList(void)
874 {
875     FontSubst *psub;
876
877     LIST_FOR_EACH_ENTRY(psub, &font_subst_list, FontSubst, entry)
878     {
879         if(psub->from.charset != -1 || psub->to.charset != -1)
880             TRACE("%s:%d -> %s:%d\n", debugstr_w(psub->from.name),
881               psub->from.charset, debugstr_w(psub->to.name), psub->to.charset);
882         else
883             TRACE("%s -> %s\n", debugstr_w(psub->from.name),
884                   debugstr_w(psub->to.name));
885     }
886     return;
887 }
888
889 static LPWSTR strdupW(LPCWSTR p)
890 {
891     LPWSTR ret;
892     DWORD len = (strlenW(p) + 1) * sizeof(WCHAR);
893     ret = HeapAlloc(GetProcessHeap(), 0, len);
894     memcpy(ret, p, len);
895     return ret;
896 }
897
898 static LPSTR strdupA(LPCSTR p)
899 {
900     LPSTR ret;
901     DWORD len = (strlen(p) + 1);
902     ret = HeapAlloc(GetProcessHeap(), 0, len);
903     memcpy(ret, p, len);
904     return ret;
905 }
906
907 static FontSubst *get_font_subst(const struct list *subst_list, const WCHAR *from_name,
908                                  INT from_charset)
909 {
910     FontSubst *element;
911
912     LIST_FOR_EACH_ENTRY(element, subst_list, FontSubst, entry)
913     {
914         if(!strcmpiW(element->from.name, from_name) &&
915            (element->from.charset == from_charset ||
916             element->from.charset == -1))
917             return element;
918     }
919
920     return NULL;
921 }
922
923 #define ADD_FONT_SUBST_FORCE  1
924
925 static BOOL add_font_subst(struct list *subst_list, FontSubst *subst, INT flags)
926 {
927     FontSubst *from_exist, *to_exist;
928
929     from_exist = get_font_subst(subst_list, subst->from.name, subst->from.charset);
930
931     if(from_exist && (flags & ADD_FONT_SUBST_FORCE))
932     {
933         list_remove(&from_exist->entry);
934         HeapFree(GetProcessHeap(), 0, &from_exist->from.name);
935         HeapFree(GetProcessHeap(), 0, &from_exist->to.name);
936         HeapFree(GetProcessHeap(), 0, from_exist);
937         from_exist = NULL;
938     }
939
940     if(!from_exist)
941     {
942         to_exist = get_font_subst(subst_list, subst->to.name, subst->to.charset);
943
944         if(to_exist)
945         {
946             HeapFree(GetProcessHeap(), 0, subst->to.name);
947             subst->to.name = strdupW(to_exist->to.name);
948         }
949             
950         list_add_tail(subst_list, &subst->entry);
951
952         return TRUE;
953     }
954
955     HeapFree(GetProcessHeap(), 0, subst->from.name);
956     HeapFree(GetProcessHeap(), 0, subst->to.name);
957     HeapFree(GetProcessHeap(), 0, subst);
958     return FALSE;
959 }
960
961 static void split_subst_info(NameCs *nc, LPSTR str)
962 {
963     CHAR *p = strrchr(str, ',');
964     DWORD len;
965
966     nc->charset = -1;
967     if(p && *(p+1)) {
968         nc->charset = strtol(p+1, NULL, 10);
969         *p = '\0';
970     }
971     len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
972     nc->name = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
973     MultiByteToWideChar(CP_ACP, 0, str, -1, nc->name, len);
974 }
975
976 static void LoadSubstList(void)
977 {
978     FontSubst *psub;
979     HKEY hkey;
980     DWORD valuelen, datalen, i = 0, type, dlen, vlen;
981     LPSTR value;
982     LPVOID data;
983
984     if(RegOpenKeyA(HKEY_LOCAL_MACHINE,
985                    "Software\\Microsoft\\Windows NT\\CurrentVersion\\FontSubstitutes",
986                    &hkey) == ERROR_SUCCESS) {
987
988         RegQueryInfoKeyA(hkey, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
989                          &valuelen, &datalen, NULL, NULL);
990
991         valuelen++; /* returned value doesn't include room for '\0' */
992         value = HeapAlloc(GetProcessHeap(), 0, valuelen * sizeof(CHAR));
993         data = HeapAlloc(GetProcessHeap(), 0, datalen);
994
995         dlen = datalen;
996         vlen = valuelen;
997         while(RegEnumValueA(hkey, i++, value, &vlen, NULL, &type, data,
998                             &dlen) == ERROR_SUCCESS) {
999             TRACE("Got %s=%s\n", debugstr_a(value), debugstr_a(data));
1000
1001             psub = HeapAlloc(GetProcessHeap(), 0, sizeof(*psub));
1002             split_subst_info(&psub->from, value);
1003             split_subst_info(&psub->to, data);
1004
1005             /* Win 2000 doesn't allow mapping between different charsets
1006                or mapping of DEFAULT_CHARSET */
1007             if ((psub->from.charset && psub->to.charset != psub->from.charset) ||
1008                psub->to.charset == DEFAULT_CHARSET) {
1009                 HeapFree(GetProcessHeap(), 0, psub->to.name);
1010                 HeapFree(GetProcessHeap(), 0, psub->from.name);
1011                 HeapFree(GetProcessHeap(), 0, psub);
1012             } else {
1013                 add_font_subst(&font_subst_list, psub, 0);
1014             }
1015             /* reset dlen and vlen */
1016             dlen = datalen;
1017             vlen = valuelen;
1018         }
1019         HeapFree(GetProcessHeap(), 0, data);
1020         HeapFree(GetProcessHeap(), 0, value);
1021         RegCloseKey(hkey);
1022     }
1023 }
1024
1025 static WCHAR *get_familyname(FT_Face ft_face)
1026 {
1027     WCHAR *family = NULL;
1028     FT_SfntName name;
1029     FT_UInt num_names, name_index, i;
1030
1031     if(FT_IS_SFNT(ft_face))
1032     {
1033         num_names = pFT_Get_Sfnt_Name_Count(ft_face);
1034
1035         for(name_index = 0; name_index < num_names; name_index++)
1036         {
1037             if(!pFT_Get_Sfnt_Name(ft_face, name_index, &name))
1038             {
1039                 if((name.name_id == TT_NAME_ID_FONT_FAMILY) &&
1040                    (name.language_id == GetUserDefaultLCID()) &&
1041                    (name.platform_id == TT_PLATFORM_MICROSOFT) &&
1042                    (name.encoding_id == TT_MS_ID_UNICODE_CS))
1043                 {
1044                     /* String is not nul terminated and string_len is a byte length. */
1045                     family = HeapAlloc(GetProcessHeap(), 0, name.string_len + 2);
1046                     for(i = 0; i < name.string_len / 2; i++)
1047                     {
1048                         WORD *tmp = (WORD *)&name.string[i * 2];
1049                         family[i] = GET_BE_WORD(*tmp);
1050                     }
1051                     family[i] = 0;
1052
1053                     TRACE("Got localised name %s\n", debugstr_w(family));
1054                     return family;
1055                 }
1056             }
1057         }
1058     }
1059
1060     return NULL;
1061 }
1062
1063
1064 /*****************************************************************
1065  *  load_sfnt_table
1066  *
1067  * Wrapper around FT_Load_Sfnt_Table to cope with older versions
1068  * of FreeType that don't export this function.
1069  *
1070  */
1071 static FT_Error load_sfnt_table(FT_Face ft_face, FT_ULong table, FT_Long offset, FT_Byte *buf, FT_ULong *len)
1072 {
1073
1074     FT_Error err;
1075
1076     /* If the FT_Load_Sfnt_Table function is there we'll use it */
1077     if(pFT_Load_Sfnt_Table)
1078     {
1079         err = pFT_Load_Sfnt_Table(ft_face, table, offset, buf, len);
1080     }
1081 #ifdef HAVE_FREETYPE_INTERNAL_SFNT_H
1082     else  /* Do it the hard way */
1083     {
1084         TT_Face tt_face = (TT_Face) ft_face;
1085         SFNT_Interface *sfnt;
1086         if (FT_Version.major==2 && FT_Version.minor==0)
1087         {
1088             /* 2.0.x */
1089             sfnt = *(SFNT_Interface**)((char*)tt_face + 528);
1090         }
1091         else
1092         {
1093             /* A field was added in the middle of the structure in 2.1.x */
1094             sfnt = *(SFNT_Interface**)((char*)tt_face + 532);
1095         }
1096         err = sfnt->load_any(tt_face, table, offset, buf, len);
1097     }
1098 #else
1099     else
1100     {
1101         static int msg;
1102         if(!msg)
1103         {
1104             MESSAGE("This version of Wine was compiled with freetype headers later than 2.2.0\n"
1105                     "but is being run with a freetype library without the FT_Load_Sfnt_Table function.\n"
1106                     "Please upgrade your freetype library.\n");
1107             msg++;
1108         }
1109         err = FT_Err_Unimplemented_Feature;
1110     }
1111 #endif
1112     return err;
1113 }
1114
1115 static inline int TestStyles(DWORD flags, DWORD styles)
1116 {
1117     return (flags & styles) == styles;
1118 }
1119
1120 static int StyleOrdering(Face *face)
1121 {
1122     if (TestStyles(face->ntmFlags, NTM_BOLD | NTM_ITALIC))
1123         return 3;
1124     if (TestStyles(face->ntmFlags, NTM_ITALIC))
1125         return 2;
1126     if (TestStyles(face->ntmFlags, NTM_BOLD))
1127         return 1;
1128     if (TestStyles(face->ntmFlags, NTM_REGULAR))
1129         return 0;
1130
1131     WARN("Don't know how to order font %s %s with flags 0x%08x\n",
1132          debugstr_w(face->family->FamilyName),
1133          debugstr_w(face->StyleName),
1134          face->ntmFlags);
1135
1136     return 9999;
1137 }
1138
1139 /* Add a style of face to a font family using an ordering of the list such
1140    that regular fonts come before bold and italic, and single styles come
1141    before compound styles.  */
1142 static void AddFaceToFamily(Face *face, Family *family)
1143 {
1144     struct list *entry;
1145
1146     LIST_FOR_EACH( entry, &family->faces )
1147     {
1148         Face *ent = LIST_ENTRY(entry, Face, entry);
1149         if (StyleOrdering(face) < StyleOrdering(ent)) break;
1150     }
1151     list_add_before( entry, &face->entry );
1152 }
1153
1154 #define ADDFONT_EXTERNAL_FONT 0x01
1155 #define ADDFONT_FORCE_BITMAP  0x02
1156 static INT AddFontToList(const char *file, void *font_data_ptr, DWORD font_data_size, char *fake_family, const WCHAR *target_family, DWORD flags)
1157 {
1158     FT_Face ft_face;
1159     TT_OS2 *pOS2;
1160     TT_Header *pHeader = NULL;
1161     WCHAR *english_family, *localised_family, *StyleW;
1162     DWORD len;
1163     Family *family;
1164     Face *face;
1165     struct list *family_elem_ptr, *face_elem_ptr;
1166     FT_Error err;
1167     FT_Long face_index = 0, num_faces;
1168 #ifdef HAVE_FREETYPE_FTWINFNT_H
1169     FT_WinFNT_HeaderRec winfnt_header;
1170 #endif
1171     int i, bitmap_num, internal_leading;
1172     FONTSIGNATURE fs;
1173
1174     /* we always load external fonts from files - otherwise we would get a crash in update_reg_entries */
1175     assert(file || !(flags & ADDFONT_EXTERNAL_FONT));
1176
1177 #ifdef HAVE_CARBON_CARBON_H
1178     if(file && !fake_family)
1179     {
1180         char **mac_list = expand_mac_font(file);
1181         if(mac_list)
1182         {
1183             BOOL had_one = FALSE;
1184             char **cursor;
1185             for(cursor = mac_list; *cursor; cursor++)
1186             {
1187                 had_one = TRUE;
1188                 AddFontToList(*cursor, NULL, 0, NULL, NULL, flags);
1189                 HeapFree(GetProcessHeap(), 0, *cursor);
1190             }
1191             HeapFree(GetProcessHeap(), 0, mac_list);
1192             if(had_one)
1193                 return 1;
1194         }
1195     }
1196 #endif /* HAVE_CARBON_CARBON_H */
1197
1198     do {
1199         char *family_name = fake_family;
1200
1201         if (file)
1202         {
1203             TRACE("Loading font file %s index %ld\n", debugstr_a(file), face_index);
1204             err = pFT_New_Face(library, file, face_index, &ft_face);
1205         } else
1206         {
1207             TRACE("Loading font from ptr %p size %d, index %ld\n", font_data_ptr, font_data_size, face_index);
1208             err = pFT_New_Memory_Face(library, font_data_ptr, font_data_size, face_index, &ft_face);
1209         }
1210
1211         if(err != 0) {
1212             WARN("Unable to load font %s/%p err = %x\n", debugstr_a(file), font_data_ptr, err);
1213             return 0;
1214         }
1215
1216         if(!FT_IS_SFNT(ft_face) && (FT_IS_SCALABLE(ft_face) || !(flags & ADDFONT_FORCE_BITMAP))) { /* for now we'll accept TT/OT or bitmap fonts*/
1217             WARN("Ignoring font %s/%p\n", debugstr_a(file), font_data_ptr);
1218             pFT_Done_Face(ft_face);
1219             return 0;
1220         }
1221
1222         /* There are too many bugs in FreeType < 2.1.9 for bitmap font support */
1223         if(!FT_IS_SCALABLE(ft_face) && FT_SimpleVersion < ((2 << 16) | (1 << 8) | (9 << 0))) {
1224             WARN("FreeType version < 2.1.9, skipping bitmap font %s/%p\n", debugstr_a(file), font_data_ptr);
1225             pFT_Done_Face(ft_face);
1226             return 0;
1227         }
1228
1229         if(FT_IS_SFNT(ft_face))
1230         {
1231             if(!(pOS2 = pFT_Get_Sfnt_Table(ft_face, ft_sfnt_os2)) ||
1232                !pFT_Get_Sfnt_Table(ft_face, ft_sfnt_hhea) ||
1233                !(pHeader = pFT_Get_Sfnt_Table(ft_face, ft_sfnt_head)))
1234             {
1235                 TRACE("Font %s/%p lacks either an OS2, HHEA or HEAD table.\n"
1236                       "Skipping this font.\n", debugstr_a(file), font_data_ptr);
1237                 pFT_Done_Face(ft_face);
1238                 return 0;
1239             }
1240
1241             /* Wine uses ttfs as an intermediate step in building its bitmap fonts;
1242                we don't want to load these. */
1243             if(!memcmp(pOS2->achVendID, "Wine", sizeof(pOS2->achVendID)))
1244             {
1245                 FT_ULong len = 0;
1246
1247                 if(!load_sfnt_table(ft_face, FT_MAKE_TAG('E','B','S','C'), 0, NULL, &len))
1248                 {
1249                     TRACE("Skipping Wine bitmap-only TrueType font %s\n", debugstr_a(file));
1250                     pFT_Done_Face(ft_face);
1251                     return 0;
1252                 }
1253             }
1254         }
1255
1256         if(!ft_face->family_name || !ft_face->style_name) {
1257             TRACE("Font %s/%p lacks either a family or style name\n", debugstr_a(file), font_data_ptr);
1258             pFT_Done_Face(ft_face);
1259             return 0;
1260         }
1261
1262         if(ft_face->family_name[0] == '.') /* Ignore fonts with names beginning with a dot */
1263         {
1264             TRACE("Ignoring %s since its family name begins with a dot\n", debugstr_a(file));
1265             pFT_Done_Face(ft_face);
1266             return 0;
1267         }
1268
1269         if (target_family)
1270         {
1271             localised_family = get_familyname(ft_face);
1272             if (localised_family && strcmpiW(localised_family,target_family)!=0)
1273             {
1274                 TRACE("Skipping Index %i: Incorrect Family name for replacement\n",(INT)face_index);
1275                 HeapFree(GetProcessHeap(), 0, localised_family);
1276                 num_faces = ft_face->num_faces;
1277                 pFT_Done_Face(ft_face);
1278                 continue;
1279             }
1280             HeapFree(GetProcessHeap(), 0, localised_family);
1281         }
1282
1283         if(!family_name)
1284             family_name = ft_face->family_name;
1285
1286         bitmap_num = 0;
1287         do {
1288             My_FT_Bitmap_Size *size = NULL;
1289             FT_ULong tmp_size;
1290
1291             if(!FT_IS_SCALABLE(ft_face))
1292                 size = (My_FT_Bitmap_Size *)ft_face->available_sizes + bitmap_num;
1293
1294             len = MultiByteToWideChar(CP_ACP, 0, family_name, -1, NULL, 0);
1295             english_family = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1296             MultiByteToWideChar(CP_ACP, 0, family_name, -1, english_family, len);
1297
1298             localised_family = NULL;
1299             if(!fake_family) {
1300                 localised_family = get_familyname(ft_face);
1301                 if(localised_family && !strcmpW(localised_family, english_family)) {
1302                     HeapFree(GetProcessHeap(), 0, localised_family);
1303                     localised_family = NULL;
1304                 }
1305             }
1306
1307             family = NULL;
1308             LIST_FOR_EACH(family_elem_ptr, &font_list) {
1309                 family = LIST_ENTRY(family_elem_ptr, Family, entry);
1310                 if(!strcmpW(family->FamilyName, localised_family ? localised_family : english_family))
1311                     break;
1312                 family = NULL;
1313             }
1314             if(!family) {
1315                 family = HeapAlloc(GetProcessHeap(), 0, sizeof(*family));
1316                 family->FamilyName = strdupW(localised_family ? localised_family : english_family);
1317                 list_init(&family->faces);
1318                 list_add_tail(&font_list, &family->entry);
1319
1320                 if(localised_family) {
1321                     FontSubst *subst = HeapAlloc(GetProcessHeap(), 0, sizeof(*subst));
1322                     subst->from.name = strdupW(english_family);
1323                     subst->from.charset = -1;
1324                     subst->to.name = strdupW(localised_family);
1325                     subst->to.charset = -1;
1326                     add_font_subst(&font_subst_list, subst, 0);
1327                 }
1328             }
1329             HeapFree(GetProcessHeap(), 0, localised_family);
1330             HeapFree(GetProcessHeap(), 0, english_family);
1331
1332             len = MultiByteToWideChar(CP_ACP, 0, ft_face->style_name, -1, NULL, 0);
1333             StyleW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1334             MultiByteToWideChar(CP_ACP, 0, ft_face->style_name, -1, StyleW, len);
1335
1336             internal_leading = 0;
1337             memset(&fs, 0, sizeof(fs));
1338
1339             pOS2 = pFT_Get_Sfnt_Table(ft_face, ft_sfnt_os2);
1340             if(pOS2) {
1341                 fs.fsCsb[0] = pOS2->ulCodePageRange1;
1342                 fs.fsCsb[1] = pOS2->ulCodePageRange2;
1343                 fs.fsUsb[0] = pOS2->ulUnicodeRange1;
1344                 fs.fsUsb[1] = pOS2->ulUnicodeRange2;
1345                 fs.fsUsb[2] = pOS2->ulUnicodeRange3;
1346                 fs.fsUsb[3] = pOS2->ulUnicodeRange4;
1347                 if(pOS2->version == 0) {
1348                     FT_UInt dummy;
1349
1350                     if(!pFT_Get_First_Char || (pFT_Get_First_Char( ft_face, &dummy ) < 0x100))
1351                         fs.fsCsb[0] |= FS_LATIN1;
1352                     else
1353                         fs.fsCsb[0] |= FS_SYMBOL;
1354                 }
1355             }
1356 #ifdef HAVE_FREETYPE_FTWINFNT_H
1357             else if(pFT_Get_WinFNT_Header && !pFT_Get_WinFNT_Header(ft_face, &winfnt_header)) {
1358                 CHARSETINFO csi;
1359                 TRACE("pix_h %d charset %d dpi %dx%d pt %d\n", winfnt_header.pixel_height, winfnt_header.charset,
1360                       winfnt_header.vertical_resolution,winfnt_header.horizontal_resolution, winfnt_header.nominal_point_size);
1361                 if(TranslateCharsetInfo((DWORD*)(UINT_PTR)winfnt_header.charset, &csi, TCI_SRCCHARSET))
1362                     fs = csi.fs;
1363                 internal_leading = winfnt_header.internal_leading;
1364             }
1365 #endif
1366
1367             face_elem_ptr = list_head(&family->faces);
1368             while(face_elem_ptr) {
1369                 face = LIST_ENTRY(face_elem_ptr, Face, entry);
1370                 face_elem_ptr = list_next(&family->faces, face_elem_ptr);
1371                 if(!strcmpW(face->StyleName, StyleW) &&
1372                    (FT_IS_SCALABLE(ft_face) || ((size->y_ppem == face->size.y_ppem) && !memcmp(&fs, &face->fs, sizeof(fs)) ))) {
1373                     TRACE("Already loaded font %s %s original version is %lx, this version is %lx\n",
1374                           debugstr_w(family->FamilyName), debugstr_w(StyleW),
1375                           face->font_version,  pHeader ? pHeader->Font_Revision : 0);
1376
1377                     if(fake_family) {
1378                         TRACE("This font is a replacement but the original really exists, so we'll skip the replacement\n");
1379                         HeapFree(GetProcessHeap(), 0, StyleW);
1380                         pFT_Done_Face(ft_face);
1381                         return 1;
1382                     }
1383                     if(!pHeader || pHeader->Font_Revision <= face->font_version) {
1384                         TRACE("Original font is newer so skipping this one\n");
1385                         HeapFree(GetProcessHeap(), 0, StyleW);
1386                         pFT_Done_Face(ft_face);
1387                         return 1;
1388                     } else {
1389                         TRACE("Replacing original with this one\n");
1390                         list_remove(&face->entry);
1391                         HeapFree(GetProcessHeap(), 0, face->file);
1392                         HeapFree(GetProcessHeap(), 0, face->StyleName);
1393                         HeapFree(GetProcessHeap(), 0, face);
1394                         break;
1395                     }
1396                 }
1397             }
1398             face = HeapAlloc(GetProcessHeap(), 0, sizeof(*face));
1399             face->cached_enum_data = NULL;
1400             face->StyleName = StyleW;
1401             if (file)
1402             {
1403                 face->file = strdupA(file);
1404                 face->font_data_ptr = NULL;
1405                 face->font_data_size = 0;
1406             }
1407             else
1408             {
1409                 face->file = NULL;
1410                 face->font_data_ptr = font_data_ptr;
1411                 face->font_data_size = font_data_size;
1412             }
1413             face->face_index = face_index;
1414             face->ntmFlags = 0;
1415             if (ft_face->style_flags & FT_STYLE_FLAG_ITALIC)
1416                 face->ntmFlags |= NTM_ITALIC;
1417             if (ft_face->style_flags & FT_STYLE_FLAG_BOLD)
1418                 face->ntmFlags |= NTM_BOLD;
1419             if (face->ntmFlags == 0) face->ntmFlags = NTM_REGULAR;
1420             face->font_version = pHeader ? pHeader->Font_Revision : 0;
1421             face->family = family;
1422             face->external = (flags & ADDFONT_EXTERNAL_FONT) ? TRUE : FALSE;
1423             face->fs = fs;
1424             memset(&face->fs_links, 0, sizeof(face->fs_links));
1425
1426             if(FT_IS_SCALABLE(ft_face)) {
1427                 memset(&face->size, 0, sizeof(face->size));
1428                 face->scalable = TRUE;
1429             } else {
1430                 TRACE("Adding bitmap size h %d w %d size %ld x_ppem %ld y_ppem %ld\n",
1431                       size->height, size->width, size->size >> 6,
1432                       size->x_ppem >> 6, size->y_ppem >> 6);
1433                 face->size.height = size->height;
1434                 face->size.width = size->width;
1435                 face->size.size = size->size;
1436                 face->size.x_ppem = size->x_ppem;
1437                 face->size.y_ppem = size->y_ppem;
1438                 face->size.internal_leading = internal_leading;
1439                 face->scalable = FALSE;
1440             }
1441
1442             /* check for the presence of the 'CFF ' table to check if the font is Type1 */
1443             tmp_size = 0;
1444             if (pFT_Load_Sfnt_Table && !pFT_Load_Sfnt_Table(ft_face, FT_MAKE_TAG('C','F','F',' '), 0, NULL, &tmp_size))
1445             {
1446                 TRACE("Font %s/%p is OTF Type1\n", wine_dbgstr_a(file), font_data_ptr);
1447                 face->ntmFlags |= NTM_PS_OPENTYPE;
1448             }
1449
1450             TRACE("fsCsb = %08x %08x/%08x %08x %08x %08x\n",
1451                   face->fs.fsCsb[0], face->fs.fsCsb[1],
1452                   face->fs.fsUsb[0], face->fs.fsUsb[1],
1453                   face->fs.fsUsb[2], face->fs.fsUsb[3]);
1454
1455
1456             if(face->fs.fsCsb[0] == 0) { /* let's see if we can find any interesting cmaps */
1457                 for(i = 0; i < ft_face->num_charmaps; i++) {
1458                     switch(ft_face->charmaps[i]->encoding) {
1459                     case FT_ENCODING_UNICODE:
1460                     case FT_ENCODING_APPLE_ROMAN:
1461                         face->fs.fsCsb[0] |= FS_LATIN1;
1462                         break;
1463                     case FT_ENCODING_MS_SYMBOL:
1464                         face->fs.fsCsb[0] |= FS_SYMBOL;
1465                         break;
1466                     default:
1467                         break;
1468                     }
1469                 }
1470             }
1471
1472             if (!(face->fs.fsCsb[0] & FS_SYMBOL))
1473                 have_installed_roman_font = TRUE;
1474
1475             AddFaceToFamily(face, family);
1476
1477         } while(!FT_IS_SCALABLE(ft_face) && ++bitmap_num < ft_face->num_fixed_sizes);
1478
1479         num_faces = ft_face->num_faces;
1480         pFT_Done_Face(ft_face);
1481         TRACE("Added font %s %s\n", debugstr_w(family->FamilyName),
1482               debugstr_w(StyleW));
1483     } while(num_faces > ++face_index);
1484     return num_faces;
1485 }
1486
1487 static INT AddFontFileToList(const char *file, char *fake_family, const WCHAR *target_family, DWORD flags)
1488 {
1489     return AddFontToList(file, NULL, 0, fake_family, target_family, flags);
1490 }
1491
1492 static void DumpFontList(void)
1493 {
1494     Family *family;
1495     Face *face;
1496     struct list *family_elem_ptr, *face_elem_ptr;
1497
1498     LIST_FOR_EACH(family_elem_ptr, &font_list) {
1499         family = LIST_ENTRY(family_elem_ptr, Family, entry); 
1500         TRACE("Family: %s\n", debugstr_w(family->FamilyName));
1501         LIST_FOR_EACH(face_elem_ptr, &family->faces) {
1502             face = LIST_ENTRY(face_elem_ptr, Face, entry);
1503             TRACE("\t%s\t%08x", debugstr_w(face->StyleName), face->fs.fsCsb[0]);
1504             if(!face->scalable)
1505                 TRACE(" %d", face->size.height);
1506             TRACE("\n");
1507         }
1508     }
1509     return;
1510 }
1511
1512 /***********************************************************
1513  * The replacement list is a way to map an entire font
1514  * family onto another family.  For example adding
1515  *
1516  * [HKCU\Software\Wine\Fonts\Replacements]
1517  * "Wingdings"="Winedings"
1518  *
1519  * would enumerate the Winedings font both as Winedings and
1520  * Wingdings.  However if a real Wingdings font is present the
1521  * replacement does not take place.
1522  * 
1523  */
1524 static void LoadReplaceList(void)
1525 {
1526     HKEY hkey;
1527     DWORD valuelen, datalen, i = 0, type, dlen, vlen;
1528     LPWSTR value;
1529     LPVOID data;
1530     Family *family;
1531     Face *face;
1532     struct list *family_elem_ptr, *face_elem_ptr;
1533     CHAR familyA[400];
1534
1535     /* @@ Wine registry key: HKCU\Software\Wine\Fonts\Replacements */
1536     if(RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Fonts\\Replacements", &hkey) == ERROR_SUCCESS)
1537     {
1538         RegQueryInfoKeyW(hkey, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
1539                          &valuelen, &datalen, NULL, NULL);
1540
1541         valuelen++; /* returned value doesn't include room for '\0' */
1542         value = HeapAlloc(GetProcessHeap(), 0, valuelen * sizeof(WCHAR));
1543         data = HeapAlloc(GetProcessHeap(), 0, datalen);
1544
1545         dlen = datalen;
1546         vlen = valuelen;
1547         while(RegEnumValueW(hkey, i++, value, &vlen, NULL, &type, data,
1548                             &dlen) == ERROR_SUCCESS) {
1549             TRACE("Got %s=%s\n", debugstr_w(value), debugstr_w(data));
1550             /* "NewName"="Oldname" */
1551             WideCharToMultiByte(CP_ACP, 0, value, -1, familyA, sizeof(familyA), NULL, NULL);
1552
1553             /* Find the old family and hence all of the font files
1554                in that family */
1555             LIST_FOR_EACH(family_elem_ptr, &font_list) {
1556                 family = LIST_ENTRY(family_elem_ptr, Family, entry);
1557                 if(!strcmpiW(family->FamilyName, data)) {
1558                     LIST_FOR_EACH(face_elem_ptr, &family->faces) {
1559                         face = LIST_ENTRY(face_elem_ptr, Face, entry);
1560                         TRACE("mapping %s %s to %s\n", debugstr_w(family->FamilyName),
1561                               debugstr_w(face->StyleName), familyA);
1562                         /* Now add a new entry with the new family name */
1563                         AddFontToList(face->file, face->font_data_ptr, face->font_data_size, familyA, family->FamilyName, ADDFONT_FORCE_BITMAP | (face->external ? ADDFONT_EXTERNAL_FONT : 0));
1564                     }
1565                     break;
1566                 }
1567             }
1568             /* reset dlen and vlen */
1569             dlen = datalen;
1570             vlen = valuelen;
1571         }
1572         HeapFree(GetProcessHeap(), 0, data);
1573         HeapFree(GetProcessHeap(), 0, value);
1574         RegCloseKey(hkey);
1575     }
1576 }
1577
1578 /*************************************************************
1579  * init_system_links
1580  */
1581 static BOOL init_system_links(void)
1582 {
1583     static const WCHAR system_link[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
1584                                         'W','i','n','d','o','w','s',' ','N','T','\\',
1585                                         'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\','F','o','n','t','L','i','n','k','\\',
1586                                         'S','y','s','t','e','m','L','i','n','k',0};
1587     HKEY hkey;
1588     BOOL ret = FALSE;
1589     DWORD type, max_val, max_data, val_len, data_len, index;
1590     WCHAR *value, *data;
1591     WCHAR *entry, *next;
1592     SYSTEM_LINKS *font_link, *system_font_link;
1593     CHILD_FONT *child_font;
1594     static const WCHAR Tahoma[] = {'T','a','h','o','m','a',0};
1595     static const WCHAR tahoma_ttf[] = {'t','a','h','o','m','a','.','t','t','f',0};
1596     static const WCHAR System[] = {'S','y','s','t','e','m',0};
1597     FONTSIGNATURE fs;
1598     Family *family;
1599     Face *face;
1600     FontSubst *psub;
1601
1602     if(RegOpenKeyW(HKEY_LOCAL_MACHINE, system_link, &hkey) == ERROR_SUCCESS)
1603     {
1604         RegQueryInfoKeyW(hkey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &max_val, &max_data, NULL, NULL);
1605         value = HeapAlloc(GetProcessHeap(), 0, (max_val + 1) * sizeof(WCHAR));
1606         data = HeapAlloc(GetProcessHeap(), 0, max_data);
1607         val_len = max_val + 1;
1608         data_len = max_data;
1609         index = 0;
1610         while(RegEnumValueW(hkey, index++, value, &val_len, NULL, &type, (LPBYTE)data, &data_len) == ERROR_SUCCESS)
1611         {
1612             TRACE("%s:\n", debugstr_w(value));
1613
1614             memset(&fs, 0, sizeof(fs));
1615             font_link = HeapAlloc(GetProcessHeap(), 0, sizeof(*font_link));
1616             psub = get_font_subst(&font_subst_list, value, -1);
1617             font_link->font_name = (psub)? strdupW(psub->to.name) : strdupW(value);
1618             list_init(&font_link->links);
1619             for(entry = data; (char*)entry < (char*)data + data_len && *entry != 0; entry = next)
1620             {
1621                 WCHAR *face_name;
1622                 CHILD_FONT *child_font;
1623
1624                 TRACE("\t%s\n", debugstr_w(entry));
1625
1626                 next = entry + strlenW(entry) + 1;
1627                 
1628                 face_name = strchrW(entry, ',');
1629                 if(face_name)
1630                 {
1631                     *face_name++ = 0;
1632                     while(isspaceW(*face_name))
1633                         face_name++;
1634
1635                     psub = get_font_subst(&font_subst_list, face_name, -1);
1636                     if(psub)
1637                         face_name = psub->to.name;
1638                 }
1639                 face = find_face_from_filename(entry, face_name);
1640                 if(!face)
1641                 {
1642                     TRACE("Unable to find file %s face name %s\n", debugstr_w(entry), debugstr_w(face_name));
1643                     continue;
1644                 }
1645
1646                 child_font = HeapAlloc(GetProcessHeap(), 0, sizeof(*child_font));
1647                 child_font->face = face;
1648                 child_font->font = NULL;
1649                 fs.fsCsb[0] |= face->fs.fsCsb[0];
1650                 fs.fsCsb[1] |= face->fs.fsCsb[1];
1651                 TRACE("Adding file %s index %ld\n", child_font->face->file, child_font->face->face_index);
1652                 list_add_tail(&font_link->links, &child_font->entry);
1653             }
1654             family = find_family_from_name(font_link->font_name);
1655             if(family)
1656             {
1657                 LIST_FOR_EACH_ENTRY(face, &family->faces, Face, entry)
1658                 {
1659                     face->fs_links = fs;
1660                 }
1661             }
1662             list_add_tail(&system_links, &font_link->entry);
1663             val_len = max_val + 1;
1664             data_len = max_data;
1665         }
1666
1667         HeapFree(GetProcessHeap(), 0, value);
1668         HeapFree(GetProcessHeap(), 0, data);
1669         RegCloseKey(hkey);
1670     }
1671
1672     /* Explicitly add an entry for the system font, this links to Tahoma and any links
1673        that Tahoma has */
1674
1675     system_font_link = HeapAlloc(GetProcessHeap(), 0, sizeof(*system_font_link));
1676     system_font_link->font_name = strdupW(System);
1677     list_init(&system_font_link->links);    
1678
1679     face = find_face_from_filename(tahoma_ttf, Tahoma);
1680     if(face)
1681     {
1682         child_font = HeapAlloc(GetProcessHeap(), 0, sizeof(*child_font));
1683         child_font->face = face;
1684         child_font->font = NULL;
1685         TRACE("Found Tahoma in %s index %ld\n", child_font->face->file, child_font->face->face_index);
1686         list_add_tail(&system_font_link->links, &child_font->entry);
1687     }
1688     LIST_FOR_EACH_ENTRY(font_link, &system_links, SYSTEM_LINKS, entry)
1689     {
1690         if(!strcmpiW(font_link->font_name, Tahoma))
1691         {
1692             CHILD_FONT *font_link_entry;
1693             LIST_FOR_EACH_ENTRY(font_link_entry, &font_link->links, CHILD_FONT, entry)
1694             {
1695                 CHILD_FONT *new_child;
1696                 new_child = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_child));
1697                 new_child->face = font_link_entry->face;
1698                 new_child->font = NULL;
1699                 list_add_tail(&system_font_link->links, &new_child->entry);
1700             }
1701             break;
1702         }
1703     }
1704     list_add_tail(&system_links, &system_font_link->entry);
1705     return ret;
1706 }
1707
1708 static BOOL ReadFontDir(const char *dirname, BOOL external_fonts)
1709 {
1710     DIR *dir;
1711     struct dirent *dent;
1712     char path[MAX_PATH];
1713
1714     TRACE("Loading fonts from %s\n", debugstr_a(dirname));
1715
1716     dir = opendir(dirname);
1717     if(!dir) {
1718         WARN("Can't open directory %s\n", debugstr_a(dirname));
1719         return FALSE;
1720     }
1721     while((dent = readdir(dir)) != NULL) {
1722         struct stat statbuf;
1723
1724         if(!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
1725             continue;
1726
1727         TRACE("Found %s in %s\n", debugstr_a(dent->d_name), debugstr_a(dirname));
1728
1729         sprintf(path, "%s/%s", dirname, dent->d_name);
1730
1731         if(stat(path, &statbuf) == -1)
1732         {
1733             WARN("Can't stat %s\n", debugstr_a(path));
1734             continue;
1735         }
1736         if(S_ISDIR(statbuf.st_mode))
1737             ReadFontDir(path, external_fonts);
1738         else
1739             AddFontFileToList(path, NULL, NULL, external_fonts ? ADDFONT_EXTERNAL_FONT : 0);
1740     }
1741     closedir(dir);
1742     return TRUE;
1743 }
1744
1745 static void load_fontconfig_fonts(void)
1746 {
1747 #ifdef SONAME_LIBFONTCONFIG
1748     void *fc_handle = NULL;
1749     FcConfig *config;
1750     FcPattern *pat;
1751     FcObjectSet *os;
1752     FcFontSet *fontset;
1753     int i, len;
1754     char *file;
1755     const char *ext;
1756
1757     fc_handle = wine_dlopen(SONAME_LIBFONTCONFIG, RTLD_NOW, NULL, 0);
1758     if(!fc_handle) {
1759         TRACE("Wine cannot find the fontconfig library (%s).\n",
1760               SONAME_LIBFONTCONFIG);
1761         return;
1762     }
1763 #define LOAD_FUNCPTR(f) if((p##f = wine_dlsym(fc_handle, #f, NULL, 0)) == NULL){WARN("Can't find symbol %s\n", #f); goto sym_not_found;}
1764 LOAD_FUNCPTR(FcConfigGetCurrent);
1765 LOAD_FUNCPTR(FcFontList);
1766 LOAD_FUNCPTR(FcFontSetDestroy);
1767 LOAD_FUNCPTR(FcInit);
1768 LOAD_FUNCPTR(FcObjectSetAdd);
1769 LOAD_FUNCPTR(FcObjectSetCreate);
1770 LOAD_FUNCPTR(FcObjectSetDestroy);
1771 LOAD_FUNCPTR(FcPatternCreate);
1772 LOAD_FUNCPTR(FcPatternDestroy);
1773 LOAD_FUNCPTR(FcPatternGetBool);
1774 LOAD_FUNCPTR(FcPatternGetString);
1775 #undef LOAD_FUNCPTR
1776
1777     if(!pFcInit()) return;
1778     
1779     config = pFcConfigGetCurrent();
1780     pat = pFcPatternCreate();
1781     os = pFcObjectSetCreate();
1782     pFcObjectSetAdd(os, FC_FILE);
1783     pFcObjectSetAdd(os, FC_SCALABLE);
1784     fontset = pFcFontList(config, pat, os);
1785     if(!fontset) return;
1786     for(i = 0; i < fontset->nfont; i++) {
1787         FcBool scalable;
1788
1789         if(pFcPatternGetString(fontset->fonts[i], FC_FILE, 0, (FcChar8**)&file) != FcResultMatch)
1790             continue;
1791         TRACE("fontconfig: %s\n", file);
1792
1793         /* We're just interested in OT/TT fonts for now, so this hack just
1794            picks up the scalable fonts without extensions .pf[ab] to save time
1795            loading every other font */
1796
1797         if(pFcPatternGetBool(fontset->fonts[i], FC_SCALABLE, 0, &scalable) == FcResultMatch && !scalable)
1798         {
1799             TRACE("not scalable\n");
1800             continue;
1801         }
1802
1803         len = strlen( file );
1804         if(len < 4) continue;
1805         ext = &file[ len - 3 ];
1806         if(strcasecmp(ext, "pfa") && strcasecmp(ext, "pfb"))
1807             AddFontFileToList(file, NULL, NULL,  ADDFONT_EXTERNAL_FONT);
1808     }
1809     pFcFontSetDestroy(fontset);
1810     pFcObjectSetDestroy(os);
1811     pFcPatternDestroy(pat);
1812  sym_not_found:
1813 #endif
1814     return;
1815 }
1816
1817 static BOOL load_font_from_data_dir(LPCWSTR file)
1818 {
1819     BOOL ret = FALSE;
1820     const char *data_dir = wine_get_data_dir();
1821
1822     if (!data_dir) data_dir = wine_get_build_dir();
1823
1824     if (data_dir)
1825     {
1826         INT len;
1827         char *unix_name;
1828
1829         len = WideCharToMultiByte(CP_UNIXCP, 0, file, -1, NULL, 0, NULL, NULL);
1830
1831         unix_name = HeapAlloc(GetProcessHeap(), 0, strlen(data_dir) + len + sizeof("/fonts/"));
1832
1833         strcpy(unix_name, data_dir);
1834         strcat(unix_name, "/fonts/");
1835
1836         WideCharToMultiByte(CP_UNIXCP, 0, file, -1, unix_name + strlen(unix_name), len, NULL, NULL);
1837
1838         EnterCriticalSection( &freetype_cs );
1839         ret = AddFontFileToList(unix_name, NULL, NULL, ADDFONT_FORCE_BITMAP);
1840         LeaveCriticalSection( &freetype_cs );
1841         HeapFree(GetProcessHeap(), 0, unix_name);
1842     }
1843     return ret;
1844 }
1845
1846 static BOOL load_font_from_winfonts_dir(LPCWSTR file)
1847 {
1848     static const WCHAR slashW[] = {'\\','\0'};
1849     BOOL ret = FALSE;
1850     WCHAR windowsdir[MAX_PATH];
1851     char *unixname;
1852
1853     GetWindowsDirectoryW(windowsdir, sizeof(windowsdir) / sizeof(WCHAR));
1854     strcatW(windowsdir, fontsW);
1855     strcatW(windowsdir, slashW);
1856     strcatW(windowsdir, file);
1857     if ((unixname = wine_get_unix_file_name(windowsdir))) {
1858         EnterCriticalSection( &freetype_cs );
1859         ret = AddFontFileToList(unixname, NULL, NULL, ADDFONT_FORCE_BITMAP);
1860         LeaveCriticalSection( &freetype_cs );
1861         HeapFree(GetProcessHeap(), 0, unixname);
1862     }
1863     return ret;
1864 }
1865
1866 static void load_system_fonts(void)
1867 {
1868     HKEY hkey;
1869     WCHAR data[MAX_PATH], windowsdir[MAX_PATH], pathW[MAX_PATH];
1870     const WCHAR * const *value;
1871     DWORD dlen, type;
1872     static const WCHAR fmtW[] = {'%','s','\\','%','s','\0'};
1873     char *unixname;
1874
1875     if(RegOpenKeyW(HKEY_CURRENT_CONFIG, system_fonts_reg_key, &hkey) == ERROR_SUCCESS) {
1876         GetWindowsDirectoryW(windowsdir, sizeof(windowsdir) / sizeof(WCHAR));
1877         strcatW(windowsdir, fontsW);
1878         for(value = SystemFontValues; *value; value++) { 
1879             dlen = sizeof(data);
1880             if(RegQueryValueExW(hkey, *value, 0, &type, (void*)data, &dlen) == ERROR_SUCCESS &&
1881                type == REG_SZ) {
1882                 BOOL added = FALSE;
1883
1884                 sprintfW(pathW, fmtW, windowsdir, data);
1885                 if((unixname = wine_get_unix_file_name(pathW))) {
1886                     added = AddFontFileToList(unixname, NULL, NULL, ADDFONT_FORCE_BITMAP);
1887                     HeapFree(GetProcessHeap(), 0, unixname);
1888                 }
1889                 if (!added)
1890                     load_font_from_data_dir(data);
1891             }
1892         }
1893         RegCloseKey(hkey);
1894     }
1895 }
1896
1897 /*************************************************************
1898  *
1899  * This adds registry entries for any externally loaded fonts
1900  * (fonts from fontconfig or FontDirs).  It also deletes entries
1901  * of no longer existing fonts.
1902  *
1903  */
1904 static void update_reg_entries(void)
1905 {
1906     HKEY winnt_key = 0, win9x_key = 0, external_key = 0;
1907     LPWSTR valueW;
1908     DWORD len, len_fam;
1909     Family *family;
1910     Face *face;
1911     struct list *family_elem_ptr, *face_elem_ptr;
1912     WCHAR *file;
1913     static const WCHAR TrueType[] = {' ','(','T','r','u','e','T','y','p','e',')','\0'};
1914     static const WCHAR spaceW[] = {' ', '\0'};
1915     char *path;
1916
1917     if(RegCreateKeyExW(HKEY_LOCAL_MACHINE, winnt_font_reg_key,
1918                        0, NULL, 0, KEY_ALL_ACCESS, NULL, &winnt_key, NULL) != ERROR_SUCCESS) {
1919         ERR("Can't create Windows font reg key\n");
1920         goto end;
1921     }
1922
1923     if(RegCreateKeyExW(HKEY_LOCAL_MACHINE, win9x_font_reg_key,
1924                        0, NULL, 0, KEY_ALL_ACCESS, NULL, &win9x_key, NULL) != ERROR_SUCCESS) {
1925         ERR("Can't create Windows font reg key\n");
1926         goto end;
1927     }
1928
1929     if(RegCreateKeyExW(HKEY_CURRENT_USER, external_fonts_reg_key,
1930                        0, NULL, 0, KEY_ALL_ACCESS, NULL, &external_key, NULL) != ERROR_SUCCESS) {
1931         ERR("Can't create external font reg key\n");
1932         goto end;
1933     }
1934
1935     /* enumerate the fonts and add external ones to the two keys */
1936
1937     LIST_FOR_EACH(family_elem_ptr, &font_list) {
1938         family = LIST_ENTRY(family_elem_ptr, Family, entry); 
1939         len_fam = strlenW(family->FamilyName) + sizeof(TrueType) / sizeof(WCHAR) + 1;
1940         LIST_FOR_EACH(face_elem_ptr, &family->faces) {
1941             face = LIST_ENTRY(face_elem_ptr, Face, entry);
1942             if(!face->external) continue;
1943             len = len_fam;
1944             if (!(face->ntmFlags & NTM_REGULAR))
1945                 len = len_fam + strlenW(face->StyleName) + 1;
1946             valueW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1947             strcpyW(valueW, family->FamilyName);
1948             if(len != len_fam) {
1949                 strcatW(valueW, spaceW);
1950                 strcatW(valueW, face->StyleName);
1951             }
1952             strcatW(valueW, TrueType);
1953
1954             file = wine_get_dos_file_name(face->file);
1955             if(file)
1956                 len = strlenW(file) + 1;
1957             else
1958             {
1959                 if((path = strrchr(face->file, '/')) == NULL)
1960                     path = face->file;
1961                 else
1962                     path++;
1963                 len = MultiByteToWideChar(CP_ACP, 0, path, -1, NULL, 0);
1964
1965                 file = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
1966                 MultiByteToWideChar(CP_ACP, 0, path, -1, file, len);
1967             }
1968             RegSetValueExW(winnt_key, valueW, 0, REG_SZ, (BYTE*)file, len * sizeof(WCHAR));
1969             RegSetValueExW(win9x_key, valueW, 0, REG_SZ, (BYTE*)file, len * sizeof(WCHAR));
1970             RegSetValueExW(external_key, valueW, 0, REG_SZ, (BYTE*)file, len * sizeof(WCHAR));
1971
1972             HeapFree(GetProcessHeap(), 0, file);
1973             HeapFree(GetProcessHeap(), 0, valueW);
1974         }
1975     }
1976  end:
1977     if(external_key) RegCloseKey(external_key);
1978     if(win9x_key) RegCloseKey(win9x_key);
1979     if(winnt_key) RegCloseKey(winnt_key);
1980     return;
1981 }
1982
1983 static void delete_external_font_keys(void)
1984 {
1985     HKEY winnt_key = 0, win9x_key = 0, external_key = 0;
1986     DWORD dlen, vlen, datalen, valuelen, i, type;
1987     LPWSTR valueW;
1988     LPVOID data;
1989
1990     if(RegCreateKeyExW(HKEY_LOCAL_MACHINE, winnt_font_reg_key,
1991                        0, NULL, 0, KEY_ALL_ACCESS, NULL, &winnt_key, NULL) != ERROR_SUCCESS) {
1992         ERR("Can't create Windows font reg key\n");
1993         goto end;
1994     }
1995
1996     if(RegCreateKeyExW(HKEY_LOCAL_MACHINE, win9x_font_reg_key,
1997                        0, NULL, 0, KEY_ALL_ACCESS, NULL, &win9x_key, NULL) != ERROR_SUCCESS) {
1998         ERR("Can't create Windows font reg key\n");
1999         goto end;
2000     }
2001
2002     if(RegCreateKeyW(HKEY_CURRENT_USER, external_fonts_reg_key, &external_key) != ERROR_SUCCESS) {
2003         ERR("Can't create external font reg key\n");
2004         goto end;
2005     }
2006
2007     /* Delete all external fonts added last time */
2008
2009     RegQueryInfoKeyW(external_key, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2010                      &valuelen, &datalen, NULL, NULL);
2011     valuelen++; /* returned value doesn't include room for '\0' */
2012     valueW = HeapAlloc(GetProcessHeap(), 0, valuelen * sizeof(WCHAR));
2013     data = HeapAlloc(GetProcessHeap(), 0, datalen * sizeof(WCHAR));
2014
2015     dlen = datalen * sizeof(WCHAR);
2016     vlen = valuelen;
2017     i = 0;
2018     while(RegEnumValueW(external_key, i++, valueW, &vlen, NULL, &type, data,
2019                         &dlen) == ERROR_SUCCESS) {
2020
2021         RegDeleteValueW(winnt_key, valueW);
2022         RegDeleteValueW(win9x_key, valueW);
2023         /* reset dlen and vlen */
2024         dlen = datalen;
2025         vlen = valuelen;
2026     }
2027     HeapFree(GetProcessHeap(), 0, data);
2028     HeapFree(GetProcessHeap(), 0, valueW);
2029
2030     /* Delete the old external fonts key */
2031     RegCloseKey(external_key);
2032     RegDeleteKeyW(HKEY_CURRENT_USER, external_fonts_reg_key);
2033
2034  end:
2035     if(win9x_key) RegCloseKey(win9x_key);
2036     if(winnt_key) RegCloseKey(winnt_key);
2037 }
2038
2039 /*************************************************************
2040  *    WineEngAddFontResourceEx
2041  *
2042  */
2043 INT WineEngAddFontResourceEx(LPCWSTR file, DWORD flags, PVOID pdv)
2044 {
2045     INT ret = 0;
2046     if (ft_handle)  /* do it only if we have freetype up and running */
2047     {
2048         char *unixname;
2049
2050         if(flags)
2051             FIXME("Ignoring flags %x\n", flags);
2052
2053         if((unixname = wine_get_unix_file_name(file)))
2054         {
2055             EnterCriticalSection( &freetype_cs );
2056             ret = AddFontFileToList(unixname, NULL, NULL, ADDFONT_FORCE_BITMAP);
2057             LeaveCriticalSection( &freetype_cs );
2058             HeapFree(GetProcessHeap(), 0, unixname);
2059         }
2060         if (!ret && !strchrW(file, '\\')) {
2061             /* Try in %WINDIR%/fonts, needed for Fotobuch Designer */
2062             ret = load_font_from_winfonts_dir(file);
2063             if (!ret) {
2064                 /* Try in datadir/fonts (or builddir/fonts),
2065                  * needed for Magic the Gathering Online
2066                  */
2067                 ret = load_font_from_data_dir(file);
2068             }
2069         }
2070     }
2071    return ret;
2072 }
2073
2074 /*************************************************************
2075  *    WineEngAddFontMemResourceEx
2076  *
2077  */
2078 HANDLE WineEngAddFontMemResourceEx(PVOID pbFont, DWORD cbFont, PVOID pdv, DWORD *pcFonts)
2079 {
2080     if (ft_handle)  /* do it only if we have freetype up and running */
2081     {
2082         PVOID pFontCopy = HeapAlloc(GetProcessHeap(), 0, cbFont);
2083
2084         TRACE("Copying %d bytes of data from %p to %p\n", cbFont, pbFont, pFontCopy);
2085         memcpy(pFontCopy, pbFont, cbFont);
2086
2087         EnterCriticalSection( &freetype_cs );
2088         *pcFonts = AddFontToList(NULL, pFontCopy, cbFont, NULL, NULL, ADDFONT_FORCE_BITMAP);
2089         LeaveCriticalSection( &freetype_cs );
2090
2091         if (*pcFonts == 0)
2092         {
2093             TRACE("AddFontToList failed\n");
2094             HeapFree(GetProcessHeap(), 0, pFontCopy);
2095             return NULL;
2096         }
2097         /* FIXME: is the handle only for use in RemoveFontMemResourceEx or should it be a true handle?
2098          * For now return something unique but quite random
2099          */
2100         TRACE("Returning handle %lx\n", ((INT_PTR)pFontCopy)^0x87654321);
2101         return (HANDLE)(((INT_PTR)pFontCopy)^0x87654321);
2102     }
2103
2104     *pcFonts = 0;
2105     return 0;
2106 }
2107
2108 /*************************************************************
2109  *    WineEngRemoveFontResourceEx
2110  *
2111  */
2112 BOOL WineEngRemoveFontResourceEx(LPCWSTR file, DWORD flags, PVOID pdv)
2113 {
2114     FIXME(":stub\n");
2115     return TRUE;
2116 }
2117
2118 static const struct nls_update_font_list
2119 {
2120     UINT ansi_cp, oem_cp;
2121     const char *oem, *fixed, *system;
2122     const char *courier, *serif, *small, *sserif;
2123     /* these are for font substitutes */
2124     const char *shelldlg, *tmsrmn;
2125     const char *fixed_0, *system_0, *courier_0, *serif_0, *small_0, *sserif_0,
2126                *helv_0, *tmsrmn_0;
2127     const struct subst
2128     {
2129         const char *from, *to;
2130     } arial_0, courier_new_0, times_new_roman_0;
2131 } nls_update_font_list[] =
2132 {
2133     /* Latin 1 (United States) */
2134     { 1252, 437, "vgaoem.fon", "vgafix.fon", "vgasys.fon",
2135       "coure.fon", "serife.fon", "smalle.fon", "sserife.fon",
2136       "Tahoma","Times New Roman",
2137       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2138       { 0 }, { 0 }, { 0 }
2139     },
2140     /* Latin 1 (Multilingual) */
2141     { 1252, 850, "vga850.fon", "vgafix.fon", "vgasys.fon",
2142       "coure.fon", "serife.fon", "smalle.fon", "sserife.fon",
2143       "Tahoma","Times New Roman",  /* FIXME unverified */
2144       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2145       { 0 }, { 0 }, { 0 }
2146     },
2147     /* Eastern Europe */
2148     { 1250, 852, "vga852.fon", "vgafixe.fon", "vgasyse.fon",
2149       "couree.fon", "serifee.fon", "smallee.fon", "sserifee.fon",
2150       "Tahoma","Times New Roman", /* FIXME unverified */
2151       "Fixedsys,238", "System,238",
2152       "Courier New,238", "MS Serif,238", "Small Fonts,238",
2153       "MS Sans Serif,238", "MS Sans Serif,238", "MS Serif,238",
2154       { "Arial CE,0", "Arial,238" },
2155       { "Courier New CE,0", "Courier New,238" },
2156       { "Times New Roman CE,0", "Times New Roman,238" }
2157     },
2158     /* Cyrillic */
2159     { 1251, 866, "vga866.fon", "vgafixr.fon", "vgasysr.fon",
2160       "courer.fon", "serifer.fon", "smaller.fon", "sserifer.fon",
2161       "Tahoma","Times New Roman", /* FIXME unverified */
2162       "Fixedsys,204", "System,204",
2163       "Courier New,204", "MS Serif,204", "Small Fonts,204",
2164       "MS Sans Serif,204", "MS Sans Serif,204", "MS Serif,204",
2165       { "Arial Cyr,0", "Arial,204" },
2166       { "Courier New Cyr,0", "Courier New,204" },
2167       { "Times New Roman Cyr,0", "Times New Roman,204" }
2168     },
2169     /* Greek */
2170     { 1253, 737, "vga869.fon", "vgafixg.fon", "vgasysg.fon",
2171       "coureg.fon", "serifeg.fon", "smalleg.fon", "sserifeg.fon",
2172       "Tahoma","Times New Roman", /* FIXME unverified */
2173       "Fixedsys,161", "System,161",
2174       "Courier New,161", "MS Serif,161", "Small Fonts,161",
2175       "MS Sans Serif,161", "MS Sans Serif,161", "MS Serif,161",
2176       { "Arial Greek,0", "Arial,161" },
2177       { "Courier New Greek,0", "Courier New,161" },
2178       { "Times New Roman Greek,0", "Times New Roman,161" }
2179     },
2180     /* Turkish */
2181     { 1254, 857, "vga857.fon", "vgafixt.fon", "vgasyst.fon",
2182       "couret.fon", "serifet.fon", "smallet.fon", "sserifet.fon",
2183       "Tahoma","Times New Roman", /* FIXME unverified */
2184       "Fixedsys,162", "System,162",
2185       "Courier New,162", "MS Serif,162", "Small Fonts,162",
2186       "MS Sans Serif,162", "MS Sans Serif,162", "MS Serif,162",
2187       { "Arial Tur,0", "Arial,162" },
2188       { "Courier New Tur,0", "Courier New,162" },
2189       { "Times New Roman Tur,0", "Times New Roman,162" }
2190     },
2191     /* Hebrew */
2192     { 1255, 862, "vgaoem.fon", "vgaf1255.fon", "vgas1255.fon",
2193       "coue1255.fon", "sere1255.fon", "smae1255.fon", "ssee1255.fon",
2194       "Tahoma","Times New Roman", /* FIXME unverified */
2195       "Fixedsys,177", "System,177",
2196       "Courier New,177", "MS Serif,177", "Small Fonts,177",
2197       "MS Sans Serif,177", "MS Sans Serif,177", "MS Serif,177",
2198       { 0 }, { 0 }, { 0 }
2199     },
2200     /* Arabic */
2201     { 1256, 720, "vgaoem.fon", "vgaf1256.fon", "vgas1256.fon",
2202       "coue1256.fon", "sere1256.fon", "smae1256.fon", "ssee1256.fon",
2203       "Tahoma","Times New Roman", /* FIXME unverified */
2204       "Fixedsys,178", "System,178",
2205       "Courier New,178", "MS Serif,178", "Small Fonts,178",
2206       "MS Sans Serif,178", "MS Sans Serif,178", "MS Serif,178",
2207       { 0 }, { 0 }, { 0 }
2208     },
2209     /* Baltic */
2210     { 1257, 775, "vga775.fon", "vgaf1257.fon", "vgas1257.fon",
2211       "coue1257.fon", "sere1257.fon", "smae1257.fon", "ssee1257.fon",
2212       "Tahoma","Times New Roman", /* FIXME unverified */
2213       "Fixedsys,186", "System,186",
2214       "Courier New,186", "MS Serif,186", "Small Fonts,186",
2215       "MS Sans Serif,186", "MS Sans Serif,186", "MS Serif,186",
2216       { "Arial Baltic,0", "Arial,186" },
2217       { "Courier New Baltic,0", "Courier New,186" },
2218       { "Times New Roman Baltic,0", "Times New Roman,186" }
2219     },
2220     /* Vietnamese */
2221     { 1258, 1258, "vga850.fon", "vgafix.fon", "vgasys.fon",
2222       "coure.fon", "serife.fon", "smalle.fon", "sserife.fon",
2223       "Tahoma","Times New Roman", /* FIXME unverified */
2224       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2225       { 0 }, { 0 }, { 0 }
2226     },
2227     /* Thai */
2228     { 874, 874, "vga850.fon", "vgaf874.fon", "vgas874.fon",
2229       "coure.fon", "serife.fon", "smalle.fon", "ssee874.fon",
2230       "Tahoma","Times New Roman", /* FIXME unverified */
2231       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2232       { 0 }, { 0 }, { 0 }
2233     },
2234     /* Japanese */
2235     { 932, 932, "vga932.fon", "jvgafix.fon", "jvgasys.fon",
2236       "coure.fon", "serife.fon", "jsmalle.fon", "sserife.fon",
2237       "MS UI Gothic","MS Serif",
2238       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2239       { 0 }, { 0 }, { 0 }
2240     },
2241     /* Chinese Simplified */
2242     { 936, 936, "vga936.fon", "svgafix.fon", "svgasys.fon",
2243       "coure.fon", "serife.fon", "smalle.fon", "sserife.fon",
2244       "Tahoma", "Times New Roman", /* FIXME unverified */
2245       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2246       { 0 }, { 0 }, { 0 }
2247     },
2248     /* Korean */
2249     { 949, 949, "vga949.fon", "hvgafix.fon", "hvgasys.fon",
2250       "coure.fon", "serife.fon", "smalle.fon", "sserife.fon",
2251       "Gulim",  "Batang",
2252       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2253       { 0 }, { 0 }, { 0 }
2254     },
2255     /* Chinese Traditional */
2256     { 950, 950, "vga950.fon", "cvgafix.fon", "cvgasys.fon",
2257       "coure.fon", "serife.fon", "smalle.fon", "sserife.fon",
2258       "PMingLiU",  "MingLiU",
2259       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2260       { 0 }, { 0 }, { 0 }
2261     }
2262 };
2263
2264 static inline BOOL is_dbcs_ansi_cp(UINT ansi_cp)
2265 {
2266     return ( ansi_cp == 932       /* CP932 for Japanese */
2267             || ansi_cp == 936     /* CP936 for Chinese Simplified */
2268             || ansi_cp == 949     /* CP949 for Korean */
2269             || ansi_cp == 950 );  /* CP950 for Chinese Traditional */
2270 }
2271
2272 static inline HKEY create_fonts_NT_registry_key(void)
2273 {
2274     HKEY hkey = 0;
2275
2276     RegCreateKeyExW(HKEY_LOCAL_MACHINE, winnt_font_reg_key, 0, NULL,
2277                     0, KEY_ALL_ACCESS, NULL, &hkey, NULL);
2278     return hkey;
2279 }
2280
2281 static inline HKEY create_fonts_9x_registry_key(void)
2282 {
2283     HKEY hkey = 0;
2284
2285     RegCreateKeyExW(HKEY_LOCAL_MACHINE, win9x_font_reg_key, 0, NULL,
2286                     0, KEY_ALL_ACCESS, NULL, &hkey, NULL);
2287     return hkey;
2288 }
2289
2290 static inline HKEY create_config_fonts_registry_key(void)
2291 {
2292     HKEY hkey = 0;
2293
2294     RegCreateKeyExW(HKEY_CURRENT_CONFIG, system_fonts_reg_key, 0, NULL,
2295                     0, KEY_ALL_ACCESS, NULL, &hkey, NULL);
2296     return hkey;
2297 }
2298
2299 static void add_font_list(HKEY hkey, const struct nls_update_font_list *fl)
2300 {
2301     RegSetValueExA(hkey, "Courier", 0, REG_SZ, (const BYTE *)fl->courier, strlen(fl->courier)+1);
2302     RegSetValueExA(hkey, "MS Serif", 0, REG_SZ, (const BYTE *)fl->serif, strlen(fl->serif)+1);
2303     RegSetValueExA(hkey, "MS Sans Serif", 0, REG_SZ, (const BYTE *)fl->sserif, strlen(fl->sserif)+1);
2304     RegSetValueExA(hkey, "Small Fonts", 0, REG_SZ, (const BYTE *)fl->small, strlen(fl->small)+1);
2305 }
2306
2307 static void set_value_key(HKEY hkey, const char *name, const char *value)
2308 {
2309     if (value)
2310         RegSetValueExA(hkey, name, 0, REG_SZ, (const BYTE *)value, strlen(value) + 1);
2311     else if (name)
2312         RegDeleteValueA(hkey, name);
2313 }
2314
2315 static void update_font_info(void)
2316 {
2317     char buf[40], cpbuf[40];
2318     DWORD len, type;
2319     HKEY hkey = 0;
2320     UINT i, ansi_cp = 0, oem_cp = 0;
2321     BOOL done = FALSE;
2322
2323     if (RegCreateKeyExA(HKEY_CURRENT_USER, "Software\\Wine\\Fonts", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hkey, NULL) != ERROR_SUCCESS)
2324         return;
2325
2326     GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTANSICODEPAGE|LOCALE_RETURN_NUMBER|LOCALE_NOUSEROVERRIDE,
2327                    (WCHAR *)&ansi_cp, sizeof(ansi_cp)/sizeof(WCHAR));
2328     GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTCODEPAGE|LOCALE_RETURN_NUMBER|LOCALE_NOUSEROVERRIDE,
2329                    (WCHAR *)&oem_cp, sizeof(oem_cp)/sizeof(WCHAR));
2330     sprintf( cpbuf, "%u,%u", ansi_cp, oem_cp );
2331
2332     /* Setup Default_Fallback usage for DBCS ANSI codepages */
2333     if (is_dbcs_ansi_cp(ansi_cp))
2334         use_default_fallback = TRUE;
2335
2336     len = sizeof(buf);
2337     if (RegQueryValueExA(hkey, "Codepages", 0, &type, (BYTE *)buf, &len) == ERROR_SUCCESS && type == REG_SZ)
2338     {
2339         if (!strcmp( buf, cpbuf ))  /* already set correctly */
2340         {
2341             RegCloseKey(hkey);
2342             return;
2343         }
2344         TRACE("updating registry, codepages changed %s -> %u,%u\n", buf, ansi_cp, oem_cp);
2345     }
2346     else TRACE("updating registry, codepages changed none -> %u,%u\n", ansi_cp, oem_cp);
2347
2348     RegSetValueExA(hkey, "Codepages", 0, REG_SZ, (const BYTE *)cpbuf, strlen(cpbuf)+1);
2349     RegCloseKey(hkey);
2350
2351     for (i = 0; i < sizeof(nls_update_font_list)/sizeof(nls_update_font_list[0]); i++)
2352     {
2353         HKEY hkey;
2354
2355         if (nls_update_font_list[i].ansi_cp == ansi_cp &&
2356             nls_update_font_list[i].oem_cp == oem_cp)
2357         {
2358             hkey = create_config_fonts_registry_key();
2359             RegSetValueExA(hkey, "OEMFONT.FON", 0, REG_SZ, (const BYTE *)nls_update_font_list[i].oem, strlen(nls_update_font_list[i].oem)+1);
2360             RegSetValueExA(hkey, "FIXEDFON.FON", 0, REG_SZ, (const BYTE *)nls_update_font_list[i].fixed, strlen(nls_update_font_list[i].fixed)+1);
2361             RegSetValueExA(hkey, "FONTS.FON", 0, REG_SZ, (const BYTE *)nls_update_font_list[i].system, strlen(nls_update_font_list[i].system)+1);
2362             RegCloseKey(hkey);
2363
2364             hkey = create_fonts_NT_registry_key();
2365             add_font_list(hkey, &nls_update_font_list[i]);
2366             RegCloseKey(hkey);
2367
2368             hkey = create_fonts_9x_registry_key();
2369             add_font_list(hkey, &nls_update_font_list[i]);
2370             RegCloseKey(hkey);
2371
2372             if (!RegCreateKeyA( HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows NT\\CurrentVersion\\FontSubstitutes", &hkey ))
2373             {
2374                 RegSetValueExA(hkey, "MS Shell Dlg", 0, REG_SZ, (const BYTE *)nls_update_font_list[i].shelldlg,
2375                                strlen(nls_update_font_list[i].shelldlg)+1);
2376                 RegSetValueExA(hkey, "Tms Rmn", 0, REG_SZ, (const BYTE *)nls_update_font_list[i].tmsrmn,
2377                                strlen(nls_update_font_list[i].tmsrmn)+1);
2378
2379                 set_value_key(hkey, "Fixedsys,0", nls_update_font_list[i].fixed_0);
2380                 set_value_key(hkey, "System,0", nls_update_font_list[i].system_0);
2381                 set_value_key(hkey, "Courier,0", nls_update_font_list[i].courier_0);
2382                 set_value_key(hkey, "MS Serif,0", nls_update_font_list[i].serif_0);
2383                 set_value_key(hkey, "Small Fonts,0", nls_update_font_list[i].small_0);
2384                 set_value_key(hkey, "MS Sans Serif,0", nls_update_font_list[i].sserif_0);
2385                 set_value_key(hkey, "Helv,0", nls_update_font_list[i].helv_0);
2386                 set_value_key(hkey, "Tms Rmn,0", nls_update_font_list[i].tmsrmn_0);
2387
2388                 set_value_key(hkey, nls_update_font_list[i].arial_0.from, nls_update_font_list[i].arial_0.to);
2389                 set_value_key(hkey, nls_update_font_list[i].courier_new_0.from, nls_update_font_list[i].courier_new_0.to);
2390                 set_value_key(hkey, nls_update_font_list[i].times_new_roman_0.from, nls_update_font_list[i].times_new_roman_0.to);
2391
2392                 RegCloseKey(hkey);
2393             }
2394             done = TRUE;
2395         }
2396         else
2397         {
2398             /* Delete the FontSubstitutes from other locales */
2399             if (!RegCreateKeyA( HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows NT\\CurrentVersion\\FontSubstitutes", &hkey ))
2400             {
2401                 set_value_key(hkey, nls_update_font_list[i].arial_0.from, NULL);
2402                 set_value_key(hkey, nls_update_font_list[i].courier_new_0.from, NULL);
2403                 set_value_key(hkey, nls_update_font_list[i].times_new_roman_0.from, NULL);
2404                 RegCloseKey(hkey);
2405             }
2406         }
2407     }
2408     if (!done)
2409         FIXME("there is no font defaults for codepages %u,%u\n", ansi_cp, oem_cp);
2410 }
2411
2412
2413 static BOOL init_freetype(void)
2414 {
2415     ft_handle = wine_dlopen(SONAME_LIBFREETYPE, RTLD_NOW, NULL, 0);
2416     if(!ft_handle) {
2417         WINE_MESSAGE(
2418       "Wine cannot find the FreeType font library.  To enable Wine to\n"
2419       "use TrueType fonts please install a version of FreeType greater than\n"
2420       "or equal to 2.0.5.\n"
2421       "http://www.freetype.org\n");
2422         return FALSE;
2423     }
2424
2425 #define LOAD_FUNCPTR(f) if((p##f = wine_dlsym(ft_handle, #f, NULL, 0)) == NULL){WARN("Can't find symbol %s\n", #f); goto sym_not_found;}
2426
2427     LOAD_FUNCPTR(FT_Vector_Unit)
2428     LOAD_FUNCPTR(FT_Done_Face)
2429     LOAD_FUNCPTR(FT_Get_Char_Index)
2430     LOAD_FUNCPTR(FT_Get_Module)
2431     LOAD_FUNCPTR(FT_Get_Sfnt_Name)
2432     LOAD_FUNCPTR(FT_Get_Sfnt_Name_Count)
2433     LOAD_FUNCPTR(FT_Get_Sfnt_Table)
2434     LOAD_FUNCPTR(FT_Init_FreeType)
2435     LOAD_FUNCPTR(FT_Load_Glyph)
2436     LOAD_FUNCPTR(FT_Matrix_Multiply)
2437     LOAD_FUNCPTR(FT_MulFix)
2438     LOAD_FUNCPTR(FT_New_Face)
2439     LOAD_FUNCPTR(FT_New_Memory_Face)
2440     LOAD_FUNCPTR(FT_Outline_Get_Bitmap)
2441     LOAD_FUNCPTR(FT_Outline_Transform)
2442     LOAD_FUNCPTR(FT_Outline_Translate)
2443     LOAD_FUNCPTR(FT_Select_Charmap)
2444     LOAD_FUNCPTR(FT_Set_Charmap)
2445     LOAD_FUNCPTR(FT_Set_Pixel_Sizes)
2446     LOAD_FUNCPTR(FT_Vector_Transform)
2447
2448 #undef LOAD_FUNCPTR
2449     /* Don't warn if these ones are missing */
2450     pFT_Library_Version = wine_dlsym(ft_handle, "FT_Library_Version", NULL, 0);
2451     pFT_Load_Sfnt_Table = wine_dlsym(ft_handle, "FT_Load_Sfnt_Table", NULL, 0);
2452     pFT_Get_First_Char = wine_dlsym(ft_handle, "FT_Get_First_Char", NULL, 0);
2453     pFT_Get_Next_Char = wine_dlsym(ft_handle, "FT_Get_Next_Char", NULL, 0);
2454     pFT_Get_TrueType_Engine_Type = wine_dlsym(ft_handle, "FT_Get_TrueType_Engine_Type", NULL, 0);
2455 #ifdef HAVE_FREETYPE_FTWINFNT_H
2456     pFT_Get_WinFNT_Header = wine_dlsym(ft_handle, "FT_Get_WinFNT_Header", NULL, 0);
2457 #endif
2458       if(!wine_dlsym(ft_handle, "FT_Get_Postscript_Name", NULL, 0) &&
2459          !wine_dlsym(ft_handle, "FT_Sqrt64", NULL, 0)) {
2460         /* try to avoid 2.0.4: >= 2.0.5 has FT_Get_Postscript_Name and
2461            <= 2.0.3 has FT_Sqrt64 */
2462           goto sym_not_found;
2463       }
2464
2465     if(pFT_Init_FreeType(&library) != 0) {
2466         ERR("Can't init FreeType library\n");
2467         wine_dlclose(ft_handle, NULL, 0);
2468         ft_handle = NULL;
2469         return FALSE;
2470     }
2471     FT_Version.major = FT_Version.minor = FT_Version.patch = -1;
2472     if (pFT_Library_Version)
2473         pFT_Library_Version(library,&FT_Version.major,&FT_Version.minor,&FT_Version.patch);
2474
2475     if (FT_Version.major<=0)
2476     {
2477         FT_Version.major=2;
2478         FT_Version.minor=0;
2479         FT_Version.patch=5;
2480     }
2481     TRACE("FreeType version is %d.%d.%d\n",FT_Version.major,FT_Version.minor,FT_Version.patch);
2482     FT_SimpleVersion = ((FT_Version.major << 16) & 0xff0000) |
2483                        ((FT_Version.minor <<  8) & 0x00ff00) |
2484                        ((FT_Version.patch      ) & 0x0000ff);
2485
2486     return TRUE;
2487
2488 sym_not_found:
2489     WINE_MESSAGE(
2490       "Wine cannot find certain functions that it needs inside the FreeType\n"
2491       "font library.  To enable Wine to use TrueType fonts please upgrade\n"
2492       "FreeType to at least version 2.0.5.\n"
2493       "http://www.freetype.org\n");
2494     wine_dlclose(ft_handle, NULL, 0);
2495     ft_handle = NULL;
2496     return FALSE;
2497 }
2498
2499 /*************************************************************
2500  *    WineEngInit
2501  *
2502  * Initialize FreeType library and create a list of available faces
2503  */
2504 BOOL WineEngInit(void)
2505 {
2506     static const WCHAR dot_fonW[] = {'.','f','o','n','\0'};
2507     static const WCHAR pathW[] = {'P','a','t','h',0};
2508     HKEY hkey;
2509     DWORD valuelen, datalen, i = 0, type, dlen, vlen;
2510     LPVOID data;
2511     WCHAR windowsdir[MAX_PATH];
2512     char *unixname;
2513     HANDLE font_mutex;
2514     const char *data_dir;
2515
2516     TRACE("\n");
2517
2518     /* update locale dependent font info in registry */
2519     update_font_info();
2520
2521     if(!init_freetype()) return FALSE;
2522
2523     if((font_mutex = CreateMutexW(NULL, FALSE, font_mutex_nameW)) == NULL) {
2524         ERR("Failed to create font mutex\n");
2525         return FALSE;
2526     }
2527     WaitForSingleObject(font_mutex, INFINITE);
2528
2529     delete_external_font_keys();
2530
2531     /* load the system bitmap fonts */
2532     load_system_fonts();
2533
2534     /* load in the fonts from %WINDOWSDIR%\\Fonts first of all */
2535     GetWindowsDirectoryW(windowsdir, sizeof(windowsdir) / sizeof(WCHAR));
2536     strcatW(windowsdir, fontsW);
2537     if((unixname = wine_get_unix_file_name(windowsdir)))
2538     {
2539         ReadFontDir(unixname, FALSE);
2540         HeapFree(GetProcessHeap(), 0, unixname);
2541     }
2542
2543     /* load the system truetype fonts */
2544     data_dir = wine_get_data_dir();
2545     if (!data_dir) data_dir = wine_get_build_dir();
2546     if (data_dir && (unixname = HeapAlloc(GetProcessHeap(), 0, strlen(data_dir) + sizeof("/fonts/")))) {
2547         strcpy(unixname, data_dir);
2548         strcat(unixname, "/fonts/");
2549         ReadFontDir(unixname, TRUE);
2550         HeapFree(GetProcessHeap(), 0, unixname);
2551     }
2552
2553     /* now look under HKLM\Software\Microsoft\Windows[ NT]\CurrentVersion\Fonts
2554        for any fonts not installed in %WINDOWSDIR%\Fonts.  They will have their
2555        full path as the entry.  Also look for any .fon fonts, since ReadFontDir
2556        will skip these. */
2557     if(RegOpenKeyW(HKEY_LOCAL_MACHINE,
2558                    is_win9x() ? win9x_font_reg_key : winnt_font_reg_key,
2559                    &hkey) == ERROR_SUCCESS) {
2560         LPWSTR valueW;
2561         RegQueryInfoKeyW(hkey, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
2562                          &valuelen, &datalen, NULL, NULL);
2563
2564         valuelen++; /* returned value doesn't include room for '\0' */
2565         valueW = HeapAlloc(GetProcessHeap(), 0, valuelen * sizeof(WCHAR));
2566         data = HeapAlloc(GetProcessHeap(), 0, datalen * sizeof(WCHAR));
2567         if (valueW && data)
2568         {
2569             dlen = datalen * sizeof(WCHAR);
2570             vlen = valuelen;
2571             while(RegEnumValueW(hkey, i++, valueW, &vlen, NULL, &type, data,
2572                                 &dlen) == ERROR_SUCCESS) {
2573                 if(((LPWSTR)data)[0] && ((LPWSTR)data)[1] == ':')
2574                 {
2575                     if((unixname = wine_get_unix_file_name((LPWSTR)data)))
2576                     {
2577                         AddFontFileToList(unixname, NULL, NULL, ADDFONT_FORCE_BITMAP);
2578                         HeapFree(GetProcessHeap(), 0, unixname);
2579                     }
2580                 }
2581                 else if(dlen / 2 >= 6 && !strcmpiW(((LPWSTR)data) + dlen / 2 - 5, dot_fonW))
2582                 {
2583                     WCHAR pathW[MAX_PATH];
2584                     static const WCHAR fmtW[] = {'%','s','\\','%','s','\0'};
2585                     BOOL added = FALSE;
2586
2587                     sprintfW(pathW, fmtW, windowsdir, data);
2588                     if((unixname = wine_get_unix_file_name(pathW)))
2589                     {
2590                         added = AddFontFileToList(unixname, NULL, NULL, ADDFONT_FORCE_BITMAP);
2591                         HeapFree(GetProcessHeap(), 0, unixname);
2592                     }
2593                     if (!added)
2594                         load_font_from_data_dir(data);
2595                 }
2596                 /* reset dlen and vlen */
2597                 dlen = datalen;
2598                 vlen = valuelen;
2599             }
2600         }
2601         HeapFree(GetProcessHeap(), 0, data);
2602         HeapFree(GetProcessHeap(), 0, valueW);
2603         RegCloseKey(hkey);
2604     }
2605
2606     load_fontconfig_fonts();
2607
2608     /* then look in any directories that we've specified in the config file */
2609     /* @@ Wine registry key: HKCU\Software\Wine\Fonts */
2610     if(RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Fonts", &hkey) == ERROR_SUCCESS)
2611     {
2612         DWORD len;
2613         LPWSTR valueW;
2614         LPSTR valueA, ptr;
2615
2616         if (RegQueryValueExW( hkey, pathW, NULL, NULL, NULL, &len ) == ERROR_SUCCESS)
2617         {
2618             len += sizeof(WCHAR);
2619             valueW = HeapAlloc( GetProcessHeap(), 0, len );
2620             if (RegQueryValueExW( hkey, pathW, NULL, NULL, (LPBYTE)valueW, &len ) == ERROR_SUCCESS)
2621             {
2622                 len = WideCharToMultiByte( CP_UNIXCP, 0, valueW, -1, NULL, 0, NULL, NULL );
2623                 valueA = HeapAlloc( GetProcessHeap(), 0, len );
2624                 WideCharToMultiByte( CP_UNIXCP, 0, valueW, -1, valueA, len, NULL, NULL );
2625                 TRACE( "got font path %s\n", debugstr_a(valueA) );
2626                 ptr = valueA;
2627                 while (ptr)
2628                 {
2629                     LPSTR next = strchr( ptr, ':' );
2630                     if (next) *next++ = 0;
2631                     ReadFontDir( ptr, TRUE );
2632                     ptr = next;
2633                 }
2634                 HeapFree( GetProcessHeap(), 0, valueA );
2635             }
2636             HeapFree( GetProcessHeap(), 0, valueW );
2637         }
2638         RegCloseKey(hkey);
2639     }
2640
2641     DumpFontList();
2642     LoadSubstList();
2643     DumpSubstList();
2644     LoadReplaceList();
2645     update_reg_entries();
2646
2647     init_system_links();
2648     
2649     ReleaseMutex(font_mutex);
2650     return TRUE;
2651 }
2652
2653
2654 static LONG calc_ppem_for_height(FT_Face ft_face, LONG height)
2655 {
2656     TT_OS2 *pOS2;
2657     TT_HoriHeader *pHori;
2658
2659     LONG ppem;
2660
2661     pOS2 = pFT_Get_Sfnt_Table(ft_face, ft_sfnt_os2);
2662     pHori = pFT_Get_Sfnt_Table(ft_face, ft_sfnt_hhea);
2663
2664     if(height == 0) height = 16;
2665
2666     /* Calc. height of EM square:
2667      *
2668      * For +ve lfHeight we have
2669      * lfHeight = (winAscent + winDescent) * ppem / units_per_em
2670      * Re-arranging gives:
2671      * ppem = units_per_em * lfheight / (winAscent + winDescent)
2672      *
2673      * For -ve lfHeight we have
2674      * |lfHeight| = ppem
2675      * [i.e. |lfHeight| = (winAscent + winDescent - il) * ppem / units_per_em
2676      * with il = winAscent + winDescent - units_per_em]
2677      *
2678      */
2679
2680     if(height > 0) {
2681         if(pOS2->usWinAscent + pOS2->usWinDescent == 0)
2682             ppem = MulDiv(ft_face->units_per_EM, height,
2683                           pHori->Ascender - pHori->Descender);
2684         else
2685             ppem = MulDiv(ft_face->units_per_EM, height,
2686                           pOS2->usWinAscent + pOS2->usWinDescent);
2687     }
2688     else
2689         ppem = -height;
2690
2691     return ppem;
2692 }
2693
2694 static struct font_mapping *map_font_file( const char *name )
2695 {
2696     struct font_mapping *mapping;
2697     struct stat st;
2698     int fd;
2699
2700     if ((fd = open( name, O_RDONLY )) == -1) return NULL;
2701     if (fstat( fd, &st ) == -1) goto error;
2702
2703     LIST_FOR_EACH_ENTRY( mapping, &mappings_list, struct font_mapping, entry )
2704     {
2705         if (mapping->dev == st.st_dev && mapping->ino == st.st_ino)
2706         {
2707             mapping->refcount++;
2708             close( fd );
2709             return mapping;
2710         }
2711     }
2712     if (!(mapping = HeapAlloc( GetProcessHeap(), 0, sizeof(*mapping) )))
2713         goto error;
2714
2715     mapping->data = mmap( NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0 );
2716     close( fd );
2717
2718     if (mapping->data == MAP_FAILED)
2719     {
2720         HeapFree( GetProcessHeap(), 0, mapping );
2721         return NULL;
2722     }
2723     mapping->refcount = 1;
2724     mapping->dev = st.st_dev;
2725     mapping->ino = st.st_ino;
2726     mapping->size = st.st_size;
2727     list_add_tail( &mappings_list, &mapping->entry );
2728     return mapping;
2729
2730 error:
2731     close( fd );
2732     return NULL;
2733 }
2734
2735 static void unmap_font_file( struct font_mapping *mapping )
2736 {
2737     if (!--mapping->refcount)
2738     {
2739         list_remove( &mapping->entry );
2740         munmap( mapping->data, mapping->size );
2741         HeapFree( GetProcessHeap(), 0, mapping );
2742     }
2743 }
2744
2745 static LONG load_VDMX(GdiFont*, LONG);
2746
2747 static FT_Face OpenFontFace(GdiFont *font, Face *face, LONG width, LONG height)
2748 {
2749     FT_Error err;
2750     FT_Face ft_face;
2751     void *data_ptr;
2752     DWORD data_size;
2753
2754     TRACE("%s/%p, %ld, %d x %d\n", debugstr_a(face->file), face->font_data_ptr, face->face_index, width, height);
2755
2756     if (face->file)
2757     {
2758         if (!(font->mapping = map_font_file( face->file )))
2759         {
2760             WARN("failed to map %s\n", debugstr_a(face->file));
2761             return 0;
2762         }
2763         data_ptr = font->mapping->data;
2764         data_size = font->mapping->size;
2765     }
2766     else
2767     {
2768         data_ptr = face->font_data_ptr;
2769         data_size = face->font_data_size;
2770     }
2771
2772     err = pFT_New_Memory_Face(library, data_ptr, data_size, face->face_index, &ft_face);
2773     if(err) {
2774         ERR("FT_New_Face rets %d\n", err);
2775         return 0;
2776     }
2777
2778     /* set it here, as load_VDMX needs it */
2779     font->ft_face = ft_face;
2780
2781     if(FT_IS_SCALABLE(ft_face)) {
2782         /* load the VDMX table if we have one */
2783         font->ppem = load_VDMX(font, height);
2784         if(font->ppem == 0)
2785             font->ppem = calc_ppem_for_height(ft_face, height);
2786         TRACE("height %d => ppem %d\n", height, font->ppem);
2787
2788         if((err = pFT_Set_Pixel_Sizes(ft_face, 0, font->ppem)) != 0)
2789             WARN("FT_Set_Pixel_Sizes %d, %d rets %x\n", 0, font->ppem, err);
2790     } else {
2791         font->ppem = height;
2792         if((err = pFT_Set_Pixel_Sizes(ft_face, width, height)) != 0)
2793             WARN("FT_Set_Pixel_Sizes %d, %d rets %x\n", width, height, err);
2794     }
2795     return ft_face;
2796 }
2797
2798
2799 static int get_nearest_charset(Face *face, int *cp)
2800 {
2801   /* Only get here if lfCharSet == DEFAULT_CHARSET or we couldn't find
2802      a single face with the requested charset.  The idea is to check if
2803      the selected font supports the current ANSI codepage, if it does
2804      return the corresponding charset, else return the first charset */
2805
2806     CHARSETINFO csi;
2807     int acp = GetACP(), i;
2808     DWORD fs0;
2809
2810     *cp = acp;
2811     if(TranslateCharsetInfo((DWORD*)(INT_PTR)acp, &csi, TCI_SRCCODEPAGE))
2812         if(csi.fs.fsCsb[0] & (face->fs.fsCsb[0] | face->fs_links.fsCsb[0]))
2813             return csi.ciCharset;
2814
2815     for(i = 0; i < 32; i++) {
2816         fs0 = 1L << i;
2817         if(face->fs.fsCsb[0] & fs0) {
2818             if(TranslateCharsetInfo(&fs0, &csi, TCI_SRCFONTSIG)) {
2819                 *cp = csi.ciACP;
2820                 return csi.ciCharset;
2821             }
2822             else
2823                 FIXME("TCI failing on %x\n", fs0);
2824         }
2825     }
2826
2827     FIXME("returning DEFAULT_CHARSET face->fs.fsCsb[0] = %08x file = %s\n",
2828           face->fs.fsCsb[0], face->file);
2829     *cp = acp;
2830     return DEFAULT_CHARSET;
2831 }
2832
2833 static GdiFont *alloc_font(void)
2834 {
2835     GdiFont *ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret));
2836     ret->gmsize = 1;
2837     ret->gm = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GM*));
2838     ret->gm[0] = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(GM) * GM_BLOCK_SIZE);
2839     ret->potm = NULL;
2840     ret->font_desc.matrix.eM11 = ret->font_desc.matrix.eM22 = 1.0;
2841     ret->total_kern_pairs = (DWORD)-1;
2842     ret->kern_pairs = NULL;
2843     list_init(&ret->hfontlist);
2844     list_init(&ret->child_fonts);
2845     return ret;
2846 }
2847
2848 static void free_font(GdiFont *font)
2849 {
2850     struct list *cursor, *cursor2;
2851     int i;
2852
2853     LIST_FOR_EACH_SAFE(cursor, cursor2, &font->child_fonts)
2854     {
2855         CHILD_FONT *child = LIST_ENTRY(cursor, CHILD_FONT, entry);
2856         struct list *first_hfont;
2857         HFONTLIST *hfontlist;
2858         list_remove(cursor);
2859         if(child->font)
2860         {
2861             first_hfont = list_head(&child->font->hfontlist);
2862             hfontlist = LIST_ENTRY(first_hfont, HFONTLIST, entry);
2863             DeleteObject(hfontlist->hfont);
2864             HeapFree(GetProcessHeap(), 0, hfontlist);
2865             free_font(child->font);
2866         }
2867         HeapFree(GetProcessHeap(), 0, child);
2868     }
2869
2870     if (font->ft_face) pFT_Done_Face(font->ft_face);
2871     if (font->mapping) unmap_font_file( font->mapping );
2872     HeapFree(GetProcessHeap(), 0, font->kern_pairs);
2873     HeapFree(GetProcessHeap(), 0, font->potm);
2874     HeapFree(GetProcessHeap(), 0, font->name);
2875     for (i = 0; i < font->gmsize; i++)
2876         HeapFree(GetProcessHeap(),0,font->gm[i]);
2877     HeapFree(GetProcessHeap(), 0, font->gm);
2878     HeapFree(GetProcessHeap(), 0, font->GSUB_Table);
2879     HeapFree(GetProcessHeap(), 0, font);
2880 }
2881
2882
2883 /*************************************************************
2884  * load_VDMX
2885  *
2886  * load the vdmx entry for the specified height
2887  */
2888
2889 #define MS_MAKE_TAG( _x1, _x2, _x3, _x4 ) \
2890           ( ( (FT_ULong)_x4 << 24 ) |     \
2891             ( (FT_ULong)_x3 << 16 ) |     \
2892             ( (FT_ULong)_x2 <<  8 ) |     \
2893               (FT_ULong)_x1         )
2894
2895 #define MS_VDMX_TAG MS_MAKE_TAG('V', 'D', 'M', 'X')
2896
2897 typedef struct {
2898     BYTE bCharSet;
2899     BYTE xRatio;
2900     BYTE yStartRatio;
2901     BYTE yEndRatio;
2902 } Ratios;
2903
2904 typedef struct {
2905     WORD recs;
2906     BYTE startsz;
2907     BYTE endsz;
2908 } VDMX_group;
2909
2910 static LONG load_VDMX(GdiFont *font, LONG height)
2911 {
2912     WORD hdr[3], tmp;
2913     VDMX_group group;
2914     BYTE devXRatio, devYRatio;
2915     USHORT numRecs, numRatios;
2916     DWORD result, offset = -1;
2917     LONG ppem = 0;
2918     int i;
2919
2920     result = WineEngGetFontData(font, MS_VDMX_TAG, 0, hdr, 6);
2921
2922     if(result == GDI_ERROR) /* no vdmx table present, use linear scaling */
2923         return ppem;
2924
2925     /* FIXME: need the real device aspect ratio */
2926     devXRatio = 1;
2927     devYRatio = 1;
2928
2929     numRecs = GET_BE_WORD(hdr[1]);
2930     numRatios = GET_BE_WORD(hdr[2]);
2931
2932     TRACE("numRecs = %d numRatios = %d\n", numRecs, numRatios);
2933     for(i = 0; i < numRatios; i++) {
2934         Ratios ratio;
2935
2936         offset = (3 * 2) + (i * sizeof(Ratios));
2937         WineEngGetFontData(font, MS_VDMX_TAG, offset, &ratio, sizeof(Ratios));
2938         offset = -1;
2939
2940         TRACE("Ratios[%d] %d  %d : %d -> %d\n", i, ratio.bCharSet, ratio.xRatio, ratio.yStartRatio, ratio.yEndRatio);
2941
2942         if((ratio.xRatio == 0 &&
2943             ratio.yStartRatio == 0 &&
2944             ratio.yEndRatio == 0) ||
2945            (devXRatio == ratio.xRatio &&
2946             devYRatio >= ratio.yStartRatio &&
2947             devYRatio <= ratio.yEndRatio))
2948             {
2949                 offset = (3 * 2) + (numRatios * 4) + (i * 2);
2950                 WineEngGetFontData(font, MS_VDMX_TAG, offset, &tmp, 2);
2951                 offset = GET_BE_WORD(tmp);
2952                 break;
2953             }
2954     }
2955
2956     if(offset == -1) {
2957         FIXME("No suitable ratio found\n");
2958         return ppem;
2959     }
2960
2961     if(WineEngGetFontData(font, MS_VDMX_TAG, offset, &group, 4) != GDI_ERROR) {
2962         USHORT recs;
2963         BYTE startsz, endsz;
2964         WORD *vTable;
2965
2966         recs = GET_BE_WORD(group.recs);
2967         startsz = group.startsz;
2968         endsz = group.endsz;
2969
2970         TRACE("recs=%d  startsz=%d  endsz=%d\n", recs, startsz, endsz);
2971
2972         vTable = HeapAlloc(GetProcessHeap(), 0, recs * 6);
2973         result = WineEngGetFontData(font, MS_VDMX_TAG, offset + 4, vTable, recs * 6);
2974         if(result == GDI_ERROR) {
2975             FIXME("Failed to retrieve vTable\n");
2976             goto end;
2977         }
2978
2979         if(height > 0) {
2980             for(i = 0; i < recs; i++) {
2981                 SHORT yMax = GET_BE_WORD(vTable[(i * 3) + 1]);
2982                 SHORT yMin = GET_BE_WORD(vTable[(i * 3) + 2]);
2983                 ppem = GET_BE_WORD(vTable[i * 3]);
2984
2985                 if(yMax + -yMin == height) {
2986                     font->yMax = yMax;
2987                     font->yMin = yMin;
2988                     TRACE("ppem %d found; height=%d  yMax=%d  yMin=%d\n", ppem, height, font->yMax, font->yMin);
2989                     break;
2990                 }
2991                 if(yMax + -yMin > height) {
2992                     if(--i < 0) {
2993                         ppem = 0;
2994                         goto end; /* failed */
2995                     }
2996                     font->yMax = GET_BE_WORD(vTable[(i * 3) + 1]);
2997                     font->yMin = GET_BE_WORD(vTable[(i * 3) + 2]);
2998                     ppem = GET_BE_WORD(vTable[i * 3]);
2999                     TRACE("ppem %d found; height=%d  yMax=%d  yMin=%d\n", ppem, height, font->yMax, font->yMin);
3000                     break;
3001                 }
3002             }
3003             if(!font->yMax) {
3004                 ppem = 0;
3005                 TRACE("ppem not found for height %d\n", height);
3006             }
3007         } else {
3008             ppem = -height;
3009             if(ppem < startsz || ppem > endsz)
3010                 goto end;
3011
3012             for(i = 0; i < recs; i++) {
3013                 USHORT yPelHeight;
3014                 yPelHeight = GET_BE_WORD(vTable[i * 3]);
3015
3016                 if(yPelHeight > ppem)
3017                     break; /* failed */
3018
3019                 if(yPelHeight == ppem) {
3020                     font->yMax = GET_BE_WORD(vTable[(i * 3) + 1]);
3021                     font->yMin = GET_BE_WORD(vTable[(i * 3) + 2]);
3022                     TRACE("ppem %d found; yMax=%d  yMin=%d\n", ppem, font->yMax, font->yMin);
3023                     break;
3024                 }
3025             }
3026         }
3027         end:
3028         HeapFree(GetProcessHeap(), 0, vTable);
3029     }
3030
3031     return ppem;
3032 }
3033
3034 static BOOL fontcmp(const GdiFont *font, FONT_DESC *fd)
3035 {
3036     if(font->font_desc.hash != fd->hash) return TRUE;
3037     if(memcmp(&font->font_desc.matrix, &fd->matrix, sizeof(fd->matrix))) return TRUE;
3038     if(memcmp(&font->font_desc.lf, &fd->lf, offsetof(LOGFONTW, lfFaceName))) return TRUE;
3039     if(!font->font_desc.can_use_bitmap != !fd->can_use_bitmap) return TRUE;
3040     return strcmpiW(font->font_desc.lf.lfFaceName, fd->lf.lfFaceName);
3041 }
3042
3043 static void calc_hash(FONT_DESC *pfd)
3044 {
3045     DWORD hash = 0, *ptr, two_chars;
3046     WORD *pwc;
3047     unsigned int i;
3048
3049     for(i = 0, ptr = (DWORD*)&pfd->matrix; i < sizeof(FMAT2)/sizeof(DWORD); i++, ptr++)
3050         hash ^= *ptr;
3051     for(i = 0, ptr = (DWORD*)&pfd->lf; i < 7; i++, ptr++)
3052         hash ^= *ptr;
3053     for(i = 0, ptr = (DWORD*)pfd->lf.lfFaceName; i < LF_FACESIZE/2; i++, ptr++) {
3054         two_chars = *ptr;
3055         pwc = (WCHAR *)&two_chars;
3056         if(!*pwc) break;
3057         *pwc = toupperW(*pwc);
3058         pwc++;
3059         *pwc = toupperW(*pwc);
3060         hash ^= two_chars;
3061         if(!*pwc) break;
3062     }
3063     hash ^= !pfd->can_use_bitmap;
3064     pfd->hash = hash;
3065     return;
3066 }
3067
3068 static GdiFont *find_in_cache(HFONT hfont, const LOGFONTW *plf, const FMAT2 *pmat, BOOL can_use_bitmap)
3069 {
3070     GdiFont *ret;
3071     FONT_DESC fd;
3072     HFONTLIST *hflist;
3073     struct list *font_elem_ptr, *hfontlist_elem_ptr;
3074
3075     fd.lf = *plf;
3076     fd.matrix = *pmat;
3077     fd.can_use_bitmap = can_use_bitmap;
3078     calc_hash(&fd);
3079
3080     /* try the in-use list */
3081     LIST_FOR_EACH(font_elem_ptr, &gdi_font_list) {
3082         ret = LIST_ENTRY(font_elem_ptr, struct tagGdiFont, entry);
3083         if(!fontcmp(ret, &fd)) {
3084             if(!can_use_bitmap && !FT_IS_SCALABLE(ret->ft_face)) continue;
3085             LIST_FOR_EACH(hfontlist_elem_ptr, &ret->hfontlist) {
3086                 hflist = LIST_ENTRY(hfontlist_elem_ptr, struct tagHFONTLIST, entry);
3087                 if(hflist->hfont == hfont)
3088                     return ret;
3089             }
3090             hflist = HeapAlloc(GetProcessHeap(), 0, sizeof(*hflist));
3091             hflist->hfont = hfont;
3092             list_add_head(&ret->hfontlist, &hflist->entry);
3093             return ret;
3094         }
3095     }
3096  
3097     /* then the unused list */
3098     font_elem_ptr = list_head(&unused_gdi_font_list);
3099     while(font_elem_ptr) {
3100         ret = LIST_ENTRY(font_elem_ptr, struct tagGdiFont, entry);
3101         font_elem_ptr = list_next(&unused_gdi_font_list, font_elem_ptr);
3102         if(!fontcmp(ret, &fd)) {
3103             if(!can_use_bitmap && !FT_IS_SCALABLE(ret->ft_face)) continue;
3104             assert(list_empty(&ret->hfontlist));
3105             TRACE("Found %p in unused list\n", ret);
3106             list_remove(&ret->entry);
3107             list_add_head(&gdi_font_list, &ret->entry);
3108             hflist = HeapAlloc(GetProcessHeap(), 0, sizeof(*hflist));
3109             hflist->hfont = hfont;
3110             list_add_head(&ret->hfontlist, &hflist->entry);
3111             return ret;
3112         }
3113     }
3114     return NULL;
3115 }
3116
3117 static void add_to_cache(GdiFont *font)
3118 {
3119     static DWORD cache_num = 1;
3120
3121     font->cache_num = cache_num++;
3122     list_add_head(&gdi_font_list, &font->entry);
3123 }
3124
3125 /*************************************************************
3126  * create_child_font_list
3127  */
3128 static BOOL create_child_font_list(GdiFont *font)
3129 {
3130     BOOL ret = FALSE;
3131     SYSTEM_LINKS *font_link;
3132     CHILD_FONT *font_link_entry, *new_child;
3133
3134     LIST_FOR_EACH_ENTRY(font_link, &system_links, SYSTEM_LINKS, entry)
3135     {
3136         if(!strcmpW(font_link->font_name, font->name))
3137         {
3138             TRACE("found entry in system list\n");
3139             LIST_FOR_EACH_ENTRY(font_link_entry, &font_link->links, CHILD_FONT, entry)
3140             {
3141                 new_child = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_child));
3142                 new_child->face = font_link_entry->face;
3143                 new_child->font = NULL;
3144                 list_add_tail(&font->child_fonts, &new_child->entry);
3145                 TRACE("font %s %ld\n", debugstr_a(new_child->face->file), new_child->face->face_index);
3146             }
3147             ret = TRUE;
3148             break;
3149         }
3150     }
3151     /*
3152      * if not SYMBOL or OEM then we also get all the fonts for Microsoft
3153      * Sans Serif.  This is how asian windows get default fallbacks for fonts
3154      */
3155     if (use_default_fallback && font->charset != SYMBOL_CHARSET &&
3156         font->charset != OEM_CHARSET &&
3157         strcmpW(font->name,szDefaultFallbackLink) != 0)
3158         LIST_FOR_EACH_ENTRY(font_link, &system_links, SYSTEM_LINKS, entry)
3159         {
3160             if(!strcmpW(font_link->font_name,szDefaultFallbackLink))
3161             {
3162                 TRACE("found entry in default fallback list\n");
3163                 LIST_FOR_EACH_ENTRY(font_link_entry, &font_link->links, CHILD_FONT, entry)
3164                 {
3165                     new_child = HeapAlloc(GetProcessHeap(), 0, sizeof(*new_child));
3166                     new_child->face = font_link_entry->face;
3167                     new_child->font = NULL;
3168                     list_add_tail(&font->child_fonts, &new_child->entry);
3169                     TRACE("font %s %ld\n", debugstr_a(new_child->face->file), new_child->face->face_index);
3170                 }
3171                 ret = TRUE;
3172                 break;
3173             }
3174         }
3175
3176     return ret;
3177 }
3178
3179 static BOOL select_charmap(FT_Face ft_face, FT_Encoding encoding)
3180 {
3181     FT_Error ft_err = FT_Err_Invalid_CharMap_Handle;
3182
3183     if (pFT_Set_Charmap)
3184     {
3185         FT_Int i;
3186         FT_CharMap cmap0, cmap1, cmap2, cmap3, cmap_def;
3187
3188         cmap0 = cmap1 = cmap2 = cmap3 = cmap_def = NULL;
3189
3190         for (i = 0; i < ft_face->num_charmaps; i++)
3191         {
3192             if (ft_face->charmaps[i]->encoding == encoding)
3193             {
3194                 TRACE("found cmap with platform_id %u, encoding_id %u\n",
3195                        ft_face->charmaps[i]->platform_id, ft_face->charmaps[i]->encoding_id);
3196
3197                 switch (ft_face->charmaps[i]->platform_id)
3198                 {
3199                     default:
3200                         cmap_def = ft_face->charmaps[i];
3201                         break;
3202                     case 0: /* Apple Unicode */
3203                         cmap0 = ft_face->charmaps[i];
3204                         break;
3205                     case 1: /* Macintosh */
3206                         cmap1 = ft_face->charmaps[i];
3207                         break;
3208                     case 2: /* ISO */
3209                         cmap2 = ft_face->charmaps[i];
3210                         break;
3211                     case 3: /* Microsoft */
3212                         cmap3 = ft_face->charmaps[i];
3213                         break;
3214                 }
3215             }
3216
3217             if (cmap3) /* prefer Microsoft cmap table */
3218                 ft_err = pFT_Set_Charmap(ft_face, cmap3);
3219             else if (cmap1)
3220                 ft_err = pFT_Set_Charmap(ft_face, cmap1);
3221             else if (cmap2)
3222                 ft_err = pFT_Set_Charmap(ft_face, cmap2);
3223             else if (cmap0)
3224                 ft_err = pFT_Set_Charmap(ft_face, cmap0);
3225             else if (cmap_def)
3226                 ft_err = pFT_Set_Charmap(ft_face, cmap_def);
3227         }
3228         return ft_err == FT_Err_Ok;
3229     }
3230
3231     return pFT_Select_Charmap(ft_face, encoding) == FT_Err_Ok;
3232 }
3233
3234 /*************************************************************
3235  * WineEngCreateFontInstance
3236  *
3237  */
3238 GdiFont *WineEngCreateFontInstance(DC *dc, HFONT hfont)
3239 {
3240     GdiFont *ret;
3241     Face *face, *best, *best_bitmap;
3242     Family *family, *last_resort_family;
3243     struct list *family_elem_ptr, *face_elem_ptr;
3244     INT height, width = 0;
3245     unsigned int score = 0, new_score;
3246     signed int diff = 0, newdiff;
3247     BOOL bd, it, can_use_bitmap;
3248     LOGFONTW lf;
3249     CHARSETINFO csi;
3250     HFONTLIST *hflist;
3251     FMAT2 dcmat;
3252     FontSubst *psub = NULL;
3253
3254     EnterCriticalSection( &freetype_cs );
3255
3256     LIST_FOR_EACH_ENTRY(ret, &child_font_list, struct tagGdiFont, entry)
3257     {
3258         struct list *first_hfont = list_head(&ret->hfontlist);
3259         hflist = LIST_ENTRY(first_hfont, HFONTLIST, entry);
3260         if(hflist->hfont == hfont)
3261         {
3262             LeaveCriticalSection( &freetype_cs );
3263             return ret;
3264         }
3265     }
3266
3267     if (!GetObjectW( hfont, sizeof(lf), &lf ))
3268     {
3269         LeaveCriticalSection( &freetype_cs );
3270         return NULL;
3271     }
3272     lf.lfWidth = abs(lf.lfWidth);
3273
3274     can_use_bitmap = GetDeviceCaps(dc->hSelf, TEXTCAPS) & TC_RA_ABLE;
3275
3276     TRACE("%s, h=%d, it=%d, weight=%d, PandF=%02x, charset=%d orient %d escapement %d\n",
3277           debugstr_w(lf.lfFaceName), lf.lfHeight, lf.lfItalic,
3278           lf.lfWeight, lf.lfPitchAndFamily, lf.lfCharSet, lf.lfOrientation,
3279           lf.lfEscapement);
3280
3281     if(dc->GraphicsMode == GM_ADVANCED)
3282         memcpy(&dcmat, &dc->xformWorld2Vport, sizeof(FMAT2));
3283     else
3284     {
3285         /* Windows 3.1 compatibility mode GM_COMPATIBLE has only limited
3286            font scaling abilities. */
3287         dcmat.eM11 = dcmat.eM22 = fabs(dc->xformWorld2Vport.eM22);
3288         dcmat.eM21 = dcmat.eM12 = 0;
3289     }
3290
3291     TRACE("DC transform %f %f %f %f\n", dcmat.eM11, dcmat.eM12,
3292                                         dcmat.eM21, dcmat.eM22);
3293
3294     /* check the cache first */
3295     if((ret = find_in_cache(hfont, &lf, &dcmat, can_use_bitmap)) != NULL) {
3296         TRACE("returning cached gdiFont(%p) for hFont %p\n", ret, hfont);
3297         LeaveCriticalSection( &freetype_cs );
3298         return ret;
3299     }
3300
3301     TRACE("not in cache\n");
3302     if(list_empty(&font_list)) /* No fonts installed */
3303     {
3304         TRACE("No fonts installed\n");
3305         LeaveCriticalSection( &freetype_cs );
3306         return NULL;
3307     }
3308     if(!have_installed_roman_font)
3309     {
3310         TRACE("No roman font installed\n");
3311         LeaveCriticalSection( &freetype_cs );
3312         return NULL;
3313     }
3314
3315     ret = alloc_font();
3316
3317     ret->font_desc.matrix = dcmat;
3318     ret->font_desc.lf = lf;
3319     ret->font_desc.can_use_bitmap = can_use_bitmap;
3320     calc_hash(&ret->font_desc);
3321     hflist = HeapAlloc(GetProcessHeap(), 0, sizeof(*hflist));
3322     hflist->hfont = hfont;
3323     list_add_head(&ret->hfontlist, &hflist->entry);
3324
3325     /* If lfFaceName is "Symbol" then Windows fixes up lfCharSet to
3326        SYMBOL_CHARSET so that Symbol gets picked irrespective of the
3327        original value lfCharSet.  Note this is a special case for
3328        Symbol and doesn't happen at least for "Wingdings*" */
3329
3330     if(!strcmpiW(lf.lfFaceName, SymbolW))
3331         lf.lfCharSet = SYMBOL_CHARSET;
3332
3333     if(!TranslateCharsetInfo((DWORD*)(INT_PTR)lf.lfCharSet, &csi, TCI_SRCCHARSET)) {
3334         switch(lf.lfCharSet) {
3335         case DEFAULT_CHARSET:
3336             csi.fs.fsCsb[0] = 0;
3337             break;
3338         default:
3339             FIXME("Untranslated charset %d\n", lf.lfCharSet);
3340             csi.fs.fsCsb[0] = 0;
3341             break;
3342         }
3343     }
3344
3345     family = NULL;
3346     if(lf.lfFaceName[0] != '\0') {
3347         SYSTEM_LINKS *font_link;
3348         CHILD_FONT *font_link_entry;
3349         LPWSTR FaceName = lf.lfFaceName;
3350
3351         /*
3352          * Check for a leading '@' this signals that the font is being
3353          * requested in tategaki mode (vertical writing substitution) but
3354          * does not affect the fontface that is to be selected.
3355          */
3356         if (lf.lfFaceName[0]=='@')
3357             FaceName = &lf.lfFaceName[1];
3358
3359         psub = get_font_subst(&font_subst_list, FaceName, lf.lfCharSet);
3360
3361         if(psub) {
3362             TRACE("substituting %s,%d -> %s,%d\n", debugstr_w(FaceName), lf.lfCharSet,
3363                   debugstr_w(psub->to.name), (psub->to.charset != -1) ? psub->to.charset : lf.lfCharSet);
3364             if (psub->to.charset != -1)
3365                 lf.lfCharSet = psub->to.charset;
3366         }
3367
3368         /* We want a match on name and charset or just name if
3369            charset was DEFAULT_CHARSET.  If the latter then
3370            we fixup the returned charset later in get_nearest_charset
3371            where we'll either use the charset of the current ansi codepage
3372            or if that's unavailable the first charset that the font supports.
3373         */
3374         LIST_FOR_EACH(family_elem_ptr, &font_list) {
3375             family = LIST_ENTRY(family_elem_ptr, Family, entry);
3376             if (!strcmpiW(family->FamilyName, FaceName) ||
3377                 (psub && !strcmpiW(family->FamilyName, psub->to.name)))
3378             {
3379                 LIST_FOR_EACH(face_elem_ptr, &family->faces) { 
3380                     face = LIST_ENTRY(face_elem_ptr, Face, entry);
3381                     if((csi.fs.fsCsb[0] & (face->fs.fsCsb[0] | face->fs_links.fsCsb[0])) || !csi.fs.fsCsb[0])
3382                         if(face->scalable || can_use_bitmap)
3383                             goto found;
3384                 }
3385             }
3386         }
3387
3388         /*
3389          * Try check the SystemLink list first for a replacement font.
3390          * We may find good replacements there.
3391          */
3392         LIST_FOR_EACH_ENTRY(font_link, &system_links, SYSTEM_LINKS, entry)
3393         {
3394             if(!strcmpiW(font_link->font_name, FaceName))
3395             {
3396                 TRACE("found entry in system list\n");
3397                 LIST_FOR_EACH_ENTRY(font_link_entry, &font_link->links, CHILD_FONT, entry)
3398                 {
3399                     face = font_link_entry->face;
3400                     family = face->family;
3401                     if(csi.fs.fsCsb[0] &
3402                         (face->fs.fsCsb[0] | face->fs_links.fsCsb[0]) || !csi.fs.fsCsb[0])
3403                     {
3404                         if(face->scalable || can_use_bitmap)
3405                             goto found;
3406                     }
3407                 }
3408             }
3409         }
3410     }
3411
3412     psub = NULL; /* substitution is no more relevant */
3413
3414     /* If requested charset was DEFAULT_CHARSET then try using charset
3415        corresponding to the current ansi codepage */
3416     if (!csi.fs.fsCsb[0] || lf.lfWeight == FW_DONTCARE)
3417     {
3418         INT acp = GetACP();
3419         if(!TranslateCharsetInfo((DWORD*)(INT_PTR)acp, &csi, TCI_SRCCODEPAGE)) {
3420             FIXME("TCI failed on codepage %d\n", acp);
3421             csi.fs.fsCsb[0] = 0;
3422         } else
3423             lf.lfCharSet = csi.ciCharset;
3424     }
3425
3426     /* Face families are in the top 4 bits of lfPitchAndFamily,
3427        so mask with 0xF0 before testing */
3428
3429     if((lf.lfPitchAndFamily & FIXED_PITCH) ||
3430        (lf.lfPitchAndFamily & 0xF0) == FF_MODERN)
3431         strcpyW(lf.lfFaceName, defFixed);
3432     else if((lf.lfPitchAndFamily & 0xF0) == FF_ROMAN)
3433         strcpyW(lf.lfFaceName, defSerif);
3434     else if((lf.lfPitchAndFamily & 0xF0) == FF_SWISS)
3435         strcpyW(lf.lfFaceName, defSans);
3436     else
3437         strcpyW(lf.lfFaceName, defSans);
3438     LIST_FOR_EACH(family_elem_ptr, &font_list) {
3439         family = LIST_ENTRY(family_elem_ptr, Family, entry);
3440         if(!strcmpiW(family->FamilyName, lf.lfFaceName)) {
3441             LIST_FOR_EACH(face_elem_ptr, &family->faces) { 
3442                 face = LIST_ENTRY(face_elem_ptr, Face, entry);
3443                 if(csi.fs.fsCsb[0] & (face->fs.fsCsb[0] | face->fs_links.fsCsb[0]))
3444                     if(face->scalable || can_use_bitmap)
3445                         goto found;
3446             }
3447         }
3448     }
3449
3450     last_resort_family = NULL;
3451     LIST_FOR_EACH(family_elem_ptr, &font_list) {
3452         family = LIST_ENTRY(family_elem_ptr, Family, entry);
3453         LIST_FOR_EACH(face_elem_ptr, &family->faces) { 
3454             face = LIST_ENTRY(face_elem_ptr, Face, entry);
3455             if(csi.fs.fsCsb[0] & (face->fs.fsCsb[0] | face->fs_links.fsCsb[0])) {
3456                 if(face->scalable)
3457                     goto found;
3458                 if(can_use_bitmap && !last_resort_family)
3459                     last_resort_family = family;
3460             }            
3461         }
3462     }
3463
3464     if(last_resort_family) {
3465         family = last_resort_family;
3466         csi.fs.fsCsb[0] = 0;
3467         goto found;
3468     }
3469
3470     LIST_FOR_EACH(family_elem_ptr, &font_list) {
3471         family = LIST_ENTRY(family_elem_ptr, Family, entry);
3472         LIST_FOR_EACH(face_elem_ptr, &family->faces) { 
3473             face = LIST_ENTRY(face_elem_ptr, Face, entry);
3474             if(face->scalable) {
3475                 csi.fs.fsCsb[0] = 0;
3476                 WARN("just using first face for now\n");
3477                 goto found;
3478             }
3479             if(can_use_bitmap && !last_resort_family)
3480                 last_resort_family = family;
3481         }
3482     }
3483     if(!last_resort_family) {
3484         FIXME("can't find a single appropriate font - bailing\n");
3485         free_font(ret);
3486         LeaveCriticalSection( &freetype_cs );
3487         return NULL;
3488     }
3489
3490     WARN("could only find a bitmap font - this will probably look awful!\n");
3491     family = last_resort_family;
3492     csi.fs.fsCsb[0] = 0;
3493
3494 found:
3495     it = lf.lfItalic ? 1 : 0;
3496     bd = lf.lfWeight > 550 ? 1 : 0;
3497
3498     height = lf.lfHeight;
3499
3500     face = best = best_bitmap = NULL;
3501     LIST_FOR_EACH_ENTRY(face, &family->faces, Face, entry)
3502     {
3503         if((csi.fs.fsCsb[0] & (face->fs.fsCsb[0] | face->fs_links.fsCsb[0])) || !csi.fs.fsCsb[0])
3504         {
3505             BOOL italic, bold;
3506
3507             italic = (face->ntmFlags & NTM_ITALIC) ? 1 : 0;
3508             bold = (face->ntmFlags & NTM_BOLD) ? 1 : 0;
3509             new_score = (italic ^ it) + (bold ^ bd);
3510             if(!best || new_score <= score)
3511             {
3512                 TRACE("(it=%d, bd=%d) is selected for (it=%d, bd=%d)\n",
3513                       italic, bold, it, bd);
3514                 score = new_score;
3515                 best = face;
3516                 if(best->scalable  && score == 0) break;
3517                 if(!best->scalable)
3518                 {
3519                     if(height > 0)
3520                         newdiff = height - (signed int)(best->size.height);
3521                     else
3522                         newdiff = -height - ((signed int)(best->size.height) - best->size.internal_leading);
3523                     if(!best_bitmap || new_score < score ||
3524                        (diff > 0 && newdiff < diff && newdiff >= 0) || (diff < 0 && newdiff > diff))
3525                     {
3526                         TRACE("%d is better for %d diff was %d\n", best->size.height, height, diff);
3527                         diff = newdiff;
3528                         best_bitmap = best;
3529                         if(score == 0 && diff == 0) break;
3530                     }
3531                 }
3532             }
3533         }
3534     }
3535     if(best)
3536         face = best->scalable ? best : best_bitmap;
3537     ret->fake_italic = (it && !(face->ntmFlags & NTM_ITALIC));
3538     ret->fake_bold = (bd && !(face->ntmFlags & NTM_BOLD));
3539
3540     ret->fs = face->fs;
3541
3542     if(csi.fs.fsCsb[0]) {
3543         ret->charset = lf.lfCharSet;
3544         ret->codepage = csi.ciACP;
3545     }
3546     else
3547         ret->charset = get_nearest_charset(face, &ret->codepage);
3548
3549     TRACE("Chosen: %s %s (%s/%p:%ld)\n", debugstr_w(family->FamilyName),
3550           debugstr_w(face->StyleName), face->file, face->font_data_ptr, face->face_index);
3551
3552     ret->aveWidth = height ? lf.lfWidth : 0;
3553
3554     if(!face->scalable) {
3555         /* Windows uses integer scaling factors for bitmap fonts */
3556         INT scale, scaled_height;
3557
3558         if (height != 0) height = diff;
3559         height += face->size.height;
3560
3561         scale = (height + face->size.height - 1) / face->size.height;
3562         scaled_height = scale * face->size.height;
3563         /* XP allows not more than 10% deviation */
3564         if (scale > 1 && scaled_height - height > scaled_height / 10) scale--;
3565         ret->scale_y = scale;
3566
3567         width = face->size.x_ppem >> 6;
3568         height = face->size.y_ppem >> 6;
3569     }
3570     else
3571         ret->scale_y = 1.0;
3572     TRACE("font scale y: %f\n", ret->scale_y);
3573
3574     ret->ft_face = OpenFontFace(ret, face, width, height);
3575
3576     if (!ret->ft_face)
3577     {
3578         free_font( ret );
3579         LeaveCriticalSection( &freetype_cs );
3580         return 0;
3581     }
3582
3583     ret->ntmFlags = face->ntmFlags;
3584
3585     if (ret->charset == SYMBOL_CHARSET && 
3586         select_charmap(ret->ft_face, FT_ENCODING_MS_SYMBOL)) {
3587         /* No ops */
3588     }
3589     else if (select_charmap(ret->ft_face, FT_ENCODING_UNICODE)) {
3590         /* No ops */
3591     }
3592     else {
3593         select_charmap(ret->ft_face, FT_ENCODING_APPLE_ROMAN);
3594     }
3595
3596     ret->orientation = FT_IS_SCALABLE(ret->ft_face) ? lf.lfOrientation : 0;
3597     ret->name = psub ? strdupW(psub->from.name) : strdupW(family->FamilyName);
3598     ret->underline = lf.lfUnderline ? 0xff : 0;
3599     ret->strikeout = lf.lfStrikeOut ? 0xff : 0;
3600     create_child_font_list(ret);
3601
3602     if (lf.lfFaceName[0]=='@') /* We need to try to load the GSUB table */
3603     {
3604         int length = WineEngGetFontData (ret, GSUB_TAG , 0, NULL, 0);
3605         if (length != GDI_ERROR)
3606         {
3607             ret->GSUB_Table = HeapAlloc(GetProcessHeap(),0,length);
3608             WineEngGetFontData(ret, GSUB_TAG , 0, ret->GSUB_Table, length);
3609             TRACE("Loaded GSUB table of %i bytes\n",length);
3610         }
3611     }
3612
3613     TRACE("caching: gdiFont=%p  hfont=%p\n", ret, hfont);
3614
3615     add_to_cache(ret);
3616     LeaveCriticalSection( &freetype_cs );
3617     return ret;
3618 }
3619
3620 static void dump_gdi_font_list(void)
3621 {
3622     GdiFont *gdiFont;
3623     struct list *elem_ptr;
3624
3625     TRACE("---------- gdiFont Cache ----------\n");
3626     LIST_FOR_EACH(elem_ptr, &gdi_font_list) {
3627         gdiFont = LIST_ENTRY(elem_ptr, struct tagGdiFont, entry);
3628         TRACE("gdiFont=%p %s %d\n",
3629               gdiFont, debugstr_w(gdiFont->font_desc.lf.lfFaceName), gdiFont->font_desc.lf.lfHeight);
3630     }
3631
3632     TRACE("---------- Unused gdiFont Cache ----------\n");
3633     LIST_FOR_EACH(elem_ptr, &unused_gdi_font_list) {
3634         gdiFont = LIST_ENTRY(elem_ptr, struct tagGdiFont, entry);
3635         TRACE("gdiFont=%p %s %d\n",
3636               gdiFont, debugstr_w(gdiFont->font_desc.lf.lfFaceName), gdiFont->font_desc.lf.lfHeight);
3637     }
3638 }
3639
3640 /*************************************************************
3641  * WineEngDestroyFontInstance
3642  *
3643  * free the gdiFont associated with this handle
3644  *
3645  */
3646 BOOL WineEngDestroyFontInstance(HFONT handle)
3647 {
3648     GdiFont *gdiFont;
3649     HFONTLIST *hflist;
3650     BOOL ret = FALSE;
3651     struct list *font_elem_ptr, *hfontlist_elem_ptr;
3652     int i = 0;
3653
3654     EnterCriticalSection( &freetype_cs );
3655
3656     LIST_FOR_EACH_ENTRY(gdiFont, &child_font_list, struct tagGdiFont, entry)
3657     {
3658         struct list *first_hfont = list_head(&gdiFont->hfontlist);
3659         hflist = LIST_ENTRY(first_hfont, HFONTLIST, entry);
3660         if(hflist->hfont == handle)
3661         {
3662             TRACE("removing child font %p from child list\n", gdiFont);
3663             list_remove(&gdiFont->entry);
3664             LeaveCriticalSection( &freetype_cs );
3665             return TRUE;
3666         }
3667     }
3668
3669     TRACE("destroying hfont=%p\n", handle);
3670     if(TRACE_ON(font))
3671         dump_gdi_font_list();
3672
3673     font_elem_ptr = list_head(&gdi_font_list);
3674     while(font_elem_ptr) {
3675         gdiFont = LIST_ENTRY(font_elem_ptr, struct tagGdiFont, entry);
3676         font_elem_ptr = list_next(&gdi_font_list, font_elem_ptr);
3677
3678         hfontlist_elem_ptr = list_head(&gdiFont->hfontlist);
3679         while(hfontlist_elem_ptr) {
3680             hflist = LIST_ENTRY(hfontlist_elem_ptr, struct tagHFONTLIST, entry);
3681             hfontlist_elem_ptr = list_next(&gdiFont->hfontlist, hfontlist_elem_ptr);
3682             if(hflist->hfont == handle) {
3683                 list_remove(&hflist->entry);
3684                 HeapFree(GetProcessHeap(), 0, hflist);
3685                 ret = TRUE;
3686             }
3687         }
3688         if(list_empty(&gdiFont->hfontlist)) {
3689             TRACE("Moving to Unused list\n");
3690             list_remove(&gdiFont->entry);
3691             list_add_head(&unused_gdi_font_list, &gdiFont->entry);
3692         }
3693     }
3694
3695
3696     font_elem_ptr = list_head(&unused_gdi_font_list);
3697     while(font_elem_ptr && i++ < UNUSED_CACHE_SIZE)
3698         font_elem_ptr = list_next(&unused_gdi_font_list, font_elem_ptr);
3699     while(font_elem_ptr) {
3700         gdiFont = LIST_ENTRY(font_elem_ptr, struct tagGdiFont, entry);
3701         font_elem_ptr = list_next(&unused_gdi_font_list, font_elem_ptr);
3702         TRACE("freeing %p\n", gdiFont);
3703         list_remove(&gdiFont->entry);
3704         free_font(gdiFont);
3705     }
3706     LeaveCriticalSection( &freetype_cs );
3707     return ret;
3708 }
3709
3710 static void GetEnumStructs(Face *face, LPENUMLOGFONTEXW pelf,
3711                            NEWTEXTMETRICEXW *pntm, LPDWORD ptype)
3712 {
3713     GdiFont *font;
3714     LONG width, height;
3715
3716     if (face->cached_enum_data)
3717     {
3718         TRACE("Cached\n");
3719         *pelf = face->cached_enum_data->elf;
3720         *pntm = face->cached_enum_data->ntm;
3721         *ptype = face->cached_enum_data->type;
3722         return;
3723     }
3724
3725     font = alloc_font();
3726
3727     if(face->scalable) {
3728         height = -2048; /* 2048 is the most common em size */
3729         width = 0;
3730     } else {
3731         height = face->size.y_ppem >> 6;
3732         width = face->size.x_ppem >> 6;
3733     }
3734     font->scale_y = 1.0;
3735     
3736     if (!(font->ft_face = OpenFontFace(font, face, width, height)))
3737     {
3738         free_font(font);
3739         return;
3740     }
3741
3742     font->name = strdupW(face->family->FamilyName);
3743     font->ntmFlags = face->ntmFlags;
3744
3745     if (WineEngGetOutlineTextMetrics(font, 0, NULL))
3746     {
3747         memcpy(&pntm->ntmTm, &font->potm->otmTextMetrics, sizeof(TEXTMETRICW));
3748
3749         pntm->ntmTm.ntmSizeEM = font->potm->otmEMSquare;
3750
3751         lstrcpynW(pelf->elfLogFont.lfFaceName,
3752                  (WCHAR*)((char*)font->potm + (ULONG_PTR)font->potm->otmpFamilyName),
3753                  LF_FACESIZE);
3754         lstrcpynW(pelf->elfFullName,
3755                  (WCHAR*)((char*)font->potm + (ULONG_PTR)font->potm->otmpFaceName),
3756                  LF_FULLFACESIZE);
3757         lstrcpynW(pelf->elfStyle,
3758                  (WCHAR*)((char*)font->potm + (ULONG_PTR)font->potm->otmpStyleName),
3759                  LF_FACESIZE);
3760     }
3761     else
3762     {
3763         WineEngGetTextMetrics(font, (TEXTMETRICW *)&pntm->ntmTm);
3764
3765         pntm->ntmTm.ntmSizeEM = pntm->ntmTm.tmHeight - pntm->ntmTm.tmInternalLeading;
3766
3767         lstrcpynW(pelf->elfLogFont.lfFaceName, face->family->FamilyName, LF_FACESIZE);
3768         lstrcpynW(pelf->elfFullName, face->family->FamilyName, LF_FULLFACESIZE);
3769         lstrcpynW(pelf->elfStyle, face->StyleName, LF_FACESIZE);
3770     }
3771
3772     pntm->ntmTm.ntmFlags = face->ntmFlags;
3773     pntm->ntmTm.ntmCellHeight = pntm->ntmTm.tmHeight;
3774     pntm->ntmTm.ntmAvgWidth = pntm->ntmTm.tmAveCharWidth;
3775     pntm->ntmFontSig = face->fs;
3776
3777     pelf->elfScript[0] = '\0'; /* This will get set in WineEngEnumFonts */
3778
3779     pelf->elfLogFont.lfEscapement = 0;
3780     pelf->elfLogFont.lfOrientation = 0;
3781     pelf->elfLogFont.lfHeight = pntm->ntmTm.tmHeight;
3782     pelf->elfLogFont.lfWidth = pntm->ntmTm.tmAveCharWidth;
3783     pelf->elfLogFont.lfWeight = pntm->ntmTm.tmWeight;
3784     pelf->elfLogFont.lfItalic = pntm->ntmTm.tmItalic;
3785     pelf->elfLogFont.lfUnderline = pntm->ntmTm.tmUnderlined;
3786     pelf->elfLogFont.lfStrikeOut = pntm->ntmTm.tmStruckOut;
3787     pelf->elfLogFont.lfCharSet = pntm->ntmTm.tmCharSet;
3788     pelf->elfLogFont.lfOutPrecision = OUT_STROKE_PRECIS;
3789     pelf->elfLogFont.lfClipPrecision = CLIP_STROKE_PRECIS;
3790     pelf->elfLogFont.lfQuality = DRAFT_QUALITY;
3791     pelf->elfLogFont.lfPitchAndFamily = (pntm->ntmTm.tmPitchAndFamily & 0xf1) + 1;
3792
3793     *ptype = 0;
3794     if (pntm->ntmTm.tmPitchAndFamily & TMPF_TRUETYPE)
3795         *ptype |= TRUETYPE_FONTTYPE;
3796     if (pntm->ntmTm.tmPitchAndFamily & TMPF_DEVICE)
3797         *ptype |= DEVICE_FONTTYPE;
3798     if(!(pntm->ntmTm.tmPitchAndFamily & TMPF_VECTOR))
3799         *ptype |= RASTER_FONTTYPE;
3800
3801     face->cached_enum_data = HeapAlloc(GetProcessHeap(), 0, sizeof(*face->cached_enum_data));
3802     if (face->cached_enum_data)
3803     {
3804         face->cached_enum_data->elf = *pelf;
3805         face->cached_enum_data->ntm = *pntm;
3806         face->cached_enum_data->type = *ptype;
3807     }
3808
3809     free_font(font);
3810 }
3811
3812 /*************************************************************
3813  * WineEngEnumFonts
3814  *
3815  */
3816 DWORD WineEngEnumFonts(LPLOGFONTW plf, FONTENUMPROCW proc, LPARAM lparam)
3817 {
3818     Family *family;
3819     Face *face;
3820     struct list *family_elem_ptr, *face_elem_ptr;
3821     ENUMLOGFONTEXW elf;
3822     NEWTEXTMETRICEXW ntm;
3823     DWORD type;
3824     FONTSIGNATURE fs;
3825     CHARSETINFO csi;
3826     LOGFONTW lf;
3827     int i;
3828
3829     if (!plf)
3830     {
3831         lf.lfCharSet = DEFAULT_CHARSET;
3832         lf.lfPitchAndFamily = 0;
3833         lf.lfFaceName[0] = 0;
3834         plf = &lf;
3835     }
3836
3837     TRACE("facename = %s charset %d\n", debugstr_w(plf->lfFaceName), plf->lfCharSet);
3838
3839     EnterCriticalSection( &freetype_cs );
3840     if(plf->lfFaceName[0]) {
3841         FontSubst *psub;
3842         psub = get_font_subst(&font_subst_list, plf->lfFaceName, plf->lfCharSet);
3843
3844         if(psub) {
3845             TRACE("substituting %s -> %s\n", debugstr_w(plf->lfFaceName),
3846                   debugstr_w(psub->to.name));
3847             lf = *plf;
3848             strcpyW(lf.lfFaceName, psub->to.name);
3849             plf = &lf;
3850         }
3851
3852         LIST_FOR_EACH(family_elem_ptr, &font_list) {
3853             family = LIST_ENTRY(family_elem_ptr, Family, entry);
3854             if(!strcmpiW(plf->lfFaceName, family->FamilyName)) {
3855                 LIST_FOR_EACH(face_elem_ptr, &family->faces) {
3856                     face = LIST_ENTRY(face_elem_ptr, Face, entry);
3857                     GetEnumStructs(face, &elf, &ntm, &type);
3858                     for(i = 0; i < 32; i++) {
3859                         if(!face->scalable && face->fs.fsCsb[0] == 0) { /* OEM bitmap */
3860                             elf.elfLogFont.lfCharSet = ntm.ntmTm.tmCharSet = OEM_CHARSET;
3861                             strcpyW(elf.elfScript, OEM_DOSW);
3862                             i = 32; /* break out of loop */
3863                         } else if(!(face->fs.fsCsb[0] & (1L << i)))
3864                             continue;
3865                         else {
3866                             fs.fsCsb[0] = 1L << i;
3867                             fs.fsCsb[1] = 0;
3868                             if(!TranslateCharsetInfo(fs.fsCsb, &csi,
3869                                                      TCI_SRCFONTSIG))
3870                                 csi.ciCharset = DEFAULT_CHARSET;
3871                             if(i == 31) csi.ciCharset = SYMBOL_CHARSET;
3872                             if(csi.ciCharset != DEFAULT_CHARSET) {
3873                                 elf.elfLogFont.lfCharSet =
3874                                     ntm.ntmTm.tmCharSet = csi.ciCharset;
3875                                 if(ElfScriptsW[i])
3876                                     strcpyW(elf.elfScript, ElfScriptsW[i]);
3877                                 else
3878                                     FIXME("Unknown elfscript for bit %d\n", i);
3879                             }
3880                         }
3881                         TRACE("enuming face %s full %s style %s charset %d type %d script %s it %d weight %d ntmflags %08x\n",
3882                               debugstr_w(elf.elfLogFont.lfFaceName),
3883                               debugstr_w(elf.elfFullName), debugstr_w(elf.elfStyle),
3884                               csi.ciCharset, type, debugstr_w(elf.elfScript),
3885                               elf.elfLogFont.lfItalic, elf.elfLogFont.lfWeight,
3886                               ntm.ntmTm.ntmFlags);
3887                         /* release section before callback (FIXME) */
3888                         LeaveCriticalSection( &freetype_cs );
3889                         if (!proc(&elf.elfLogFont, (TEXTMETRICW *)&ntm, type, lparam)) return 0;
3890                         EnterCriticalSection( &freetype_cs );
3891                     }
3892                 }
3893             }
3894         }
3895     } else {
3896         LIST_FOR_EACH(family_elem_ptr, &font_list) {
3897             family = LIST_ENTRY(family_elem_ptr, Family, entry);
3898             face_elem_ptr = list_head(&family->faces);
3899             face = LIST_ENTRY(face_elem_ptr, Face, entry);
3900             GetEnumStructs(face, &elf, &ntm, &type);
3901             for(i = 0; i < 32; i++) {
3902                 if(!face->scalable && face->fs.fsCsb[0] == 0) { /* OEM bitmap */
3903                     elf.elfLogFont.lfCharSet = ntm.ntmTm.tmCharSet = OEM_CHARSET;
3904                     strcpyW(elf.elfScript, OEM_DOSW);
3905                     i = 32; /* break out of loop */
3906                 } else if(!(face->fs.fsCsb[0] & (1L << i)))
3907                     continue;
3908                 else {
3909                     fs.fsCsb[0] = 1L << i;
3910                     fs.fsCsb[1] = 0;
3911                     if(!TranslateCharsetInfo(fs.fsCsb, &csi,
3912                                              TCI_SRCFONTSIG))
3913                         csi.ciCharset = DEFAULT_CHARSET;
3914                     if(i == 31) csi.ciCharset = SYMBOL_CHARSET;
3915                     if(csi.ciCharset != DEFAULT_CHARSET) {
3916                         elf.elfLogFont.lfCharSet = ntm.ntmTm.tmCharSet =
3917                           csi.ciCharset;
3918                           if(ElfScriptsW[i])
3919                               strcpyW(elf.elfScript, ElfScriptsW[i]);
3920                           else
3921                               FIXME("Unknown elfscript for bit %d\n", i);
3922                     }
3923                 }
3924                 TRACE("enuming face %s full %s style %s charset = %d type %d script %s it %d weight %d ntmflags %08x\n",
3925                       debugstr_w(elf.elfLogFont.lfFaceName),
3926                       debugstr_w(elf.elfFullName), debugstr_w(elf.elfStyle),
3927                       csi.ciCharset, type, debugstr_w(elf.elfScript),
3928                       elf.elfLogFont.lfItalic, elf.elfLogFont.lfWeight,
3929                       ntm.ntmTm.ntmFlags);
3930                 /* release section before callback (FIXME) */
3931                 LeaveCriticalSection( &freetype_cs );
3932                 if (!proc(&elf.elfLogFont, (TEXTMETRICW *)&ntm, type, lparam)) return 0;
3933                 EnterCriticalSection( &freetype_cs );
3934             }
3935         }
3936     }
3937     LeaveCriticalSection( &freetype_cs );
3938     return 1;
3939 }
3940
3941 static void FTVectorToPOINTFX(FT_Vector *vec, POINTFX *pt)
3942 {
3943     pt->x.value = vec->x >> 6;
3944     pt->x.fract = (vec->x & 0x3f) << 10;
3945     pt->x.fract |= ((pt->x.fract >> 6) | (pt->x.fract >> 12));
3946     pt->y.value = vec->y >> 6;
3947     pt->y.fract = (vec->y & 0x3f) << 10;
3948     pt->y.fract |= ((pt->y.fract >> 6) | (pt->y.fract >> 12));
3949     return;
3950 }
3951
3952 /***************************************************
3953  * According to the MSDN documentation on WideCharToMultiByte,
3954  * certain codepages cannot set the default_used parameter.
3955  * This returns TRUE if the codepage can set that parameter, false else
3956  * so that calls to WideCharToMultiByte don't fail with ERROR_INVALID_PARAMETER
3957  */
3958 static BOOL codepage_sets_default_used(UINT codepage)
3959 {
3960    switch (codepage)
3961    {
3962        case CP_UTF7:
3963        case CP_UTF8:
3964        case CP_SYMBOL:
3965            return FALSE;
3966        default:
3967            return TRUE;
3968    }
3969 }
3970
3971 /*
3972  * GSUB Table handling functions
3973  */
3974
3975 static INT GSUB_is_glyph_covered(LPCVOID table , UINT glyph)
3976 {
3977     const GSUB_CoverageFormat1* cf1;
3978
3979     cf1 = (GSUB_CoverageFormat1*)table;
3980
3981     if (GET_BE_WORD(cf1->CoverageFormat) == 1)
3982     {
3983         int count = GET_BE_WORD(cf1->GlyphCount);
3984         int i;
3985         TRACE("Coverage Format 1, %i glyphs\n",count);
3986         for (i = 0; i < count; i++)
3987             if (glyph == GET_BE_WORD(cf1->GlyphArray[i]))
3988                 return i;
3989         return -1;
3990     }
3991     else if (GET_BE_WORD(cf1->CoverageFormat) == 2)
3992     {
3993         const GSUB_CoverageFormat2* cf2;
3994         int i;
3995         int count;
3996         cf2 = (GSUB_CoverageFormat2*)cf1;
3997
3998         count = GET_BE_WORD(cf2->RangeCount);
3999         TRACE("Coverage Format 2, %i ranges\n",count);
4000         for (i = 0; i < count; i++)
4001         {
4002             if (glyph < GET_BE_WORD(cf2->RangeRecord[i].Start))
4003                 return -1;
4004             if ((glyph >= GET_BE_WORD(cf2->RangeRecord[i].Start)) &&
4005                 (glyph <= GET_BE_WORD(cf2->RangeRecord[i].End)))
4006             {
4007                 return (GET_BE_WORD(cf2->RangeRecord[i].StartCoverageIndex) +
4008                     glyph - GET_BE_WORD(cf2->RangeRecord[i].Start));
4009             }
4010         }
4011         return -1;
4012     }
4013     else
4014         ERR("Unknown CoverageFormat %i\n",GET_BE_WORD(cf1->CoverageFormat));
4015
4016     return -1;
4017 }
4018
4019 static const GSUB_Script* GSUB_get_script_table( const GSUB_Header* header, const char* tag)
4020 {
4021     const GSUB_ScriptList *script;
4022     const GSUB_Script *deflt = NULL;
4023     int i;
4024     script = (GSUB_ScriptList*)((LPBYTE)header + GET_BE_WORD(header->ScriptList));
4025
4026     TRACE("%i scripts in this font\n",GET_BE_WORD(script->ScriptCount));
4027     for (i = 0; i < GET_BE_WORD(script->ScriptCount); i++)
4028     {
4029         const GSUB_Script *scr;
4030         int offset;
4031
4032         offset = GET_BE_WORD(script->ScriptRecord[i].Script);
4033         scr = (GSUB_Script*)((LPBYTE)script + offset);
4034
4035         if (strncmp(script->ScriptRecord[i].ScriptTag, tag,4)==0)
4036             return scr;
4037         if (strncmp(script->ScriptRecord[i].ScriptTag, "dflt",4)==0)
4038             deflt = scr;
4039     }
4040     return deflt;
4041 }
4042
4043 static const GSUB_LangSys* GSUB_get_lang_table( const GSUB_Script* script, const char* tag)
4044 {
4045     int i;
4046     int offset;
4047     const GSUB_LangSys *Lang;
4048
4049     TRACE("Deflang %x, LangCount %i\n",GET_BE_WORD(script->DefaultLangSys), GET_BE_WORD(script->LangSysCount));
4050
4051     for (i = 0; i < GET_BE_WORD(script->LangSysCount) ; i++)
4052     {
4053         offset = GET_BE_WORD(script->LangSysRecord[i].LangSys);
4054         Lang = (GSUB_LangSys*)((LPBYTE)script + offset);
4055
4056         if ( strncmp(script->LangSysRecord[i].LangSysTag,tag,4)==0)
4057             return Lang;
4058     }
4059     offset = GET_BE_WORD(script->DefaultLangSys);
4060     if (offset)
4061     {
4062         Lang = (GSUB_LangSys*)((LPBYTE)script + offset);
4063         return Lang;
4064     }
4065     return NULL;
4066 }
4067
4068 static const GSUB_Feature * GSUB_get_feature(const GSUB_Header *header, const GSUB_LangSys *lang, const char* tag)
4069 {
4070     int i;
4071     const GSUB_FeatureList *feature;
4072     feature = (GSUB_FeatureList*)((LPBYTE)header + GET_BE_WORD(header->FeatureList));
4073
4074     TRACE("%i features\n",GET_BE_WORD(lang->FeatureCount));
4075     for (i = 0; i < GET_BE_WORD(lang->FeatureCount); i++)
4076     {
4077         int index = GET_BE_WORD(lang->FeatureIndex[i]);
4078         if (strncmp(feature->FeatureRecord[index].FeatureTag,tag,4)==0)
4079         {
4080             const GSUB_Feature *feat;
4081             feat = (GSUB_Feature*)((LPBYTE)feature + GET_BE_WORD(feature->FeatureRecord[index].Feature));
4082             return feat;
4083         }
4084     }
4085     return NULL;
4086 }
4087
4088 static FT_UInt GSUB_apply_feature(const GSUB_Header * header, const GSUB_Feature* feature, UINT glyph)
4089 {
4090     int i;
4091     int offset;
4092     const GSUB_LookupList *lookup;
4093     lookup = (GSUB_LookupList*)((LPBYTE)header + GET_BE_WORD(header->LookupList));
4094
4095     TRACE("%i lookups\n", GET_BE_WORD(feature->LookupCount));
4096     for (i = 0; i < GET_BE_WORD(feature->LookupCount); i++)
4097     {
4098         const GSUB_LookupTable *look;
4099         offset = GET_BE_WORD(lookup->Lookup[GET_BE_WORD(feature->LookupListIndex[i])]);
4100         look = (GSUB_LookupTable*)((LPBYTE)lookup + offset);
4101         TRACE("type %i, flag %x, subtables %i\n",GET_BE_WORD(look->LookupType),GET_BE_WORD(look->LookupFlag),GET_BE_WORD(look->SubTableCount));
4102         if (GET_BE_WORD(look->LookupType) != 1)
4103             FIXME("We only handle SubType 1\n");
4104         else
4105         {
4106             int j;
4107
4108             for (j = 0; j < GET_BE_WORD(look->SubTableCount); j++)
4109             {
4110                 const GSUB_SingleSubstFormat1 *ssf1;
4111                 offset = GET_BE_WORD(look->SubTable[j]);
4112                 ssf1 = (GSUB_SingleSubstFormat1*)((LPBYTE)look+offset);
4113                 if (GET_BE_WORD(ssf1->SubstFormat) == 1)
4114                 {
4115                     int offset = GET_BE_WORD(ssf1->Coverage);
4116                     TRACE("  subtype 1, delta %i\n", GET_BE_WORD(ssf1->DeltaGlyphID));
4117                     if (GSUB_is_glyph_covered((LPBYTE)ssf1+offset, glyph) != -1)
4118                     {
4119                         TRACE("  Glyph 0x%x ->",glyph);
4120                         glyph += GET_BE_WORD(ssf1->DeltaGlyphID);
4121                         TRACE(" 0x%x\n",glyph);
4122                     }
4123                 }
4124                 else
4125                 {
4126                     const GSUB_SingleSubstFormat2 *ssf2;
4127                     INT index;
4128                     INT offset;
4129
4130                     ssf2 = (GSUB_SingleSubstFormat2 *)ssf1;
4131                     offset = GET_BE_WORD(ssf1->Coverage);
4132                     TRACE("  subtype 2,  glyph count %i\n", GET_BE_WORD(ssf2->GlyphCount));
4133                     index = GSUB_is_glyph_covered((LPBYTE)ssf2+offset, glyph);
4134                     TRACE("  Coverage index %i\n",index);
4135                     if (index != -1)
4136                     {
4137                         TRACE("    Glyph is 0x%x ->",glyph);
4138                         glyph = GET_BE_WORD(ssf2->Substitute[index]);
4139                         TRACE("0x%x\n",glyph);
4140                     }
4141                 }
4142             }
4143         }
4144     }
4145     return glyph;
4146 }
4147
4148 static const char* get_opentype_script(const GdiFont *font)
4149 {
4150     /*
4151      * I am not sure if this is the correct way to generate our script tag
4152      */
4153
4154     switch (font->charset)
4155     {
4156         case ANSI_CHARSET: return "latn";
4157         case BALTIC_CHARSET: return "latn"; /* ?? */
4158         case CHINESEBIG5_CHARSET: return "hani";
4159         case EASTEUROPE_CHARSET: return "latn"; /* ?? */
4160         case GB2312_CHARSET: return "hani";
4161         case GREEK_CHARSET: return "grek";
4162         case HANGUL_CHARSET: return "hang";
4163         case RUSSIAN_CHARSET: return "cyrl";
4164         case SHIFTJIS_CHARSET: return "kana";
4165         case TURKISH_CHARSET: return "latn"; /* ?? */
4166         case VIETNAMESE_CHARSET: return "latn";
4167         case JOHAB_CHARSET: return "latn"; /* ?? */
4168         case ARABIC_CHARSET: return "arab";
4169         case HEBREW_CHARSET: return "hebr";
4170         case THAI_CHARSET: return "thai";
4171         default: return "latn";
4172     }
4173 }
4174
4175 static FT_UInt get_GSUB_vert_glyph(const GdiFont *font, UINT glyph)
4176 {
4177     const GSUB_Header *header;
4178     const GSUB_Script *script;
4179     const GSUB_LangSys *language;
4180     const GSUB_Feature *feature;
4181
4182     if (!font->GSUB_Table)
4183         return glyph;
4184
4185     header = font->GSUB_Table;
4186
4187     script = GSUB_get_script_table(header, get_opentype_script(font));
4188     if (!script)
4189     {
4190         TRACE("Script not found\n");
4191         return glyph;
4192     }
4193     language = GSUB_get_lang_table(script, "xxxx"); /* Need to get Lang tag */
4194     if (!language)
4195     {
4196         TRACE("Language not found\n");
4197         return glyph;
4198     }
4199     feature  =  GSUB_get_feature(header, language, "vrt2");
4200     if (!feature)
4201         feature  =  GSUB_get_feature(header, language, "vert");
4202     if (!feature)
4203     {
4204         TRACE("vrt2/vert feature not found\n");
4205         return glyph;
4206     }
4207     return GSUB_apply_feature(header, feature, glyph);
4208 }
4209
4210 static FT_UInt get_glyph_index(const GdiFont *font, UINT glyph)
4211 {
4212     FT_UInt glyphId;
4213
4214     if(font->ft_face->charmap->encoding == FT_ENCODING_NONE) {
4215         WCHAR wc = (WCHAR)glyph;
4216         BOOL default_used;
4217         BOOL *default_used_pointer;
4218         FT_UInt ret;
4219         char buf;
4220         default_used_pointer = NULL;
4221         default_used = FALSE;
4222         if (codepage_sets_default_used(font->codepage))
4223             default_used_pointer = &default_used;
4224         if(!WideCharToMultiByte(font->codepage, 0, &wc, 1, &buf, sizeof(buf), NULL, default_used_pointer) || default_used)
4225             ret = 0;
4226         else
4227             ret = pFT_Get_Char_Index(font->ft_face, (unsigned char)buf);
4228         TRACE("%04x (%02x) -> ret %d def_used %d\n", glyph, buf, ret, default_used);
4229         return get_GSUB_vert_glyph(font,ret);
4230     }
4231
4232     if(font->ft_face->charmap->encoding == FT_ENCODING_MS_SYMBOL && glyph < 0x100)
4233         glyph = glyph + 0xf000;
4234     glyphId = pFT_Get_Char_Index(font->ft_face, glyph);
4235     return get_GSUB_vert_glyph(font,glyphId);
4236 }
4237
4238 /*************************************************************
4239  * WineEngGetGlyphIndices
4240  *
4241  */
4242 DWORD WineEngGetGlyphIndices(GdiFont *font, LPCWSTR lpstr, INT count,
4243                                 LPWORD pgi, DWORD flags)
4244 {
4245     int i;
4246     int default_char = -1;
4247
4248     if  (flags & GGI_MARK_NONEXISTING_GLYPHS) default_char = 0xffff;  /* XP would use 0x1f for bitmap fonts */
4249
4250     for(i = 0; i < count; i++)
4251     {
4252         pgi[i] = get_glyph_index(font, lpstr[i]);
4253         if  (pgi[i] == 0)
4254         {
4255             if (default_char == -1)
4256             {
4257                 if (FT_IS_SFNT(font->ft_face))
4258                 {
4259                     TT_OS2 *pOS2 = pFT_Get_Sfnt_Table(font->ft_face, ft_sfnt_os2);
4260                     default_char = (pOS2->usDefaultChar ? get_glyph_index(font, pOS2->usDefaultChar) : 0);
4261                 }
4262                 else
4263                 {
4264                     TEXTMETRICW textm;
4265                     WineEngGetTextMetrics(font, &textm);
4266                     default_char = textm.tmDefaultChar;
4267                 }
4268             }
4269             pgi[i] = default_char;
4270         }
4271     }
4272     return count;
4273 }
4274
4275 static inline BOOL is_identity_FMAT2(const FMAT2 *matrix)
4276 {
4277     static const FMAT2 identity = { 1.0, 0.0, 0.0, 1.0 };
4278     return !memcmp(matrix, &identity, sizeof(FMAT2));
4279 }
4280
4281 static inline BOOL is_identity_MAT2(const MAT2 *matrix)
4282 {
4283     static const MAT2 identity = { {0,1}, {0,0}, {0,0}, {0,1} };
4284     return !memcmp(matrix, &identity, sizeof(MAT2));
4285 }
4286
4287 /*************************************************************
4288  * WineEngGetGlyphOutline
4289  *
4290  * Behaves in exactly the same way as the win32 api GetGlyphOutline
4291  * except that the first parameter is the HWINEENGFONT of the font in
4292  * question rather than an HDC.
4293  *
4294  */
4295 DWORD WineEngGetGlyphOutline(GdiFont *incoming_font, UINT glyph, UINT format,
4296                              LPGLYPHMETRICS lpgm, DWORD buflen, LPVOID buf,
4297                              const MAT2* lpmat)
4298 {
4299     static const FT_Matrix identityMat = {(1 << 16), 0, 0, (1 << 16)};
4300     FT_Face ft_face = incoming_font->ft_face;
4301     GdiFont *font = incoming_font;
4302     FT_UInt glyph_index;
4303     DWORD width, height, pitch, needed = 0;
4304     FT_Bitmap ft_bitmap;
4305     FT_Error err;
4306     INT left, right, top = 0, bottom = 0, adv, lsb, bbx;
4307     FT_Angle angle = 0;
4308     FT_Int load_flags = FT_LOAD_DEFAULT | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
4309     double widthRatio = 1.0;
4310     FT_Matrix transMat = identityMat;
4311     FT_Matrix transMatUnrotated;
4312     BOOL needsTransform = FALSE;
4313     BOOL tategaki = (font->GSUB_Table != NULL);
4314     UINT original_index;
4315
4316     TRACE("%p, %04x, %08x, %p, %08x, %p, %p\n", font, glyph, format, lpgm,
4317           buflen, buf, lpmat);
4318
4319     TRACE("font transform %f %f %f %f\n",
4320           font->font_desc.matrix.eM11, font->font_desc.matrix.eM12,
4321           font->font_desc.matrix.eM21, font->font_desc.matrix.eM22);
4322
4323     EnterCriticalSection( &freetype_cs );
4324
4325     if(format & GGO_GLYPH_INDEX) {
4326         glyph_index = get_GSUB_vert_glyph(incoming_font,glyph);
4327         original_index = glyph;
4328         format &= ~GGO_GLYPH_INDEX;
4329     } else {
4330         get_glyph_index_linked(incoming_font, glyph, &font, &glyph_index);
4331         ft_face = font->ft_face;
4332         original_index = glyph_index;
4333     }
4334
4335     /* tategaki never appears to happen to lower glyph index */
4336     if (glyph_index < TATEGAKI_LOWER_BOUND )
4337         tategaki = FALSE;
4338
4339     if(original_index >= font->gmsize * GM_BLOCK_SIZE) {
4340         font->gmsize = (original_index / GM_BLOCK_SIZE + 1);
4341         font->gm = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, font->gm,
4342                                font->gmsize * sizeof(GM*));
4343     } else {
4344         if (format == GGO_METRICS && font->gm[original_index / GM_BLOCK_SIZE] != NULL &&
4345             FONT_GM(font,original_index)->init && (!lpmat || is_identity_MAT2(lpmat)))
4346         {
4347             *lpgm = FONT_GM(font,original_index)->gm;
4348             TRACE("cached: %u,%u,%s,%d,%d\n", lpgm->gmBlackBoxX, lpgm->gmBlackBoxY,
4349                   wine_dbgstr_point(&lpgm->gmptGlyphOrigin),
4350                   lpgm->gmCellIncX, lpgm->gmCellIncY);
4351             LeaveCriticalSection( &freetype_cs );
4352             return 1; /* FIXME */
4353         }
4354     }
4355
4356     if (!font->gm[original_index / GM_BLOCK_SIZE])
4357         font->gm[original_index / GM_BLOCK_SIZE] = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, sizeof(GM) * GM_BLOCK_SIZE);
4358
4359     if(font->orientation || (format != GGO_METRICS && format != GGO_BITMAP && format != WINE_GGO_GRAY16_BITMAP) || lpmat)
4360         load_flags |= FT_LOAD_NO_BITMAP;
4361
4362     err = pFT_Load_Glyph(ft_face, glyph_index, load_flags);
4363
4364     if(err) {
4365         WARN("FT_Load_Glyph on index %x returns %d\n", glyph_index, err);
4366         LeaveCriticalSection( &freetype_cs );
4367         return GDI_ERROR;
4368     }
4369         
4370     /* Scaling factor */
4371     if (font->aveWidth)
4372     {
4373         TEXTMETRICW tm;
4374
4375         WineEngGetTextMetrics(font, &tm);
4376
4377         widthRatio = (double)font->aveWidth;
4378         widthRatio /= (double)font->potm->otmTextMetrics.tmAveCharWidth;
4379     }
4380     else
4381         widthRatio = font->scale_y;
4382
4383     left = (INT)(ft_face->glyph->metrics.horiBearingX) & -64;
4384     right = (INT)((ft_face->glyph->metrics.horiBearingX + ft_face->glyph->metrics.width) + 63) & -64;
4385
4386     adv = (INT)((ft_face->glyph->metrics.horiAdvance) + 63) >> 6;
4387     lsb = left >> 6;
4388     bbx = (right - left) >> 6;
4389
4390     /* Scaling transform */
4391     if (widthRatio != 1.0 || font->scale_y != 1.0)
4392     {
4393         FT_Matrix scaleMat;
4394         scaleMat.xx = FT_FixedFromFloat(widthRatio);
4395         scaleMat.xy = 0;
4396         scaleMat.yx = 0;
4397         scaleMat.yy = FT_FixedFromFloat(font->scale_y);
4398
4399         pFT_Matrix_Multiply(&scaleMat, &transMat);
4400         needsTransform = TRUE;
4401     }
4402
4403     /* Slant transform */
4404     if (font->fake_italic) {
4405         FT_Matrix slantMat;
4406         
4407         slantMat.xx = (1 << 16);
4408         slantMat.xy = ((1 << 16) >> 2);
4409         slantMat.yx = 0;
4410         slantMat.yy = (1 << 16);
4411         pFT_Matrix_Multiply(&slantMat, &transMat);
4412         needsTransform = TRUE;
4413     }
4414
4415     /* Rotation transform */
4416     transMatUnrotated = transMat;
4417     if(font->orientation && !tategaki) {
4418         FT_Matrix rotationMat;
4419         FT_Vector vecAngle;
4420         angle = FT_FixedFromFloat((double)font->orientation / 10.0);
4421         pFT_Vector_Unit(&vecAngle, angle);
4422         rotationMat.xx = vecAngle.x;
4423         rotationMat.xy = -vecAngle.y;
4424         rotationMat.yx = -rotationMat.xy;
4425         rotationMat.yy = rotationMat.xx;
4426         
4427         pFT_Matrix_Multiply(&rotationMat, &transMat);
4428         needsTransform = TRUE;
4429     }
4430
4431     /* World transform */
4432     if (!is_identity_FMAT2(&font->font_desc.matrix))
4433     {
4434         FT_Matrix worldMat;
4435         worldMat.xx = FT_FixedFromFloat(font->font_desc.matrix.eM11);
4436         worldMat.xy = FT_FixedFromFloat(font->font_desc.matrix.eM21);
4437         worldMat.yx = FT_FixedFromFloat(font->font_desc.matrix.eM12);
4438         worldMat.yy = FT_FixedFromFloat(font->font_desc.matrix.eM22);
4439         pFT_Matrix_Multiply(&worldMat, &transMat);
4440         pFT_Matrix_Multiply(&worldMat, &transMatUnrotated);
4441         needsTransform = TRUE;
4442     }
4443
4444     /* Extra transformation specified by caller */
4445     if (lpmat && !is_identity_MAT2(lpmat))
4446     {
4447         FT_Matrix extraMat;
4448         extraMat.xx = FT_FixedFromFIXED(lpmat->eM11);
4449         extraMat.xy = FT_FixedFromFIXED(lpmat->eM21);
4450         extraMat.yx = FT_FixedFromFIXED(lpmat->eM12);
4451         extraMat.yy = FT_FixedFromFIXED(lpmat->eM22);
4452         pFT_Matrix_Multiply(&extraMat, &transMat);
4453         pFT_Matrix_Multiply(&extraMat, &transMatUnrotated);
4454         needsTransform = TRUE;
4455     }
4456
4457     if(!needsTransform) {
4458         top = (ft_face->glyph->metrics.horiBearingY + 63) & -64;
4459         bottom = (ft_face->glyph->metrics.horiBearingY -
4460                   ft_face->glyph->metrics.height) & -64;
4461         lpgm->gmCellIncX = adv;
4462         lpgm->gmCellIncY = 0;
4463     } else {
4464         INT xc, yc;
4465         FT_Vector vec;
4466         for(xc = 0; xc < 2; xc++) {
4467             for(yc = 0; yc < 2; yc++) {
4468                 vec.x = (ft_face->glyph->metrics.horiBearingX +
4469                   xc * ft_face->glyph->metrics.width);
4470                 vec.y = ft_face->glyph->metrics.horiBearingY -
4471                   yc * ft_face->glyph->metrics.height;
4472                 TRACE("Vec %ld,%ld\n", vec.x, vec.y);
4473                 pFT_Vector_Transform(&vec, &transMat);
4474                 if(xc == 0 && yc == 0) {
4475                     left = right = vec.x;
4476                     top = bottom = vec.y;
4477                 } else {
4478                     if(vec.x < left) left = vec.x;
4479                     else if(vec.x > right) right = vec.x;
4480                     if(vec.y < bottom) bottom = vec.y;
4481                     else if(vec.y > top) top = vec.y;
4482                 }
4483             }
4484         }
4485         left = left & -64;
4486         right = (right + 63) & -64;
4487         bottom = bottom & -64;
4488         top = (top + 63) & -64;
4489
4490         TRACE("transformed box: (%d,%d - %d,%d)\n", left, top, right, bottom);
4491         vec.x = ft_face->glyph->metrics.horiAdvance;
4492         vec.y = 0;
4493         pFT_Vector_Transform(&vec, &transMat);
4494         lpgm->gmCellIncX = (vec.x+63) >> 6;
4495         lpgm->gmCellIncY = -((vec.y+63) >> 6);
4496
4497         vec.x = ft_face->glyph->metrics.horiAdvance;
4498         vec.y = 0;
4499         pFT_Vector_Transform(&vec, &transMatUnrotated);
4500         adv = (vec.x+63) >> 6;
4501     }
4502     lpgm->gmBlackBoxX = (right - left) >> 6;
4503     lpgm->gmBlackBoxY = (top - bottom) >> 6;
4504     lpgm->gmptGlyphOrigin.x = left >> 6;
4505     lpgm->gmptGlyphOrigin.y = top >> 6;
4506
4507     TRACE("%u,%u,%s,%d,%d\n", lpgm->gmBlackBoxX, lpgm->gmBlackBoxY,
4508           wine_dbgstr_point(&lpgm->gmptGlyphOrigin),
4509           lpgm->gmCellIncX, lpgm->gmCellIncY);
4510
4511     if ((format == GGO_METRICS || format == GGO_BITMAP || format ==  WINE_GGO_GRAY16_BITMAP) &&
4512         (!lpmat || is_identity_MAT2(lpmat))) /* don't cache custom transforms */
4513     {
4514         FONT_GM(font,original_index)->gm = *lpgm;
4515         FONT_GM(font,original_index)->adv = adv;
4516         FONT_GM(font,original_index)->lsb = lsb;
4517         FONT_GM(font,original_index)->bbx = bbx;
4518         FONT_GM(font,original_index)->init = TRUE;
4519     }
4520
4521     if(format == GGO_METRICS)
4522     {
4523         LeaveCriticalSection( &freetype_cs );
4524         return 1; /* FIXME */
4525     }
4526
4527     if(ft_face->glyph->format != ft_glyph_format_outline && format != GGO_BITMAP && format != WINE_GGO_GRAY16_BITMAP) {
4528         TRACE("loaded a bitmap\n");
4529         LeaveCriticalSection( &freetype_cs );
4530         return GDI_ERROR;
4531     }
4532
4533     switch(format) {
4534     case GGO_BITMAP:
4535         width = lpgm->gmBlackBoxX;
4536         height = lpgm->gmBlackBoxY;
4537         pitch = ((width + 31) >> 5) << 2;
4538         needed = pitch * height;
4539
4540         if(!buf || !buflen) break;
4541
4542         switch(ft_face->glyph->format) {
4543         case ft_glyph_format_bitmap:
4544           {
4545             BYTE *src = ft_face->glyph->bitmap.buffer, *dst = buf;
4546             INT w = (ft_face->glyph->bitmap.width + 7) >> 3;
4547             INT h = ft_face->glyph->bitmap.rows;
4548             while(h--) {
4549                 memcpy(dst, src, w);
4550                 src += ft_face->glyph->bitmap.pitch;
4551                 dst += pitch;
4552             }
4553             break;
4554           }
4555
4556         case ft_glyph_format_outline:
4557             ft_bitmap.width = width;
4558             ft_bitmap.rows = height;
4559             ft_bitmap.pitch = pitch;
4560             ft_bitmap.pixel_mode = ft_pixel_mode_mono;
4561             ft_bitmap.buffer = buf;
4562
4563                 if(needsTransform) {
4564                         pFT_Outline_Transform(&ft_face->glyph->outline, &transMat);
4565             }
4566
4567             pFT_Outline_Translate(&ft_face->glyph->outline, -left, -bottom );
4568
4569             /* Note: FreeType will only set 'black' bits for us. */
4570             memset(buf, 0, needed);
4571             pFT_Outline_Get_Bitmap(library, &ft_face->glyph->outline, &ft_bitmap);
4572             break;
4573
4574         default:
4575             FIXME("loaded glyph format %x\n", ft_face->glyph->format);
4576             LeaveCriticalSection( &freetype_cs );
4577             return GDI_ERROR;
4578         }
4579         break;
4580
4581     case GGO_GRAY2_BITMAP:
4582     case GGO_GRAY4_BITMAP:
4583     case GGO_GRAY8_BITMAP:
4584     case WINE_GGO_GRAY16_BITMAP:
4585       {
4586         unsigned int mult, row, col;
4587         BYTE *start, *ptr;
4588
4589         width = lpgm->gmBlackBoxX;
4590         height = lpgm->gmBlackBoxY;
4591         pitch = (width + 3) / 4 * 4;
4592         needed = pitch * height;
4593
4594         if(!buf || !buflen) break;
4595
4596         switch(ft_face->glyph->format) {
4597         case ft_glyph_format_bitmap:
4598           {
4599             BYTE *src = ft_face->glyph->bitmap.buffer, *dst = buf;
4600             INT h = ft_face->glyph->bitmap.rows;
4601             INT x;
4602             while(h--) {
4603                 for(x = 0; x < pitch; x++)
4604                 {
4605                     if(x < ft_face->glyph->bitmap.width)
4606                         dst[x] = (src[x / 8] & (1 << ( (7 - (x % 8))))) ? 0xff : 0;
4607                     else
4608                         dst[x] = 0;
4609                 }
4610                 src += ft_face->glyph->bitmap.pitch;
4611                 dst += pitch;
4612             }
4613             LeaveCriticalSection( &freetype_cs );
4614             return needed;
4615           }
4616         case ft_glyph_format_outline:
4617           {
4618             ft_bitmap.width = width;
4619             ft_bitmap.rows = height;
4620             ft_bitmap.pitch = pitch;
4621             ft_bitmap.pixel_mode = ft_pixel_mode_grays;
4622             ft_bitmap.buffer = buf;
4623
4624             if(needsTransform)
4625                 pFT_Outline_Transform(&ft_face->glyph->outline, &transMat);
4626
4627             pFT_Outline_Translate(&ft_face->glyph->outline, -left, -bottom );
4628
4629             memset(ft_bitmap.buffer, 0, buflen);
4630
4631             pFT_Outline_Get_Bitmap(library, &ft_face->glyph->outline, &ft_bitmap);
4632
4633             if(format == GGO_GRAY2_BITMAP)
4634                 mult = 4;
4635             else if(format == GGO_GRAY4_BITMAP)
4636                 mult = 16;
4637             else if(format == GGO_GRAY8_BITMAP)
4638                 mult = 64;
4639             else /* format == WINE_GGO_GRAY16_BITMAP */
4640             {
4641                 LeaveCriticalSection( &freetype_cs );
4642                 return needed;
4643             }
4644             break;
4645           }
4646         default:
4647             FIXME("loaded glyph format %x\n", ft_face->glyph->format);
4648             LeaveCriticalSection( &freetype_cs );
4649             return GDI_ERROR;
4650         }
4651
4652         start = buf;
4653         for(row = 0; row < height; row++) {
4654             ptr = start;
4655             for(col = 0; col < width; col++, ptr++) {
4656                 *ptr = (((int)*ptr) * mult + 128) / 256;
4657             }
4658             start += pitch;
4659         }
4660         break;
4661       }
4662
4663     case GGO_NATIVE:
4664       {
4665         int contour, point = 0, first_pt;
4666         FT_Outline *outline = &ft_face->glyph->outline;
4667         TTPOLYGONHEADER *pph;
4668         TTPOLYCURVE *ppc;
4669         DWORD pph_start, cpfx, type;
4670
4671         if(buflen == 0) buf = NULL;
4672
4673         if (needsTransform && buf) {
4674                 pFT_Outline_Transform(outline, &transMat);
4675         }
4676
4677         for(contour = 0; contour < outline->n_contours; contour++) {
4678             pph_start = needed;
4679             pph = (TTPOLYGONHEADER *)((char *)buf + needed);
4680             first_pt = point;
4681             if(buf) {
4682                 pph->dwType = TT_POLYGON_TYPE;
4683                 FTVectorToPOINTFX(&outline->points[point], &pph->pfxStart);
4684             }
4685             needed += sizeof(*pph);
4686             point++;
4687             while(point <= outline->contours[contour]) {
4688                 ppc = (TTPOLYCURVE *)((char *)buf + needed);
4689                 type = (outline->tags[point] & FT_Curve_Tag_On) ?
4690                   TT_PRIM_LINE : TT_PRIM_QSPLINE;
4691                 cpfx = 0;
4692                 do {
4693                     if(buf)
4694                         FTVectorToPOINTFX(&outline->points[point], &ppc->apfx[cpfx]);
4695                     cpfx++;
4696                     point++;
4697                 } while(point <= outline->contours[contour] &&
4698                         (outline->tags[point] & FT_Curve_Tag_On) ==
4699                         (outline->tags[point-1] & FT_Curve_Tag_On));
4700                 /* At the end of a contour Windows adds the start point, but
4701                    only for Beziers */
4702                 if(point > outline->contours[contour] &&
4703                    !(outline->tags[point-1] & FT_Curve_Tag_On)) {
4704                     if(buf)
4705                         FTVectorToPOINTFX(&outline->points[first_pt], &ppc->apfx[cpfx]);
4706                     cpfx++;
4707                 } else if(point <= outline->contours[contour] &&
4708                           outline->tags[point] & FT_Curve_Tag_On) {
4709                   /* add closing pt for bezier */
4710                     if(buf)
4711                         FTVectorToPOINTFX(&outline->points[point], &ppc->apfx[cpfx]);
4712                     cpfx++;
4713                     point++;
4714                 }
4715                 if(buf) {
4716                     ppc->wType = type;
4717                     ppc->cpfx = cpfx;
4718                 }
4719                 needed += sizeof(*ppc) + (cpfx - 1) * sizeof(POINTFX);
4720             }
4721             if(buf)
4722                 pph->cb = needed - pph_start;
4723         }
4724         break;
4725       }
4726     case GGO_BEZIER:
4727       {
4728         /* Convert the quadratic Beziers to cubic Beziers.
4729            The parametric eqn for a cubic Bezier is, from PLRM:
4730            r(t) = at^3 + bt^2 + ct + r0
4731            with the control points:
4732            r1 = r0 + c/3
4733            r2 = r1 + (c + b)/3
4734            r3 = r0 + c + b + a
4735
4736            A quadratic Beizer has the form:
4737            p(t) = (1-t)^2 p0 + 2(1-t)t p1 + t^2 p2
4738
4739            So equating powers of t leads to:
4740            r1 = 2/3 p1 + 1/3 p0
4741            r2 = 2/3 p1 + 1/3 p2
4742            and of course r0 = p0, r3 = p2
4743         */
4744
4745         int contour, point = 0, first_pt;
4746         FT_Outline *outline = &ft_face->glyph->outline;
4747         TTPOLYGONHEADER *pph;
4748         TTPOLYCURVE *ppc;
4749         DWORD pph_start, cpfx, type;
4750         FT_Vector cubic_control[4];
4751         if(buflen == 0) buf = NULL;
4752
4753         if (needsTransform && buf) {
4754                 pFT_Outline_Transform(outline, &transMat);
4755         }
4756
4757         for(contour = 0; contour < outline->n_contours; contour++) {
4758             pph_start = needed;
4759             pph = (TTPOLYGONHEADER *)((char *)buf + needed);
4760             first_pt = point;
4761             if(buf) {
4762                 pph->dwType = TT_POLYGON_TYPE;
4763                 FTVectorToPOINTFX(&outline->points[point], &pph->pfxStart);
4764             }
4765             needed += sizeof(*pph);
4766             point++;
4767             while(point <= outline->contours[contour]) {
4768                 ppc = (TTPOLYCURVE *)((char *)buf + needed);
4769                 type = (outline->tags[point] & FT_Curve_Tag_On) ?
4770                   TT_PRIM_LINE : TT_PRIM_CSPLINE;
4771                 cpfx = 0;
4772                 do {
4773                     if(type == TT_PRIM_LINE) {
4774                         if(buf)
4775                             FTVectorToPOINTFX(&outline->points[point], &ppc->apfx[cpfx]);
4776                         cpfx++;
4777                         point++;
4778                     } else {
4779                       /* Unlike QSPLINEs, CSPLINEs always have their endpoint
4780                          so cpfx = 3n */
4781
4782                       /* FIXME: Possible optimization in endpoint calculation
4783                          if there are two consecutive curves */
4784                         cubic_control[0] = outline->points[point-1];
4785                         if(!(outline->tags[point-1] & FT_Curve_Tag_On)) {
4786                             cubic_control[0].x += outline->points[point].x + 1;
4787                             cubic_control[0].y += outline->points[point].y + 1;
4788                             cubic_control[0].x >>= 1;
4789                             cubic_control[0].y >>= 1;
4790                         }
4791                         if(point+1 > outline->contours[contour])
4792                             cubic_control[3] = outline->points[first_pt];
4793                         else {
4794                             cubic_control[3] = outline->points[point+1];
4795                             if(!(outline->tags[point+1] & FT_Curve_Tag_On)) {
4796                                 cubic_control[3].x += outline->points[point].x + 1;
4797                                 cubic_control[3].y += outline->points[point].y + 1;
4798                                 cubic_control[3].x >>= 1;
4799                                 cubic_control[3].y >>= 1;
4800                             }
4801                         }
4802                         /* r1 = 1/3 p0 + 2/3 p1
4803                            r2 = 1/3 p2 + 2/3 p1 */
4804                         cubic_control[1].x = (2 * outline->points[point].x + 1) / 3;
4805                         cubic_control[1].y = (2 * outline->points[point].y + 1) / 3;
4806                         cubic_control[2] = cubic_control[1];
4807                         cubic_control[1].x += (cubic_control[0].x + 1) / 3;
4808                         cubic_control[1].y += (cubic_control[0].y + 1) / 3;
4809                         cubic_control[2].x += (cubic_control[3].x + 1) / 3;
4810                         cubic_control[2].y += (cubic_control[3].y + 1) / 3;
4811                         if(buf) {
4812                             FTVectorToPOINTFX(&cubic_control[1], &ppc->apfx[cpfx]);
4813                             FTVectorToPOINTFX(&cubic_control[2], &ppc->apfx[cpfx+1]);
4814                             FTVectorToPOINTFX(&cubic_control[3], &ppc->apfx[cpfx+2]);
4815                         }
4816                         cpfx += 3;
4817                         point++;
4818                     }
4819                 } while(point <= outline->contours[contour] &&
4820                         (outline->tags[point] & FT_Curve_Tag_On) ==
4821                         (outline->tags[point-1] & FT_Curve_Tag_On));
4822                 /* At the end of a contour Windows adds the start point,
4823                    but only for Beziers and we've already done that.
4824                 */
4825                 if(point <= outline->contours[contour] &&
4826                    outline->tags[point] & FT_Curve_Tag_On) {
4827                   /* This is the closing pt of a bezier, but we've already
4828                      added it, so just inc point and carry on */
4829                     point++;
4830                 }
4831                 if(buf) {
4832                     ppc->wType = type;
4833                     ppc->cpfx = cpfx;
4834                 }
4835                 needed += sizeof(*ppc) + (cpfx - 1) * sizeof(POINTFX);
4836             }
4837             if(buf)
4838                 pph->cb = needed - pph_start;
4839         }
4840         break;
4841       }
4842
4843     default:
4844         FIXME("Unsupported format %d\n", format);
4845         LeaveCriticalSection( &freetype_cs );
4846         return GDI_ERROR;
4847     }
4848     LeaveCriticalSection( &freetype_cs );
4849     return needed;
4850 }
4851
4852 static BOOL get_bitmap_text_metrics(GdiFont *font)
4853 {
4854     FT_Face ft_face = font->ft_face;
4855 #ifdef HAVE_FREETYPE_FTWINFNT_H
4856     FT_WinFNT_HeaderRec winfnt_header;
4857 #endif
4858     const DWORD size = offsetof(OUTLINETEXTMETRICW, otmFiller); 
4859     font->potm = HeapAlloc(GetProcessHeap(), 0, size);
4860     font->potm->otmSize = size;
4861
4862 #define TM font->potm->otmTextMetrics
4863 #ifdef HAVE_FREETYPE_FTWINFNT_H
4864     if(pFT_Get_WinFNT_Header && !pFT_Get_WinFNT_Header(ft_face, &winfnt_header))
4865     {
4866         TM.tmHeight = winfnt_header.pixel_height;
4867         TM.tmAscent = winfnt_header.ascent;
4868         TM.tmDescent = TM.tmHeight - TM.tmAscent;
4869         TM.tmInternalLeading = winfnt_header.internal_leading;
4870         TM.tmExternalLeading = winfnt_header.external_leading;
4871         TM.tmAveCharWidth = winfnt_header.avg_width;
4872         TM.tmMaxCharWidth = winfnt_header.max_width;
4873         TM.tmWeight = winfnt_header.weight;
4874         TM.tmOverhang = 0;
4875         TM.tmDigitizedAspectX = winfnt_header.horizontal_resolution;
4876         TM.tmDigitizedAspectY = winfnt_header.vertical_resolution;
4877         TM.tmFirstChar = winfnt_header.first_char;
4878         TM.tmLastChar = winfnt_header.last_char;
4879         TM.tmDefaultChar = winfnt_header.default_char + winfnt_header.first_char;
4880         TM.tmBreakChar = winfnt_header.break_char + winfnt_header.first_char;
4881         TM.tmItalic = winfnt_header.italic;
4882         TM.tmUnderlined = font->underline;
4883         TM.tmStruckOut = font->strikeout;
4884         TM.tmPitchAndFamily = winfnt_header.pitch_and_family;
4885         TM.tmCharSet = winfnt_header.charset;
4886     }
4887     else
4888 #endif
4889     {
4890         TM.tmAscent = ft_face->size->metrics.ascender >> 6;
4891         TM.tmDescent = -ft_face->size->metrics.descender >> 6;
4892         TM.tmHeight = TM.tmAscent + TM.tmDescent;
4893         TM.tmInternalLeading = TM.tmHeight - ft_face->size->metrics.y_ppem;
4894         TM.tmExternalLeading = (ft_face->size->metrics.height >> 6) - TM.tmHeight;
4895         TM.tmMaxCharWidth = ft_face->size->metrics.max_advance >> 6;
4896         TM.tmAveCharWidth = TM.tmMaxCharWidth * 2 / 3; /* FIXME */
4897         TM.tmWeight = ft_face->style_flags & FT_STYLE_FLAG_BOLD ? FW_BOLD : FW_NORMAL;
4898         TM.tmOverhang = 0;
4899         TM.tmDigitizedAspectX = 96; /* FIXME */
4900         TM.tmDigitizedAspectY = 96; /* FIXME */
4901         TM.tmFirstChar = 1;
4902         TM.tmLastChar = 255;
4903         TM.tmDefaultChar = 32;
4904         TM.tmBreakChar = 32;
4905         TM.tmItalic = ft_face->style_flags & FT_STYLE_FLAG_ITALIC ? 1 : 0;
4906         TM.tmUnderlined = font->underline;
4907         TM.tmStruckOut = font->strikeout;
4908         /* NB inverted meaning of TMPF_FIXED_PITCH */
4909         TM.tmPitchAndFamily = ft_face->face_flags & FT_FACE_FLAG_FIXED_WIDTH ? 0 : TMPF_FIXED_PITCH;
4910         TM.tmCharSet = font->charset;
4911     }
4912 #undef TM
4913
4914     return TRUE;
4915 }
4916
4917
4918 static void scale_font_metrics(const GdiFont *font, LPTEXTMETRICW ptm)
4919 {
4920     double scale_x, scale_y;
4921
4922     if (font->aveWidth)
4923     {
4924         scale_x = (double)font->aveWidth;
4925         scale_x /= (double)font->potm->otmTextMetrics.tmAveCharWidth;
4926     }
4927     else
4928         scale_x = font->scale_y;
4929
4930     scale_x *= fabs(font->font_desc.matrix.eM11);
4931     scale_y = font->scale_y * fabs(font->font_desc.matrix.eM22);
4932
4933 #define SCALE_X(x) (x) = GDI_ROUND((double)(x) * (scale_x))
4934 #define SCALE_Y(y) (y) = GDI_ROUND((double)(y) * (scale_y))
4935
4936     SCALE_Y(ptm->tmHeight);
4937     SCALE_Y(ptm->tmAscent);
4938     SCALE_Y(ptm->tmDescent);
4939     SCALE_Y(ptm->tmInternalLeading);
4940     SCALE_Y(ptm->tmExternalLeading);
4941     SCALE_Y(ptm->tmOverhang);
4942
4943     SCALE_X(ptm->tmAveCharWidth);
4944     SCALE_X(ptm->tmMaxCharWidth);
4945
4946 #undef SCALE_X
4947 #undef SCALE_Y
4948 }
4949
4950 static void scale_outline_font_metrics(const GdiFont *font, OUTLINETEXTMETRICW *potm)
4951 {
4952     double scale_x, scale_y;
4953
4954     if (font->aveWidth)
4955     {
4956         scale_x = (double)font->aveWidth;
4957         scale_x /= (double)font->potm->otmTextMetrics.tmAveCharWidth;
4958     }
4959     else
4960         scale_x = font->scale_y;
4961
4962     scale_x *= fabs(font->font_desc.matrix.eM11);
4963     scale_y = font->scale_y * fabs(font->font_desc.matrix.eM22);
4964
4965     scale_font_metrics(font, &potm->otmTextMetrics);
4966
4967 #define SCALE_X(x) (x) = GDI_ROUND((double)(x) * (scale_x))
4968 #define SCALE_Y(y) (y) = GDI_ROUND((double)(y) * (scale_y))
4969
4970     SCALE_Y(potm->otmAscent);
4971     SCALE_Y(potm->otmDescent);
4972     SCALE_Y(potm->otmLineGap);
4973     SCALE_Y(potm->otmsCapEmHeight);
4974     SCALE_Y(potm->otmsXHeight);
4975     SCALE_Y(potm->otmrcFontBox.top);
4976     SCALE_Y(potm->otmrcFontBox.bottom);
4977     SCALE_X(potm->otmrcFontBox.left);
4978     SCALE_X(potm->otmrcFontBox.right);
4979     SCALE_Y(potm->otmMacAscent);
4980     SCALE_Y(potm->otmMacDescent);
4981     SCALE_Y(potm->otmMacLineGap);
4982     SCALE_X(potm->otmptSubscriptSize.x);
4983     SCALE_Y(potm->otmptSubscriptSize.y);
4984     SCALE_X(potm->otmptSubscriptOffset.x);
4985     SCALE_Y(potm->otmptSubscriptOffset.y);
4986     SCALE_X(potm->otmptSuperscriptSize.x);
4987     SCALE_Y(potm->otmptSuperscriptSize.y);
4988     SCALE_X(potm->otmptSuperscriptOffset.x);
4989     SCALE_Y(potm->otmptSuperscriptOffset.y);
4990     SCALE_Y(potm->otmsStrikeoutSize);
4991     SCALE_Y(potm->otmsStrikeoutPosition);
4992     SCALE_Y(potm->otmsUnderscoreSize);
4993     SCALE_Y(potm->otmsUnderscorePosition);
4994
4995 #undef SCALE_X
4996 #undef SCALE_Y
4997 }
4998
4999 /*************************************************************
5000  * WineEngGetTextMetrics
5001  *
5002  */
5003 BOOL WineEngGetTextMetrics(GdiFont *font, LPTEXTMETRICW ptm)
5004 {
5005     EnterCriticalSection( &freetype_cs );
5006     if(!font->potm) {
5007         if(!WineEngGetOutlineTextMetrics(font, 0, NULL))
5008             if(!get_bitmap_text_metrics(font))
5009             {
5010                 LeaveCriticalSection( &freetype_cs );
5011                 return FALSE;
5012             }
5013     }
5014     if(!font->potm)
5015     {
5016         LeaveCriticalSection( &freetype_cs );
5017         return FALSE;
5018     }
5019     *ptm = font->potm->otmTextMetrics;
5020     scale_font_metrics(font, ptm);
5021     LeaveCriticalSection( &freetype_cs );
5022     return TRUE;
5023 }
5024
5025
5026 /*************************************************************
5027  * WineEngGetOutlineTextMetrics
5028  *
5029  */
5030 UINT WineEngGetOutlineTextMetrics(GdiFont *font, UINT cbSize,
5031                                   OUTLINETEXTMETRICW *potm)
5032 {
5033     FT_Face ft_face = font->ft_face;
5034     UINT needed, lenfam, lensty, ret;
5035     TT_OS2 *pOS2;
5036     TT_HoriHeader *pHori;
5037     TT_Postscript *pPost;
5038     FT_Fixed x_scale, y_scale;
5039     WCHAR *family_nameW, *style_nameW;
5040     static const WCHAR spaceW[] = {' ', '\0'};
5041     char *cp;
5042     INT ascent, descent;
5043
5044     TRACE("font=%p\n", font);
5045
5046     if(!FT_IS_SCALABLE(ft_face))
5047         return 0;
5048
5049     EnterCriticalSection( &freetype_cs );
5050
5051     if(font->potm) {
5052         if(cbSize >= font->potm->otmSize)
5053         {
5054             memcpy(potm, font->potm, font->potm->otmSize);
5055             scale_outline_font_metrics(font, potm);
5056         }
5057         LeaveCriticalSection( &freetype_cs );
5058         return font->potm->otmSize;
5059     }
5060
5061
5062     needed = sizeof(*potm);
5063
5064     lenfam = (strlenW(font->name) + 1) * sizeof(WCHAR);
5065     family_nameW = strdupW(font->name);
5066
5067     lensty = MultiByteToWideChar(CP_ACP, 0, ft_face->style_name, -1, NULL, 0)
5068       * sizeof(WCHAR);
5069     style_nameW = HeapAlloc(GetProcessHeap(), 0, lensty);
5070     MultiByteToWideChar(CP_ACP, 0, ft_face->style_name, -1,
5071                         style_nameW, lensty/sizeof(WCHAR));
5072
5073     /* These names should be read from the TT name table */
5074
5075     /* length of otmpFamilyName */
5076     needed += lenfam;
5077
5078     /* length of otmpFaceName */
5079     if ((ft_face->style_flags & (FT_STYLE_FLAG_ITALIC | FT_STYLE_FLAG_BOLD)) == 0) {
5080       needed += lenfam; /* just the family name */
5081     } else {
5082       needed += lenfam + lensty; /* family + " " + style */
5083     }
5084
5085     /* length of otmpStyleName */
5086     needed += lensty;
5087
5088     /* length of otmpFullName */
5089     needed += lenfam + lensty;
5090
5091
5092     x_scale = ft_face->size->metrics.x_scale;
5093     y_scale = ft_face->size->metrics.y_scale;
5094
5095     pOS2 = pFT_Get_Sfnt_Table(ft_face, ft_sfnt_os2);
5096     if(!pOS2) {
5097         FIXME("Can't find OS/2 table - not TT font?\n");
5098         ret = 0;
5099         goto end;
5100     }
5101
5102     pHori = pFT_Get_Sfnt_Table(ft_face, ft_sfnt_hhea);
5103     if(!pHori) {
5104         FIXME("Can't find HHEA table - not TT font?\n");
5105         ret = 0;
5106         goto end;
5107     }
5108
5109     pPost = pFT_Get_Sfnt_Table(ft_face, ft_sfnt_post); /* we can live with this failing */
5110
5111     TRACE("OS/2 winA = %d winD = %d typoA = %d typoD = %d typoLG = %d FT_Face a = %d, d = %d, h = %d: HORZ a = %d, d = %d lg = %d maxY = %ld minY = %ld\n",
5112           pOS2->usWinAscent, pOS2->usWinDescent,
5113           pOS2->sTypoAscender, pOS2->sTypoDescender, pOS2->sTypoLineGap,
5114           ft_face->ascender, ft_face->descender, ft_face->height,
5115           pHori->Ascender, pHori->Descender, pHori->Line_Gap,
5116           ft_face->bbox.yMax, ft_face->bbox.yMin);
5117
5118     font->potm = HeapAlloc(GetProcessHeap(), 0, needed);
5119     font->potm->otmSize = needed;
5120
5121 #define TM font->potm->otmTextMetrics
5122
5123     if(pOS2->usWinAscent + pOS2->usWinDescent == 0) {
5124         ascent = pHori->Ascender;
5125         descent = -pHori->Descender;
5126     } else {
5127         ascent = pOS2->usWinAscent;
5128         descent = pOS2->usWinDescent;
5129     }
5130
5131     if(font->yMax) {
5132         TM.tmAscent = font->yMax;
5133         TM.tmDescent = -font->yMin;
5134         TM.tmInternalLeading = (TM.tmAscent + TM.tmDescent) - ft_face->size->metrics.y_ppem;
5135     } else {
5136         TM.tmAscent = (pFT_MulFix(ascent, y_scale) + 32) >> 6;
5137         TM.tmDescent = (pFT_MulFix(descent, y_scale) + 32) >> 6;
5138         TM.tmInternalLeading = (pFT_MulFix(ascent + descent
5139                                             - ft_face->units_per_EM, y_scale) + 32) >> 6;
5140     }
5141
5142     TM.tmHeight = TM.tmAscent + TM.tmDescent;
5143
5144     /* MSDN says:
5145      el = MAX(0, LineGap - ((WinAscent + WinDescent) - (Ascender - Descender)))
5146     */
5147     TM.tmExternalLeading = max(0, (pFT_MulFix(pHori->Line_Gap -
5148                  ((ascent + descent) -
5149                   (pHori->Ascender - pHori->Descender)), y_scale) + 32) >> 6);
5150
5151     TM.tmAveCharWidth = (pFT_MulFix(pOS2->xAvgCharWidth, x_scale) + 32) >> 6;
5152     if (TM.tmAveCharWidth == 0) {
5153         TM.tmAveCharWidth = 1; 
5154     }
5155     TM.tmMaxCharWidth = (pFT_MulFix(ft_face->bbox.xMax - ft_face->bbox.xMin, x_scale) + 32) >> 6;
5156     TM.tmWeight = font->fake_bold ? FW_BOLD : pOS2->usWeightClass;
5157     TM.tmOverhang = 0;
5158     TM.tmDigitizedAspectX = 300;
5159     TM.tmDigitizedAspectY = 300;
5160     /* It appears that for fonts with SYMBOL_CHARSET Windows always sets
5161      * symbol range to 0 - f0ff
5162      */
5163     if (font->charset == SYMBOL_CHARSET)
5164     {
5165         TM.tmFirstChar = 0;
5166         TM.tmDefaultChar = pOS2->usDefaultChar ? pOS2->usDefaultChar : 0x1f;
5167     }
5168     else
5169     {
5170         TM.tmFirstChar = pOS2->usFirstCharIndex;
5171         TM.tmDefaultChar = pOS2->usDefaultChar ? pOS2->usDefaultChar : 0xffff;
5172     }
5173     TM.tmLastChar = pOS2->usLastCharIndex;
5174     TM.tmBreakChar = pOS2->usBreakChar ? pOS2->usBreakChar : ' ';
5175     TM.tmItalic = font->fake_italic ? 255 : ((ft_face->style_flags & FT_STYLE_FLAG_ITALIC) ? 255 : 0);
5176     TM.tmUnderlined = font->underline;
5177     TM.tmStruckOut = font->strikeout;
5178
5179     /* Yes TPMF_FIXED_PITCH is correct; braindead api */
5180     if(!FT_IS_FIXED_WIDTH(ft_face) &&
5181        (pOS2->version == 0xFFFFU || 
5182         pOS2->panose[PAN_PROPORTION_INDEX] != PAN_PROP_MONOSPACED))
5183         TM.tmPitchAndFamily = TMPF_FIXED_PITCH;
5184     else
5185         TM.tmPitchAndFamily = 0;
5186
5187     switch(pOS2->panose[PAN_FAMILYTYPE_INDEX]) {
5188     case PAN_FAMILY_SCRIPT:
5189         TM.tmPitchAndFamily |= FF_SCRIPT;
5190         break;
5191     case PAN_FAMILY_DECORATIVE:
5192     case PAN_FAMILY_PICTORIAL:
5193         TM.tmPitchAndFamily |= FF_DECORATIVE;
5194         break;
5195     case PAN_FAMILY_TEXT_DISPLAY:
5196         if(TM.tmPitchAndFamily == 0) /* fixed */
5197             TM.tmPitchAndFamily = FF_MODERN;
5198         else {
5199             switch(pOS2->panose[PAN_SERIFSTYLE_INDEX]) {
5200             case PAN_SERIF_NORMAL_SANS:
5201             case PAN_SERIF_OBTUSE_SANS:
5202             case PAN_SERIF_PERP_SANS:
5203                 TM.tmPitchAndFamily |= FF_SWISS;
5204                 break;
5205             default:
5206                 TM.tmPitchAndFamily |= FF_ROMAN;
5207             }
5208         }
5209         break;
5210     default:
5211         TM.tmPitchAndFamily |= FF_DONTCARE;
5212     }
5213
5214     if(FT_IS_SCALABLE(ft_face))
5215         TM.tmPitchAndFamily |= TMPF_VECTOR;
5216
5217     if(FT_IS_SFNT(ft_face))
5218     {
5219         if (font->ntmFlags & NTM_PS_OPENTYPE)
5220             TM.tmPitchAndFamily |= TMPF_DEVICE;
5221         else
5222             TM.tmPitchAndFamily |= TMPF_TRUETYPE;
5223     }
5224
5225     TM.tmCharSet = font->charset;
5226
5227     font->potm->otmFiller = 0;
5228     memcpy(&font->potm->otmPanoseNumber, pOS2->panose, PANOSE_COUNT);
5229     font->potm->otmfsSelection = pOS2->fsSelection;
5230     font->potm->otmfsType = pOS2->fsType;
5231     font->potm->otmsCharSlopeRise = pHori->caret_Slope_Rise;
5232     font->potm->otmsCharSlopeRun = pHori->caret_Slope_Run;
5233     font->potm->otmItalicAngle = 0; /* POST table */
5234     font->potm->otmEMSquare = ft_face->units_per_EM;
5235     font->potm->otmAscent = (pFT_MulFix(pOS2->sTypoAscender, y_scale) + 32) >> 6;
5236     font->potm->otmDescent = (pFT_MulFix(pOS2->sTypoDescender, y_scale) + 32) >> 6;
5237     font->potm->otmLineGap = (pFT_MulFix(pOS2->sTypoLineGap, y_scale) + 32) >> 6;
5238     font->potm->otmsCapEmHeight = (pFT_MulFix(pOS2->sCapHeight, y_scale) + 32) >> 6;
5239     font->potm->otmsXHeight = (pFT_MulFix(pOS2->sxHeight, y_scale) + 32) >> 6;
5240     font->potm->otmrcFontBox.left = (pFT_MulFix(ft_face->bbox.xMin, x_scale) + 32) >> 6;
5241     font->potm->otmrcFontBox.right = (pFT_MulFix(ft_face->bbox.xMax, x_scale) + 32) >> 6;
5242     font->potm->otmrcFontBox.top = (pFT_MulFix(ft_face->bbox.yMax, y_scale) + 32) >> 6;
5243     font->potm->otmrcFontBox.bottom = (pFT_MulFix(ft_face->bbox.yMin, y_scale) + 32) >> 6;
5244     font->potm->otmMacAscent = TM.tmAscent;
5245     font->potm->otmMacDescent = -TM.tmDescent;
5246     font->potm->otmMacLineGap = font->potm->otmLineGap;
5247     font->potm->otmusMinimumPPEM = 0; /* TT Header */
5248     font->potm->otmptSubscriptSize.x = (pFT_MulFix(pOS2->ySubscriptXSize, x_scale) + 32) >> 6;
5249     font->potm->otmptSubscriptSize.y = (pFT_MulFix(pOS2->ySubscriptYSize, y_scale) + 32) >> 6;
5250     font->potm->otmptSubscriptOffset.x = (pFT_MulFix(pOS2->ySubscriptXOffset, x_scale) + 32) >> 6;
5251     font->potm->otmptSubscriptOffset.y = (pFT_MulFix(pOS2->ySubscriptYOffset, y_scale) + 32) >> 6;
5252     font->potm->otmptSuperscriptSize.x = (pFT_MulFix(pOS2->ySuperscriptXSize, x_scale) + 32) >> 6;
5253     font->potm->otmptSuperscriptSize.y = (pFT_MulFix(pOS2->ySuperscriptYSize, y_scale) + 32) >> 6;
5254     font->potm->otmptSuperscriptOffset.x = (pFT_MulFix(pOS2->ySuperscriptXOffset, x_scale) + 32) >> 6;
5255     font->potm->otmptSuperscriptOffset.y = (pFT_MulFix(pOS2->ySuperscriptYOffset, y_scale) + 32) >> 6;
5256     font->potm->otmsStrikeoutSize = (pFT_MulFix(pOS2->yStrikeoutSize, y_scale) + 32) >> 6;
5257     font->potm->otmsStrikeoutPosition = (pFT_MulFix(pOS2->yStrikeoutPosition, y_scale) + 32) >> 6;
5258     if(!pPost) {
5259         font->potm->otmsUnderscoreSize = 0;
5260         font->potm->otmsUnderscorePosition = 0;
5261     } else {
5262         font->potm->otmsUnderscoreSize = (pFT_MulFix(pPost->underlineThickness, y_scale) + 32) >> 6;
5263         font->potm->otmsUnderscorePosition = (pFT_MulFix(pPost->underlinePosition, y_scale) + 32) >> 6;
5264     }
5265 #undef TM
5266
5267     /* otmp* members should clearly have type ptrdiff_t, but M$ knows best */
5268     cp = (char*)font->potm + sizeof(*font->potm);
5269     font->potm->otmpFamilyName = (LPSTR)(cp - (char*)font->potm);
5270     strcpyW((WCHAR*)cp, family_nameW);
5271     cp += lenfam;
5272     font->potm->otmpStyleName = (LPSTR)(cp - (char*)font->potm);
5273     strcpyW((WCHAR*)cp, style_nameW);
5274     cp += lensty;
5275     font->potm->otmpFaceName = (LPSTR)(cp - (char*)font->potm);
5276     strcpyW((WCHAR*)cp, family_nameW);
5277     if (ft_face->style_flags & (FT_STYLE_FLAG_ITALIC | FT_STYLE_FLAG_BOLD)) {
5278         strcatW((WCHAR*)cp, spaceW);
5279         strcatW((WCHAR*)cp, style_nameW);
5280         cp += lenfam + lensty;
5281     } else
5282         cp += lenfam;
5283     font->potm->otmpFullName = (LPSTR)(cp - (char*)font->potm);
5284     strcpyW((WCHAR*)cp, family_nameW);
5285     strcatW((WCHAR*)cp, spaceW);
5286     strcatW((WCHAR*)cp, style_nameW);
5287     ret = needed;
5288
5289     if(potm && needed <= cbSize)
5290     {
5291         memcpy(potm, font->potm, font->potm->otmSize);
5292         scale_outline_font_metrics(font, potm);
5293     }
5294
5295 end:
5296     HeapFree(GetProcessHeap(), 0, style_nameW);
5297     HeapFree(GetProcessHeap(), 0, family_nameW);
5298
5299     LeaveCriticalSection( &freetype_cs );
5300     return ret;
5301 }
5302
5303 static BOOL load_child_font(GdiFont *font, CHILD_FONT *child)
5304 {
5305     HFONTLIST *hfontlist;
5306     child->font = alloc_font();
5307     child->font->ft_face = OpenFontFace(child->font, child->face, 0, -font->ppem);
5308     if(!child->font->ft_face)
5309     {
5310         free_font(child->font);
5311         child->font = NULL;
5312         return FALSE;
5313     }
5314
5315     child->font->ntmFlags = child->face->ntmFlags;
5316     child->font->orientation = font->orientation;
5317     child->font->scale_y = font->scale_y;
5318     hfontlist = HeapAlloc(GetProcessHeap(), 0, sizeof(*hfontlist));
5319     hfontlist->hfont = CreateFontIndirectW(&font->font_desc.lf);
5320     list_add_head(&child->font->hfontlist, &hfontlist->entry);
5321     child->font->base_font = font;
5322     list_add_head(&child_font_list, &child->font->entry);
5323     TRACE("created child font hfont %p for base %p child %p\n", hfontlist->hfont, font, child->font);
5324     return TRUE;
5325 }
5326
5327 static BOOL get_glyph_index_linked(GdiFont *font, UINT c, GdiFont **linked_font, FT_UInt *glyph)
5328 {
5329     FT_UInt g;
5330     CHILD_FONT *child_font;
5331
5332     if(font->base_font)
5333         font = font->base_font;
5334
5335     *linked_font = font;
5336
5337     if((*glyph = get_glyph_index(font, c)))
5338         return TRUE;
5339
5340     LIST_FOR_EACH_ENTRY(child_font, &font->child_fonts, CHILD_FONT, entry)
5341     {
5342         if(!child_font->font)
5343             if(!load_child_font(font, child_font))
5344                 continue;
5345
5346         if(!child_font->font->ft_face)
5347             continue;
5348         g = get_glyph_index(child_font->font, c);
5349         if(g)
5350         {
5351             *glyph = g;
5352             *linked_font = child_font->font;
5353             return TRUE;
5354         }
5355     }
5356     return FALSE;
5357 }
5358
5359 /*************************************************************
5360  * WineEngGetCharWidth
5361  *
5362  */
5363 BOOL WineEngGetCharWidth(GdiFont *font, UINT firstChar, UINT lastChar,
5364                          LPINT buffer)
5365 {
5366     UINT c;
5367     GLYPHMETRICS gm;
5368     FT_UInt glyph_index;
5369     GdiFont *linked_font;
5370
5371     TRACE("%p, %d, %d, %p\n", font, firstChar, lastChar, buffer);
5372
5373     EnterCriticalSection( &freetype_cs );
5374     for(c = firstChar; c <= lastChar; c++) {
5375         get_glyph_index_linked(font, c, &linked_font, &glyph_index);
5376         WineEngGetGlyphOutline(linked_font, glyph_index, GGO_METRICS | GGO_GLYPH_INDEX,
5377                                &gm, 0, NULL, NULL);
5378         buffer[c - firstChar] = FONT_GM(linked_font,glyph_index)->adv;
5379     }
5380     LeaveCriticalSection( &freetype_cs );
5381     return TRUE;
5382 }
5383
5384 /*************************************************************
5385  * WineEngGetCharABCWidths
5386  *
5387  */
5388 BOOL WineEngGetCharABCWidths(GdiFont *font, UINT firstChar, UINT lastChar,
5389                              LPABC buffer)
5390 {
5391     UINT c;
5392     GLYPHMETRICS gm;
5393     FT_UInt glyph_index;
5394     GdiFont *linked_font;
5395
5396     TRACE("%p, %d, %d, %p\n", font, firstChar, lastChar, buffer);
5397
5398     if(!FT_IS_SCALABLE(font->ft_face))
5399         return FALSE;
5400
5401     EnterCriticalSection( &freetype_cs );
5402
5403     for(c = firstChar; c <= lastChar; c++) {
5404         get_glyph_index_linked(font, c, &linked_font, &glyph_index);
5405         WineEngGetGlyphOutline(linked_font, glyph_index, GGO_METRICS | GGO_GLYPH_INDEX,
5406                                &gm, 0, NULL, NULL);
5407         buffer[c - firstChar].abcA = FONT_GM(linked_font,glyph_index)->lsb;
5408         buffer[c - firstChar].abcB = FONT_GM(linked_font,glyph_index)->bbx;
5409         buffer[c - firstChar].abcC = FONT_GM(linked_font,glyph_index)->adv - FONT_GM(linked_font,glyph_index)->lsb -
5410             FONT_GM(linked_font,glyph_index)->bbx;
5411     }
5412     LeaveCriticalSection( &freetype_cs );
5413     return TRUE;
5414 }
5415
5416 /*************************************************************
5417  * WineEngGetCharABCWidthsI
5418  *
5419  */
5420 BOOL WineEngGetCharABCWidthsI(GdiFont *font, UINT firstChar, UINT count, LPWORD pgi,
5421                               LPABC buffer)
5422 {
5423     UINT c;
5424     GLYPHMETRICS gm;
5425     FT_UInt glyph_index;
5426     GdiFont *linked_font;
5427
5428     if(!FT_HAS_HORIZONTAL(font->ft_face))
5429         return FALSE;
5430
5431     EnterCriticalSection( &freetype_cs );
5432
5433     get_glyph_index_linked(font, 'a', &linked_font, &glyph_index);
5434     if (!pgi)
5435         for(c = firstChar; c < firstChar+count; c++) {
5436             WineEngGetGlyphOutline(linked_font, c, GGO_METRICS | GGO_GLYPH_INDEX,
5437                                    &gm, 0, NULL, NULL);
5438             buffer[c - firstChar].abcA = FONT_GM(linked_font,c)->lsb;
5439             buffer[c - firstChar].abcB = FONT_GM(linked_font,c)->bbx;
5440             buffer[c - firstChar].abcC = FONT_GM(linked_font,c)->adv - FONT_GM(linked_font,c)->lsb
5441                 - FONT_GM(linked_font,c)->bbx;
5442         }
5443     else
5444         for(c = 0; c < count; c++) {
5445             WineEngGetGlyphOutline(linked_font, pgi[c], GGO_METRICS | GGO_GLYPH_INDEX,
5446                                    &gm, 0, NULL, NULL);
5447             buffer[c].abcA = FONT_GM(linked_font,pgi[c])->lsb;
5448             buffer[c].abcB = FONT_GM(linked_font,pgi[c])->bbx;
5449             buffer[c].abcC = FONT_GM(linked_font,pgi[c])->adv
5450                 - FONT_GM(linked_font,pgi[c])->lsb - FONT_GM(linked_font,pgi[c])->bbx;
5451         }
5452
5453     LeaveCriticalSection( &freetype_cs );
5454     return TRUE;
5455 }
5456
5457 /*************************************************************
5458  * WineEngGetTextExtentExPoint
5459  *
5460  */
5461 BOOL WineEngGetTextExtentExPoint(GdiFont *font, LPCWSTR wstr, INT count,
5462                                  INT max_ext, LPINT pnfit, LPINT dxs, LPSIZE size)
5463 {
5464     INT idx;
5465     INT nfit = 0, ext;
5466     GLYPHMETRICS gm;
5467     TEXTMETRICW tm;
5468     FT_UInt glyph_index;
5469     GdiFont *linked_font;
5470
5471     TRACE("%p, %s, %d, %d, %p\n", font, debugstr_wn(wstr, count), count,
5472           max_ext, size);
5473
5474     EnterCriticalSection( &freetype_cs );
5475
5476     size->cx = 0;
5477     WineEngGetTextMetrics(font, &tm);
5478     size->cy = tm.tmHeight;
5479
5480     for(idx = 0; idx < count; idx++) {
5481         get_glyph_index_linked(font, wstr[idx], &linked_font, &glyph_index);
5482         WineEngGetGlyphOutline(linked_font, glyph_index, GGO_METRICS | GGO_GLYPH_INDEX,
5483                                &gm, 0, NULL, NULL);
5484         size->cx += FONT_GM(linked_font,glyph_index)->adv;
5485         ext = size->cx;
5486         if (! pnfit || ext <= max_ext) {
5487             ++nfit;
5488             if (dxs)
5489                 dxs[idx] = ext;
5490         }
5491     }
5492
5493     if (pnfit)
5494         *pnfit = nfit;
5495
5496     LeaveCriticalSection( &freetype_cs );
5497     TRACE("return %d, %d, %d\n", size->cx, size->cy, nfit);
5498     return TRUE;
5499 }
5500
5501 /*************************************************************
5502  * WineEngGetTextExtentExPointI
5503  *
5504  */
5505 BOOL WineEngGetTextExtentExPointI(GdiFont *font, const WORD *indices, INT count,
5506                                   INT max_ext, LPINT pnfit, LPINT dxs, LPSIZE size)
5507 {
5508     INT idx;
5509     INT nfit = 0, ext;
5510     GLYPHMETRICS gm;
5511     TEXTMETRICW tm;
5512
5513     TRACE("%p, %p, %d, %d, %p\n", font, indices, count, max_ext, size);
5514
5515     EnterCriticalSection( &freetype_cs );
5516
5517     size->cx = 0;
5518     WineEngGetTextMetrics(font, &tm);
5519     size->cy = tm.tmHeight;
5520
5521     for(idx = 0; idx < count; idx++) {
5522         WineEngGetGlyphOutline(font, indices[idx],
5523                                GGO_METRICS | GGO_GLYPH_INDEX, &gm, 0, NULL,
5524                                NULL);
5525         size->cx += FONT_GM(font,indices[idx])->adv;
5526         ext = size->cx;
5527         if (! pnfit || ext <= max_ext) {
5528             ++nfit;
5529             if (dxs)
5530                 dxs[idx] = ext;
5531         }
5532     }
5533
5534     if (pnfit)
5535         *pnfit = nfit;
5536
5537     LeaveCriticalSection( &freetype_cs );
5538     TRACE("return %d, %d, %d\n", size->cx, size->cy, nfit);
5539     return TRUE;
5540 }
5541
5542 /*************************************************************
5543  * WineEngGetFontData
5544  *
5545  */
5546 DWORD WineEngGetFontData(GdiFont *font, DWORD table, DWORD offset, LPVOID buf,
5547                          DWORD cbData)
5548 {
5549     FT_Face ft_face = font->ft_face;
5550     FT_ULong len;
5551     FT_Error err;
5552
5553     TRACE("font=%p, table=%c%c%c%c, offset=0x%x, buf=%p, cbData=0x%x\n",
5554         font, LOBYTE(LOWORD(table)), HIBYTE(LOWORD(table)),
5555         LOBYTE(HIWORD(table)), HIBYTE(HIWORD(table)), offset, buf, cbData);
5556
5557     if(!FT_IS_SFNT(ft_face))
5558         return GDI_ERROR;
5559
5560     if(!buf || !cbData)
5561         len = 0;
5562     else
5563         len = cbData;
5564
5565     if(table) { /* MS tags differ in endianness from FT ones */
5566         table = table >> 24 | table << 24 |
5567           (table >> 8 & 0xff00) | (table << 8 & 0xff0000);
5568     }
5569
5570     /* make sure value of len is the value freetype says it needs */
5571     if(buf && len)
5572     {
5573         FT_ULong needed = 0;
5574         err = load_sfnt_table(ft_face, table, offset, NULL, &needed);
5575         if( !err && needed < len) len = needed;
5576     }
5577     err = load_sfnt_table(ft_face, table, offset, buf, &len);
5578
5579     if(err) {
5580         TRACE("Can't find table %c%c%c%c\n",
5581               /* bytes were reversed */
5582               HIBYTE(HIWORD(table)), LOBYTE(HIWORD(table)),
5583               HIBYTE(LOWORD(table)), LOBYTE(LOWORD(table)));
5584         return GDI_ERROR;
5585     }
5586     return len;
5587 }
5588
5589 /*************************************************************
5590  * WineEngGetTextFace
5591  *
5592  */
5593 INT WineEngGetTextFace(GdiFont *font, INT count, LPWSTR str)
5594 {
5595     INT n = strlenW(font->name) + 1;
5596     if(str) {
5597         lstrcpynW(str, font->name, count);
5598         return min(count, n);
5599     } else
5600         return n;
5601 }
5602
5603 UINT WineEngGetTextCharsetInfo(GdiFont *font, LPFONTSIGNATURE fs, DWORD flags)
5604 {
5605     if (fs) *fs = font->fs;
5606     return font->charset;
5607 }
5608
5609 BOOL WineEngGetLinkedHFont(DC *dc, WCHAR c, HFONT *new_hfont, UINT *glyph)
5610 {
5611     GdiFont *font = dc->gdiFont, *linked_font;
5612     struct list *first_hfont;
5613     BOOL ret;
5614
5615     EnterCriticalSection( &freetype_cs );
5616     ret = get_glyph_index_linked(font, c, &linked_font, glyph);
5617     TRACE("get_glyph_index_linked glyph %d font %p\n", *glyph, linked_font);
5618     if(font == linked_font)
5619         *new_hfont = dc->hFont;
5620     else
5621     {
5622         first_hfont = list_head(&linked_font->hfontlist);
5623         *new_hfont = LIST_ENTRY(first_hfont, struct tagHFONTLIST, entry)->hfont;
5624     }
5625     LeaveCriticalSection( &freetype_cs );
5626     return ret;
5627 }
5628     
5629 /* Retrieve a list of supported Unicode ranges for a given font.
5630  * Can be called with NULL gs to calculate the buffer size. Returns
5631  * the number of ranges found.
5632  */
5633 static DWORD get_font_unicode_ranges(FT_Face face, GLYPHSET *gs)
5634 {
5635     DWORD num_ranges = 0;
5636
5637     if (face->charmap->encoding == FT_ENCODING_UNICODE && pFT_Get_First_Char)
5638     {
5639         FT_UInt glyph_code;
5640         FT_ULong char_code, char_code_prev;
5641
5642         glyph_code = 0;
5643         char_code_prev = char_code = pFT_Get_First_Char(face, &glyph_code);
5644
5645         TRACE("face encoding FT_ENCODING_UNICODE, number of glyphs %ld, first glyph %u, first char %04lx\n",
5646                face->num_glyphs, glyph_code, char_code);
5647
5648         if (!glyph_code) return 0;
5649
5650         if (gs)
5651         {
5652             gs->ranges[0].wcLow = (USHORT)char_code;
5653             gs->ranges[0].cGlyphs = 0;
5654             gs->cGlyphsSupported = 0;
5655         }
5656
5657         num_ranges = 1;
5658         while (glyph_code)
5659         {
5660             if (char_code < char_code_prev)
5661             {
5662                 ERR("expected increasing char code from FT_Get_Next_Char\n");
5663                 return 0;
5664             }
5665             if (char_code - char_code_prev > 1)
5666             {
5667                 num_ranges++;
5668                 if (gs)
5669                 {
5670                     gs->ranges[num_ranges - 1].wcLow = (USHORT)char_code;
5671                     gs->ranges[num_ranges - 1].cGlyphs = 1;
5672                     gs->cGlyphsSupported++;
5673                 }
5674             }
5675             else if (gs)
5676             {
5677                 gs->ranges[num_ranges - 1].cGlyphs++;
5678                 gs->cGlyphsSupported++;
5679             }
5680             char_code_prev = char_code;
5681             char_code = pFT_Get_Next_Char(face, char_code, &glyph_code);
5682         }
5683     }
5684     else
5685         FIXME("encoding %u not supported\n", face->charmap->encoding);
5686
5687     return num_ranges;
5688 }
5689
5690 DWORD WineEngGetFontUnicodeRanges(GdiFont *font, LPGLYPHSET glyphset)
5691 {
5692     DWORD size = 0;
5693     DWORD num_ranges = get_font_unicode_ranges(font->ft_face, glyphset);
5694
5695     size = sizeof(GLYPHSET) + sizeof(WCRANGE) * (num_ranges - 1);
5696     if (glyphset)
5697     {
5698         glyphset->cbThis = size;
5699         glyphset->cRanges = num_ranges;
5700     }
5701     return size;
5702 }
5703
5704 /*************************************************************
5705  *     FontIsLinked
5706  */
5707 BOOL WineEngFontIsLinked(GdiFont *font)
5708 {
5709     BOOL ret;
5710     EnterCriticalSection( &freetype_cs );
5711     ret = !list_empty(&font->child_fonts);
5712     LeaveCriticalSection( &freetype_cs );
5713     return ret;
5714 }
5715
5716 static BOOL is_hinting_enabled(void)
5717 {
5718     /* Use the >= 2.2.0 function if available */
5719     if(pFT_Get_TrueType_Engine_Type)
5720     {
5721         FT_TrueTypeEngineType type = pFT_Get_TrueType_Engine_Type(library);
5722         return type == FT_TRUETYPE_ENGINE_TYPE_PATENTED;
5723     }
5724 #ifdef FT_DRIVER_HAS_HINTER
5725     else
5726     {
5727         FT_Module mod;
5728
5729         /* otherwise if we've been compiled with < 2.2.0 headers 
5730            use the internal macro */
5731         mod = pFT_Get_Module(library, "truetype");
5732         if(mod && FT_DRIVER_HAS_HINTER(mod))
5733             return TRUE;
5734     }
5735 #endif
5736
5737     return FALSE;
5738 }
5739
5740 /*************************************************************************
5741  *             GetRasterizerCaps   (GDI32.@)
5742  */
5743 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
5744 {
5745     static int hinting = -1;
5746
5747     if(hinting == -1)
5748     {
5749         hinting = is_hinting_enabled();
5750         TRACE("hinting is %senabled\n", hinting ? "" : "NOT ");
5751     }
5752
5753     lprs->nSize = sizeof(RASTERIZER_STATUS);
5754     lprs->wFlags = TT_AVAILABLE | TT_ENABLED | (hinting ? WINE_TT_HINTER_ENABLED : 0);
5755     lprs->nLanguageID = 0;
5756     return TRUE;
5757 }
5758
5759 /*************************************************************
5760  *     WineEngRealizationInfo
5761  */
5762 BOOL WineEngRealizationInfo(GdiFont *font, realization_info_t *info)
5763 {
5764     FIXME("(%p, %p): stub!\n", font, info);
5765
5766     info->flags = 1;
5767     if(FT_IS_SCALABLE(font->ft_face))
5768         info->flags |= 2;
5769
5770     info->cache_num = font->cache_num;
5771     info->unknown2 = -1;
5772     return TRUE;
5773 }
5774
5775 /*************************************************************************
5776  * Kerning support for TrueType fonts
5777  */
5778 #define MS_KERN_TAG MS_MAKE_TAG('k', 'e', 'r', 'n')
5779
5780 struct TT_kern_table
5781 {
5782     USHORT version;
5783     USHORT nTables;
5784 };
5785
5786 struct TT_kern_subtable
5787 {
5788     USHORT version;
5789     USHORT length;
5790     union
5791     {
5792         USHORT word;
5793         struct
5794         {
5795             USHORT horizontal : 1;
5796             USHORT minimum : 1;
5797             USHORT cross_stream: 1;
5798             USHORT override : 1;
5799             USHORT reserved1 : 4;
5800             USHORT format : 8;
5801         } bits;
5802     } coverage;
5803 };
5804
5805 struct TT_format0_kern_subtable
5806 {
5807     USHORT nPairs;
5808     USHORT searchRange;
5809     USHORT entrySelector;
5810     USHORT rangeShift;
5811 };
5812
5813 struct TT_kern_pair
5814 {
5815     USHORT left;
5816     USHORT right;
5817     short  value;
5818 };
5819
5820 static DWORD parse_format0_kern_subtable(GdiFont *font,
5821                                          const struct TT_format0_kern_subtable *tt_f0_ks,
5822                                          const USHORT *glyph_to_char,
5823                                          KERNINGPAIR *kern_pair, DWORD cPairs)
5824 {
5825     USHORT i, nPairs;
5826     const struct TT_kern_pair *tt_kern_pair;
5827
5828     TRACE("font height %d, units_per_EM %d\n", font->ppem, font->ft_face->units_per_EM);
5829
5830     nPairs = GET_BE_WORD(tt_f0_ks->nPairs);
5831
5832     TRACE("nPairs %u, searchRange %u, entrySelector %u, rangeShift %u\n",
5833            nPairs, GET_BE_WORD(tt_f0_ks->searchRange),
5834            GET_BE_WORD(tt_f0_ks->entrySelector), GET_BE_WORD(tt_f0_ks->rangeShift));
5835
5836     if (!kern_pair || !cPairs)
5837         return nPairs;
5838
5839     tt_kern_pair = (const struct TT_kern_pair *)(tt_f0_ks + 1);
5840
5841     nPairs = min(nPairs, cPairs);
5842
5843     for (i = 0; i < nPairs; i++)
5844     {
5845         kern_pair->wFirst = glyph_to_char[GET_BE_WORD(tt_kern_pair[i].left)];
5846         kern_pair->wSecond = glyph_to_char[GET_BE_WORD(tt_kern_pair[i].right)];
5847         /* this algorithm appears to better match what Windows does */
5848         kern_pair->iKernAmount = (short)GET_BE_WORD(tt_kern_pair[i].value) * font->ppem;
5849         if (kern_pair->iKernAmount < 0)
5850         {
5851             kern_pair->iKernAmount -= font->ft_face->units_per_EM / 2;
5852             kern_pair->iKernAmount -= font->ppem;
5853         }
5854         else if (kern_pair->iKernAmount > 0)
5855         {
5856             kern_pair->iKernAmount += font->ft_face->units_per_EM / 2;
5857             kern_pair->iKernAmount += font->ppem;
5858         }
5859         kern_pair->iKernAmount /= font->ft_face->units_per_EM;
5860
5861         TRACE("left %u right %u value %d\n",
5862                kern_pair->wFirst, kern_pair->wSecond, kern_pair->iKernAmount);
5863
5864         kern_pair++;
5865     }
5866     TRACE("copied %u entries\n", nPairs);
5867     return nPairs;
5868 }
5869
5870 DWORD WineEngGetKerningPairs(GdiFont *font, DWORD cPairs, KERNINGPAIR *kern_pair)
5871 {
5872     DWORD length;
5873     void *buf;
5874     const struct TT_kern_table *tt_kern_table;
5875     const struct TT_kern_subtable *tt_kern_subtable;
5876     USHORT i, nTables;
5877     USHORT *glyph_to_char;
5878
5879     EnterCriticalSection( &freetype_cs );
5880     if (font->total_kern_pairs != (DWORD)-1)
5881     {
5882         if (cPairs && kern_pair)
5883         {
5884             cPairs = min(cPairs, font->total_kern_pairs);
5885             memcpy(kern_pair, font->kern_pairs, cPairs * sizeof(*kern_pair));
5886             LeaveCriticalSection( &freetype_cs );
5887             return cPairs;
5888         }
5889         LeaveCriticalSection( &freetype_cs );
5890         return font->total_kern_pairs;
5891     }
5892
5893     font->total_kern_pairs = 0;
5894
5895     length = WineEngGetFontData(font, MS_KERN_TAG, 0, NULL, 0);
5896
5897     if (length == GDI_ERROR)
5898     {
5899         TRACE("no kerning data in the font\n");
5900         LeaveCriticalSection( &freetype_cs );
5901         return 0;
5902     }
5903
5904     buf = HeapAlloc(GetProcessHeap(), 0, length);
5905     if (!buf)
5906     {
5907         WARN("Out of memory\n");
5908         LeaveCriticalSection( &freetype_cs );
5909         return 0;
5910     }
5911
5912     WineEngGetFontData(font, MS_KERN_TAG, 0, buf, length);
5913
5914     /* build a glyph index to char code map */
5915     glyph_to_char = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(USHORT) * 65536);
5916     if (!glyph_to_char)
5917     {
5918         WARN("Out of memory allocating a glyph index to char code map\n");
5919         HeapFree(GetProcessHeap(), 0, buf);
5920         LeaveCriticalSection( &freetype_cs );
5921         return 0;
5922     }
5923
5924     if (font->ft_face->charmap->encoding == FT_ENCODING_UNICODE && pFT_Get_First_Char)
5925     {
5926         FT_UInt glyph_code;
5927         FT_ULong char_code;
5928
5929         glyph_code = 0;
5930         char_code = pFT_Get_First_Char(font->ft_face, &glyph_code);
5931
5932         TRACE("face encoding FT_ENCODING_UNICODE, number of glyphs %ld, first glyph %u, first char %lu\n",
5933                font->ft_face->num_glyphs, glyph_code, char_code);
5934
5935         while (glyph_code)
5936         {
5937             /*TRACE("Char %04lX -> Index %u%s\n", char_code, glyph_code, glyph_to_char[glyph_code] ? "  !" : "" );*/
5938
5939             /* FIXME: This doesn't match what Windows does: it does some fancy
5940              * things with duplicate glyph index to char code mappings, while
5941              * we just avoid overriding existing entries.
5942              */
5943             if (glyph_code <= 65535 && !glyph_to_char[glyph_code])
5944                 glyph_to_char[glyph_code] = (USHORT)char_code;
5945
5946             char_code = pFT_Get_Next_Char(font->ft_face, char_code, &glyph_code);
5947         }
5948     }
5949     else
5950     {
5951         ULONG n;
5952
5953         FIXME("encoding %u not supported\n", font->ft_face->charmap->encoding);
5954         for (n = 0; n <= 65535; n++)
5955             glyph_to_char[n] = (USHORT)n;
5956     }
5957
5958     tt_kern_table = buf;
5959     nTables = GET_BE_WORD(tt_kern_table->nTables);
5960     TRACE("version %u, nTables %u\n",
5961            GET_BE_WORD(tt_kern_table->version), nTables);
5962
5963     tt_kern_subtable = (const struct TT_kern_subtable *)(tt_kern_table + 1);
5964
5965     for (i = 0; i < nTables; i++)
5966     {
5967         struct TT_kern_subtable tt_kern_subtable_copy;
5968
5969         tt_kern_subtable_copy.version = GET_BE_WORD(tt_kern_subtable->version);
5970         tt_kern_subtable_copy.length = GET_BE_WORD(tt_kern_subtable->length);
5971         tt_kern_subtable_copy.coverage.word = GET_BE_WORD(tt_kern_subtable->coverage.word);
5972
5973         TRACE("version %u, length %u, coverage %u, subtable format %u\n",
5974                tt_kern_subtable_copy.version, tt_kern_subtable_copy.length,
5975                tt_kern_subtable_copy.coverage.word, tt_kern_subtable_copy.coverage.bits.format);
5976
5977         /* According to the TrueType specification this is the only format
5978          * that will be properly interpreted by Windows and OS/2
5979          */
5980         if (tt_kern_subtable_copy.coverage.bits.format == 0)
5981         {
5982             DWORD new_chunk, old_total = font->total_kern_pairs;
5983
5984             new_chunk = parse_format0_kern_subtable(font, (const struct TT_format0_kern_subtable *)(tt_kern_subtable + 1),
5985                                                     glyph_to_char, NULL, 0);
5986             font->total_kern_pairs += new_chunk;
5987
5988             if (!font->kern_pairs)
5989                 font->kern_pairs = HeapAlloc(GetProcessHeap(), 0,
5990                                              font->total_kern_pairs * sizeof(*font->kern_pairs));
5991             else
5992                 font->kern_pairs = HeapReAlloc(GetProcessHeap(), 0, font->kern_pairs,
5993                                                font->total_kern_pairs * sizeof(*font->kern_pairs));
5994
5995             parse_format0_kern_subtable(font, (const struct TT_format0_kern_subtable *)(tt_kern_subtable + 1),
5996                         glyph_to_char, font->kern_pairs + old_total, new_chunk);
5997         }
5998         else
5999             TRACE("skipping kerning table format %u\n", tt_kern_subtable_copy.coverage.bits.format);
6000
6001         tt_kern_subtable = (const struct TT_kern_subtable *)((const char *)tt_kern_subtable + tt_kern_subtable_copy.length);
6002     }
6003
6004     HeapFree(GetProcessHeap(), 0, glyph_to_char);
6005     HeapFree(GetProcessHeap(), 0, buf);
6006
6007     if (cPairs && kern_pair)
6008     {
6009         cPairs = min(cPairs, font->total_kern_pairs);
6010         memcpy(kern_pair, font->kern_pairs, cPairs * sizeof(*kern_pair));
6011         LeaveCriticalSection( &freetype_cs );
6012         return cPairs;
6013     }
6014     LeaveCriticalSection( &freetype_cs );
6015     return font->total_kern_pairs;
6016 }
6017
6018 #else /* HAVE_FREETYPE */
6019
6020 /*************************************************************************/
6021
6022 BOOL WineEngInit(void)
6023 {
6024     return FALSE;
6025 }
6026 GdiFont *WineEngCreateFontInstance(DC *dc, HFONT hfont)
6027 {
6028     return NULL;
6029 }
6030 BOOL WineEngDestroyFontInstance(HFONT hfont)
6031 {
6032     return FALSE;
6033 }
6034
6035 DWORD WineEngEnumFonts(LPLOGFONTW plf, FONTENUMPROCW proc, LPARAM lparam)
6036 {
6037     return 1;
6038 }
6039
6040 DWORD WineEngGetGlyphIndices(GdiFont *font, LPCWSTR lpstr, INT count,
6041                                 LPWORD pgi, DWORD flags)
6042 {
6043     return GDI_ERROR;
6044 }
6045
6046 DWORD WineEngGetGlyphOutline(GdiFont *font, UINT glyph, UINT format,
6047                              LPGLYPHMETRICS lpgm, DWORD buflen, LPVOID buf,
6048                              const MAT2* lpmat)
6049 {
6050     ERR("called but we don't have FreeType\n");
6051     return GDI_ERROR;
6052 }
6053
6054 BOOL WineEngGetTextMetrics(GdiFont *font, LPTEXTMETRICW ptm)
6055 {
6056     ERR("called but we don't have FreeType\n");
6057     return FALSE;
6058 }
6059
6060 UINT WineEngGetOutlineTextMetrics(GdiFont *font, UINT cbSize,
6061                                   OUTLINETEXTMETRICW *potm)
6062 {
6063     ERR("called but we don't have FreeType\n");
6064     return 0;
6065 }
6066
6067 BOOL WineEngGetCharWidth(GdiFont *font, UINT firstChar, UINT lastChar,
6068                          LPINT buffer)
6069 {
6070     ERR("called but we don't have FreeType\n");
6071     return FALSE;
6072 }
6073
6074 BOOL WineEngGetCharABCWidths(GdiFont *font, UINT firstChar, UINT lastChar,
6075                              LPABC buffer)
6076 {
6077     ERR("called but we don't have FreeType\n");
6078     return FALSE;
6079 }
6080
6081 BOOL WineEngGetCharABCWidthsI(GdiFont *font, UINT firstChar, UINT count, LPWORD pgi,
6082                               LPABC buffer)
6083 {
6084     ERR("called but we don't have FreeType\n");
6085     return FALSE;
6086 }
6087
6088 BOOL WineEngGetTextExtentExPoint(GdiFont *font, LPCWSTR wstr, INT count,
6089                                  INT max_ext, LPINT nfit, LPINT dx, LPSIZE size)
6090 {
6091     ERR("called but we don't have FreeType\n");
6092     return FALSE;
6093 }
6094
6095 BOOL WineEngGetTextExtentExPointI(GdiFont *font, const WORD *indices, INT count,
6096                                   INT max_ext, LPINT nfit, LPINT dx, LPSIZE size)
6097 {
6098     ERR("called but we don't have FreeType\n");
6099     return FALSE;
6100 }
6101
6102 DWORD WineEngGetFontData(GdiFont *font, DWORD table, DWORD offset, LPVOID buf,
6103                          DWORD cbData)
6104 {
6105     ERR("called but we don't have FreeType\n");
6106     return GDI_ERROR;
6107 }
6108
6109 INT WineEngGetTextFace(GdiFont *font, INT count, LPWSTR str)
6110 {
6111     ERR("called but we don't have FreeType\n");
6112     return 0;
6113 }
6114
6115 INT WineEngAddFontResourceEx(LPCWSTR file, DWORD flags, PVOID pdv)
6116 {
6117     FIXME(":stub\n");
6118     return 1;
6119 }
6120
6121 INT WineEngRemoveFontResourceEx(LPCWSTR file, DWORD flags, PVOID pdv)
6122 {
6123     FIXME(":stub\n");
6124     return TRUE;
6125 }
6126
6127 HANDLE WineEngAddFontMemResourceEx(PVOID pbFont, DWORD cbFont, PVOID pdv, DWORD *pcFonts)
6128 {
6129     FIXME(":stub\n");
6130     return NULL;
6131 }
6132
6133 UINT WineEngGetTextCharsetInfo(GdiFont *font, LPFONTSIGNATURE fs, DWORD flags)
6134 {
6135     FIXME(":stub\n");
6136     return DEFAULT_CHARSET;
6137 }
6138
6139 BOOL WineEngGetLinkedHFont(DC *dc, WCHAR c, HFONT *new_hfont, UINT *glyph)
6140 {
6141     return FALSE;
6142 }
6143
6144 DWORD WineEngGetFontUnicodeRanges(GdiFont *font, LPGLYPHSET glyphset)
6145 {
6146     FIXME("(%p, %p): stub\n", font, glyphset);
6147     return 0;
6148 }
6149
6150 BOOL WineEngFontIsLinked(GdiFont *font)
6151 {
6152     return FALSE;
6153 }
6154
6155 /*************************************************************************
6156  *             GetRasterizerCaps   (GDI32.@)
6157  */
6158 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
6159 {
6160     lprs->nSize = sizeof(RASTERIZER_STATUS);
6161     lprs->wFlags = 0;
6162     lprs->nLanguageID = 0;
6163     return TRUE;
6164 }
6165
6166 DWORD WineEngGetKerningPairs(GdiFont *font, DWORD cPairs, KERNINGPAIR *kern_pair)
6167 {
6168     ERR("called but we don't have FreeType\n");
6169     return 0;
6170 }
6171
6172 #endif /* HAVE_FREETYPE */