- Implement AddFontResource*, add stubs for RemoveFontResource*.
[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   { VIETNAMESE_CHARSET, 1258, FS(8)},
102   /* reserved by ANSI */
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   { SYMBOL_CHARSET, CP_SYMBOL, FS(31)},
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(dc->gdiFont)
1108         ret = WineEngGetTextFace(dc->gdiFont, count, name);
1109     else if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
1110     {
1111         if (name)
1112         {
1113             lstrcpynW( name, font->logfont.lfFaceName, count );
1114             ret = strlenW(name);
1115         }
1116         else ret = strlenW(font->logfont.lfFaceName) + 1;
1117         GDI_ReleaseObj( dc->hFont );
1118     }
1119     GDI_ReleaseObj( hdc );
1120     return ret;
1121 }
1122
1123
1124 /***********************************************************************
1125  *           GetTextExtent    (GDI.91)
1126  */
1127 DWORD WINAPI GetTextExtent16( HDC16 hdc, LPCSTR str, INT16 count )
1128 {
1129     SIZE16 size;
1130     if (!GetTextExtentPoint16( hdc, str, count, &size )) return 0;
1131     return MAKELONG( size.cx, size.cy );
1132 }
1133
1134
1135 /***********************************************************************
1136  *           GetTextExtentPoint    (GDI.471)
1137  *
1138  * FIXME: Should this have a bug for compatibility?
1139  * Original Windows versions of GetTextExtentPoint{A,W} have documented
1140  * bugs (-> MSDN KB q147647.txt).
1141  */
1142 BOOL16 WINAPI GetTextExtentPoint16( HDC16 hdc, LPCSTR str, INT16 count,
1143                                     LPSIZE16 size )
1144 {
1145     SIZE size32;
1146     BOOL ret;
1147     TRACE("%04x, %p (%s), %d, %p\n", hdc, str, debugstr_an(str, count), count, size);
1148     ret = GetTextExtentPoint32A( hdc, str, count, &size32 );
1149     size->cx = size32.cx;
1150     size->cy = size32.cy;
1151     return (BOOL16)ret;
1152 }
1153
1154
1155 /***********************************************************************
1156  *           GetTextExtentPoint32A    (GDI32.@)
1157  */
1158 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
1159                                      LPSIZE size )
1160 {
1161     BOOL ret = FALSE;
1162     INT wlen;
1163     LPWSTR p = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1164
1165     if (p) {
1166         ret = GetTextExtentPoint32W( hdc, p, wlen, size );
1167         HeapFree( GetProcessHeap(), 0, p );
1168     }
1169
1170     TRACE("(%08x %s %d %p): returning %ld x %ld\n",
1171           hdc, debugstr_an (str, count), count, size, size->cx, size->cy );
1172     return ret;
1173 }
1174
1175
1176 /***********************************************************************
1177  * GetTextExtentPoint32W [GDI32.@]  Computes width/height for a string
1178  *
1179  * Computes width and height of the specified string.
1180  *
1181  * RETURNS
1182  *    Success: TRUE
1183  *    Failure: FALSE
1184  */
1185 BOOL WINAPI GetTextExtentPoint32W(
1186     HDC hdc,     /* [in]  Handle of device context */
1187     LPCWSTR str,   /* [in]  Address of text string */
1188     INT count,   /* [in]  Number of characters in string */
1189     LPSIZE size) /* [out] Address of structure for string size */
1190 {
1191     BOOL ret = FALSE;
1192     DC * dc = DC_GetDCPtr( hdc );
1193     if (!dc) return FALSE;
1194
1195     if(dc->gdiFont) {
1196         ret = WineEngGetTextExtentPoint(dc->gdiFont, str, count, size);
1197         size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
1198         size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
1199     }
1200     else if(dc->funcs->pGetTextExtentPoint)
1201         ret = dc->funcs->pGetTextExtentPoint( dc->physDev, str, count, size );
1202
1203     GDI_ReleaseObj( hdc );
1204
1205     TRACE("(%08x %s %d %p): returning %ld x %ld\n",
1206           hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
1207     return ret;
1208 }
1209
1210 /***********************************************************************
1211  * GetTextExtentPointI [GDI32.@]
1212  *
1213  * Computes width and height of the array of glyph indices.
1214  *
1215  * RETURNS
1216  *    Success: TRUE
1217  *    Failure: FALSE
1218  */
1219 BOOL WINAPI GetTextExtentPointI(
1220     HDC hdc,     /* [in]  Handle of device context */
1221     const WORD *indices,   /* [in]  Address of glyph index array */
1222     INT count,   /* [in]  Number of glyphs in array */
1223     LPSIZE size) /* [out] Address of structure for string size */
1224 {
1225     BOOL ret = FALSE;
1226     DC * dc = DC_GetDCPtr( hdc );
1227     if (!dc) return FALSE;
1228
1229     if(dc->gdiFont) {
1230         ret = WineEngGetTextExtentPointI(dc->gdiFont, indices, count, size);
1231         size->cx = abs(INTERNAL_XDSTOWS(dc, size->cx));
1232         size->cy = abs(INTERNAL_YDSTOWS(dc, size->cy));
1233     }
1234     else if(dc->funcs->pGetTextExtentPoint) {
1235         FIXME("calling GetTextExtentPoint\n");
1236         ret = dc->funcs->pGetTextExtentPoint( dc->physDev, (LPCWSTR)indices, count, size );
1237     }
1238
1239     GDI_ReleaseObj( hdc );
1240
1241     TRACE("(%08x %p %d %p): returning %ld x %ld\n",
1242           hdc, indices, count, size, size->cx, size->cy );
1243     return ret;
1244 }
1245
1246
1247 /***********************************************************************
1248  *           GetTextExtentPointA    (GDI32.@)
1249  */
1250 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
1251                                           LPSIZE size )
1252 {
1253     TRACE("not bug compatible.\n");
1254     return GetTextExtentPoint32A( hdc, str, count, size );
1255 }
1256
1257 /***********************************************************************
1258  *           GetTextExtentPointW   (GDI32.@)
1259  */
1260 BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
1261                                           LPSIZE size )
1262 {
1263     TRACE("not bug compatible.\n");
1264     return GetTextExtentPoint32W( hdc, str, count, size );
1265 }
1266
1267
1268 /***********************************************************************
1269  *           GetTextExtentExPointA    (GDI32.@)
1270  */
1271 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
1272                                    INT maxExt, LPINT lpnFit,
1273                                    LPINT alpDx, LPSIZE size )
1274 {
1275     BOOL ret;
1276     INT wlen;
1277     LPWSTR p = FONT_mbtowc( hdc, str, count, &wlen, NULL);
1278     ret = GetTextExtentExPointW( hdc, p, wlen, maxExt, lpnFit, alpDx, size);
1279     HeapFree( GetProcessHeap(), 0, p );
1280     return ret;
1281 }
1282
1283
1284 /***********************************************************************
1285  *           GetTextExtentExPointW    (GDI32.@)
1286  *
1287  * Return the size of the string as it would be if it was output properly by
1288  * e.g. TextOut.
1289  *
1290  * This should include
1291  * - Intercharacter spacing
1292  * - justification spacing (not yet done)
1293  * - kerning? see below
1294  *
1295  * Kerning.  Since kerning would be carried out by the rendering code it should
1296  * be done by the driver.  However they don't support it yet.  Also I am not
1297  * yet persuaded that (certainly under Win95) any kerning is actually done.
1298  *
1299  * str: According to MSDN this should be null-terminated.  That is not true; a
1300  *      null will not terminate it early.
1301  * size: Certainly under Win95 this appears buggy or weird if *lpnFit is less
1302  *       than count.  I have seen it be either the size of the full string or
1303  *       1 less than the size of the full string.  I have not seen it bear any
1304  *       resemblance to the portion that would fit.
1305  * lpnFit: What exactly is fitting?  Stupidly, in my opinion, it includes the
1306  *         trailing intercharacter spacing and any trailing justification.
1307  *
1308  * FIXME
1309  * Currently we do this by measuring each character etc.  We should do it by
1310  * passing the request to the driver, perhaps by extending the
1311  * pGetTextExtentPoint function to take the alpDx argument.  That would avoid
1312  * thinking about kerning issues and rounding issues in the justification.
1313  */
1314
1315 BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
1316                                    INT maxExt, LPINT lpnFit,
1317                                    LPINT alpDx, LPSIZE size )
1318 {
1319     int index, nFit, extent;
1320     SIZE tSize;
1321     BOOL ret = FALSE;
1322
1323     TRACE("(%08x, %s, %d)\n",hdc,debugstr_wn(str,count),maxExt);
1324
1325     size->cx = size->cy = nFit = extent = 0;
1326     for(index = 0; index < count; index++)
1327     {
1328         if(!GetTextExtentPoint32W( hdc, str, 1, &tSize )) goto done;
1329         /* GetTextExtentPoint includes intercharacter spacing. */
1330         /* FIXME - justification needs doing yet.  Remember that the base
1331          * data will not be in logical coordinates.
1332          */
1333         extent += tSize.cx;
1334         if( !lpnFit || extent <= maxExt )
1335         /* It is allowed to be equal. */
1336         {
1337             nFit++;
1338             if( alpDx ) alpDx[index] = extent;
1339         }
1340         if( tSize.cy > size->cy ) size->cy = tSize.cy;
1341         str++;
1342     }
1343     size->cx = extent;
1344     if(lpnFit) *lpnFit = nFit;
1345     ret = TRUE;
1346
1347     TRACE("returning %d %ld x %ld\n",nFit,size->cx,size->cy);
1348
1349 done:
1350     return ret;
1351 }
1352
1353 /***********************************************************************
1354  *           GetTextMetrics    (GDI.93)
1355  */
1356 BOOL16 WINAPI GetTextMetrics16( HDC16 hdc, TEXTMETRIC16 *metrics )
1357 {
1358     TEXTMETRICW tm32;
1359
1360     if (!GetTextMetricsW( (HDC)hdc, &tm32 )) return FALSE;
1361     FONT_TextMetricWTo16( &tm32, metrics );
1362     return TRUE;
1363 }
1364
1365
1366 /***********************************************************************
1367  *           GetTextMetricsA    (GDI32.@)
1368  */
1369 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1370 {
1371     TEXTMETRICW tm32;
1372
1373     if (!GetTextMetricsW( hdc, &tm32 )) return FALSE;
1374     FONT_TextMetricWToA( &tm32, metrics );
1375     return TRUE;
1376 }
1377
1378 /***********************************************************************
1379  *           GetTextMetricsW    (GDI32.@)
1380  */
1381 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1382 {
1383     BOOL ret = FALSE;
1384     DC * dc = DC_GetDCPtr( hdc );
1385     if (!dc) return FALSE;
1386
1387     if (dc->gdiFont)
1388         ret = WineEngGetTextMetrics(dc->gdiFont, metrics);
1389     else if (dc->funcs->pGetTextMetrics)
1390         ret = dc->funcs->pGetTextMetrics( dc->physDev, metrics );
1391
1392     if (ret)
1393     {
1394     /* device layer returns values in device units
1395      * therefore we have to convert them to logical */
1396
1397 #define WDPTOLP(x) ((x<0)?                                      \
1398                 (-abs(INTERNAL_XDSTOWS(dc, (x)))):              \
1399                 (abs(INTERNAL_XDSTOWS(dc, (x)))))
1400 #define HDPTOLP(y) ((y<0)?                                      \
1401                 (-abs(INTERNAL_YDSTOWS(dc, (y)))):              \
1402                 (abs(INTERNAL_YDSTOWS(dc, (y)))))
1403
1404     metrics->tmHeight           = HDPTOLP(metrics->tmHeight);
1405     metrics->tmAscent           = HDPTOLP(metrics->tmAscent);
1406     metrics->tmDescent          = HDPTOLP(metrics->tmDescent);
1407     metrics->tmInternalLeading  = HDPTOLP(metrics->tmInternalLeading);
1408     metrics->tmExternalLeading  = HDPTOLP(metrics->tmExternalLeading);
1409     metrics->tmAveCharWidth     = WDPTOLP(metrics->tmAveCharWidth);
1410     metrics->tmMaxCharWidth     = WDPTOLP(metrics->tmMaxCharWidth);
1411     metrics->tmOverhang         = WDPTOLP(metrics->tmOverhang);
1412         ret = TRUE;
1413
1414     TRACE("text metrics:\n"
1415           "    Weight = %03li\t FirstChar = %i\t AveCharWidth = %li\n"
1416           "    Italic = % 3i\t LastChar = %i\t\t MaxCharWidth = %li\n"
1417           "    UnderLined = %01i\t DefaultChar = %i\t Overhang = %li\n"
1418           "    StruckOut = %01i\t BreakChar = %i\t CharSet = %i\n"
1419           "    PitchAndFamily = %02x\n"
1420           "    --------------------\n"
1421           "    InternalLeading = %li\n"
1422           "    Ascent = %li\n"
1423           "    Descent = %li\n"
1424           "    Height = %li\n",
1425           metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1426           metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1427           metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1428           metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1429           metrics->tmPitchAndFamily,
1430           metrics->tmInternalLeading,
1431           metrics->tmAscent,
1432           metrics->tmDescent,
1433           metrics->tmHeight );
1434     }
1435     GDI_ReleaseObj( hdc );
1436     return ret;
1437 }
1438
1439
1440 /***********************************************************************
1441  * GetOutlineTextMetrics [GDI.308]  Gets metrics for TrueType fonts.
1442  *
1443  * NOTES
1444  *    lpOTM should be LPOUTLINETEXTMETRIC
1445  *
1446  * RETURNS
1447  *    Success: Non-zero or size of required buffer
1448  *    Failure: 0
1449  */
1450 UINT16 WINAPI GetOutlineTextMetrics16(
1451     HDC16 hdc,    /* [in]  Handle of device context */
1452     UINT16 cbData, /* [in]  Size of metric data array */
1453     LPOUTLINETEXTMETRIC16 lpOTM)  /* [out] Address of metric data array */
1454 {
1455     FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
1456     return 0;
1457 }
1458
1459
1460 /***********************************************************************
1461  *              GetOutlineTextMetricsA (GDI32.@)
1462  * Gets metrics for TrueType fonts.
1463  *
1464  *
1465  * RETURNS
1466  *    Success: Non-zero or size of required buffer
1467  *    Failure: 0
1468  */
1469 UINT WINAPI GetOutlineTextMetricsA(
1470     HDC hdc,    /* [in]  Handle of device context */
1471     UINT cbData, /* [in]  Size of metric data array */
1472     LPOUTLINETEXTMETRICA lpOTM)  /* [out] Address of metric data array */
1473 {
1474     char buf[512], *ptr;
1475     UINT ret, needed;
1476     OUTLINETEXTMETRICW *lpOTMW = (OUTLINETEXTMETRICW *)buf;
1477     INT left, len;
1478
1479     if((ret = GetOutlineTextMetricsW(hdc, sizeof(buf), lpOTMW)) == 0) {
1480         if((ret = GetOutlineTextMetricsW(hdc, 0, NULL)) == 0)
1481             return 0;
1482         lpOTMW = HeapAlloc(GetProcessHeap(), 0, ret);
1483         GetOutlineTextMetricsW(hdc, ret, lpOTMW);
1484     }
1485
1486     needed = sizeof(OUTLINETEXTMETRICA);
1487     if(lpOTMW->otmpFamilyName)
1488         needed += WideCharToMultiByte(CP_ACP, 0,
1489            (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1490                                       NULL, 0, NULL, NULL);
1491     if(lpOTMW->otmpFaceName)
1492         needed += WideCharToMultiByte(CP_ACP, 0,
1493            (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1494                                       NULL, 0, NULL, NULL);
1495     if(lpOTMW->otmpStyleName)
1496         needed += WideCharToMultiByte(CP_ACP, 0,
1497            (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1498                                       NULL, 0, NULL, NULL);
1499     if(lpOTMW->otmpFullName)
1500         needed += WideCharToMultiByte(CP_ACP, 0,
1501            (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1502                                       NULL, 0, NULL, NULL);
1503
1504     if(!lpOTM) {
1505         ret = needed;
1506         goto end;
1507     }
1508
1509     if(needed > cbData) {
1510         ret = 0;
1511         goto end;
1512     }
1513
1514
1515     lpOTM->otmSize = needed;
1516     FONT_TextMetricWToA( &lpOTMW->otmTextMetrics, &lpOTM->otmTextMetrics );
1517     lpOTM->otmFiller = 0;
1518     lpOTM->otmPanoseNumber = lpOTMW->otmPanoseNumber;
1519     lpOTM->otmfsSelection = lpOTMW->otmfsSelection;
1520     lpOTM->otmfsType = lpOTMW->otmfsType;
1521     lpOTM->otmsCharSlopeRise = lpOTMW->otmsCharSlopeRise;
1522     lpOTM->otmsCharSlopeRun = lpOTMW->otmsCharSlopeRun;
1523     lpOTM->otmItalicAngle = lpOTMW->otmItalicAngle;
1524     lpOTM->otmEMSquare = lpOTMW->otmEMSquare;
1525     lpOTM->otmAscent = lpOTMW->otmAscent;
1526     lpOTM->otmDescent = lpOTMW->otmDescent;
1527     lpOTM->otmLineGap = lpOTMW->otmLineGap;
1528     lpOTM->otmsCapEmHeight = lpOTMW->otmsCapEmHeight;
1529     lpOTM->otmsXHeight = lpOTMW->otmsXHeight;
1530     lpOTM->otmrcFontBox = lpOTMW->otmrcFontBox;
1531     lpOTM->otmMacAscent = lpOTMW->otmMacAscent;
1532     lpOTM->otmMacDescent = lpOTMW->otmMacDescent;
1533     lpOTM->otmMacLineGap = lpOTMW->otmMacLineGap;
1534     lpOTM->otmusMinimumPPEM = lpOTMW->otmusMinimumPPEM;
1535     lpOTM->otmptSubscriptSize = lpOTMW->otmptSubscriptSize;
1536     lpOTM->otmptSubscriptOffset = lpOTMW->otmptSubscriptOffset;
1537     lpOTM->otmptSuperscriptSize = lpOTMW->otmptSuperscriptSize;
1538     lpOTM->otmptSuperscriptOffset = lpOTMW->otmptSuperscriptOffset;
1539     lpOTM->otmsStrikeoutSize = lpOTMW->otmsStrikeoutSize;
1540     lpOTM->otmsStrikeoutPosition = lpOTMW->otmsStrikeoutPosition;
1541     lpOTM->otmsUnderscoreSize = lpOTMW->otmsUnderscoreSize;
1542     lpOTM->otmsUnderscorePosition = lpOTMW->otmsUnderscorePosition;
1543
1544
1545     ptr = (char*)(lpOTM + 1);
1546     left = needed - sizeof(*lpOTM);
1547
1548     if(lpOTMW->otmpFamilyName) {
1549         lpOTM->otmpFamilyName = (LPSTR)(ptr - (char*)lpOTM);
1550         len = WideCharToMultiByte(CP_ACP, 0,
1551              (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFamilyName), -1,
1552                                   ptr, left, NULL, NULL);
1553         left -= len;
1554         ptr += len;
1555     } else
1556         lpOTM->otmpFamilyName = 0;
1557
1558     if(lpOTMW->otmpFaceName) {
1559         lpOTM->otmpFaceName = (LPSTR)(ptr - (char*)lpOTM);
1560         len = WideCharToMultiByte(CP_ACP, 0,
1561              (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFaceName), -1,
1562                                   ptr, left, NULL, NULL);
1563         left -= len;
1564         ptr += len;
1565     } else
1566         lpOTM->otmpFaceName = 0;
1567
1568     if(lpOTMW->otmpStyleName) {
1569         lpOTM->otmpStyleName = (LPSTR)(ptr - (char*)lpOTM);
1570         len = WideCharToMultiByte(CP_ACP, 0,
1571              (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpStyleName), -1,
1572                                   ptr, left, NULL, NULL);
1573         left -= len;
1574         ptr += len;
1575     } else
1576         lpOTM->otmpStyleName = 0;
1577
1578     if(lpOTMW->otmpFullName) {
1579         lpOTM->otmpFullName = (LPSTR)(ptr - (char*)lpOTM);
1580         len = WideCharToMultiByte(CP_ACP, 0,
1581              (WCHAR*)((char*)lpOTMW + (ptrdiff_t)lpOTMW->otmpFullName), -1,
1582                                   ptr, left, NULL, NULL);
1583         left -= len;
1584     } else
1585         lpOTM->otmpFullName = 0;
1586
1587     assert(left == 0);
1588
1589     ret = needed;
1590
1591 end:
1592     if(lpOTMW != (OUTLINETEXTMETRICW *)buf)
1593         HeapFree(GetProcessHeap(), 0, lpOTMW);
1594
1595     return ret;
1596 }
1597
1598
1599 /***********************************************************************
1600  *           GetOutlineTextMetricsW [GDI32.@]
1601  */
1602 UINT WINAPI GetOutlineTextMetricsW(
1603     HDC hdc,    /* [in]  Handle of device context */
1604     UINT cbData, /* [in]  Size of metric data array */
1605     LPOUTLINETEXTMETRICW lpOTM)  /* [out] Address of metric data array */
1606 {
1607     DC *dc = DC_GetDCPtr( hdc );
1608     UINT ret;
1609
1610     TRACE("(%d,%d,%p)\n", hdc, cbData, lpOTM);
1611     if(!dc) return 0;
1612
1613     if(dc->gdiFont)
1614         ret = WineEngGetOutlineTextMetrics(dc->gdiFont, cbData, lpOTM);
1615
1616     else { /* This stuff was in GetOutlineTextMetricsA, I've moved it here
1617               but really this should just be a return 0. */
1618
1619         ret = sizeof(*lpOTM);
1620         if (lpOTM) {
1621             if(cbData < ret)
1622                 ret = 0;
1623             else {
1624                 memset(lpOTM, 0, ret);
1625                 lpOTM->otmSize = sizeof(*lpOTM);
1626                 GetTextMetricsW(hdc, &lpOTM->otmTextMetrics);
1627                 /*
1628                   Further fill of the structure not implemented,
1629                   Needs real values for the structure members
1630                 */
1631             }
1632         }
1633     }
1634     GDI_ReleaseObj(hdc);
1635     return ret;
1636 }
1637
1638
1639 /***********************************************************************
1640  *           GetCharWidth    (GDI.350)
1641  */
1642 BOOL16 WINAPI GetCharWidth16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1643                               LPINT16 buffer )
1644 {
1645     BOOL        retVal = FALSE;
1646
1647     if( firstChar != lastChar )
1648     {
1649         LPINT   buf32 = (LPINT)HeapAlloc(GetProcessHeap(), 0,
1650                                  sizeof(INT)*(1 + (lastChar - firstChar)));
1651         if( buf32 )
1652         {
1653             LPINT       obuf32 = buf32;
1654             int         i;
1655
1656             retVal = GetCharWidth32A(hdc, firstChar, lastChar, buf32);
1657             if (retVal)
1658             {
1659                 for (i = firstChar; i <= lastChar; i++)
1660                     *buffer++ = *buf32++;
1661             }
1662             HeapFree(GetProcessHeap(), 0, obuf32);
1663         }
1664     }
1665     else /* happens quite often to warrant a special treatment */
1666     {
1667         INT chWidth;
1668         retVal = GetCharWidth32A(hdc, firstChar, lastChar, &chWidth );
1669        *buffer = chWidth;
1670     }
1671     return retVal;
1672 }
1673
1674
1675 /***********************************************************************
1676  *           GetCharWidthW      (GDI32.@)
1677  *           GetCharWidth32W    (GDI32.@)
1678  */
1679 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1680                                LPINT buffer )
1681 {
1682     UINT i, extra;
1683     BOOL ret = FALSE;
1684     DC * dc = DC_GetDCPtr( hdc );
1685     if (!dc) return FALSE;
1686
1687     if (dc->gdiFont)
1688         ret = WineEngGetCharWidth( dc->gdiFont, firstChar, lastChar, buffer );
1689     else if (dc->funcs->pGetCharWidth)
1690         ret = dc->funcs->pGetCharWidth( dc->physDev, firstChar, lastChar, buffer);
1691
1692     if (ret)
1693     {
1694         /* convert device units to logical */
1695
1696         extra = dc->vportExtX >> 1;
1697         for( i = firstChar; i <= lastChar; i++, buffer++ )
1698             *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX;
1699         ret = TRUE;
1700     }
1701     GDI_ReleaseObj( hdc );
1702     return ret;
1703 }
1704
1705
1706 /***********************************************************************
1707  *           GetCharWidthA      (GDI32.@)
1708  *           GetCharWidth32A    (GDI32.@)
1709  */
1710 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1711                                LPINT buffer )
1712 {
1713     INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1714     LPSTR str;
1715     LPWSTR wstr;
1716     BOOL ret = TRUE;
1717
1718     if(count <= 0) return FALSE;
1719
1720     str = HeapAlloc(GetProcessHeap(), 0, count);
1721     for(i = 0; i < count; i++)
1722         str[i] = (BYTE)(firstChar + i);
1723
1724     wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1725
1726     for(i = 0; i < wlen; i++)
1727     {
1728         if(!GetCharWidth32W(hdc, wstr[i], wstr[i], buffer))
1729         {
1730             ret = FALSE;
1731             break;
1732         }
1733         buffer++;
1734     }
1735
1736     HeapFree(GetProcessHeap(), 0, str);
1737     HeapFree(GetProcessHeap(), 0, wstr);
1738
1739     return ret;
1740 }
1741
1742
1743 /* FIXME: all following APIs ******************************************/
1744
1745
1746 /***********************************************************************
1747  *           SetMapperFlags    (GDI.349)
1748  */
1749 DWORD WINAPI SetMapperFlags16( HDC16 hDC, DWORD dwFlag )
1750 {
1751     return SetMapperFlags( hDC, dwFlag );
1752 }
1753
1754
1755 /***********************************************************************
1756  *           SetMapperFlags    (GDI32.@)
1757  */
1758 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1759 {
1760     DC *dc = DC_GetDCPtr( hDC );
1761     DWORD ret = 0;
1762     if(!dc) return 0;
1763     if(dc->funcs->pSetMapperFlags)
1764         ret = dc->funcs->pSetMapperFlags( dc->physDev, dwFlag );
1765     else
1766         FIXME("(0x%04x, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1767     GDI_ReleaseObj( hDC );
1768     return ret;
1769 }
1770
1771 /***********************************************************************
1772  *          GetAspectRatioFilterEx  (GDI.486)
1773  */
1774 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1775 {
1776   FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1777   return FALSE;
1778 }
1779
1780 /***********************************************************************
1781  *          GetAspectRatioFilterEx  (GDI32.@)
1782  */
1783 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1784 {
1785   FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1786   return FALSE;
1787 }
1788
1789 /***********************************************************************
1790  *           GetCharABCWidths   (GDI.307)
1791  */
1792 BOOL16 WINAPI GetCharABCWidths16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1793                                   LPABC16 abc )
1794 {
1795     LPABC       abc32 = HeapAlloc(GetProcessHeap(),0,sizeof(ABC)*(lastChar-firstChar+1));
1796     int         i;
1797
1798     if (!GetCharABCWidthsA( hdc, firstChar, lastChar, abc32 )) {
1799         HeapFree(GetProcessHeap(),0,abc32);
1800         return FALSE;
1801     }
1802
1803     for (i=firstChar;i<=lastChar;i++) {
1804         abc[i-firstChar].abcA = abc32[i-firstChar].abcA;
1805         abc[i-firstChar].abcB = abc32[i-firstChar].abcB;
1806         abc[i-firstChar].abcC = abc32[i-firstChar].abcC;
1807     }
1808     HeapFree(GetProcessHeap(),0,abc32);
1809     return TRUE;
1810 }
1811
1812
1813 /***********************************************************************
1814  *           GetCharABCWidthsA   (GDI32.@)
1815  */
1816 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1817                                   LPABC abc )
1818 {
1819     INT i, wlen, count = (INT)(lastChar - firstChar + 1);
1820     LPSTR str;
1821     LPWSTR wstr;
1822     BOOL ret = TRUE;
1823
1824     if(count <= 0) return FALSE;
1825
1826     str = HeapAlloc(GetProcessHeap(), 0, count);
1827     for(i = 0; i < count; i++)
1828         str[i] = (BYTE)(firstChar + i);
1829
1830     wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
1831
1832     for(i = 0; i < wlen; i++)
1833     {
1834         if(!GetCharABCWidthsW(hdc, wstr[i], wstr[i], abc))
1835         {
1836             ret = FALSE;
1837             break;
1838         }
1839         abc++;
1840     }
1841
1842     HeapFree(GetProcessHeap(), 0, str);
1843     HeapFree(GetProcessHeap(), 0, wstr);
1844
1845     return ret;
1846 }
1847
1848
1849 /******************************************************************************
1850  * GetCharABCWidthsW [GDI32.@]  Retrieves widths of characters in range
1851  *
1852  * PARAMS
1853  *    hdc       [I] Handle of device context
1854  *    firstChar [I] First character in range to query
1855  *    lastChar  [I] Last character in range to query
1856  *    abc       [O] Address of character-width structure
1857  *
1858  * NOTES
1859  *    Only works with TrueType fonts
1860  *
1861  * RETURNS
1862  *    Success: TRUE
1863  *    Failure: FALSE
1864  */
1865 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1866                                    LPABC abc )
1867 {
1868     DC *dc = DC_GetDCPtr(hdc);
1869     int         i;
1870     GLYPHMETRICS gm;
1871     BOOL ret = FALSE;
1872
1873     if(dc->gdiFont) {
1874         for (i=firstChar;i<=lastChar;i++) {
1875             GetGlyphOutlineW(hdc, i, GGO_METRICS, &gm, 0, NULL, NULL);
1876             abc[i-firstChar].abcA = gm.gmptGlyphOrigin.x;
1877             abc[i-firstChar].abcB = gm.gmBlackBoxX;
1878             abc[i-firstChar].abcC = gm.gmCellIncX - gm.gmptGlyphOrigin.x - gm.gmBlackBoxX;
1879         }
1880         ret = TRUE;
1881     }
1882     GDI_ReleaseObj(hdc);
1883     return ret;
1884 }
1885
1886
1887 /***********************************************************************
1888  *           GetGlyphOutline    (GDI.309)
1889  */
1890 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1891                                 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1892                                 LPVOID lpBuffer, const MAT2 *lpmat2 )
1893 {
1894     FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1895           hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1896     return (DWORD)-1; /* failure */
1897 }
1898
1899
1900 /***********************************************************************
1901  *           GetGlyphOutlineA    (GDI32.@)
1902  */
1903 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1904                                  LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1905                                  LPVOID lpBuffer, const MAT2 *lpmat2 )
1906 {
1907     LPWSTR p = NULL;
1908     DWORD ret;
1909     UINT c;
1910
1911     if(!(fuFormat & GGO_GLYPH_INDEX)) {
1912         p = FONT_mbtowc(hdc, (char*)&uChar, 1, NULL, NULL);
1913         c = p[0];
1914     } else
1915         c = uChar;
1916     ret = GetGlyphOutlineW(hdc, c, fuFormat, lpgm, cbBuffer, lpBuffer,
1917                            lpmat2);
1918     if(p)
1919         HeapFree(GetProcessHeap(), 0, p);
1920     return ret;
1921 }
1922
1923 /***********************************************************************
1924  *           GetGlyphOutlineW    (GDI32.@)
1925  */
1926 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1927                                  LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1928                                  LPVOID lpBuffer, const MAT2 *lpmat2 )
1929 {
1930     DC *dc = DC_GetDCPtr(hdc);
1931     DWORD ret;
1932
1933     TRACE("(%04x, %04x, %04x, %p, %ld, %p, %p)\n",
1934           hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1935
1936     if(!dc) return GDI_ERROR;
1937
1938     if(dc->gdiFont)
1939       ret = WineEngGetGlyphOutline(dc->gdiFont, uChar, fuFormat, lpgm,
1940                                    cbBuffer, lpBuffer, lpmat2);
1941     else
1942       ret = GDI_ERROR;
1943
1944     GDI_ReleaseObj(hdc);
1945     return ret;
1946 }
1947
1948 /***********************************************************************
1949  *           CreateScalableFontResource   (GDI.310)
1950  */
1951 BOOL16 WINAPI CreateScalableFontResource16( UINT16 fHidden,
1952                                             LPCSTR lpszResourceFile,
1953                                             LPCSTR fontFile, LPCSTR path )
1954 {
1955     return CreateScalableFontResourceA( fHidden, lpszResourceFile,
1956                                           fontFile, path );
1957 }
1958
1959 /***********************************************************************
1960  *           CreateScalableFontResourceA   (GDI32.@)
1961  */
1962 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1963                                              LPCSTR lpszResourceFile,
1964                                              LPCSTR lpszFontFile,
1965                                              LPCSTR lpszCurrentPath )
1966 {
1967     /* fHidden=1 - only visible for the calling app, read-only, not
1968      * enumbered with EnumFonts/EnumFontFamilies
1969      * lpszCurrentPath can be NULL
1970      */
1971     FIXME("(%ld,%s,%s,%s): stub\n",
1972           fHidden, debugstr_a(lpszResourceFile), debugstr_a(lpszFontFile),
1973           debugstr_a(lpszCurrentPath) );
1974     return FALSE; /* create failed */
1975 }
1976
1977 /***********************************************************************
1978  *           CreateScalableFontResourceW   (GDI32.@)
1979  */
1980 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1981                                              LPCWSTR lpszResourceFile,
1982                                              LPCWSTR lpszFontFile,
1983                                              LPCWSTR lpszCurrentPath )
1984 {
1985     FIXME("(%ld,%p,%p,%p): stub\n",
1986           fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1987     return FALSE; /* create failed */
1988 }
1989
1990
1991 /*************************************************************************
1992  *             GetRasterizerCaps   (GDI.313)
1993  */
1994 BOOL16 WINAPI GetRasterizerCaps16( LPRASTERIZER_STATUS lprs, UINT16 cbNumBytes)
1995 {
1996     return GetRasterizerCaps( lprs, cbNumBytes );
1997 }
1998
1999
2000 /*************************************************************************
2001  *             GetRasterizerCaps   (GDI32.@)
2002  */
2003 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
2004 {
2005   lprs->nSize = sizeof(RASTERIZER_STATUS);
2006   lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
2007   lprs->nLanguageID = 0;
2008   return TRUE;
2009 }
2010
2011
2012 /*************************************************************************
2013  *             GetKerningPairs   (GDI.332)
2014  *
2015  */
2016 INT16 WINAPI GetKerningPairs16( HDC16 hDC, INT16 cPairs,
2017                                 LPKERNINGPAIR16 lpKerningPairs )
2018 {
2019     /* At this time kerning is ignored (set to 0) */
2020     int i;
2021     FIXME("(%x,%d,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
2022     if (lpKerningPairs)
2023         for (i = 0; i < cPairs; i++)
2024             lpKerningPairs[i].iKernAmount = 0;
2025  /* FIXME: Should this function call SetLastError (0)?  This is yet another
2026   * Microsoft function that can return 0 on success or failure
2027   */
2028     return 0;
2029 }
2030
2031
2032
2033 /*************************************************************************
2034  *             GetKerningPairsA   (GDI32.@)
2035  */
2036 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs,
2037                                  LPKERNINGPAIR lpKerningPairs )
2038 {
2039     int i;
2040     FIXME("(%x,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
2041     for (i = 0; i < cPairs; i++)
2042         lpKerningPairs[i].iKernAmount = 0;
2043     return 0;
2044 }
2045
2046
2047 /*************************************************************************
2048  *             GetKerningPairsW   (GDI32.@)
2049  */
2050 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
2051                                  LPKERNINGPAIR lpKerningPairs )
2052 {
2053     return GetKerningPairsA( hDC, cPairs, lpKerningPairs );
2054 }
2055
2056 /*************************************************************************
2057  * TranslateCharsetInfo [GDI32.@]
2058  * TranslateCharsetInfo [USER32.@]
2059  *
2060  * Fills a CHARSETINFO structure for a character set, code page, or
2061  * font. This allows making the correspondance between different labelings
2062  * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges)
2063  * of the same encoding.
2064  *
2065  * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
2066  * only one codepage should be set in *lpSrc.
2067  *
2068  * RETURNS
2069  *   TRUE on success, FALSE on failure.
2070  *
2071  */
2072 BOOL WINAPI TranslateCharsetInfo(
2073   LPDWORD lpSrc, /* [in]
2074        if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
2075        if flags == TCI_SRCCHARSET: a character set value
2076        if flags == TCI_SRCCODEPAGE: a code page value
2077                  */
2078   LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
2079   DWORD flags /* [in] determines interpretation of lpSrc */
2080 ) {
2081     int index = 0;
2082     switch (flags) {
2083     case TCI_SRCFONTSIG:
2084         while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
2085       break;
2086     case TCI_SRCCODEPAGE:
2087       while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
2088       break;
2089     case TCI_SRCCHARSET:
2090       while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
2091       break;
2092     default:
2093       return FALSE;
2094     }
2095     if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
2096     memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
2097     return TRUE;
2098 }
2099
2100 /*************************************************************************
2101  *             GetFontLanguageInfo   (GDI32.@)
2102  */
2103 DWORD WINAPI GetFontLanguageInfo(HDC hdc)
2104 {
2105         FONTSIGNATURE fontsig;
2106         static const DWORD GCP_DBCS_MASK=0x003F0000,
2107                 GCP_DIACRITIC_MASK=0x00000000,
2108                 FLI_GLYPHS_MASK=0x00000000,
2109                 GCP_GLYPHSHAPE_MASK=0x00000040,
2110                 GCP_KASHIDA_MASK=0x00000000,
2111                 GCP_LIGATE_MASK=0x00000000,
2112                 GCP_USEKERNING_MASK=0x00000000,
2113                 GCP_REORDER_MASK=0x00000060;
2114         
2115         DWORD result=0;
2116         
2117         GetTextCharsetInfo( hdc, &fontsig, 0 );
2118         /* We detect each flag we return using a bitmask on the Codepage Bitfields */
2119
2120         if( (fontsig.fsCsb[0]&GCP_DBCS_MASK)!=0 )
2121                 result|=GCP_DBCS;
2122         
2123         if( (fontsig.fsCsb[0]&GCP_DIACRITIC_MASK)!=0 )
2124                 result|=GCP_DIACRITIC;
2125         
2126         if( (fontsig.fsCsb[0]&FLI_GLYPHS_MASK)!=0 )
2127                 result|=FLI_GLYPHS;
2128         
2129         if( (fontsig.fsCsb[0]&GCP_GLYPHSHAPE_MASK)!=0 )
2130                 result|=GCP_GLYPHSHAPE;
2131         
2132         if( (fontsig.fsCsb[0]&GCP_KASHIDA_MASK)!=0 )
2133                 result|=GCP_KASHIDA;
2134         
2135         if( (fontsig.fsCsb[0]&GCP_LIGATE_MASK)!=0 )
2136                 result|=GCP_LIGATE;
2137
2138         if( (fontsig.fsCsb[0]&GCP_USEKERNING_MASK)!=0 )
2139                 result|=GCP_USEKERNING;
2140         
2141         if( (fontsig.fsCsb[0]&GCP_REORDER_MASK)!=0 )
2142                 result|=GCP_REORDER;
2143         
2144         return result;
2145 }
2146
2147 /*************************************************************************
2148  *             GetFontLanguageInfo   (GDI.616)
2149  */
2150 DWORD WINAPI GetFontLanguageInfo16(HDC16 hdc) {
2151         /* return value 0 is correct for most cases anyway */
2152         FIXME("(%x):stub!\n",hdc);
2153         return 0;
2154 }
2155
2156 /*************************************************************************
2157  * GetFontData [GDI32.@] Retrieve data for TrueType font
2158  *
2159  * RETURNS
2160  *
2161  * success: Number of bytes returned
2162  * failure: GDI_ERROR
2163  *
2164  * NOTES
2165  *
2166  * Calls SetLastError()
2167  *
2168  */
2169 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset,
2170     LPVOID buffer, DWORD length)
2171 {
2172     DC *dc = DC_GetDCPtr(hdc);
2173     DWORD ret = GDI_ERROR;
2174
2175     if(!dc) return GDI_ERROR;
2176
2177     if(dc->gdiFont)
2178       ret = WineEngGetFontData(dc->gdiFont, table, offset, buffer, length);
2179
2180     GDI_ReleaseObj(hdc);
2181     return ret;
2182 }
2183
2184 /*************************************************************************
2185  * GetFontData [GDI.311]
2186  *
2187  */
2188 DWORD WINAPI GetFontData16(HDC16 hdc, DWORD dwTable, DWORD dwOffset,
2189                             LPVOID lpvBuffer, DWORD cbData)
2190 {
2191     return GetFontData(hdc, dwTable, dwOffset, lpvBuffer, cbData);
2192 }
2193
2194 /*************************************************************************
2195  * GetGlyphIndicesA [GDI32.@]
2196  */
2197 DWORD WINAPI GetGlyphIndicesA(HDC hdc, LPCSTR lpstr, INT count,
2198                               LPWORD pgi, DWORD flags)
2199 {
2200     DWORD ret;
2201     WCHAR *lpstrW;
2202     INT countW;
2203
2204     TRACE("(%04x, %s, %d, %p, 0x%lx)\n",
2205         hdc, debugstr_an(lpstr, count), count, pgi, flags);
2206
2207     lpstrW = FONT_mbtowc(hdc, lpstr, count, &countW, NULL);
2208     ret = GetGlyphIndicesW(hdc, lpstrW, countW, pgi, flags);
2209     HeapFree(GetProcessHeap(), 0, lpstrW);
2210
2211     return ret;
2212 }
2213
2214 /*************************************************************************
2215  * GetGlyphIndicesW [GDI32.@]
2216  */
2217 DWORD WINAPI GetGlyphIndicesW(HDC hdc, LPCWSTR lpstr, INT count,
2218                               LPWORD pgi, DWORD flags)
2219 {
2220     DC *dc = DC_GetDCPtr(hdc);
2221     DWORD ret = GDI_ERROR;
2222
2223     TRACE("(%04x, %s, %d, %p, 0x%lx)\n",
2224         hdc, debugstr_wn(lpstr, count), count, pgi, flags);
2225
2226     if(!dc) return GDI_ERROR;
2227
2228     if(dc->gdiFont)
2229         ret = WineEngGetGlyphIndices(dc->gdiFont, lpstr, count, pgi, flags);
2230
2231     GDI_ReleaseObj(hdc);
2232     return ret;
2233 }
2234
2235 /*************************************************************************
2236  * GetCharacterPlacementA [GDI32.@]
2237  *
2238  * NOTES:
2239  *  the web browser control of ie4 calls this with dwFlags=0
2240  */
2241 DWORD WINAPI
2242 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
2243                          INT nMaxExtent, GCP_RESULTSA *lpResults,
2244                          DWORD dwFlags)
2245 {
2246     WCHAR *lpStringW;
2247     INT uCountW, i;
2248     GCP_RESULTSW resultsW;
2249     DWORD ret;
2250     UINT font_cp;
2251
2252     TRACE("%s, %d, %d, 0x%08lx\n",
2253           debugstr_an(lpString, uCount), uCount, nMaxExtent, dwFlags);
2254
2255     /* both structs are equal in size */
2256     memcpy(&resultsW, lpResults, sizeof(resultsW));
2257
2258     lpStringW = FONT_mbtowc(hdc, lpString, uCount, &uCountW, &font_cp);
2259     if(lpResults->lpOutString)
2260         resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, uCountW);
2261     else
2262         resultsW.lpOutString = NULL;
2263
2264     ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, &resultsW, dwFlags);
2265
2266     if(lpResults->lpOutString) {
2267         if(font_cp != CP_SYMBOL)
2268             WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW,
2269                                 lpResults->lpOutString, uCount, NULL, NULL );
2270         else
2271             for(i = 0; i < uCount; i++)
2272                 lpResults->lpOutString[i] = (CHAR)resultsW.lpOutString[i];
2273     }
2274
2275     HeapFree(GetProcessHeap(), 0, lpStringW);
2276     HeapFree(GetProcessHeap(), 0, resultsW.lpOutString);
2277
2278     return ret;
2279 }
2280
2281 /*************************************************************************
2282  * GetCharacterPlacementW [GDI32.@]
2283  *
2284  *   Retrieve information about a string. This includes the width, reordering,
2285  *   Glyphing and so on.
2286  *
2287  * RETURNS
2288  *
2289  *   The width and height of the string if succesful, 0 if failed.
2290  *
2291  * BUGS
2292  *
2293  *   All flags except GCP_REORDER are not yet implemented.
2294  *   Reordering is not 100% complient to the Windows BiDi method.
2295  *   Caret positioning is not yet implemented.
2296  *   Classes are not yet implemented.
2297  *
2298  */
2299 DWORD WINAPI
2300 GetCharacterPlacementW(
2301                 HDC hdc,        /* Device context for which the rendering is to be done */
2302                 LPCWSTR lpString,       /* The string for which information is to be returned */
2303                 INT uCount,     /* Number of WORDS in string. */
2304                 INT nMaxExtent, /* Maximum extent the string is to take (in HDC logical units) */
2305                 GCP_RESULTSW *lpResults,        /* A pointer to a GCP_RESULTSW struct */
2306                 DWORD dwFlags   /* Flags specifying how to process the string */
2307                 )
2308 {
2309     DWORD ret=0;
2310     SIZE size;
2311     UINT i, nSet;
2312
2313     TRACE("%s, %d, %d, 0x%08lx\n",
2314           debugstr_wn(lpString, uCount), uCount, nMaxExtent, dwFlags);
2315
2316     TRACE("lStructSize=%ld, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p\n"
2317           "lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n",
2318             lpResults->lStructSize, lpResults->lpOutString, lpResults->lpOrder,
2319             lpResults->lpDx, lpResults->lpCaretPos, lpResults->lpClass,
2320             lpResults->lpGlyphs, lpResults->nGlyphs, lpResults->nMaxFit);
2321
2322     if(dwFlags&(~GCP_REORDER))                  FIXME("flags 0x%08lx ignored\n", dwFlags);
2323     if(lpResults->lpCaretPos)   FIXME("caret positions not implemented\n");
2324     if(lpResults->lpClass)      FIXME("classes not implemented\n");
2325
2326         nSet = (UINT)uCount;
2327         if(nSet > lpResults->nGlyphs)
2328                 nSet = lpResults->nGlyphs;
2329
2330         /* return number of initialized fields */
2331         lpResults->nGlyphs = nSet;
2332
2333         if(dwFlags==0)
2334         {
2335                 /* Treat the case where no special handling was requested in a fastpath way */
2336                 /* copy will do if the GCP_REORDER flag is not set */
2337                 if(lpResults->lpOutString)
2338                         lstrcpynW(lpResults->lpOutString, lpString, uCount);
2339
2340                 if(lpResults->lpOrder)
2341                 {
2342                         for(i = 0; i < nSet; i++)
2343                                 lpResults->lpOrder[i] = i;
2344                 }
2345                 
2346         } else
2347         {
2348                 WORD *pwCharType;
2349                 int run_end;
2350                 /* Keep a static table that translates the C2 types to something meaningful */
2351                 /* 1 - left to right
2352                  * -1 - right to left
2353                  * 0 - neutral
2354                  */
2355                 static const int chardir[]={ 0, 1, -1, 1, 1, 1, -1, 1, 0, 0, 0, 0 };
2356                 
2357                 WARN("The BiDi algorythm doesn't conform to Windows' yet\n");
2358                 if( (pwCharType=HeapAlloc(GetProcessHeap(), 0, uCount * sizeof(WORD)))==NULL )
2359                 {
2360                         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2361                         
2362                         return 0;
2363                 }
2364                 
2365                 /* Fill in the order array with directionality values */
2366                 GetStringTypeW(CT_CTYPE2, lpString, uCount, pwCharType);
2367                 
2368                 /* The complete and correct (at list according to MS) BiDi algorythm is not
2369                  * yet implemented here. Instead, we just make sure that consecutive runs of
2370                  * the same direction (or neutral) are ordered correctly
2371                  */
2372                 for( i=0; i<uCount; i+=run_end )
2373                 {
2374                         for( run_end=1; i+run_end<uCount &&
2375                              (chardir[pwCharType[i+run_end]]==chardir[pwCharType[i]] ||
2376                              chardir[pwCharType[i+run_end]]==0); ++run_end )
2377                                 ;
2378                         
2379                         if( chardir[pwCharType[i]]==1 || chardir[pwCharType[i]]==0 )
2380                         {
2381                                 /* A LTR run */
2382                                 if(lpResults->lpOutString)
2383                                 {
2384                                         int j;
2385                                         for( j=0; j<run_end; j++ )
2386                                         {
2387                                                 lpResults->lpOutString[i+j]=lpString[i+j];
2388                                         }
2389                                 }
2390                                 
2391                                 if(lpResults->lpOrder)
2392                                 {
2393                                         int j;
2394                                         for( j=0; j<run_end; j++ )
2395                                                 lpResults->lpOrder[i+j] = i+j;
2396                                 }
2397                         } else
2398                         {
2399                                 /* A RTL run */
2400                                 if(lpResults->lpOutString)
2401                                 {
2402                                         int j;
2403                                         for( j=0; j<run_end; j++ )
2404                                         {
2405                                                 lpResults->lpOutString[i+j]=lpString[i+run_end-j-1];
2406                                         }
2407                                 }
2408                                 
2409                                 if(lpResults->lpOrder)
2410                                 {
2411                                         int j;
2412                                         for( j=0; j<run_end; j++ )
2413                                                 lpResults->lpOrder[i+j] = i+run_end-j-1;
2414                                 }
2415                         }
2416                 }
2417                 
2418                 HeapFree(GetProcessHeap(), 0, pwCharType);
2419         }
2420
2421         /* FIXME: Will use the placement chars */
2422         if (lpResults->lpDx)
2423         {
2424                 int c;
2425                 for (i = 0; i < nSet; i++)
2426                 {
2427                         if (GetCharWidth32W(hdc, lpString[i], lpString[i], &c))
2428                                 lpResults->lpDx[i]= c;
2429                 }
2430         }
2431
2432     if(lpResults->lpGlyphs)
2433         GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);
2434
2435     if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
2436       ret = MAKELONG(size.cx, size.cy);
2437
2438     return ret;
2439 }
2440
2441 /*************************************************************************
2442  *      GetCharABCWidthsFloatA [GDI32.@]
2443  */
2444 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
2445                                         LPABCFLOAT lpABCF)
2446 {
2447        FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
2448        return 0;
2449 }
2450
2451 /*************************************************************************
2452  *      GetCharABCWidthsFloatW [GDI32.@]
2453  */
2454 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
2455                                         UINT iLastChar, LPABCFLOAT lpABCF)
2456 {
2457        FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
2458        return 0;
2459 }
2460
2461 /*************************************************************************
2462  *      GetCharWidthFloatA [GDI32.@]
2463  */
2464 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
2465                                     UINT iLastChar, PFLOAT pxBuffer)
2466 {
2467        FIXME_(gdi)("GetCharWidthFloatA, stub\n");
2468        return 0;
2469 }
2470
2471 /*************************************************************************
2472  *      GetCharWidthFloatW [GDI32.@]
2473  */
2474 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
2475                                     UINT iLastChar, PFLOAT pxBuffer)
2476 {
2477        FIXME_(gdi)("GetCharWidthFloatW, stub\n");
2478        return 0;
2479 }
2480
2481
2482 /***********************************************************************
2483  *                                                                     *
2484  *           Font Resource API                                         *
2485  *                                                                     *
2486  ***********************************************************************/
2487 /***********************************************************************
2488  *           AddFontResource    (GDI.119)
2489  *
2490  *  Can be either .FON, or .FNT, or .TTF, or .FOT font file.
2491  *
2492  */
2493 INT16 WINAPI AddFontResource16( LPCSTR filename )
2494 {
2495     return AddFontResourceA( filename );
2496 }
2497
2498 /***********************************************************************
2499  *           AddFontResourceA    (GDI32.@)
2500  */
2501 INT WINAPI AddFontResourceA( LPCSTR str )
2502 {
2503     return AddFontResourceExA( str, 0, NULL);
2504 }
2505
2506 /***********************************************************************
2507  *           AddFontResourceW    (GDI32.@)
2508  */
2509 INT WINAPI AddFontResourceW( LPCWSTR str )
2510 {
2511     return AddFontResourceExW(str, 0, NULL);
2512 }
2513
2514
2515 /***********************************************************************
2516  *           AddFontResourceExA    (GDI32.@)
2517  */
2518 INT WINAPI AddFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2519 {
2520     DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2521     LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2522     INT ret;
2523
2524     MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2525     ret = AddFontResourceExW(strW, fl, pdv);
2526     HeapFree(GetProcessHeap(), 0, strW);
2527     return ret;
2528 }
2529
2530 /***********************************************************************
2531  *           AddFontResourceExW    (GDI32.@)
2532  */
2533 INT WINAPI AddFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2534 {
2535     return WineEngAddFontResourceEx(str, fl, pdv);
2536 }
2537
2538 /***********************************************************************
2539  *           RemoveFontResource    (GDI.136)
2540  */
2541 BOOL16 WINAPI RemoveFontResource16( LPCSTR str )
2542 {
2543     return RemoveFontResourceA(str);
2544 }
2545
2546 /***********************************************************************
2547  *           RemoveFontResourceA    (GDI32.@)
2548  */
2549 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
2550 {
2551     return RemoveFontResourceExA(str, 0, 0);
2552 }
2553
2554 /***********************************************************************
2555  *           RemoveFontResourceW    (GDI32.@)
2556  */
2557 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
2558 {
2559     return RemoveFontResourceExW(str, 0, 0);
2560 }
2561
2562 /***********************************************************************
2563  *           RemoveFontResourceExA    (GDI32.@)
2564  */
2565 BOOL WINAPI RemoveFontResourceExA( LPCSTR str, DWORD fl, PVOID pdv )
2566 {
2567     DWORD len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
2568     LPWSTR strW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2569     INT ret;
2570
2571     MultiByteToWideChar(CP_ACP, 0, str, -1, strW, len);
2572     ret = RemoveFontResourceExW(strW, fl, pdv);
2573     HeapFree(GetProcessHeap(), 0, strW);
2574     return ret;
2575 }
2576
2577 /***********************************************************************
2578  *           RemoveFontResourceExW    (GDI32.@)
2579  */
2580 BOOL WINAPI RemoveFontResourceExW( LPCWSTR str, DWORD fl, PVOID pdv )
2581 {
2582     return WineEngRemoveFontResourceEx(str, fl, pdv);
2583 }