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