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