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