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