Fixed font enumeration.
[wine] / objects / font.c
1 /*
2  * GDI font objects
3  *
4  * Copyright 1993 Alexandre Julliard
5  *           1997 Alex Korobka
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include <stdlib.h>
23 #include <string.h>
24 #include <assert.h>
25 #include "winerror.h"
26 #include "winnls.h"
27 #include "wine/unicode.h"
28 #include "font.h"
29 #include "options.h"
30 #include "wine/debug.h"
31 #include "gdi.h"
32
33 WINE_DEFAULT_DEBUG_CHANNEL(font);
34 WINE_DECLARE_DEBUG_CHANNEL(gdi);
35
36 #define ENUM_UNICODE    0x00000001
37 #define ENUM_CALLED     0x00000002
38
39 typedef struct
40 {
41   LPLOGFONT16           lpLogFontParam;
42   FONTENUMPROCEX16      lpEnumFunc;
43   LPARAM                lpData;
44
45   LPNEWTEXTMETRICEX16   lpTextMetric;
46   LPENUMLOGFONTEX16     lpLogFont;
47   SEGPTR                segTextMetric;
48   SEGPTR                segLogFont;
49 } fontEnum16;
50
51 typedef struct
52 {
53   LPLOGFONTW          lpLogFontParam;
54   FONTENUMPROCEXW     lpEnumFunc;
55   LPARAM              lpData;
56   DWORD               dwFlags;
57 } fontEnum32;
58  
59 /*
60  *  For TranslateCharsetInfo
61  */
62 #define FS(x) {{0,0,0,0},{0x1<<(x),0}}
63 #define MAXTCIINDEX 32
64 static CHARSETINFO FONT_tci[MAXTCIINDEX] = {
65   /* ANSI */
66   { ANSI_CHARSET, 1252, FS(0)},
67   { EASTEUROPE_CHARSET, 1250, FS(1)},
68   { RUSSIAN_CHARSET, 1251, FS(2)},
69   { GREEK_CHARSET, 1253, FS(3)},
70   { TURKISH_CHARSET, 1254, FS(4)},
71   { HEBREW_CHARSET, 1255, FS(5)},
72   { ARABIC_CHARSET, 1256, FS(6)},
73   { BALTIC_CHARSET, 1257, FS(7)},
74   /* reserved by ANSI */
75   { DEFAULT_CHARSET, 0, FS(0)},
76   { DEFAULT_CHARSET, 0, FS(0)},
77   { DEFAULT_CHARSET, 0, FS(0)},
78   { DEFAULT_CHARSET, 0, FS(0)},
79   { DEFAULT_CHARSET, 0, FS(0)},
80   { DEFAULT_CHARSET, 0, FS(0)},
81   { DEFAULT_CHARSET, 0, FS(0)},
82   { DEFAULT_CHARSET, 0, FS(0)},
83   /* ANSI and OEM */
84   { THAI_CHARSET,  874,  FS(16)},
85   { SHIFTJIS_CHARSET, 932, FS(17)},
86   { GB2312_CHARSET, 936, FS(18)},
87   { HANGEUL_CHARSET, 949, FS(19)},
88   { CHINESEBIG5_CHARSET, 950, FS(20)},
89   { JOHAB_CHARSET, 1361, FS(21)}, 
90   /* reserved for alternate ANSI and OEM */
91   { DEFAULT_CHARSET, 0, FS(0)},
92   { DEFAULT_CHARSET, 0, FS(0)},
93   { DEFAULT_CHARSET, 0, FS(0)},
94   { DEFAULT_CHARSET, 0, FS(0)},
95   { DEFAULT_CHARSET, 0, FS(0)},
96   { DEFAULT_CHARSET, 0, FS(0)},
97   { DEFAULT_CHARSET, 0, FS(0)},
98   { DEFAULT_CHARSET, 0, FS(0)},
99   /* reserved for system */
100   { DEFAULT_CHARSET, 0, FS(0)},
101   { DEFAULT_CHARSET, 0, FS(0)},
102 };
103
104 /* ### start build ### */
105 extern WORD CALLBACK FONT_CallTo16_word_llwl(FONTENUMPROCEX16,LONG,LONG,WORD,LONG);
106 /* ### stop build ### */
107
108 /***********************************************************************
109  *              LOGFONT conversion functions.
110  */
111 void FONT_LogFontATo16( const LOGFONTA* font32, LPLOGFONT16 font16 )
112 {
113     font16->lfHeight = font32->lfHeight;
114     font16->lfWidth = font32->lfWidth;
115     font16->lfEscapement = font32->lfEscapement;
116     font16->lfOrientation = font32->lfOrientation;
117     font16->lfWeight = font32->lfWeight;
118     font16->lfItalic = font32->lfItalic;
119     font16->lfUnderline = font32->lfUnderline;
120     font16->lfStrikeOut = font32->lfStrikeOut;
121     font16->lfCharSet = font32->lfCharSet;
122     font16->lfOutPrecision = font32->lfOutPrecision;
123     font16->lfClipPrecision = font32->lfClipPrecision;
124     font16->lfQuality = font32->lfQuality;
125     font16->lfPitchAndFamily = font32->lfPitchAndFamily;
126     lstrcpynA( font16->lfFaceName, font32->lfFaceName, LF_FACESIZE );
127 }
128
129 void FONT_LogFontWTo16( const LOGFONTW* font32, LPLOGFONT16 font16 )
130 {
131     font16->lfHeight = font32->lfHeight;
132     font16->lfWidth = font32->lfWidth;
133     font16->lfEscapement = font32->lfEscapement;
134     font16->lfOrientation = font32->lfOrientation;
135     font16->lfWeight = font32->lfWeight;
136     font16->lfItalic = font32->lfItalic;
137     font16->lfUnderline = font32->lfUnderline;
138     font16->lfStrikeOut = font32->lfStrikeOut;
139     font16->lfCharSet = font32->lfCharSet;
140     font16->lfOutPrecision = font32->lfOutPrecision;
141     font16->lfClipPrecision = font32->lfClipPrecision;
142     font16->lfQuality = font32->lfQuality;
143     font16->lfPitchAndFamily = font32->lfPitchAndFamily;
144     WideCharToMultiByte( CP_ACP, 0, font32->lfFaceName, -1,
145                          font16->lfFaceName, LF_FACESIZE, NULL, NULL );
146     font16->lfFaceName[LF_FACESIZE-1] = 0;
147 }
148
149 void FONT_LogFont16ToA( const LOGFONT16 *font16, LPLOGFONTA font32 )
150 {
151     font32->lfHeight = font16->lfHeight;
152     font32->lfWidth = font16->lfWidth;
153     font32->lfEscapement = font16->lfEscapement;
154     font32->lfOrientation = font16->lfOrientation;
155     font32->lfWeight = font16->lfWeight;
156     font32->lfItalic = font16->lfItalic;
157     font32->lfUnderline = font16->lfUnderline;
158     font32->lfStrikeOut = font16->lfStrikeOut;
159     font32->lfCharSet = font16->lfCharSet;
160     font32->lfOutPrecision = font16->lfOutPrecision;
161     font32->lfClipPrecision = font16->lfClipPrecision;
162     font32->lfQuality = font16->lfQuality;
163     font32->lfPitchAndFamily = font16->lfPitchAndFamily;
164     lstrcpynA( font32->lfFaceName, font16->lfFaceName, LF_FACESIZE );
165 }
166
167 void FONT_LogFont16ToW( const LOGFONT16 *font16, LPLOGFONTW font32 )
168 {
169     font32->lfHeight = font16->lfHeight;
170     font32->lfWidth = font16->lfWidth;
171     font32->lfEscapement = font16->lfEscapement;
172     font32->lfOrientation = font16->lfOrientation;
173     font32->lfWeight = font16->lfWeight;
174     font32->lfItalic = font16->lfItalic;
175     font32->lfUnderline = font16->lfUnderline;
176     font32->lfStrikeOut = font16->lfStrikeOut;
177     font32->lfCharSet = font16->lfCharSet;
178     font32->lfOutPrecision = font16->lfOutPrecision;
179     font32->lfClipPrecision = font16->lfClipPrecision;
180     font32->lfQuality = font16->lfQuality;
181     font32->lfPitchAndFamily = font16->lfPitchAndFamily;
182     MultiByteToWideChar( CP_ACP, 0, font16->lfFaceName, -1, font32->lfFaceName, LF_FACESIZE );
183     font32->lfFaceName[LF_FACESIZE-1] = 0;
184 }
185
186 void FONT_LogFontAToW( const LOGFONTA *fontA, LPLOGFONTW fontW )
187 {
188     memcpy(fontW, fontA, sizeof(LOGFONTA) - LF_FACESIZE);
189     MultiByteToWideChar(CP_ACP, 0, fontA->lfFaceName, -1, fontW->lfFaceName,
190                         LF_FACESIZE);
191 }
192
193 void FONT_LogFontWToA( const LOGFONTW *fontW, LPLOGFONTA fontA )
194 {
195     memcpy(fontA, fontW, sizeof(LOGFONTA) - LF_FACESIZE);
196     WideCharToMultiByte(CP_ACP, 0, fontW->lfFaceName, -1, fontA->lfFaceName,
197                         LF_FACESIZE, NULL, NULL);
198 }
199
200 void FONT_EnumLogFontEx16ToA( const ENUMLOGFONTEX16 *font16, LPENUMLOGFONTEXA font32 )
201 {
202     FONT_LogFont16ToA( (LPLOGFONT16)font16, (LPLOGFONTA)font32);
203     lstrcpynA( font32->elfFullName, font16->elfFullName, LF_FULLFACESIZE );
204     lstrcpynA( font32->elfStyle, font16->elfStyle, LF_FACESIZE );
205     lstrcpynA( font32->elfScript, font16->elfScript, LF_FACESIZE );
206 }
207
208 void FONT_EnumLogFontEx16ToW( const ENUMLOGFONTEX16 *font16, LPENUMLOGFONTEXW font32 )
209 {
210     FONT_LogFont16ToW( (LPLOGFONT16)font16, (LPLOGFONTW)font32);
211
212     MultiByteToWideChar( CP_ACP, 0, font16->elfFullName, -1, font32->elfFullName, LF_FULLFACESIZE );
213     font32->elfFullName[LF_FULLFACESIZE-1] = 0;
214     MultiByteToWideChar( CP_ACP, 0, font16->elfStyle, -1, font32->elfStyle, LF_FACESIZE );
215     font32->elfStyle[LF_FACESIZE-1] = 0;
216     MultiByteToWideChar( CP_ACP, 0, font16->elfScript, -1, font32->elfScript, LF_FACESIZE );
217     font32->elfScript[LF_FACESIZE-1] = 0;
218 }
219
220 void FONT_EnumLogFontExWTo16( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEX16 font16 )
221 {
222     FONT_LogFontWTo16( (LPLOGFONTW)fontW, (LPLOGFONT16)font16);
223
224     WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
225                          font16->elfFullName, LF_FULLFACESIZE, NULL, NULL );
226     font16->elfFullName[LF_FULLFACESIZE-1] = '\0';
227     WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
228                          font16->elfStyle, LF_FACESIZE, NULL, NULL );
229     font16->elfStyle[LF_FACESIZE-1] = '\0';
230     WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
231                          font16->elfScript, LF_FACESIZE, NULL, NULL );
232     font16->elfScript[LF_FACESIZE-1] = '\0';
233 }
234
235 void FONT_EnumLogFontExWToA( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEXA fontA )
236 {
237     FONT_LogFontWToA( (LPLOGFONTW)fontW, (LPLOGFONTA)fontA);
238
239     WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1,
240                          fontA->elfFullName, LF_FULLFACESIZE, NULL, NULL );
241     fontA->elfFullName[LF_FULLFACESIZE-1] = '\0';
242     WideCharToMultiByte( CP_ACP, 0, fontW->elfStyle, -1,
243                          fontA->elfStyle, LF_FACESIZE, NULL, NULL );
244     fontA->elfStyle[LF_FACESIZE-1] = '\0';
245     WideCharToMultiByte( CP_ACP, 0, fontW->elfScript, -1,
246                          fontA->elfScript, LF_FACESIZE, NULL, NULL );
247     fontA->elfScript[LF_FACESIZE-1] = '\0';
248 }
249
250 /***********************************************************************
251  *              TEXTMETRIC conversion functions.
252  */
253 void FONT_TextMetricATo16(const TEXTMETRICA *ptm32, LPTEXTMETRIC16 ptm16 )
254 {
255     ptm16->tmHeight = ptm32->tmHeight;
256     ptm16->tmAscent = ptm32->tmAscent;
257     ptm16->tmDescent = ptm32->tmDescent;
258     ptm16->tmInternalLeading = ptm32->tmInternalLeading;
259     ptm16->tmExternalLeading = ptm32->tmExternalLeading;
260     ptm16->tmAveCharWidth = ptm32->tmAveCharWidth;
261     ptm16->tmMaxCharWidth = ptm32->tmMaxCharWidth;
262     ptm16->tmWeight = ptm32->tmWeight;
263     ptm16->tmOverhang = ptm32->tmOverhang;
264     ptm16->tmDigitizedAspectX = ptm32->tmDigitizedAspectX;
265     ptm16->tmDigitizedAspectY = ptm32->tmDigitizedAspectY;
266     ptm16->tmFirstChar = ptm32->tmFirstChar;
267     ptm16->tmLastChar = ptm32->tmLastChar;
268     ptm16->tmDefaultChar = ptm32->tmDefaultChar;
269     ptm16->tmBreakChar = ptm32->tmBreakChar;
270     ptm16->tmItalic = ptm32->tmItalic;
271     ptm16->tmUnderlined = ptm32->tmUnderlined;
272     ptm16->tmStruckOut = ptm32->tmStruckOut;
273     ptm16->tmPitchAndFamily = ptm32->tmPitchAndFamily;
274     ptm16->tmCharSet = ptm32->tmCharSet;
275 }
276
277 void FONT_TextMetricWTo16(const TEXTMETRICW *ptm32, LPTEXTMETRIC16 ptm16 )
278 {
279     ptm16->tmHeight = ptm32->tmHeight;
280     ptm16->tmAscent = ptm32->tmAscent;
281     ptm16->tmDescent = ptm32->tmDescent;
282     ptm16->tmInternalLeading = ptm32->tmInternalLeading;
283     ptm16->tmExternalLeading = ptm32->tmExternalLeading;
284     ptm16->tmAveCharWidth = ptm32->tmAveCharWidth;
285     ptm16->tmMaxCharWidth = ptm32->tmMaxCharWidth;
286     ptm16->tmWeight = ptm32->tmWeight;
287     ptm16->tmOverhang = ptm32->tmOverhang;
288     ptm16->tmDigitizedAspectX = ptm32->tmDigitizedAspectX;
289     ptm16->tmDigitizedAspectY = ptm32->tmDigitizedAspectY;
290     ptm16->tmFirstChar = ptm32->tmFirstChar;
291     ptm16->tmLastChar = ptm32->tmLastChar;
292     ptm16->tmDefaultChar = ptm32->tmDefaultChar;
293     ptm16->tmBreakChar = ptm32->tmBreakChar;
294     ptm16->tmItalic = ptm32->tmItalic;
295     ptm16->tmUnderlined = ptm32->tmUnderlined;
296     ptm16->tmStruckOut = ptm32->tmStruckOut;
297     ptm16->tmPitchAndFamily = ptm32->tmPitchAndFamily;
298     ptm16->tmCharSet = ptm32->tmCharSet;
299 }
300
301 void FONT_TextMetric16ToA(const TEXTMETRIC16 *ptm16, LPTEXTMETRICA ptm32 )
302 {
303     ptm32->tmHeight = ptm16->tmHeight;
304     ptm32->tmAscent = ptm16->tmAscent;
305     ptm32->tmDescent = ptm16->tmDescent;
306     ptm32->tmInternalLeading = ptm16->tmInternalLeading;
307     ptm32->tmExternalLeading = ptm16->tmExternalLeading;
308     ptm32->tmAveCharWidth = ptm16->tmAveCharWidth;
309     ptm32->tmMaxCharWidth = ptm16->tmMaxCharWidth;
310     ptm32->tmWeight = ptm16->tmWeight;
311     ptm32->tmOverhang = ptm16->tmOverhang;
312     ptm32->tmDigitizedAspectX = ptm16->tmDigitizedAspectX;
313     ptm32->tmDigitizedAspectY = ptm16->tmDigitizedAspectY;
314     ptm32->tmFirstChar = ptm16->tmFirstChar;
315     ptm32->tmLastChar = ptm16->tmLastChar;
316     ptm32->tmDefaultChar = ptm16->tmDefaultChar;
317     ptm32->tmBreakChar = ptm16->tmBreakChar;
318     ptm32->tmItalic = ptm16->tmItalic;
319     ptm32->tmUnderlined = ptm16->tmUnderlined;
320     ptm32->tmStruckOut = ptm16->tmStruckOut;
321     ptm32->tmPitchAndFamily = ptm16->tmPitchAndFamily;
322     ptm32->tmCharSet = ptm16->tmCharSet;
323 }
324
325 void FONT_TextMetric16ToW(const TEXTMETRIC16 *ptm16, LPTEXTMETRICW ptm32 )
326 {
327     ptm32->tmHeight = ptm16->tmHeight;
328     ptm32->tmAscent = ptm16->tmAscent;
329     ptm32->tmDescent = ptm16->tmDescent;
330     ptm32->tmInternalLeading = ptm16->tmInternalLeading;
331     ptm32->tmExternalLeading = ptm16->tmExternalLeading;
332     ptm32->tmAveCharWidth = ptm16->tmAveCharWidth;
333     ptm32->tmMaxCharWidth = ptm16->tmMaxCharWidth;
334     ptm32->tmWeight = ptm16->tmWeight;
335     ptm32->tmOverhang = ptm16->tmOverhang;
336     ptm32->tmDigitizedAspectX = ptm16->tmDigitizedAspectX;
337     ptm32->tmDigitizedAspectY = ptm16->tmDigitizedAspectY;
338     ptm32->tmFirstChar = ptm16->tmFirstChar;
339     ptm32->tmLastChar = ptm16->tmLastChar;
340     ptm32->tmDefaultChar = ptm16->tmDefaultChar;
341     ptm32->tmBreakChar = ptm16->tmBreakChar;
342     ptm32->tmItalic = ptm16->tmItalic;
343     ptm32->tmUnderlined = ptm16->tmUnderlined;
344     ptm32->tmStruckOut = ptm16->tmStruckOut;
345     ptm32->tmPitchAndFamily = ptm16->tmPitchAndFamily;
346     ptm32->tmCharSet = ptm16->tmCharSet;
347 }
348
349 void FONT_TextMetricAToW(const TEXTMETRICA *ptm32A, LPTEXTMETRICW ptm32W )
350 {
351     ptm32W->tmHeight = ptm32A->tmHeight;
352     ptm32W->tmAscent = ptm32A->tmAscent;
353     ptm32W->tmDescent = ptm32A->tmDescent;
354     ptm32W->tmInternalLeading = ptm32A->tmInternalLeading;
355     ptm32W->tmExternalLeading = ptm32A->tmExternalLeading;
356     ptm32W->tmAveCharWidth = ptm32A->tmAveCharWidth;
357     ptm32W->tmMaxCharWidth = ptm32A->tmMaxCharWidth;
358     ptm32W->tmWeight = ptm32A->tmWeight;
359     ptm32W->tmOverhang = ptm32A->tmOverhang;
360     ptm32W->tmDigitizedAspectX = ptm32A->tmDigitizedAspectX;
361     ptm32W->tmDigitizedAspectY = ptm32A->tmDigitizedAspectY;
362     ptm32W->tmFirstChar = ptm32A->tmFirstChar;
363     ptm32W->tmLastChar = ptm32A->tmLastChar;
364     ptm32W->tmDefaultChar = ptm32A->tmDefaultChar;
365     ptm32W->tmBreakChar = ptm32A->tmBreakChar;
366     ptm32W->tmItalic = ptm32A->tmItalic;
367     ptm32W->tmUnderlined = ptm32A->tmUnderlined;
368     ptm32W->tmStruckOut = ptm32A->tmStruckOut;
369     ptm32W->tmPitchAndFamily = ptm32A->tmPitchAndFamily;
370     ptm32W->tmCharSet = ptm32A->tmCharSet;
371 }
372
373 void FONT_TextMetricWToA(const TEXTMETRICW *ptmW, LPTEXTMETRICA ptmA )
374 {
375     ptmA->tmHeight = ptmW->tmHeight;
376     ptmA->tmAscent = ptmW->tmAscent;
377     ptmA->tmDescent = ptmW->tmDescent;
378     ptmA->tmInternalLeading = ptmW->tmInternalLeading;
379     ptmA->tmExternalLeading = ptmW->tmExternalLeading;
380     ptmA->tmAveCharWidth = ptmW->tmAveCharWidth;
381     ptmA->tmMaxCharWidth = ptmW->tmMaxCharWidth;
382     ptmA->tmWeight = ptmW->tmWeight;
383     ptmA->tmOverhang = ptmW->tmOverhang;
384     ptmA->tmDigitizedAspectX = ptmW->tmDigitizedAspectX;
385     ptmA->tmDigitizedAspectY = ptmW->tmDigitizedAspectY;
386     ptmA->tmFirstChar = ptmW->tmFirstChar;
387     ptmA->tmLastChar = ptmW->tmLastChar;
388     ptmA->tmDefaultChar = ptmW->tmDefaultChar;
389     ptmA->tmBreakChar = ptmW->tmBreakChar;
390     ptmA->tmItalic = ptmW->tmItalic;
391     ptmA->tmUnderlined = ptmW->tmUnderlined;
392     ptmA->tmStruckOut = ptmW->tmStruckOut;
393     ptmA->tmPitchAndFamily = ptmW->tmPitchAndFamily;
394     ptmA->tmCharSet = ptmW->tmCharSet;
395 }
396
397
398 void FONT_NewTextMetricExWTo16(const NEWTEXTMETRICEXW *ptmW, LPNEWTEXTMETRICEX16 ptm16 )
399 {
400     FONT_TextMetricWTo16((LPTEXTMETRICW)ptmW, (LPTEXTMETRIC16)ptm16);
401     ptm16->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
402     ptm16->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
403     ptm16->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
404     ptm16->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
405     memcpy(&ptm16->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
406 }
407
408 void FONT_NewTextMetricExWToA(const NEWTEXTMETRICEXW *ptmW, LPNEWTEXTMETRICEXA ptmA )
409 {
410     FONT_TextMetricWToA((LPTEXTMETRICW)ptmW, (LPTEXTMETRICA)ptmA);
411     ptmA->ntmTm.ntmFlags = ptmW->ntmTm.ntmFlags;
412     ptmA->ntmTm.ntmSizeEM = ptmW->ntmTm.ntmSizeEM;
413     ptmA->ntmTm.ntmCellHeight = ptmW->ntmTm.ntmCellHeight;
414     ptmA->ntmTm.ntmAvgWidth = ptmW->ntmTm.ntmAvgWidth;
415     memcpy(&ptmA->ntmFontSig, &ptmW->ntmFontSig, sizeof(FONTSIGNATURE));
416 }
417
418 void FONT_NewTextMetricEx16ToW(const NEWTEXTMETRICEX16 *ptm16, LPNEWTEXTMETRICEXW ptmW )
419 {
420     FONT_TextMetric16ToW((LPTEXTMETRIC16)ptm16, (LPTEXTMETRICW)ptmW);
421     ptmW->ntmTm.ntmFlags = ptm16->ntmTm.ntmFlags;
422     ptmW->ntmTm.ntmSizeEM = ptm16->ntmTm.ntmSizeEM;
423     ptmW->ntmTm.ntmCellHeight = ptm16->ntmTm.ntmCellHeight;
424     ptmW->ntmTm.ntmAvgWidth = ptm16->ntmTm.ntmAvgWidth;
425     memcpy(&ptmW->ntmFontSig, &ptm16->ntmFontSig, sizeof(FONTSIGNATURE));
426 }
427
428
429 /***********************************************************************
430  *           CreateFontIndirect   (GDI.57)
431  */
432 HFONT16 WINAPI CreateFontIndirect16( const LOGFONT16 *plf16 )
433 {
434     LOGFONTW lfW;
435
436     if(plf16) {
437         FONT_LogFont16ToW( plf16, &lfW );
438         return CreateFontIndirectW( &lfW );
439     } else {
440         return CreateFontIndirectW( NULL );
441     }
442 }
443
444
445 /***********************************************************************
446  *           CreateFontIndirectA   (GDI32.@)
447  */
448 HFONT WINAPI CreateFontIndirectA( const LOGFONTA *plfA )
449 {
450     LOGFONTW lfW;
451
452     if (plfA) {
453         FONT_LogFontAToW( plfA, &lfW );
454         return CreateFontIndirectW( &lfW );
455      } else
456         return CreateFontIndirectW( NULL );
457
458 }
459
460 /***********************************************************************
461  *           CreateFontIndirectW   (GDI32.@)
462  */
463 HFONT WINAPI CreateFontIndirectW( const LOGFONTW *plf )
464 {
465     HFONT hFont = 0;
466
467     if (plf)
468     {
469         FONTOBJ* fontPtr;
470         if ((fontPtr = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC, &hFont )))
471         {
472             memcpy( &fontPtr->logfont, plf, sizeof(LOGFONTW) );
473
474             TRACE("(%ld %ld %ld %ld %x) %s %s %s => %04x\n",
475                   plf->lfHeight, plf->lfWidth, 
476                   plf->lfEscapement, plf->lfOrientation,
477                   plf->lfPitchAndFamily,
478                   debugstr_w(plf->lfFaceName),
479                   plf->lfWeight > 400 ? "Bold" : "",
480                   plf->lfItalic ? "Italic" : "", hFont);
481
482             if (plf->lfEscapement != plf->lfOrientation) {
483               /* this should really depend on whether GM_ADVANCED is set */
484               fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
485               WARN("orientation angle %f set to "
486                    "escapement angle %f for new font %04x\n", 
487                    plf->lfOrientation/10., plf->lfEscapement/10., hFont);
488             }
489             GDI_ReleaseObj( hFont );
490         }
491     }
492     else WARN("(NULL) => NULL\n");
493
494     return hFont;
495 }
496
497 /***********************************************************************
498  *           CreateFont    (GDI.56)
499  */
500 HFONT16 WINAPI CreateFont16(INT16 height, INT16 width, INT16 esc, INT16 orient,
501                             INT16 weight, BYTE italic, BYTE underline,
502                             BYTE strikeout, BYTE charset, BYTE outpres,
503                             BYTE clippres, BYTE quality, BYTE pitch,
504                             LPCSTR name )
505 {
506     LOGFONT16 logfont;
507
508     logfont.lfHeight = height;
509     logfont.lfWidth = width;
510     logfont.lfEscapement = esc;
511     logfont.lfOrientation = orient;
512     logfont.lfWeight = weight;
513     logfont.lfItalic = italic;
514     logfont.lfUnderline = underline;
515     logfont.lfStrikeOut = strikeout;
516     logfont.lfCharSet = charset;
517     logfont.lfOutPrecision = outpres;
518     logfont.lfClipPrecision = clippres;
519     logfont.lfQuality = quality;
520     logfont.lfPitchAndFamily = pitch;
521    
522     if (name) 
523         lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
524     else 
525         logfont.lfFaceName[0] = '\0';
526
527     return CreateFontIndirect16( &logfont );
528 }
529
530 /*************************************************************************
531  *           CreateFontA    (GDI32.@)
532  */
533 HFONT WINAPI CreateFontA( INT height, INT width, INT esc,
534                               INT orient, INT weight, DWORD italic,
535                               DWORD underline, DWORD strikeout, DWORD charset,
536                               DWORD outpres, DWORD clippres, DWORD quality,
537                               DWORD pitch, LPCSTR name )
538 {
539     LOGFONTA logfont;
540
541     logfont.lfHeight = height;
542     logfont.lfWidth = width;
543     logfont.lfEscapement = esc;
544     logfont.lfOrientation = orient;
545     logfont.lfWeight = weight;
546     logfont.lfItalic = italic;
547     logfont.lfUnderline = underline;
548     logfont.lfStrikeOut = strikeout;
549     logfont.lfCharSet = charset;
550     logfont.lfOutPrecision = outpres;
551     logfont.lfClipPrecision = clippres;
552     logfont.lfQuality = quality;
553     logfont.lfPitchAndFamily = pitch;
554    
555     if (name) 
556         lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
557     else 
558         logfont.lfFaceName[0] = '\0';
559
560     return CreateFontIndirectA( &logfont );
561 }
562
563 /*************************************************************************
564  *           CreateFontW    (GDI32.@)
565  */
566 HFONT WINAPI CreateFontW( INT height, INT width, INT esc,
567                               INT orient, INT weight, DWORD italic,
568                               DWORD underline, DWORD strikeout, DWORD charset,
569                               DWORD outpres, DWORD clippres, DWORD quality,
570                               DWORD pitch, LPCWSTR name )
571 {
572     LOGFONTW logfont;
573
574     logfont.lfHeight = height;
575     logfont.lfWidth = width;
576     logfont.lfEscapement = esc;
577     logfont.lfOrientation = orient;
578     logfont.lfWeight = weight;
579     logfont.lfItalic = italic;
580     logfont.lfUnderline = underline;
581     logfont.lfStrikeOut = strikeout;
582     logfont.lfCharSet = charset;
583     logfont.lfOutPrecision = outpres;
584     logfont.lfClipPrecision = clippres;
585     logfont.lfQuality = quality;
586     logfont.lfPitchAndFamily = pitch;
587    
588     if (name) 
589         lstrcpynW(logfont.lfFaceName, name, 
590                   sizeof(logfont.lfFaceName) / sizeof(WCHAR));
591     else 
592         logfont.lfFaceName[0] = '\0';
593
594     return CreateFontIndirectW( &logfont );
595 }
596
597
598 /***********************************************************************
599  *           FONT_GetObject16
600  */
601 INT16 FONT_GetObject16( FONTOBJ * font, INT16 count, LPSTR buffer )
602 {
603     LOGFONT16 lf16;
604
605     FONT_LogFontWTo16( &font->logfont, &lf16 );
606
607     if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
608     memcpy( buffer, &lf16, count );
609     return count;
610 }
611
612 /***********************************************************************
613  *           FONT_GetObjectA
614  */
615 INT FONT_GetObjectA( FONTOBJ *font, INT count, LPSTR buffer )
616 {
617     LOGFONTA lfA;
618
619     FONT_LogFontWToA( &font->logfont, &lfA );
620
621     if (count > sizeof(lfA)) count = sizeof(lfA);
622     memcpy( buffer, &lfA, count );
623     return count;
624 }
625 /***********************************************************************
626  *           FONT_GetObjectW
627  */
628 INT FONT_GetObjectW( FONTOBJ *font, INT count, LPSTR buffer )
629 {
630     if (count > sizeof(LOGFONTW)) count = sizeof(LOGFONTW);
631     memcpy( buffer, &font->logfont, count );
632     return count;
633 }
634
635
636 /***********************************************************************
637  *              FONT_EnumInstance16
638  *
639  * Called by the device driver layer to pass font info
640  * down to the application.
641  */
642 static INT FONT_EnumInstance16( LPENUMLOGFONTEXW plf, LPNEWTEXTMETRICEXW ptm,
643                                 DWORD fType, LPARAM lp )
644 {
645 #define pfe ((fontEnum16*)lp)
646     if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET || 
647         pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
648     {
649         FONT_EnumLogFontExWTo16(plf, pfe->lpLogFont);
650         FONT_NewTextMetricExWTo16(ptm, pfe->lpTextMetric);
651
652         return FONT_CallTo16_word_llwl( pfe->lpEnumFunc, pfe->segLogFont, pfe->segTextMetric,
653                                         (UINT16)fType, (LPARAM)pfe->lpData );
654     }
655 #undef pfe
656     return 1;
657 }
658
659 /***********************************************************************
660  *              FONT_EnumInstance
661  */
662 static INT FONT_EnumInstance( LPENUMLOGFONTEXW plf, LPNEWTEXTMETRICEXW ptm,
663                               DWORD fType, LPARAM lp )
664 {
665     /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
666
667 #define pfe ((fontEnum32*)lp)
668     if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET || 
669         pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
670     {
671         /* convert font metrics */
672
673         pfe->dwFlags |= ENUM_CALLED;
674         if( pfe->dwFlags & ENUM_UNICODE )
675         {
676             return pfe->lpEnumFunc( plf, ptm, fType, pfe->lpData );
677         }
678         else
679         {
680             ENUMLOGFONTEXA logfont;
681             NEWTEXTMETRICEXA tmA;
682
683             FONT_EnumLogFontExWToA( plf, &logfont);
684             FONT_NewTextMetricExWToA( ptm, &tmA );
685
686             return pfe->lpEnumFunc( (LPENUMLOGFONTEXW)&logfont, 
687                                     (LPNEWTEXTMETRICEXW)&tmA, fType,
688                                     pfe->lpData );
689         }
690     }
691 #undef pfe
692     return 1;
693 }
694
695 /***********************************************************************
696  *              EnumFontFamiliesEx      (GDI.613)
697  */
698 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
699                                    FONTENUMPROCEX16 efproc, LPARAM lParam,
700                                    DWORD dwFlags)
701 {
702     BOOL (*enum_func)(HDC,LPLOGFONTW,DEVICEFONTENUMPROC,LPARAM);
703     INT16       retVal = 0;
704     DC*         dc = DC_GetDCPtr( hDC );
705
706     if (!dc) return 0;
707     enum_func = dc->funcs->pEnumDeviceFonts;
708     GDI_ReleaseObj( hDC );
709
710     if (enum_func)
711     {
712         NEWTEXTMETRICEX16 tm16;
713         ENUMLOGFONTEX16 lf16;
714         fontEnum16 fe16;
715         LOGFONTW lfW;
716         FONT_LogFont16ToW(plf, &lfW);
717
718         fe16.lpLogFontParam = plf;
719         fe16.lpEnumFunc = efproc;
720         fe16.lpData = lParam;
721         fe16.lpTextMetric = &tm16;
722         fe16.lpLogFont = &lf16;
723         fe16.segTextMetric = MapLS( &tm16 );
724         fe16.segLogFont = MapLS( &lf16 );
725
726         retVal = enum_func( hDC, &lfW, FONT_EnumInstance16, (LPARAM)&fe16 );
727         UnMapLS( fe16.segTextMetric );
728         UnMapLS( fe16.segLogFont );
729     }
730     return retVal;
731 }
732
733 /***********************************************************************
734  *              FONT_EnumFontFamiliesEx
735  */
736 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf,
737                                     FONTENUMPROCEXW efproc, 
738                                     LPARAM lParam, DWORD dwUnicode)
739 {
740     BOOL (*enum_func)(HDC,LPLOGFONTW,DEVICEFONTENUMPROC,LPARAM);
741     INT ret = 1, ret2;
742     DC *dc = DC_GetDCPtr( hDC );
743     fontEnum32 fe32;
744     BOOL enum_gdi_fonts;
745
746     if (!dc) return 0;
747
748     TRACE("lfFaceName = %s lfCharset = %d\n", debugstr_w(plf->lfFaceName),
749           plf->lfCharSet);
750     fe32.lpLogFontParam = plf;
751     fe32.lpEnumFunc = efproc;
752     fe32.lpData = lParam;
753     fe32.dwFlags = dwUnicode;
754
755     enum_func = dc->funcs->pEnumDeviceFonts;
756     GDI_ReleaseObj( hDC );
757     enum_gdi_fonts = GetDeviceCaps(hDC, TEXTCAPS) & TC_VA_ABLE;
758
759     if (!enum_func && !enum_gdi_fonts) return 0;
760     
761     if (enum_gdi_fonts)
762         ret = WineEngEnumFonts( plf, FONT_EnumInstance, (LPARAM)&fe32 );
763     fe32.dwFlags &= ~ENUM_CALLED;
764     if (ret && enum_func) {
765         ret2 = enum_func( hDC, plf, FONT_EnumInstance, (LPARAM)&fe32 );
766         if(fe32.dwFlags & ENUM_CALLED) /* update ret iff a font gets enumed */
767             ret = ret2;
768     }
769     return ret;
770 }
771
772 /***********************************************************************
773  *              EnumFontFamiliesExW     (GDI32.@)
774  */
775 INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
776                                     FONTENUMPROCEXW efproc, 
777                                     LPARAM lParam, DWORD dwFlags )
778 {
779     return  FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam, ENUM_UNICODE );
780 }
781
782 /***********************************************************************
783  *              EnumFontFamiliesExA     (GDI32.@)
784  */
785 INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf,
786                                     FONTENUMPROCEXA efproc, 
787                                     LPARAM lParam, DWORD dwFlags)
788 {
789     LOGFONTW lfW;
790     FONT_LogFontAToW( plf, &lfW );
791
792     return  FONT_EnumFontFamiliesEx( hDC, &lfW,
793                                      (FONTENUMPROCEXW)efproc, lParam, 0);
794 }
795
796 /***********************************************************************
797  *              EnumFontFamilies        (GDI.330)
798  */
799 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
800                                  FONTENUMPROC16 efproc, LPARAM lpData )
801 {
802     LOGFONT16   lf;
803
804     lf.lfCharSet = DEFAULT_CHARSET;
805     if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
806     else lf.lfFaceName[0] = '\0';
807
808     return EnumFontFamiliesEx16( hDC, &lf, efproc, lpData, 0 );
809 }
810
811 /***********************************************************************
812  *              EnumFontFamiliesA       (GDI32.@)
813  */
814 INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
815                                   FONTENUMPROCA efproc, LPARAM lpData )
816 {
817     LOGFONTA    lf;
818
819     lf.lfCharSet = DEFAULT_CHARSET;
820     if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
821     else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
822
823     return EnumFontFamiliesExA( hDC, &lf, (FONTENUMPROCEXA)efproc, lpData, 0 );
824 }
825
826 /***********************************************************************
827  *              EnumFontFamiliesW       (GDI32.@)
828  */
829 INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
830                                   FONTENUMPROCW efproc, LPARAM lpData )
831 {
832     LOGFONTW  lf;
833
834     lf.lfCharSet = DEFAULT_CHARSET;
835     if( lpFamily ) lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
836     else lf.lfFaceName[0] = 0;
837
838     return EnumFontFamiliesExW( hDC, &lf, (FONTENUMPROCEXW)efproc, lpData, 0 );
839 }
840
841 /***********************************************************************
842  *              EnumFonts               (GDI.70)
843  */
844 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
845                           LPARAM lpData )
846 {
847     return EnumFontFamilies16( hDC, lpName, (FONTENUMPROCEX16)efproc, lpData );
848 }
849
850 /***********************************************************************
851  *              EnumFontsA              (GDI32.@)
852  */
853 INT WINAPI EnumFontsA( HDC hDC, LPCSTR lpName, FONTENUMPROCA efproc,
854                            LPARAM lpData )
855 {
856     return EnumFontFamiliesA( hDC, lpName, efproc, lpData );
857 }
858
859 /***********************************************************************
860  *              EnumFontsW              (GDI32.@)
861  */
862 INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
863                            LPARAM lpData )
864 {
865     return EnumFontFamiliesW( hDC, lpName, efproc, lpData );
866 }
867
868
869 /***********************************************************************
870  *           GetTextCharacterExtra    (GDI.89)
871  */
872 INT16 WINAPI GetTextCharacterExtra16( HDC16 hdc )
873 {
874     return (INT16)GetTextCharacterExtra( hdc );
875 }
876
877
878 /***********************************************************************
879  *           GetTextCharacterExtra    (GDI32.@)
880  */
881 INT WINAPI GetTextCharacterExtra( HDC hdc )
882 {
883     INT ret;
884     DC *dc = DC_GetDCPtr( hdc );
885     if (!dc) return 0;
886     ret = abs( (dc->charExtra * dc->wndExtX + dc->vportExtX / 2)
887                  / dc->vportExtX );
888     GDI_ReleaseObj( hdc );
889     return ret;
890 }
891
892
893 /***********************************************************************
894  *           SetTextCharacterExtra    (GDI.8)
895  */
896 INT16 WINAPI SetTextCharacterExtra16( HDC16 hdc, INT16 extra )
897 {
898     return (INT16)SetTextCharacterExtra( hdc, extra );
899 }
900
901
902 /***********************************************************************
903  *           SetTextCharacterExtra    (GDI32.@)
904  */
905 INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
906 {
907     INT prev;
908     DC * dc = DC_GetDCPtr( hdc );
909     if (!dc) return 0;
910     if (dc->funcs->pSetTextCharacterExtra)
911         prev = dc->funcs->pSetTextCharacterExtra( dc->physDev, extra );
912     else
913     {
914         extra = (extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX;
915         prev = (dc->charExtra * dc->wndExtX + dc->vportExtX / 2) / dc->vportExtX;
916         dc->charExtra = abs(extra);
917     }
918     GDI_ReleaseObj( hdc );
919     return prev;
920 }
921
922
923 /***********************************************************************
924  *           SetTextJustification    (GDI.10)
925  */
926 INT16 WINAPI SetTextJustification16( HDC16 hdc, INT16 extra, INT16 breaks )
927 {
928     return SetTextJustification( hdc, extra, breaks );
929 }
930
931
932 /***********************************************************************
933  *           SetTextJustification    (GDI32.@)
934  */
935 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
936 {
937     BOOL ret = TRUE;
938     DC * dc = DC_GetDCPtr( hdc );
939     if (!dc) return FALSE;
940     if (dc->funcs->pSetTextJustification)
941         ret = dc->funcs->pSetTextJustification( dc->physDev, extra, breaks );
942     else
943     {
944         extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
945         if (!extra) breaks = 0;
946         dc->breakTotalExtra = extra;
947         dc->breakCount = breaks;
948         if (breaks)
949         {
950             dc->breakExtra = extra / breaks;
951             dc->breakRem   = extra - (dc->breakCount * dc->breakExtra);
952         }
953         else
954         {
955             dc->breakExtra = 0;
956             dc->breakRem   = 0;
957         }
958     }
959     GDI_ReleaseObj( hdc );
960     return ret;
961 }
962
963
964 /***********************************************************************
965  *           GetTextFace    (GDI.92)
966  */
967 INT16 WINAPI GetTextFace16( HDC16 hdc, INT16 count, LPSTR name )
968 {
969         return GetTextFaceA(hdc,count,name);
970 }
971
972 /***********************************************************************
973  *           GetTextFaceA    (GDI32.@)
974  */
975 INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
976 {
977     INT res = GetTextFaceW(hdc, 0, NULL);
978     LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
979     GetTextFaceW( hdc, res, nameW );
980     
981     if (name)
982         res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count,
983                                    NULL, NULL);
984     else
985         res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
986     HeapFree( GetProcessHeap(), 0, nameW );
987     return res;
988 }
989
990 /***********************************************************************
991  *           GetTextFaceW    (GDI32.@)
992  */
993 INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
994 {
995     FONTOBJ *font;
996     INT     ret = 0;
997
998     DC * dc = DC_GetDCPtr( hdc );
999     if (!dc) return 0;
1000
1001     if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
1002     {
1003         if (name)
1004         {
1005             lstrcpynW( name, font->logfont.lfFaceName, count );
1006             ret = strlenW(name);
1007         }
1008         else ret = strlenW(font->logfont.lfFaceName) + 1;
1009         GDI_ReleaseObj( dc->hFont );
1010     }
1011     GDI_ReleaseObj( hdc );
1012     return ret;
1013 }
1014
1015
1016 /***********************************************************************
1017  *           GetTextExtent    (GDI.91)
1018  */
1019 DWORD WINAPI GetTextExtent16( HDC16 hdc, LPCSTR str, INT16 count )
1020 {
1021     SIZE16 size;
1022     if (!GetTextExtentPoint16( hdc, str, count, &size )) return 0;
1023     return MAKELONG( size.cx, size.cy );
1024 }
1025
1026
1027 /***********************************************************************
1028  *           GetTextExtentPoint    (GDI.471)
1029  *
1030  * FIXME: Should this have a bug for compatibility?
1031  * Original Windows versions of GetTextExtentPoint{A,W} have documented
1032  * bugs (-> MSDN KB q147647.txt).
1033  */
1034 BOOL16 WINAPI GetTextExtentPoint16( HDC16 hdc, LPCSTR str, INT16 count,
1035                                     LPSIZE16 size )
1036 {
1037     SIZE size32;
1038     BOOL ret;
1039     TRACE("%04x, %p (%s), %d, %p\n", hdc, str, debugstr_an(str, count), count, size);
1040     ret = GetTextExtentPoint32A( hdc, str, count, &size32 );
1041     size->cx = size32.cx;
1042     size->cy = size32.cy;
1043     return (BOOL16)ret;
1044 }
1045
1046
1047 /***********************************************************************
1048  *           GetTextExtentPoint32A    (GDI32.@)
1049  */
1050 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
1051                                      LPSIZE size )
1052 {
1053     BOOL ret = FALSE;
1054     INT wlen;
1055     LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1056
1057     if (p) {
1058         ret = GetTextExtentPoint32W( hdc, p, wlen, size );
1059         HeapFree( GetProcessHeap(), 0, p );
1060     }
1061
1062     TRACE("(%08x %s %d %p): returning %ld x %ld\n",
1063           hdc, debugstr_an (str, count), count, size, size->cx, size->cy );
1064     return ret;
1065 }
1066
1067
1068 /***********************************************************************
1069  * GetTextExtentPoint32W [GDI32.@]  Computes width/height for a string
1070  *
1071  * Computes width and height of the specified string.
1072  *
1073  * RETURNS
1074  *    Success: TRUE
1075  *    Failure: FALSE
1076  */
1077 BOOL WINAPI GetTextExtentPoint32W(
1078     HDC hdc,     /* [in]  Handle of device context */
1079     LPCWSTR str,   /* [in]  Address of text string */
1080     INT count,   /* [in]  Number of characters in string */
1081     LPSIZE size) /* [out] Address of structure for string size */
1082 {
1083     BOOL ret = FALSE;
1084     DC * dc = DC_GetDCPtr( hdc );
1085     if (!dc) return FALSE;
1086
1087     if(dc->gdiFont)
1088         ret = WineEngGetTextExtentPoint(dc->gdiFont, str, count, size);
1089     else if(dc->funcs->pGetTextExtentPoint)
1090         ret = dc->funcs->pGetTextExtentPoint( dc->physDev, str, count, size );
1091
1092     GDI_ReleaseObj( hdc );
1093
1094     TRACE("(%08x %s %d %p): returning %ld x %ld\n",
1095           hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
1096     return ret;
1097 }
1098
1099
1100 /***********************************************************************
1101  *           GetTextExtentPointA    (GDI32.@)
1102  */
1103 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
1104                                           LPSIZE size )
1105 {
1106     TRACE("not bug compatible.\n");
1107     return GetTextExtentPoint32A( hdc, str, count, size );
1108 }
1109
1110 /***********************************************************************
1111  *           GetTextExtentPointW   (GDI32.@)
1112  */
1113 BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
1114                                           LPSIZE size )
1115 {
1116     TRACE("not bug compatible.\n");
1117     return GetTextExtentPoint32W( hdc, str, count, size );
1118 }
1119
1120
1121 /***********************************************************************
1122  *           GetTextExtentExPointA    (GDI32.@)
1123  */
1124 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
1125                                    INT maxExt, LPINT lpnFit,
1126                                    LPINT alpDx, LPSIZE size )
1127 {
1128     BOOL ret;
1129     INT wlen;
1130     LPWSTR p = FONT_mbtowc( hdc, str, count, &wlen, NULL);
1131     ret = GetTextExtentExPointW( hdc, p, wlen, maxExt, lpnFit, alpDx, size);
1132     HeapFree( GetProcessHeap(), 0, p );
1133     return ret;
1134 }
1135
1136
1137 /***********************************************************************
1138  *           GetTextExtentExPointW    (GDI32.@)
1139  *
1140  * Return the size of the string as it would be if it was output properly by
1141  * e.g. TextOut.
1142  *
1143  * This should include
1144  * - Intercharacter spacing
1145  * - justification spacing (not yet done)
1146  * - kerning? see below
1147  *
1148  * Kerning.  Since kerning would be carried out by the rendering code it should
1149  * be done by the driver.  However they don't support it yet.  Also I am not 
1150  * yet persuaded that (certainly under Win95) any kerning is actually done.
1151  *
1152  * str: According to MSDN this should be null-terminated.  That is not true; a
1153  *      null will not terminate it early.
1154  * size: Certainly under Win95 this appears buggy or weird if *lpnFit is less
1155  *       than count.  I have seen it be either the size of the full string or
1156  *       1 less than the size of the full string.  I have not seen it bear any
1157  *       resemblance to the portion that would fit.
1158  * lpnFit: What exactly is fitting?  Stupidly, in my opinion, it includes the
1159  *         trailing intercharacter spacing and any trailing justification.
1160  *
1161  * FIXME
1162  * Currently we do this by measuring each character etc.  We should do it by
1163  * passing the request to the driver, perhaps by extending the
1164  * pGetTextExtentPoint function to take the alpDx argument.  That would avoid
1165  * thinking about kerning issues and rounding issues in the justification.
1166  */
1167
1168 BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
1169                                    INT maxExt, LPINT lpnFit,
1170                                    LPINT alpDx, LPSIZE size )
1171 {
1172     int index, nFit, extent;
1173     SIZE tSize;
1174     BOOL ret = FALSE;
1175
1176     TRACE("(%08x, %s, %d)\n",hdc,debugstr_wn(str,count),maxExt);
1177
1178     size->cx = size->cy = nFit = extent = 0;
1179     for(index = 0; index < count; index++)
1180     {
1181         if(!GetTextExtentPoint32W( hdc, str, 1, &tSize )) goto done;
1182         /* GetTextExtentPoint includes intercharacter spacing. */
1183         /* FIXME - justification needs doing yet.  Remember that the base
1184          * data will not be in logical coordinates.
1185          */
1186         extent += tSize.cx;
1187         if( !lpnFit || extent <= maxExt )
1188         /* It is allowed to be equal. */
1189         {
1190             nFit++;
1191             if( alpDx ) alpDx[index] = extent;
1192         }
1193         if( tSize.cy > size->cy ) size->cy = tSize.cy;
1194         str++;
1195     }
1196     size->cx = extent;
1197     if(lpnFit) *lpnFit = nFit;
1198     ret = TRUE;
1199
1200     TRACE("returning %d %ld x %ld\n",nFit,size->cx,size->cy);
1201
1202 done:
1203     return ret;
1204 }
1205
1206 /***********************************************************************
1207  *           GetTextMetrics    (GDI.93)
1208  */
1209 BOOL16 WINAPI GetTextMetrics16( HDC16 hdc, TEXTMETRIC16 *metrics )
1210 {
1211     TEXTMETRICW tm32;
1212
1213     if (!GetTextMetricsW( (HDC)hdc, &tm32 )) return FALSE;
1214     FONT_TextMetricWTo16( &tm32, metrics );
1215     return TRUE;
1216 }
1217
1218
1219 /***********************************************************************
1220  *           GetTextMetricsA    (GDI32.@)
1221  */
1222 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1223 {
1224     TEXTMETRICW tm32;
1225
1226     if (!GetTextMetricsW( hdc, &tm32 )) return FALSE;
1227     FONT_TextMetricWToA( &tm32, metrics );
1228     return TRUE;
1229 }
1230
1231 /***********************************************************************
1232  *           GetTextMetricsW    (GDI32.@)
1233  */
1234 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1235 {
1236     BOOL ret = FALSE;
1237     DC * dc = DC_GetDCPtr( hdc );
1238     if (!dc) return FALSE;
1239
1240     if (dc->gdiFont)
1241         ret = WineEngGetTextMetrics(dc->gdiFont, metrics);
1242     else if (dc->funcs->pGetTextMetrics)
1243         ret = dc->funcs->pGetTextMetrics( dc->physDev, metrics );
1244
1245     if (ret)
1246     {
1247     /* device layer returns values in device units
1248      * therefore we have to convert them to logical */
1249
1250 #define WDPTOLP(x) ((x<0)?                                      \
1251                 (-abs((x)*dc->wndExtX/dc->vportExtX)):          \
1252                 (abs((x)*dc->wndExtX/dc->vportExtX)))
1253 #define HDPTOLP(y) ((y<0)?                                      \
1254                 (-abs((y)*dc->wndExtY/dc->vportExtY)):          \
1255                 (abs((y)*dc->wndExtY/dc->vportExtY)))
1256         
1257     metrics->tmHeight           = HDPTOLP(metrics->tmHeight);
1258     metrics->tmAscent           = HDPTOLP(metrics->tmAscent);
1259     metrics->tmDescent          = HDPTOLP(metrics->tmDescent);
1260     metrics->tmInternalLeading  = HDPTOLP(metrics->tmInternalLeading);
1261     metrics->tmExternalLeading  = HDPTOLP(metrics->tmExternalLeading);
1262     metrics->tmAveCharWidth     = WDPTOLP(metrics->tmAveCharWidth);
1263     metrics->tmMaxCharWidth     = WDPTOLP(metrics->tmMaxCharWidth);
1264     metrics->tmOverhang         = WDPTOLP(metrics->tmOverhang);
1265         ret = TRUE;
1266
1267     TRACE("text metrics:\n"
1268           "    Weight = %03li\t FirstChar = %i\t AveCharWidth = %li\n"
1269           "    Italic = % 3i\t LastChar = %i\t\t MaxCharWidth = %li\n"
1270           "    UnderLined = %01i\t DefaultChar = %i\t Overhang = %li\n"
1271           "    StruckOut = %01i\t BreakChar = %i\t CharSet = %i\n"
1272           "    PitchAndFamily = %02x\n"
1273           "    --------------------\n"
1274           "    InternalLeading = %li\n"
1275           "    Ascent = %li\n"
1276           "    Descent = %li\n"
1277           "    Height = %li\n",
1278           metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1279           metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1280           metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1281           metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1282           metrics->tmPitchAndFamily,
1283           metrics->tmInternalLeading,
1284           metrics->tmAscent,
1285           metrics->tmDescent,
1286           metrics->tmHeight );
1287     }
1288     GDI_ReleaseObj( hdc );
1289     return ret;
1290 }
1291
1292
1293 /***********************************************************************
1294  * GetOutlineTextMetrics [GDI.308]  Gets metrics for TrueType fonts.
1295  *
1296  * NOTES
1297  *    lpOTM should be LPOUTLINETEXTMETRIC
1298  *
1299  * RETURNS
1300  *    Success: Non-zero or size of required buffer
1301  *    Failure: 0
1302  */
1303 UINT16 WINAPI GetOutlineTextMetrics16(
1304     HDC16 hdc,    /* [in]  Handle of device context */
1305     UINT16 cbData, /* [in]  Size of metric data array */
1306     LPOUTLINETEXTMETRIC16 lpOTM)  /* [out] Address of metric data array */
1307 {
1308     FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
1309     return 0;
1310 }
1311
1312
1313 /***********************************************************************
1314  *              GetOutlineTextMetricsA (GDI32.@)
1315  * Gets metrics for TrueType fonts.
1316  *
1317  *
1318  * RETURNS
1319  *    Success: Non-zero or size of required buffer
1320  *    Failure: 0
1321  */
1322 UINT WINAPI GetOutlineTextMetricsA(
1323     HDC hdc,    /* [in]  Handle of device context */
1324     UINT cbData, /* [in]  Size of metric data array */
1325     LPOUTLINETEXTMETRICA lpOTM)  /* [out] Address of metric data array */
1326 {
1327     char buf[512], *ptr;
1328     UINT ret, needed;
1329     OUTLINETEXTMETRICW *lpOTMW = (OUTLINETEXTMETRICW *)buf;
1330     INT left, len;
1331
1332     if((ret = GetOutlineTextMetricsW(hdc, sizeof(buf), lpOTMW)) == 0) {
1333         if((ret = GetOutlineTextMetricsW(hdc, 0, NULL)) == 0)
1334             return 0;
1335         lpOTMW = HeapAlloc(GetProcessHeap(), 0, ret);
1336         GetOutlineTextMetricsW(hdc, ret, lpOTMW);
1337     }
1338
1339     needed = sizeof(OUTLINETEXTMETRICA);
1340     if(lpOTMW->otmpFamilyName)
1341         needed += WideCharToMultiByte(CP_ACP, 0,
1342            (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1, 
1343                                       NULL, 0, NULL, NULL);
1344     if(lpOTMW->otmpFaceName)
1345         needed += WideCharToMultiByte(CP_ACP, 0,
1346            (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1, 
1347                                       NULL, 0, NULL, NULL);
1348     if(lpOTMW->otmpStyleName)
1349         needed += WideCharToMultiByte(CP_ACP, 0,
1350            (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1, 
1351                                       NULL, 0, NULL, NULL);
1352     if(lpOTMW->otmpFullName)
1353         needed += WideCharToMultiByte(CP_ACP, 0,
1354            (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1, 
1355                                       NULL, 0, NULL, NULL);
1356
1357     if(!lpOTM) {
1358         ret = needed;
1359         goto end;
1360     }
1361
1362     if(needed > cbData) {
1363         ret = 0;
1364         goto end;
1365     }
1366
1367
1368     lpOTM->otmSize = needed;
1369     FONT_TextMetricWToA( &lpOTMW->otmTextMetrics, &lpOTM->otmTextMetrics );
1370     lpOTM->otmFiller = 0;
1371     lpOTM->otmPanoseNumber = lpOTMW->otmPanoseNumber;
1372     lpOTM->otmfsSelection = lpOTMW->otmfsSelection;
1373     lpOTM->otmfsType = lpOTMW->otmfsType;
1374     lpOTM->otmsCharSlopeRise = lpOTMW->otmsCharSlopeRise;
1375     lpOTM->otmsCharSlopeRun = lpOTMW->otmsCharSlopeRun;
1376     lpOTM->otmItalicAngle = lpOTMW->otmItalicAngle;
1377     lpOTM->otmEMSquare = lpOTMW->otmEMSquare;
1378     lpOTM->otmAscent = lpOTMW->otmAscent;
1379     lpOTM->otmDescent = lpOTMW->otmDescent;
1380     lpOTM->otmLineGap = lpOTMW->otmLineGap;
1381     lpOTM->otmsCapEmHeight = lpOTMW->otmsCapEmHeight;
1382     lpOTM->otmsXHeight = lpOTMW->otmsXHeight;
1383     lpOTM->otmrcFontBox = lpOTMW->otmrcFontBox;
1384     lpOTM->otmMacAscent = lpOTMW->otmMacAscent;
1385     lpOTM->otmMacDescent = lpOTMW->otmMacDescent;
1386     lpOTM->otmMacLineGap = lpOTMW->otmMacLineGap;
1387     lpOTM->otmusMinimumPPEM = lpOTMW->otmusMinimumPPEM;
1388     lpOTM->otmptSubscriptSize = lpOTMW->otmptSubscriptSize;
1389     lpOTM->otmptSubscriptOffset = lpOTMW->otmptSubscriptOffset;
1390     lpOTM->otmptSuperscriptSize = lpOTMW->otmptSuperscriptSize;
1391     lpOTM->otmptSuperscriptOffset = lpOTMW->otmptSuperscriptOffset;
1392     lpOTM->otmsStrikeoutSize = lpOTMW->otmsStrikeoutSize;
1393     lpOTM->otmsStrikeoutPosition = lpOTMW->otmsStrikeoutPosition;
1394     lpOTM->otmsUnderscoreSize = lpOTMW->otmsUnderscoreSize;
1395     lpOTM->otmsUnderscorePosition = lpOTMW->otmsUnderscorePosition;
1396
1397
1398     ptr = (char*)(lpOTM + 1);
1399     left = needed - sizeof(*lpOTM);
1400
1401     if(lpOTMW->otmpFamilyName) {
1402         lpOTM->otmpFamilyName = (LPSTR)(ptr - (char*)lpOTM);
1403         len = WideCharToMultiByte(CP_ACP, 0,
1404              (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1, 
1405                                   ptr, left, NULL, NULL);
1406         left -= len;
1407         ptr += len;
1408     } else
1409         lpOTM->otmpFamilyName = 0;
1410
1411     if(lpOTMW->otmpFaceName) {
1412         lpOTM->otmpFaceName = (LPSTR)(ptr - (char*)lpOTM);
1413         len = WideCharToMultiByte(CP_ACP, 0,
1414              (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1, 
1415                                   ptr, left, NULL, NULL);
1416         left -= len;
1417         ptr += len;
1418     } else
1419         lpOTM->otmpFaceName = 0;
1420
1421     if(lpOTMW->otmpStyleName) {
1422         lpOTM->otmpStyleName = (LPSTR)(ptr - (char*)lpOTM);
1423         len = WideCharToMultiByte(CP_ACP, 0,
1424              (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1, 
1425                                   ptr, left, NULL, NULL);
1426         left -= len;
1427         ptr += len;
1428     } else
1429         lpOTM->otmpStyleName = 0;
1430
1431     if(lpOTMW->otmpFullName) {
1432         lpOTM->otmpFullName = (LPSTR)(ptr - (char*)lpOTM);
1433         len = WideCharToMultiByte(CP_ACP, 0,
1434              (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1, 
1435                                   ptr, left, NULL, NULL);
1436         left -= len;
1437     } else
1438         lpOTM->otmpFullName = 0;
1439     
1440     assert(left == 0);
1441     
1442     ret = needed;
1443
1444 end:
1445     if(lpOTMW != (OUTLINETEXTMETRICW *)buf)
1446         HeapFree(GetProcessHeap(), 0, lpOTMW);
1447
1448     return ret;
1449 }
1450
1451
1452 /***********************************************************************
1453  *           GetOutlineTextMetricsW [GDI32.@]
1454  */
1455 UINT WINAPI GetOutlineTextMetricsW(
1456     HDC hdc,    /* [in]  Handle of device context */
1457     UINT cbData, /* [in]  Size of metric data array */
1458     LPOUTLINETEXTMETRICW lpOTM)  /* [out] Address of metric data array */
1459 {
1460     DC *dc = DC_GetDCPtr( hdc );
1461     UINT ret;
1462
1463     TRACE("(%d,%d,%p)\n", hdc, cbData, lpOTM);
1464     if(!dc) return 0;
1465
1466     if(dc->gdiFont)
1467         ret = WineEngGetOutlineTextMetrics(dc->gdiFont, cbData, lpOTM);
1468
1469     else { /* This stuff was in GetOutlineTextMetricsA, I've moved it here
1470               but really this should just be a return 0. */
1471
1472         ret = sizeof(*lpOTM);
1473         if (lpOTM) {
1474             if(cbData < ret)
1475                 ret = 0;
1476             else {
1477                 memset(lpOTM, 0, ret);
1478                 lpOTM->otmSize = sizeof(*lpOTM);
1479                 GetTextMetricsW(hdc, &lpOTM->otmTextMetrics);
1480                 /*
1481                   Further fill of the structure not implemented,
1482                   Needs real values for the structure members
1483                 */
1484             }
1485         }
1486     }
1487     GDI_ReleaseObj(hdc);
1488     return ret;
1489 }
1490
1491
1492 /***********************************************************************
1493  *           GetCharWidth    (GDI.350)
1494  */
1495 BOOL16 WINAPI GetCharWidth16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1496                               LPINT16 buffer )
1497 {
1498     BOOL        retVal = FALSE;
1499
1500     if( firstChar != lastChar )
1501     {
1502         LPINT   buf32 = (LPINT)HeapAlloc(GetProcessHeap(), 0,
1503                                  sizeof(INT)*(1 + (lastChar - firstChar)));
1504         if( buf32 )
1505         {
1506             LPINT       obuf32 = buf32;
1507             int         i;
1508
1509             retVal = GetCharWidth32A(hdc, firstChar, lastChar, buf32);
1510             if (retVal)
1511             {
1512                 for (i = firstChar; i <= lastChar; i++)
1513                     *buffer++ = *buf32++;
1514             }
1515             HeapFree(GetProcessHeap(), 0, obuf32);
1516         }
1517     }
1518     else /* happens quite often to warrant a special treatment */
1519     {
1520         INT chWidth;
1521         retVal = GetCharWidth32A(hdc, firstChar, lastChar, &chWidth );
1522        *buffer = chWidth;
1523     }
1524     return retVal;
1525 }
1526
1527
1528 /***********************************************************************
1529  *           GetCharWidthW      (GDI32.@)
1530  *           GetCharWidth32W    (GDI32.@)
1531  */
1532 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1533                                LPINT buffer )
1534 {
1535     UINT i, extra;
1536     BOOL ret = FALSE;
1537     DC * dc = DC_GetDCPtr( hdc );
1538     if (!dc) return FALSE;
1539
1540     if (dc->gdiFont)
1541         ret = WineEngGetCharWidth( dc->gdiFont, firstChar, lastChar, buffer );
1542     else if (dc->funcs->pGetCharWidth)
1543         ret = dc->funcs->pGetCharWidth( dc->physDev, firstChar, lastChar, buffer);
1544
1545     if (ret)
1546     {
1547         /* convert device units to logical */
1548
1549         extra = dc->vportExtX >> 1;
1550         for( i = firstChar; i <= lastChar; i++, buffer++ )
1551             *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX;
1552         ret = TRUE;
1553     }
1554     GDI_ReleaseObj( hdc );
1555     return ret;
1556 }
1557
1558
1559 /***********************************************************************
1560  *           GetCharWidthA      (GDI32.@)
1561  *           GetCharWidth32A    (GDI32.@)
1562  */
1563 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1564                                LPINT buffer )
1565 {
1566     INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1567     LPSTR str;
1568     LPWSTR wstr;
1569     BOOL ret = TRUE;
1570
1571     if(count <= 0) return FALSE;
1572     
1573     str = HeapAlloc(GetProcessHeap(), 0, count);
1574     for(i = 0; i < count; i++)
1575         str[i] = (BYTE)(firstChar + i);
1576
1577     wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1578
1579     for(i = 0; i < wlen; i++)
1580     {
1581         if(!GetCharWidth32W(hdc, wstr[i], wstr[i], buffer))
1582         {
1583             ret = FALSE;
1584             break;
1585         }
1586         buffer++;
1587     }
1588
1589     HeapFree(GetProcessHeap(), 0, str);
1590     HeapFree(GetProcessHeap(), 0, wstr);
1591
1592     return ret;
1593 }
1594
1595
1596 /* FIXME: all following APIs ******************************************/
1597  
1598
1599 /***********************************************************************
1600  *           SetMapperFlags    (GDI.349)
1601  */
1602 DWORD WINAPI SetMapperFlags16( HDC16 hDC, DWORD dwFlag )
1603 {
1604     return SetMapperFlags( hDC, dwFlag );
1605 }
1606
1607
1608 /***********************************************************************
1609  *           SetMapperFlags    (GDI32.@)
1610  */
1611 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1612 {
1613     DC *dc = DC_GetDCPtr( hDC );
1614     DWORD ret = 0; 
1615     if(!dc) return 0;
1616     if(dc->funcs->pSetMapperFlags)
1617         ret = dc->funcs->pSetMapperFlags( dc->physDev, dwFlag );
1618     else
1619         FIXME("(0x%04x, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1620     GDI_ReleaseObj( hDC );
1621     return ret;
1622 }
1623
1624 /***********************************************************************
1625  *          GetAspectRatioFilterEx  (GDI.486)
1626  */
1627 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1628 {
1629   FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1630   return FALSE;
1631 }
1632
1633 /***********************************************************************
1634  *          GetAspectRatioFilterEx  (GDI32.@)
1635  */
1636 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1637 {
1638   FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1639   return FALSE;
1640 }
1641
1642 /***********************************************************************
1643  *           GetCharABCWidths   (GDI.307)
1644  */
1645 BOOL16 WINAPI GetCharABCWidths16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1646                                   LPABC16 abc )
1647 {
1648     LPABC       abc32 = HeapAlloc(GetProcessHeap(),0,sizeof(ABC)*(lastChar-firstChar+1));
1649     int         i;
1650
1651     if (!GetCharABCWidthsA( hdc, firstChar, lastChar, abc32 )) {
1652         HeapFree(GetProcessHeap(),0,abc32);
1653         return FALSE;
1654     }
1655
1656     for (i=firstChar;i<=lastChar;i++) {
1657         abc[i-firstChar].abcA = abc32[i-firstChar].abcA;
1658         abc[i-firstChar].abcB = abc32[i-firstChar].abcB;
1659         abc[i-firstChar].abcC = abc32[i-firstChar].abcC;
1660     }
1661     HeapFree(GetProcessHeap(),0,abc32);
1662     return TRUE;
1663 }
1664
1665
1666 /***********************************************************************
1667  *           GetCharABCWidthsA   (GDI32.@)
1668  */
1669 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1670                                   LPABC abc )
1671 {
1672     INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1673     LPSTR str;
1674     LPWSTR wstr;
1675     BOOL ret = TRUE;
1676
1677     if(count <= 0) return FALSE;
1678     
1679     str = HeapAlloc(GetProcessHeap(), 0, count);
1680     for(i = 0; i < count; i++)
1681         str[i] = (BYTE)(firstChar + i);
1682
1683     wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1684
1685     for(i = 0; i < wlen; i++)
1686     {
1687         if(!GetCharABCWidthsW(hdc, wstr[i], wstr[i], abc))
1688         {
1689             ret = FALSE;
1690             break;
1691         }
1692         abc++;
1693     }
1694
1695     HeapFree(GetProcessHeap(), 0, str);
1696     HeapFree(GetProcessHeap(), 0, wstr);
1697
1698     return ret;
1699 }
1700
1701
1702 /******************************************************************************
1703  * GetCharABCWidthsW [GDI32.@]  Retrieves widths of characters in range
1704  *
1705  * PARAMS
1706  *    hdc       [I] Handle of device context
1707  *    firstChar [I] First character in range to query
1708  *    lastChar  [I] Last character in range to query
1709  *    abc       [O] Address of character-width structure
1710  *
1711  * NOTES
1712  *    Only works with TrueType fonts
1713  *
1714  * RETURNS
1715  *    Success: TRUE
1716  *    Failure: FALSE
1717  */
1718 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1719                                    LPABC abc )
1720 {
1721     DC *dc = DC_GetDCPtr(hdc);
1722     int         i;
1723     GLYPHMETRICS gm;
1724     BOOL ret = FALSE;
1725
1726     if(dc->gdiFont) {
1727         for (i=firstChar;i<=lastChar;i++) {
1728             GetGlyphOutlineW(hdc, i, GGO_METRICS, &gm, 0, NULL, NULL);
1729             abc[i-firstChar].abcA = gm.gmptGlyphOrigin.x;
1730             abc[i-firstChar].abcB = gm.gmBlackBoxX;
1731             abc[i-firstChar].abcC = gm.gmCellIncX - gm.gmptGlyphOrigin.x - gm.gmBlackBoxX;
1732         }
1733         ret = TRUE;
1734     }
1735     GDI_ReleaseObj(hdc);
1736     return ret;
1737 }
1738
1739
1740 /***********************************************************************
1741  *           GetGlyphOutline    (GDI.309)
1742  */
1743 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1744                                 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1745                                 LPVOID lpBuffer, const MAT2 *lpmat2 )
1746 {
1747     FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1748           hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1749     return (DWORD)-1; /* failure */
1750 }
1751
1752
1753 /***********************************************************************
1754  *           GetGlyphOutlineA    (GDI32.@)
1755  */
1756 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1757                                  LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1758                                  LPVOID lpBuffer, const MAT2 *lpmat2 )
1759 {
1760     LPWSTR p = NULL;
1761     DWORD ret;
1762     UINT c;
1763
1764     if(!(fuFormat & GGO_GLYPH_INDEX)) {
1765         p = FONT_mbtowc(hdc, (char*)&uChar, 1, NULL, NULL);
1766         c = p[0];
1767     } else
1768         c = uChar;
1769     ret = GetGlyphOutlineW(hdc, c, fuFormat, lpgm, cbBuffer, lpBuffer,
1770                            lpmat2);
1771     if(p)
1772         HeapFree(GetProcessHeap(), 0, p);
1773     return ret;
1774 }
1775
1776 /***********************************************************************
1777  *           GetGlyphOutlineW    (GDI32.@)
1778  */
1779 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1780                                  LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1781                                  LPVOID lpBuffer, const MAT2 *lpmat2 )
1782 {
1783     DC *dc = DC_GetDCPtr(hdc);
1784     DWORD ret;
1785
1786     TRACE("(%04x, %04x, %04x, %p, %ld, %p, %p)\n",
1787           hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1788
1789     if(!dc) return GDI_ERROR;
1790
1791     if(dc->gdiFont)
1792       ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
1793                                    cbBuffer, lpBuffer, lpmat2);
1794     else
1795       ret = GDI_ERROR;
1796
1797     GDI_ReleaseObj(hdc);
1798     return ret;
1799 }
1800
1801 /***********************************************************************
1802  *           CreateScalableFontResource   (GDI.310)
1803  */
1804 BOOL16 WINAPI CreateScalableFontResource16( UINT16 fHidden,
1805                                             LPCSTR lpszResourceFile,
1806                                             LPCSTR fontFile, LPCSTR path )
1807 {
1808     return CreateScalableFontResourceA( fHidden, lpszResourceFile,
1809                                           fontFile, path );
1810 }
1811
1812 /***********************************************************************
1813  *           CreateScalableFontResourceA   (GDI32.@)
1814  */
1815 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1816                                              LPCSTR lpszResourceFile,
1817                                              LPCSTR lpszFontFile,
1818                                              LPCSTR lpszCurrentPath )
1819 {
1820     /* fHidden=1 - only visible for the calling app, read-only, not
1821      * enumbered with EnumFonts/EnumFontFamilies
1822      * lpszCurrentPath can be NULL
1823      */
1824     FIXME("(%ld,%s,%s,%s): stub\n",
1825           fHidden, debugstr_a(lpszResourceFile), debugstr_a(lpszFontFile),
1826           debugstr_a(lpszCurrentPath) );
1827     return FALSE; /* create failed */
1828 }
1829
1830 /***********************************************************************
1831  *           CreateScalableFontResourceW   (GDI32.@)
1832  */
1833 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1834                                              LPCWSTR lpszResourceFile,
1835                                              LPCWSTR lpszFontFile,
1836                                              LPCWSTR lpszCurrentPath )
1837 {
1838     FIXME("(%ld,%p,%p,%p): stub\n",
1839           fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1840     return FALSE; /* create failed */
1841 }
1842
1843
1844 /*************************************************************************
1845  *             GetRasterizerCaps   (GDI.313)
1846  */
1847 BOOL16 WINAPI GetRasterizerCaps16( LPRASTERIZER_STATUS lprs, UINT16 cbNumBytes)
1848 {
1849     return GetRasterizerCaps( lprs, cbNumBytes );
1850 }
1851
1852
1853 /*************************************************************************
1854  *             GetRasterizerCaps   (GDI32.@)
1855  */
1856 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
1857 {
1858   lprs->nSize = sizeof(RASTERIZER_STATUS);
1859   lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
1860   lprs->nLanguageID = 0;
1861   return TRUE;
1862 }
1863
1864
1865 /*************************************************************************
1866  *             GetKerningPairs   (GDI.332)
1867  *
1868  */
1869 INT16 WINAPI GetKerningPairs16( HDC16 hDC, INT16 cPairs,
1870                                 LPKERNINGPAIR16 lpKerningPairs )
1871 {
1872     /* At this time kerning is ignored (set to 0) */
1873     int i;
1874     FIXME("(%x,%d,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1875     if (lpKerningPairs)
1876         for (i = 0; i < cPairs; i++) 
1877             lpKerningPairs[i].iKernAmount = 0;
1878  /* FIXME: Should this function call SetLastError (0)?  This is yet another
1879   * Microsoft function that can return 0 on success or failure
1880   */
1881     return 0;
1882 }
1883
1884
1885
1886 /*************************************************************************
1887  *             GetKerningPairsA   (GDI32.@)
1888  */
1889 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs,
1890                                  LPKERNINGPAIR lpKerningPairs )
1891 {
1892     int i;
1893     FIXME("(%x,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1894     for (i = 0; i < cPairs; i++) 
1895         lpKerningPairs[i].iKernAmount = 0;
1896     return 0;
1897 }
1898
1899
1900 /*************************************************************************
1901  *             GetKerningPairsW   (GDI32.@)
1902  */
1903 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
1904                                  LPKERNINGPAIR lpKerningPairs )
1905 {
1906     return GetKerningPairsA( hDC, cPairs, lpKerningPairs );
1907 }
1908
1909 /*************************************************************************
1910  * TranslateCharsetInfo [GDI32.@]
1911  * TranslateCharsetInfo [USER32.@]
1912  *
1913  * Fills a CHARSETINFO structure for a character set, code page, or
1914  * font. This allows making the correspondance between different labelings
1915  * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges) 
1916  * of the same encoding.
1917  *
1918  * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
1919  * only one codepage should be set in *lpSrc.
1920  *
1921  * RETURNS
1922  *   TRUE on success, FALSE on failure.
1923  *
1924  */
1925 BOOL WINAPI TranslateCharsetInfo(
1926   LPDWORD lpSrc, /* [in]
1927        if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
1928        if flags == TCI_SRCCHARSET: a character set value
1929        if flags == TCI_SRCCODEPAGE: a code page value
1930                  */
1931   LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
1932   DWORD flags /* [in] determines interpretation of lpSrc */
1933 ) {
1934     int index = 0;
1935     switch (flags) {
1936     case TCI_SRCFONTSIG:
1937         while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
1938       break;
1939     case TCI_SRCCODEPAGE:
1940       while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
1941       break;
1942     case TCI_SRCCHARSET:
1943       while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
1944       break;
1945     default:
1946       return FALSE;
1947     }
1948     if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
1949     memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
1950     return TRUE;
1951 }
1952
1953 /*************************************************************************
1954  *             GetFontLanguageInfo   (GDI32.@)
1955  */
1956 DWORD WINAPI GetFontLanguageInfo(HDC hdc) {
1957         /* return value 0 is correct for most cases anyway */
1958         FIXME("(%x):stub!\n", hdc);
1959         return 0;
1960 }
1961
1962 /*************************************************************************
1963  *             GetFontLanguageInfo   (GDI.616)
1964  */
1965 DWORD WINAPI GetFontLanguageInfo16(HDC16 hdc) {
1966         /* return value 0 is correct for most cases anyway */
1967         FIXME("(%x):stub!\n",hdc);
1968         return 0;
1969 }
1970
1971 /*************************************************************************
1972  * GetFontData [GDI32.@] Retrieve data for TrueType font
1973  *
1974  * RETURNS
1975  *
1976  * success: Number of bytes returned 
1977  * failure: GDI_ERROR
1978  *
1979  * NOTES
1980  *
1981  * Calls SetLastError()  
1982  *
1983  */
1984 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset, 
1985     LPVOID buffer, DWORD length)
1986 {
1987     DC *dc = DC_GetDCPtr(hdc);
1988     DWORD ret = GDI_ERROR;
1989
1990     if(!dc) return GDI_ERROR;
1991
1992     if(dc->gdiFont)
1993       ret = WineEngGetFontData(dc->gdiFont, table, offset, buffer, length);
1994
1995     GDI_ReleaseObj(hdc);
1996     return ret;
1997 }
1998
1999 /*************************************************************************
2000  * GetFontData [GDI.311]
2001  *
2002  */
2003 DWORD WINAPI GetFontData16(HDC16 hdc, DWORD dwTable, DWORD dwOffset,
2004                             LPVOID lpvBuffer, DWORD cbData)
2005 {
2006     return GetFontData(hdc, dwTable, dwOffset, lpvBuffer, cbData);
2007 }
2008
2009 /*************************************************************************
2010  * GetGlyphIndicesA [GDI32.@]
2011  */
2012 DWORD WINAPI GetGlyphIndicesA(HDC hdc, LPCSTR lpstr, INT count,
2013                               LPWORD pgi, DWORD flags)
2014 {
2015     DWORD ret;
2016     WCHAR *lpstrW;
2017     INT countW;
2018
2019     TRACE("(%04x, %s, %d, %p, 0x%lx)\n",
2020         hdc, debugstr_an(lpstr, count), count, pgi, flags);
2021
2022     lpstrW = FONT_mbtowc(hdc, lpstr, count, &countW, NULL);
2023     ret = GetGlyphIndicesW(hdc, lpstrW, countW, pgi, flags);
2024     HeapFree(GetProcessHeap(), 0, lpstrW);
2025
2026     return ret;
2027 }
2028
2029 /*************************************************************************
2030  * GetGlyphIndicesW [GDI32.@]
2031  */
2032 DWORD WINAPI GetGlyphIndicesW(HDC hdc, LPCWSTR lpstr, INT count,
2033                               LPWORD pgi, DWORD flags)
2034 {
2035     DC *dc = DC_GetDCPtr(hdc);
2036     DWORD ret = GDI_ERROR;
2037
2038     TRACE("(%04x, %s, %d, %p, 0x%lx)\n",
2039         hdc, debugstr_wn(lpstr, count), count, pgi, flags);
2040
2041     if(!dc) return GDI_ERROR;
2042
2043     if(dc->gdiFont)
2044         ret = WineEngGetGlyphIndices(dc->gdiFont, lpstr, count, pgi, flags);
2045
2046     GDI_ReleaseObj(hdc);
2047     return ret;
2048 }
2049
2050 /*************************************************************************
2051  * GetCharacterPlacementA [GDI32.@]
2052  *
2053  * NOTES:
2054  *  the web browser control of ie4 calls this with dwFlags=0
2055  */
2056 DWORD WINAPI
2057 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
2058                          INT nMaxExtent, GCP_RESULTSA *lpResults,
2059                          DWORD dwFlags)
2060 {
2061     WCHAR *lpStringW;
2062     INT uCountW;
2063     GCP_RESULTSW resultsW;
2064     DWORD ret;
2065     UINT font_cp;
2066
2067     TRACE("%s, %d, %d, 0x%08lx\n",
2068           debugstr_an(lpString, uCount), uCount, nMaxExtent, dwFlags);
2069
2070     /* both structs are equal in size */
2071     memcpy(&resultsW, lpResults, sizeof(resultsW));
2072
2073     lpStringW = FONT_mbtowc(hdc, lpString, uCount, &uCountW, &font_cp);
2074     if(lpResults->lpOutString)
2075         resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, uCountW);
2076     else
2077         resultsW.lpOutString = NULL;
2078
2079     ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, &resultsW, dwFlags);
2080
2081     if(lpResults->lpOutString)
2082         WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW,
2083                             lpResults->lpOutString, uCount, NULL, NULL );
2084
2085     HeapFree(GetProcessHeap(), 0, lpStringW);
2086     HeapFree(GetProcessHeap(), 0, resultsW.lpOutString);
2087
2088     return ret;
2089 }
2090
2091 /*************************************************************************
2092  * GetCharacterPlacementW [GDI32.@]
2093  */
2094 DWORD WINAPI
2095 GetCharacterPlacementW(HDC hdc, LPCWSTR lpString, INT uCount,
2096                          INT nMaxExtent, GCP_RESULTSW *lpResults,
2097                          DWORD dwFlags)
2098 {
2099     DWORD ret=0;
2100     SIZE size;
2101     UINT i, nSet;
2102
2103     TRACE("%s, %d, %d, 0x%08lx\n",
2104           debugstr_wn(lpString, uCount), uCount, nMaxExtent, dwFlags);
2105
2106     TRACE("lStructSize=%ld, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p\n"
2107           "lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n",
2108             lpResults->lStructSize, lpResults->lpOutString, lpResults->lpOrder,
2109             lpResults->lpDx, lpResults->lpCaretPos, lpResults->lpClass,
2110             lpResults->lpGlyphs, lpResults->nGlyphs, lpResults->nMaxFit);
2111
2112     if(dwFlags)                 FIXME("flags 0x%08lx ignored\n", dwFlags);
2113     if(lpResults->lpCaretPos)   FIXME("caret positions not implemented\n");
2114     if(lpResults->lpClass)      FIXME("classes not implemented\n");
2115
2116     /* FIXME: reordering not implemented */
2117     /* copy will do if the GCP_REORDER flag is not set */
2118     if(lpResults->lpOutString)
2119       lstrcpynW(lpResults->lpOutString, lpString, uCount);
2120
2121     nSet = (UINT)uCount;
2122     if(nSet > lpResults->nGlyphs)
2123         nSet = lpResults->nGlyphs;
2124
2125     /* return number of initialized fields */
2126     lpResults->nGlyphs = nSet;
2127
2128     if(lpResults->lpOrder)
2129     {
2130         for(i = 0; i < nSet; i++)
2131             lpResults->lpOrder[i] = i;
2132     }
2133
2134     if (lpResults->lpDx)
2135     {
2136       int c;
2137       for (i = 0; i < nSet; i++)
2138       { 
2139         if (GetCharWidth32W(hdc, lpString[i], lpString[i], &c))
2140           lpResults->lpDx[i]= c;
2141       }
2142     }
2143
2144     if(lpResults->lpGlyphs)
2145         GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);
2146
2147     if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
2148       ret = MAKELONG(size.cx, size.cy);
2149
2150     return ret;
2151 }
2152
2153 /*************************************************************************
2154  *      GetCharABCWidthsFloatA [GDI32.@]
2155  */
2156 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
2157                                         LPABCFLOAT lpABCF)
2158 {
2159        FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
2160        return 0;
2161 }
2162
2163 /*************************************************************************
2164  *      GetCharABCWidthsFloatW [GDI32.@]
2165  */
2166 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
2167                                         UINT iLastChar, LPABCFLOAT lpABCF)
2168 {
2169        FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
2170        return 0;
2171 }
2172
2173 /*************************************************************************
2174  *      GetCharWidthFloatA [GDI32.@]
2175  */
2176 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
2177                                     UINT iLastChar, PFLOAT pxBuffer)
2178 {
2179        FIXME_(gdi)("GetCharWidthFloatA, stub\n");
2180        return 0;
2181 }
2182
2183 /*************************************************************************
2184  *      GetCharWidthFloatW [GDI32.@]
2185  */
2186 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
2187                                     UINT iLastChar, PFLOAT pxBuffer)
2188 {
2189        FIXME_(gdi)("GetCharWidthFloatW, stub\n");
2190        return 0;
2191 }
2192  
2193
2194 /***********************************************************************
2195  *                                                                     *
2196  *           Font Resource API                                         *
2197  *                                                                     *
2198  ***********************************************************************/
2199 /***********************************************************************
2200  *           AddFontResource    (GDI.119)
2201  *
2202  *  Can be either .FON, or .FNT, or .TTF, or .FOT font file.
2203  *
2204  *  FIXME: Load header and find the best-matching font in the fontList;
2205  *         fixup dfPoints if all metrics are identical, otherwise create
2206  *         new fontAlias. When soft font support is ready this will
2207  *         simply create a new fontResource ('filename' will go into
2208  *         the pfr->resource field) with FR_SOFTFONT/FR_SOFTRESOURCE 
2209  *         flag set. 
2210  */
2211 INT16 WINAPI AddFontResource16( LPCSTR filename )
2212 {
2213     return AddFontResourceA( filename );
2214 }
2215
2216
2217 /***********************************************************************
2218  *           AddFontResourceA    (GDI32.@)
2219  */
2220 INT WINAPI AddFontResourceA( LPCSTR str )
2221 {
2222     FIXME("(%s): stub! Read the Wine User Guide on how to install "
2223             "this font manually.\n", debugres_a(str));
2224     return 1;
2225 }
2226
2227
2228 /***********************************************************************
2229  *           AddFontResourceW    (GDI32.@)
2230  */
2231 INT WINAPI AddFontResourceW( LPCWSTR str )
2232 {
2233     FIXME("(%s): stub! Read the Wine User Guide on how to install "
2234             "this font manually.\n", debugres_w(str));
2235     return 1;
2236 }
2237
2238 /***********************************************************************
2239  *           RemoveFontResource    (GDI.136)
2240  */
2241 BOOL16 WINAPI RemoveFontResource16( LPCSTR str )
2242 {
2243     FIXME("(%s): stub\n", debugres_a(str));
2244     return TRUE;
2245 }
2246
2247
2248 /***********************************************************************
2249  *           RemoveFontResourceA    (GDI32.@)
2250  */
2251 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
2252 {
2253 /*  This is how it should look like */
2254 /*
2255     fontResource** ppfr;
2256     BOOL32 retVal = FALSE;
2257
2258     EnterCriticalSection( &crtsc_fonts_X11 );
2259     for( ppfr = &fontList; *ppfr; ppfr = &(*ppfr)->next )
2260          if( !strcasecmp( (*ppfr)->lfFaceName, str ) )
2261          {
2262              if(((*ppfr)->fr_flags & (FR_SOFTFONT | FR_SOFTRESOURCE)) &&
2263                  (*ppfr)->hOwnerProcess == GetCurrentProcess() )
2264              {
2265                  if( (*ppfr)->fo_count )
2266                      (*ppfr)->fr_flags |= FR_REMOVED;
2267                  else
2268                      XFONT_RemoveFontResource( ppfr );
2269              }
2270              retVal = TRUE;
2271          }
2272     LeaveCriticalSection( &crtsc_fonts_X11 );
2273     return retVal;
2274  */
2275     FIXME("(%s): stub\n", debugres_a(str));
2276     return TRUE;
2277 }
2278
2279
2280 /***********************************************************************
2281  *           RemoveFontResourceW    (GDI32.@)
2282  */
2283 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
2284 {
2285     FIXME("(%s): stub\n", debugres_w(str) );
2286     return TRUE;
2287 }