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