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