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