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