Added an unknown VxD error code.
[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 "winerror.h"
11 #include "winnls.h"
12 #include "font.h"
13 #include "heap.h"
14 #include "metafile.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  *           CreateFontIndirect16   (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  *           CreateFont16    (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 = 0;
729     DC *dc = DC_GetDCPtr( hDC );
730
731     if (!dc) return 0;
732     enum_func = dc->funcs->pEnumDeviceFonts;
733     GDI_ReleaseObj( hDC );
734
735     if (enum_func)
736     {
737         fontEnum32 fe32;
738
739         fe32.lpLogFontParam = plf;
740         fe32.lpEnumFunc = efproc;
741         fe32.lpData = lParam;
742         
743         fe32.dwFlags = dwUnicode;
744
745         ret = enum_func( hDC, plf, FONT_EnumInstance, (LPARAM)&fe32 );
746     }
747     return ret;
748 }
749
750 /***********************************************************************
751  *              EnumFontFamiliesExW     (GDI32.@)
752  */
753 INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
754                                     FONTENUMPROCEXW efproc, 
755                                     LPARAM lParam, DWORD dwFlags )
756 {
757     return  FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam, ENUM_UNICODE );
758 }
759
760 /***********************************************************************
761  *              EnumFontFamiliesExA     (GDI32.@)
762  */
763 INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf,
764                                     FONTENUMPROCEXA efproc, 
765                                     LPARAM lParam, DWORD dwFlags)
766 {
767     LOGFONTW lfW;
768     FONT_LogFontAToW( plf, &lfW );
769
770     return  FONT_EnumFontFamiliesEx( hDC, &lfW,
771                                      (FONTENUMPROCEXW)efproc, lParam, 0);
772 }
773
774 /***********************************************************************
775  *              EnumFontFamilies16      (GDI.330)
776  */
777 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
778                                  FONTENUMPROC16 efproc, LPARAM lpData )
779 {
780     LOGFONT16   lf;
781
782     lf.lfCharSet = DEFAULT_CHARSET;
783     if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
784     else lf.lfFaceName[0] = '\0';
785
786     return EnumFontFamiliesEx16( hDC, &lf, (FONTENUMPROCEX16)efproc, lpData, 0 );
787 }
788
789 /***********************************************************************
790  *              EnumFontFamiliesA       (GDI32.@)
791  */
792 INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
793                                   FONTENUMPROCA efproc, LPARAM lpData )
794 {
795     LOGFONTA    lf;
796
797     lf.lfCharSet = DEFAULT_CHARSET;
798     if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
799     else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
800
801     return EnumFontFamiliesExA( hDC, &lf, (FONTENUMPROCEXA)efproc, lpData, 0 );
802 }
803
804 /***********************************************************************
805  *              EnumFontFamiliesW       (GDI32.@)
806  */
807 INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
808                                   FONTENUMPROCW efproc, LPARAM lpData )
809 {
810     LOGFONTW  lf;
811
812     lf.lfCharSet = DEFAULT_CHARSET;
813     if( lpFamily ) lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
814     else lf.lfFaceName[0] = 0;
815
816     return EnumFontFamiliesExW( hDC, &lf, (FONTENUMPROCEXW)efproc, lpData, 0 );
817 }
818
819 /***********************************************************************
820  *              EnumFonts16             (GDI.70)
821  */
822 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
823                           LPARAM lpData )
824 {
825     return EnumFontFamilies16( hDC, lpName, (FONTENUMPROCEX16)efproc, lpData );
826 }
827
828 /***********************************************************************
829  *              EnumFontsA              (GDI32.@)
830  */
831 INT WINAPI EnumFontsA( HDC hDC, LPCSTR lpName, FONTENUMPROCA efproc,
832                            LPARAM lpData )
833 {
834     return EnumFontFamiliesA( hDC, lpName, efproc, lpData );
835 }
836
837 /***********************************************************************
838  *              EnumFontsW              (GDI32.@)
839  */
840 INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
841                            LPARAM lpData )
842 {
843     return EnumFontFamiliesW( hDC, lpName, efproc, lpData );
844 }
845
846
847 /***********************************************************************
848  *           GetTextCharacterExtra16    (GDI.89)
849  */
850 INT16 WINAPI GetTextCharacterExtra16( HDC16 hdc )
851 {
852     return (INT16)GetTextCharacterExtra( hdc );
853 }
854
855
856 /***********************************************************************
857  *           GetTextCharacterExtra    (GDI32.@)
858  */
859 INT WINAPI GetTextCharacterExtra( HDC hdc )
860 {
861     INT ret;
862     DC *dc = DC_GetDCPtr( hdc );
863     if (!dc) return 0;
864     ret = abs( (dc->charExtra * dc->wndExtX + dc->vportExtX / 2)
865                  / dc->vportExtX );
866     GDI_ReleaseObj( hdc );
867     return ret;
868 }
869
870
871 /***********************************************************************
872  *           SetTextCharacterExtra16    (GDI.8)
873  */
874 INT16 WINAPI SetTextCharacterExtra16( HDC16 hdc, INT16 extra )
875 {
876     return (INT16)SetTextCharacterExtra( hdc, extra );
877 }
878
879
880 /***********************************************************************
881  *           SetTextCharacterExtra    (GDI32.@)
882  */
883 INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
884 {
885     INT prev;
886     DC * dc = DC_GetDCPtr( hdc );
887     if (!dc) return 0;
888     if (dc->funcs->pSetTextCharacterExtra)
889         prev = dc->funcs->pSetTextCharacterExtra( dc, extra );
890     else
891     {
892         extra = (extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX;
893         prev = (dc->charExtra * dc->wndExtX + dc->vportExtX / 2) / dc->vportExtX;
894         dc->charExtra = abs(extra);
895     }
896     GDI_ReleaseObj( hdc );
897     return prev;
898 }
899
900
901 /***********************************************************************
902  *           SetTextJustification16    (GDI.10)
903  */
904 INT16 WINAPI SetTextJustification16( HDC16 hdc, INT16 extra, INT16 breaks )
905 {
906     return SetTextJustification( hdc, extra, breaks );
907 }
908
909
910 /***********************************************************************
911  *           SetTextJustification    (GDI32.@)
912  */
913 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
914 {
915     BOOL ret = TRUE;
916     DC * dc = DC_GetDCPtr( hdc );
917     if (!dc) return FALSE;
918     if (dc->funcs->pSetTextJustification)
919         ret = dc->funcs->pSetTextJustification( dc, extra, breaks );
920     else
921     {
922         extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
923         if (!extra) breaks = 0;
924         dc->breakTotalExtra = extra;
925         dc->breakCount = breaks;
926         if (breaks)
927         {
928             dc->breakExtra = extra / breaks;
929             dc->breakRem   = extra - (dc->breakCount * dc->breakExtra);
930         }
931         else
932         {
933             dc->breakExtra = 0;
934             dc->breakRem   = 0;
935         }
936     }
937     GDI_ReleaseObj( hdc );
938     return ret;
939 }
940
941
942 /***********************************************************************
943  *           GetTextFace16    (GDI.92)
944  */
945 INT16 WINAPI GetTextFace16( HDC16 hdc, INT16 count, LPSTR name )
946 {
947         return GetTextFaceA(hdc,count,name);
948 }
949
950 /***********************************************************************
951  *           GetTextFaceA    (GDI32.@)
952  */
953 INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
954 {
955     INT res = GetTextFaceW(hdc, 0, NULL);
956     LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
957     GetTextFaceW( hdc, res, nameW );
958     
959     if (name)
960         res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count,
961                                    NULL, NULL);
962     else
963         res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
964     HeapFree( GetProcessHeap(), 0, nameW );
965     return res;
966 }
967
968 /***********************************************************************
969  *           GetTextFaceW    (GDI32.@)
970  */
971 INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
972 {
973     FONTOBJ *font;
974     INT     ret = 0;
975
976     DC * dc = DC_GetDCPtr( hdc );
977     if (!dc) return 0;
978
979     if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
980     {
981         if (name)
982         {
983             lstrcpynW( name, font->logfont.lfFaceName, count );
984             ret = strlenW(name);
985         }
986         else ret = strlenW(font->logfont.lfFaceName) + 1;
987         GDI_ReleaseObj( dc->hFont );
988     }
989     GDI_ReleaseObj( hdc );
990     return ret;
991 }
992
993
994 /***********************************************************************
995  *           GetTextExtent16    (GDI.91)
996  */
997 DWORD WINAPI GetTextExtent16( HDC16 hdc, LPCSTR str, INT16 count )
998 {
999     SIZE16 size;
1000     if (!GetTextExtentPoint16( hdc, str, count, &size )) return 0;
1001     return MAKELONG( size.cx, size.cy );
1002 }
1003
1004
1005 /***********************************************************************
1006  *           GetTextExtentPoint16    (GDI.471)
1007  *
1008  * FIXME: Should this have a bug for compatibility?
1009  * Original Windows versions of GetTextExtentPoint{A,W} have documented
1010  * bugs (-> MSDN KB q147647.txt).
1011  */
1012 BOOL16 WINAPI GetTextExtentPoint16( HDC16 hdc, LPCSTR str, INT16 count,
1013                                     LPSIZE16 size )
1014 {
1015     SIZE size32;
1016     BOOL ret;
1017     TRACE("%04x, %p (%s), %d, %p\n", hdc, str, debugstr_an(str, count), count, size);
1018     ret = GetTextExtentPoint32A( hdc, str, count, &size32 );
1019     size->cx = size32.cx;
1020     size->cy = size32.cy;
1021     return (BOOL16)ret;
1022 }
1023
1024
1025 /***********************************************************************
1026  *           GetTextExtentPoint32A    (GDI32.@)
1027  */
1028 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
1029                                      LPSIZE size )
1030 {
1031     BOOL ret = FALSE;
1032     UINT codepage = CP_ACP; /* FIXME: get codepage of font charset */
1033     DC * dc = DC_GetDCPtr( hdc );
1034
1035     if (!dc) return FALSE;
1036
1037     if (dc->funcs->pGetTextExtentPoint)
1038     {
1039         /* str may not be 0 terminated so we can't use HEAP_strdupWtoA.
1040          * So we use MultiByteToWideChar.
1041          */
1042         UINT wlen = MultiByteToWideChar(codepage,0,str,count,NULL,0);
1043         LPWSTR p = HeapAlloc( GetProcessHeap(), 0, wlen * sizeof(WCHAR) );
1044         if (p)
1045         {
1046             wlen = MultiByteToWideChar(codepage,0,str,count,p,wlen);
1047             ret = dc->funcs->pGetTextExtentPoint( dc, p, wlen, size );
1048             HeapFree( GetProcessHeap(), 0, p );
1049         }
1050     }
1051     GDI_ReleaseObj( hdc );
1052     TRACE("(%08x %s %d %p): returning %ld x %ld\n",
1053           hdc, debugstr_an (str, count), count, size, size->cx, size->cy );
1054     return ret;
1055 }
1056
1057
1058 /***********************************************************************
1059  * GetTextExtentPoint32W [GDI32.@]  Computes width/height for a string
1060  *
1061  * Computes width and height of the specified string.
1062  *
1063  * RETURNS
1064  *    Success: TRUE
1065  *    Failure: FALSE
1066  */
1067 BOOL WINAPI GetTextExtentPoint32W(
1068     HDC hdc,     /* [in]  Handle of device context */
1069     LPCWSTR str,   /* [in]  Address of text string */
1070     INT count,   /* [in]  Number of characters in string */
1071     LPSIZE size) /* [out] Address of structure for string size */
1072 {
1073     BOOL ret = FALSE;
1074     DC * dc = DC_GetDCPtr( hdc );
1075     if (dc)
1076     {
1077         if(dc->funcs->pGetTextExtentPoint)
1078             ret = dc->funcs->pGetTextExtentPoint( dc, str, count, size );
1079         GDI_ReleaseObj( hdc );
1080     }
1081     TRACE("(%08x %s %d %p): returning %ld x %ld\n",
1082           hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
1083     return ret;
1084 }
1085
1086
1087 /***********************************************************************
1088  *           GetTextExtentPointA    (GDI32.@)
1089  */
1090 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
1091                                           LPSIZE size )
1092 {
1093     TRACE("not bug compatible.\n");
1094     return GetTextExtentPoint32A( hdc, str, count, size );
1095 }
1096
1097 /***********************************************************************
1098  *           GetTextExtentPointW   (GDI32.@)
1099  */
1100 BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
1101                                           LPSIZE size )
1102 {
1103     TRACE("not bug compatible.\n");
1104     return GetTextExtentPoint32W( hdc, str, count, size );
1105 }
1106
1107
1108 /***********************************************************************
1109  *           GetTextExtentExPointA    (GDI32.@)
1110  */
1111 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
1112                                    INT maxExt, LPINT lpnFit,
1113                                    LPINT alpDx, LPSIZE size )
1114 {
1115     BOOL ret;
1116
1117     DWORD len = MultiByteToWideChar( CP_ACP, 0, str, count, NULL, 0 );
1118     LPWSTR p = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
1119     MultiByteToWideChar( CP_ACP, 0, str, count, p, len );
1120     ret = GetTextExtentExPointW( hdc, p, len, maxExt, lpnFit, alpDx, size);
1121     HeapFree( GetProcessHeap(), 0, p );
1122     return ret;
1123 }
1124
1125
1126 /***********************************************************************
1127  *           GetTextExtentExPointW    (GDI32.@)
1128  */
1129
1130 BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
1131                                    INT maxExt, LPINT lpnFit,
1132                                    LPINT alpDx, LPSIZE size )
1133 {
1134     int index, nFit, extent;
1135     SIZE tSize;
1136     BOOL ret = FALSE;
1137     DC * dc = DC_GetDCPtr( hdc );
1138     if (!dc) return FALSE;
1139
1140     if (!dc->funcs->pGetTextExtentPoint) goto done;
1141
1142     size->cx = size->cy = nFit = extent = 0;
1143     for(index = 0; index < count; index++)
1144     {
1145         if(!dc->funcs->pGetTextExtentPoint( dc, str, 1, &tSize )) goto done;
1146         if( extent+tSize.cx < maxExt )
1147         {
1148             extent+=tSize.cx;
1149             nFit++;
1150             str++;
1151             if( alpDx ) alpDx[index] = extent;
1152             if( tSize.cy > size->cy ) size->cy = tSize.cy;
1153         }
1154         else break;
1155     }
1156     size->cx = extent;
1157     if(lpnFit) *lpnFit = nFit;
1158     ret = TRUE;
1159
1160     TRACE("(%08x %s %d) returning %d %ld x %ld\n",
1161           hdc,debugstr_wn(str,count),maxExt,nFit, size->cx,size->cy);
1162
1163 done:
1164     GDI_ReleaseObj( hdc );
1165     return ret;
1166 }
1167
1168 /***********************************************************************
1169  *           GetTextMetrics16    (GDI.93)
1170  */
1171 BOOL16 WINAPI GetTextMetrics16( HDC16 hdc, TEXTMETRIC16 *metrics )
1172 {
1173     TEXTMETRICW tm32;
1174
1175     if (!GetTextMetricsW( (HDC)hdc, &tm32 )) return FALSE;
1176     FONT_TextMetricWTo16( &tm32, metrics );
1177     return TRUE;
1178 }
1179
1180
1181 /***********************************************************************
1182  *           GetTextMetricsA    (GDI32.@)
1183  */
1184 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1185 {
1186     TEXTMETRICW tm32;
1187
1188     if (!GetTextMetricsW( hdc, &tm32 )) return FALSE;
1189     FONT_TextMetricWToA( &tm32, metrics );
1190     return TRUE;
1191 }
1192
1193 /***********************************************************************
1194  *           GetTextMetricsW    (GDI32.@)
1195  */
1196 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1197 {
1198     BOOL ret = FALSE;
1199     DC * dc = DC_GetDCPtr( hdc );
1200     if (!dc) return FALSE;
1201
1202     if (dc->funcs->pGetTextMetrics && dc->funcs->pGetTextMetrics( dc, metrics ))
1203     {
1204     /* device layer returns values in device units
1205      * therefore we have to convert them to logical */
1206
1207 #define WDPTOLP(x) ((x<0)?                                      \
1208                 (-abs((x)*dc->wndExtX/dc->vportExtX)):          \
1209                 (abs((x)*dc->wndExtX/dc->vportExtX)))
1210 #define HDPTOLP(y) ((y<0)?                                      \
1211                 (-abs((y)*dc->wndExtY/dc->vportExtY)):          \
1212                 (abs((y)*dc->wndExtY/dc->vportExtY)))
1213         
1214     metrics->tmHeight           = HDPTOLP(metrics->tmHeight);
1215     metrics->tmAscent           = HDPTOLP(metrics->tmAscent);
1216     metrics->tmDescent          = HDPTOLP(metrics->tmDescent);
1217     metrics->tmInternalLeading  = HDPTOLP(metrics->tmInternalLeading);
1218     metrics->tmExternalLeading  = HDPTOLP(metrics->tmExternalLeading);
1219     metrics->tmAveCharWidth     = WDPTOLP(metrics->tmAveCharWidth);
1220     metrics->tmMaxCharWidth     = WDPTOLP(metrics->tmMaxCharWidth);
1221     metrics->tmOverhang         = WDPTOLP(metrics->tmOverhang);
1222         ret = TRUE;
1223
1224     TRACE("text metrics:\n"
1225           "    Weight = %03li\t FirstChar = %i\t AveCharWidth = %li\n"
1226           "    Italic = % 3i\t LastChar = %i\t\t MaxCharWidth = %li\n"
1227           "    UnderLined = %01i\t DefaultChar = %i\t Overhang = %li\n"
1228           "    StruckOut = %01i\t BreakChar = %i\t CharSet = %i\n"
1229           "    PitchAndFamily = %02x\n"
1230           "    --------------------\n"
1231           "    InternalLeading = %li\n"
1232           "    Ascent = %li\n"
1233           "    Descent = %li\n"
1234           "    Height = %li\n",
1235           metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1236           metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1237           metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1238           metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1239           metrics->tmPitchAndFamily,
1240           metrics->tmInternalLeading,
1241           metrics->tmAscent,
1242           metrics->tmDescent,
1243           metrics->tmHeight );
1244     }
1245     GDI_ReleaseObj( hdc );
1246     return ret;
1247 }
1248
1249
1250 /***********************************************************************
1251  * GetOutlineTextMetrics16 [GDI.308]  Gets metrics for TrueType fonts.
1252  *
1253  * NOTES
1254  *    lpOTM should be LPOUTLINETEXTMETRIC
1255  *
1256  * RETURNS
1257  *    Success: Non-zero or size of required buffer
1258  *    Failure: 0
1259  */
1260 UINT16 WINAPI GetOutlineTextMetrics16(
1261     HDC16 hdc,    /* [in]  Handle of device context */
1262     UINT16 cbData, /* [in]  Size of metric data array */
1263     LPOUTLINETEXTMETRIC16 lpOTM)  /* [out] Address of metric data array */
1264 {
1265     FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
1266     return 0;
1267 }
1268
1269
1270 /***********************************************************************
1271  *              GetOutlineTextMetrics (GDI.207)
1272  *              GetOutlineTextMetricsA (GDI32.@)
1273  * Gets metrics for TrueType fonts.
1274  *
1275  *
1276  * RETURNS
1277  *    Success: Non-zero or size of required buffer
1278  *    Failure: 0
1279  */
1280 UINT WINAPI GetOutlineTextMetricsA(
1281     HDC hdc,    /* [in]  Handle of device context */
1282     UINT cbData, /* [in]  Size of metric data array */
1283     LPOUTLINETEXTMETRICA lpOTM)  /* [out] Address of metric data array */
1284 {
1285
1286
1287     UINT rtn = FALSE;
1288     LPTEXTMETRICA lptxtMetr;
1289
1290
1291
1292     if (lpOTM == 0)
1293     {
1294         
1295         lpOTM = (LPOUTLINETEXTMETRICA)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(OUTLINETEXTMETRICA));
1296         rtn = sizeof(OUTLINETEXTMETRICA);
1297         cbData = rtn;
1298     } else
1299     {
1300         cbData = sizeof(*lpOTM);
1301         rtn = cbData;
1302     };
1303
1304     lpOTM->otmSize = cbData;
1305
1306     lptxtMetr =HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(TEXTMETRICA));
1307     
1308     if (!GetTextMetricsA(hdc,lptxtMetr))
1309     {
1310         return 0;
1311     } else
1312     {
1313        memcpy(&(lpOTM->otmTextMetrics),lptxtMetr,sizeof(TEXTMETRICA));
1314     };
1315
1316     HeapFree(GetProcessHeap(),HEAP_ZERO_MEMORY,lptxtMetr);
1317     
1318     lpOTM->otmFiller = 0;
1319
1320     lpOTM->otmPanoseNumber.bFamilyType  = 0;
1321     lpOTM->otmPanoseNumber.bSerifStyle  = 0;
1322     lpOTM->otmPanoseNumber.bWeight      = 0;
1323     lpOTM->otmPanoseNumber.bProportion  = 0;
1324     lpOTM->otmPanoseNumber.bContrast    = 0;
1325     lpOTM->otmPanoseNumber.bStrokeVariation = 0;
1326     lpOTM->otmPanoseNumber.bArmStyle    = 0;
1327     lpOTM->otmPanoseNumber.bLetterform  = 0;
1328     lpOTM->otmPanoseNumber.bMidline     = 0;
1329     lpOTM->otmPanoseNumber.bXHeight     = 0;
1330
1331     lpOTM->otmfsSelection     = 0;
1332     lpOTM->otmfsType          = 0;
1333
1334     /*
1335      Further fill of the structure not implemented,
1336      Needs real values for the structure members
1337      */
1338     
1339     return rtn;
1340 }
1341
1342 /***********************************************************************
1343  *           GetOutlineTextMetricsW [GDI32.@]
1344  */
1345 UINT WINAPI GetOutlineTextMetricsW(
1346     HDC hdc,    /* [in]  Handle of device context */
1347     UINT cbData, /* [in]  Size of metric data array */
1348     LPOUTLINETEXTMETRICW lpOTM)  /* [out] Address of metric data array */
1349 {
1350     FIXME("(%d,%d,%p): stub\n", hdc, cbData, lpOTM);
1351     return 0; 
1352 }
1353
1354 /***********************************************************************
1355  *           GetCharWidth16    (GDI.350)
1356  *           GetCharWidth16    (DISPLAY.350)
1357  */
1358 BOOL16 WINAPI GetCharWidth16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1359                               LPINT16 buffer )
1360 {
1361     BOOL        retVal = FALSE;
1362
1363     if( firstChar != lastChar )
1364     {
1365         LPINT   buf32 = (LPINT)HeapAlloc(GetProcessHeap(), 0,
1366                                  sizeof(INT)*(1 + (lastChar - firstChar)));
1367         if( buf32 )
1368         {
1369             LPINT       obuf32 = buf32;
1370             int         i;
1371
1372             retVal = GetCharWidth32A(hdc, firstChar, lastChar, buf32);
1373             if (retVal)
1374             {
1375                 for (i = firstChar; i <= lastChar; i++)
1376                     *buffer++ = *buf32++;
1377             }
1378             HeapFree(GetProcessHeap(), 0, obuf32);
1379         }
1380     }
1381     else /* happens quite often to warrant a special treatment */
1382     {
1383         INT chWidth;
1384         retVal = GetCharWidth32A(hdc, firstChar, lastChar, &chWidth );
1385        *buffer = chWidth;
1386     }
1387     return retVal;
1388 }
1389
1390
1391 /***********************************************************************
1392  *           GetCharWidth32A    (GDI32.@)
1393  */
1394 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1395                                LPINT buffer )
1396 {
1397     UINT i, extra;
1398     BOOL ret = FALSE;
1399     DC * dc = DC_GetDCPtr( hdc );
1400     if (!dc) return FALSE;
1401
1402     if (dc->funcs->pGetCharWidth && dc->funcs->pGetCharWidth( dc, firstChar, lastChar, buffer))
1403     {
1404         /* convert device units to logical */
1405
1406         extra = dc->vportExtX >> 1;
1407         for( i = firstChar; i <= lastChar; i++, buffer++ )
1408             *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX;
1409         ret = TRUE;
1410     }
1411     GDI_ReleaseObj( hdc );
1412     return ret;
1413 }
1414
1415
1416 /***********************************************************************
1417  *           GetCharWidth32W    (GDI32.@)
1418  */
1419 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1420                                LPINT buffer )
1421 {
1422     return GetCharWidth32A( hdc, firstChar, lastChar, buffer );
1423 }
1424
1425
1426 /* FIXME: all following APIs ******************************************/
1427  
1428
1429 /***********************************************************************
1430  *           SetMapperFlags16    (GDI.349)
1431  */
1432 DWORD WINAPI SetMapperFlags16( HDC16 hDC, DWORD dwFlag )
1433 {
1434     return SetMapperFlags( hDC, dwFlag );
1435 }
1436
1437
1438 /***********************************************************************
1439  *           SetMapperFlags    (GDI32.@)
1440  */
1441 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1442 {
1443     DC *dc = DC_GetDCPtr( hDC );
1444     DWORD ret = 0; 
1445     if(!dc) return 0;
1446     if(dc->funcs->pSetMapperFlags)
1447         ret = dc->funcs->pSetMapperFlags( dc, dwFlag );
1448     else
1449         FIXME("(0x%04x, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1450     GDI_ReleaseObj( hDC );
1451     return ret;
1452 }
1453
1454 /***********************************************************************
1455  *          GetAspectRatioFilterEx16  (GDI.486)
1456  */
1457 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1458 {
1459   FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1460   return FALSE;
1461 }
1462
1463 /***********************************************************************
1464  *          GetAspectRatioFilterEx  (GDI32.@)
1465  */
1466 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1467 {
1468   FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1469   return FALSE;
1470 }
1471
1472 /***********************************************************************
1473  *           GetCharABCWidths16   (GDI.307)
1474  */
1475 BOOL16 WINAPI GetCharABCWidths16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1476                                   LPABC16 abc )
1477 {
1478     LPABC       abc32 = HeapAlloc(GetProcessHeap(),0,sizeof(ABC)*(lastChar-firstChar+1));
1479     int         i;
1480
1481     if (!GetCharABCWidthsA( hdc, firstChar, lastChar, abc32 )) {
1482         HeapFree(GetProcessHeap(),0,abc32);
1483         return FALSE;
1484     }
1485
1486     for (i=firstChar;i<=lastChar;i++) {
1487         abc[i-firstChar].abcA = abc32[i-firstChar].abcA;
1488         abc[i-firstChar].abcB = abc32[i-firstChar].abcB;
1489         abc[i-firstChar].abcC = abc32[i-firstChar].abcC;
1490     }
1491     HeapFree(GetProcessHeap(),0,abc32);
1492     return TRUE;
1493 }
1494
1495
1496 /***********************************************************************
1497  *           GetCharABCWidthsA   (GDI32.@)
1498  */
1499 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1500                                   LPABC abc )
1501 {
1502     return GetCharABCWidthsW( hdc, firstChar, lastChar, abc );
1503 }
1504
1505
1506 /******************************************************************************
1507  * GetCharABCWidthsW [GDI32.@]  Retrieves widths of characters in range
1508  *
1509  * PARAMS
1510  *    hdc       [I] Handle of device context
1511  *    firstChar [I] First character in range to query
1512  *    lastChar  [I] Last character in range to query
1513  *    abc       [O] Address of character-width structure
1514  *
1515  * NOTES
1516  *    Only works with TrueType fonts
1517  *
1518  * RETURNS
1519  *    Success: TRUE
1520  *    Failure: FALSE
1521  */
1522 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1523                                    LPABC abc )
1524 {
1525     int         i;
1526     LPINT       widths = HeapAlloc(GetProcessHeap(),0,(lastChar-firstChar+1)*sizeof(INT));
1527
1528     FIXME("(%04x,%04x,%04x,%p), returns slightly bogus values.\n", hdc, firstChar, lastChar, abc);
1529
1530     GetCharWidth32A(hdc,firstChar,lastChar,widths);
1531
1532     for (i=firstChar;i<=lastChar;i++) {
1533         abc[i-firstChar].abcA = 0;      /* left distance */
1534         abc[i-firstChar].abcB = widths[i-firstChar];/* width */
1535         abc[i-firstChar].abcC = 0;      /* right distance */
1536     }
1537     HeapFree(GetProcessHeap(),0,widths);
1538     return TRUE;
1539 }
1540
1541
1542 /***********************************************************************
1543  *           GetGlyphOutline16    (GDI.309)
1544  */
1545 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1546                                 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1547                                 LPVOID lpBuffer, const MAT2 *lpmat2 )
1548 {
1549     FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1550           hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1551     return (DWORD)-1; /* failure */
1552 }
1553
1554
1555 /***********************************************************************
1556  *           GetGlyphOutlineA    (GDI32.@)
1557  */
1558 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1559                                  LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1560                                  LPVOID lpBuffer, const MAT2 *lpmat2 )
1561 {
1562     FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1563           hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1564     return (DWORD)-1; /* failure */
1565 }
1566
1567 /***********************************************************************
1568  *           GetGlyphOutlineW    (GDI32.@)
1569  */
1570 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1571                                  LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1572                                  LPVOID lpBuffer, const MAT2 *lpmat2 )
1573 {
1574     FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1575           hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1576     return (DWORD)-1; /* failure */
1577 }
1578
1579 /***********************************************************************
1580  *           CreateScalableFontResource16   (GDI.310)
1581  */
1582 BOOL16 WINAPI CreateScalableFontResource16( UINT16 fHidden,
1583                                             LPCSTR lpszResourceFile,
1584                                             LPCSTR fontFile, LPCSTR path )
1585 {
1586     return CreateScalableFontResourceA( fHidden, lpszResourceFile,
1587                                           fontFile, path );
1588 }
1589
1590 /***********************************************************************
1591  *           CreateScalableFontResourceA   (GDI32.@)
1592  */
1593 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1594                                              LPCSTR lpszResourceFile,
1595                                              LPCSTR lpszFontFile,
1596                                              LPCSTR lpszCurrentPath )
1597 {
1598     /* fHidden=1 - only visible for the calling app, read-only, not
1599      * enumbered with EnumFonts/EnumFontFamilies
1600      * lpszCurrentPath can be NULL
1601      */
1602     FIXME("(%ld,%s,%s,%s): stub\n",
1603           fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1604     return FALSE; /* create failed */
1605 }
1606
1607 /***********************************************************************
1608  *           CreateScalableFontResourceW   (GDI32.@)
1609  */
1610 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1611                                              LPCWSTR lpszResourceFile,
1612                                              LPCWSTR lpszFontFile,
1613                                              LPCWSTR lpszCurrentPath )
1614 {
1615     FIXME("(%ld,%p,%p,%p): stub\n",
1616           fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1617     return FALSE; /* create failed */
1618 }
1619
1620
1621 /*************************************************************************
1622  *             GetRasterizerCaps16   (GDI.313)
1623  */
1624 BOOL16 WINAPI GetRasterizerCaps16( LPRASTERIZER_STATUS lprs, UINT16 cbNumBytes)
1625 {
1626     return GetRasterizerCaps( lprs, cbNumBytes );
1627 }
1628
1629
1630 /*************************************************************************
1631  *             GetRasterizerCaps   (GDI32.@)
1632  */
1633 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
1634 {
1635   lprs->nSize = sizeof(RASTERIZER_STATUS);
1636   lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
1637   lprs->nLanguageID = 0;
1638   return TRUE;
1639 }
1640
1641
1642 /*************************************************************************
1643  *             GetKerningPairs16   (GDI.332)
1644  */
1645 INT16 WINAPI GetKerningPairs16( HDC16 hDC, INT16 cPairs,
1646                                 LPKERNINGPAIR16 lpKerningPairs )
1647 {
1648     /* At this time kerning is ignored (set to 0) */
1649     int i;
1650     FIXME("(%x,%d,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1651     for (i = 0; i < cPairs; i++) 
1652         lpKerningPairs[i].iKernAmount = 0;
1653     return 0;
1654 }
1655
1656
1657
1658 /*************************************************************************
1659  *             GetKerningPairsA   (GDI32.@)
1660  */
1661 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs,
1662                                  LPKERNINGPAIR lpKerningPairs )
1663 {
1664     int i;
1665     FIXME("(%x,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1666     for (i = 0; i < cPairs; i++) 
1667         lpKerningPairs[i].iKernAmount = 0;
1668     return 0;
1669 }
1670
1671
1672 /*************************************************************************
1673  *             GetKerningPairsW   (GDI32.@)
1674  */
1675 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
1676                                  LPKERNINGPAIR lpKerningPairs )
1677 {
1678     return GetKerningPairsA( hDC, cPairs, lpKerningPairs );
1679 }
1680
1681 /*************************************************************************
1682  * TranslateCharsetInfo [GDI32.@]
1683  *
1684  * Fills a CHARSETINFO structure for a character set, code page, or
1685  * font. This allows making the correspondance between different labelings
1686  * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges) 
1687  * of the same encoding.
1688  *
1689  * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
1690  * only one codepage should be set in *lpSrc.
1691  *
1692  * RETURNS
1693  *   TRUE on success, FALSE on failure.
1694  *
1695  */
1696 BOOL WINAPI TranslateCharsetInfo(
1697   LPDWORD lpSrc, /* [in]
1698        if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
1699        if flags == TCI_SRCCHARSET: a character set value
1700        if flags == TCI_SRCCODEPAGE: a code page value
1701                  */
1702   LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
1703   DWORD flags /* [in] determines interpretation of lpSrc */
1704 ) {
1705     int index = 0;
1706     switch (flags) {
1707     case TCI_SRCFONTSIG:
1708         while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
1709       break;
1710     case TCI_SRCCODEPAGE:
1711       while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
1712       break;
1713     case TCI_SRCCHARSET:
1714       while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
1715       break;
1716     default:
1717       return FALSE;
1718     }
1719     if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
1720     memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
1721     return TRUE;
1722 }
1723
1724 /*************************************************************************
1725  *             GetFontLanguageInfo   (GDI32.@)
1726  */
1727 DWORD WINAPI GetFontLanguageInfo(HDC hdc) {
1728         /* return value 0 is correct for most cases anyway */
1729         FIXME("(%x):stub!\n", hdc);
1730         return 0;
1731 }
1732
1733 /*************************************************************************
1734  *             GetFontLanguageInfo   (GDI.616)
1735  */
1736 DWORD WINAPI GetFontLanguageInfo16(HDC16 hdc) {
1737         /* return value 0 is correct for most cases anyway */
1738         FIXME("(%x):stub!\n",hdc);
1739         return 0;
1740 }
1741
1742 /*************************************************************************
1743  * GetFontData [GDI32.@] Retrieve data for TrueType font
1744  *
1745  * RETURNS
1746  *
1747  * success: Number of bytes returned 
1748  * failure: GDI_ERROR
1749  *
1750  * NOTES
1751  *
1752  * Calls SetLastError()  
1753  *
1754  * BUGS
1755  *
1756  * Unimplemented
1757  */
1758 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset, 
1759     LPVOID buffer, DWORD length)
1760 {
1761     FIXME("(%x,%ld,%ld,%p,%ld): stub\n", hdc, table, offset, buffer, length);
1762     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1763     return GDI_ERROR;
1764 }
1765
1766 /*************************************************************************
1767  * GetFontData16 [GDI.311]
1768  *
1769  */
1770 DWORD WINAPI GetFontData16(HDC16 hdc, DWORD dwTable, DWORD dwOffset,
1771                             LPVOID lpvBuffer, DWORD cbData)
1772 {
1773     return GetFontData(hdc, dwTable, dwOffset, lpvBuffer, cbData);
1774 }
1775
1776 /*************************************************************************
1777  * GetCharacterPlacementA [GDI32.@]
1778  *
1779  * NOTES:
1780  *  the web browser control of ie4 calls this with dwFlags=0
1781  */
1782 DWORD WINAPI
1783 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
1784                          INT nMaxExtent, GCP_RESULTSA *lpResults,
1785                          DWORD dwFlags)
1786 {
1787     DWORD ret=0;
1788     SIZE size;
1789
1790     TRACE("%s 0x%08x 0x%08x 0x%08lx:stub!\n",
1791           debugstr_a(lpString), uCount, nMaxExtent, dwFlags);
1792
1793     TRACE("lpOrder=%p lpDx=%p lpCaretPos=%p lpClass=%p "
1794           "lpOutString=%p lpGlyphs=%p\n",
1795           lpResults->lpOrder, lpResults->lpDx, lpResults->lpCaretPos,
1796           lpResults->lpClass, lpResults->lpOutString, lpResults->lpGlyphs);
1797
1798     if(dwFlags)                 FIXME("flags 0x%08lx ignored\n", dwFlags);
1799     if(lpResults->lpOrder)      FIXME("reordering not implemented\n");
1800     if(lpResults->lpCaretPos)   FIXME("caret positions not implemented\n");
1801     if(lpResults->lpClass)      FIXME("classes not implemented\n");
1802     if(lpResults->lpGlyphs)     FIXME("glyphs not implemented\n");
1803
1804     /* copy will do if the GCP_REORDER flag is not set */
1805     if(lpResults->lpOutString)
1806     {
1807       lstrcpynA(lpResults->lpOutString, lpString, uCount);
1808     }
1809
1810     if (lpResults->lpDx)
1811     {
1812       int i, c;
1813       for (i=0; i<uCount;i++)
1814       { 
1815         if (GetCharWidth32A(hdc, lpString[i], lpString[i], &c))
1816           lpResults->lpDx[i]= c;
1817       }
1818     }
1819
1820     if (GetTextExtentPoint32A(hdc, lpString, uCount, &size))
1821       ret = MAKELONG(size.cx, size.cy);
1822
1823     return ret;
1824 }
1825
1826 /*************************************************************************
1827  * GetCharacterPlacementW [GDI32.@]
1828  */
1829 DWORD WINAPI
1830 GetCharacterPlacementW(HDC hdc, LPCWSTR lpString, INT uCount,
1831                          INT nMaxExtent, GCP_RESULTSW *lpResults,
1832                          DWORD dwFlags)
1833 {
1834     /* return value 0 is correct for most cases anyway */
1835     FIXME(":stub!\n");
1836     return 0;
1837 }
1838
1839 /*************************************************************************
1840  *      GetCharABCWidthsFloatA [GDI32.@]
1841  */
1842 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
1843                                         LPABCFLOAT lpABCF)
1844 {
1845        FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
1846        return 0;
1847 }
1848
1849 /*************************************************************************
1850  *      GetCharABCWidthsFloatW [GDI32.@]
1851  */
1852 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
1853                                         UINT iLastChar, LPABCFLOAT lpABCF)
1854 {
1855        FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
1856        return 0;
1857 }
1858
1859 /*************************************************************************
1860  *      GetCharWidthFloatA [GDI32.@]
1861  */
1862 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
1863                                     UINT iLastChar, PFLOAT pxBuffer)
1864 {
1865        FIXME_(gdi)("GetCharWidthFloatA, stub\n");
1866        return 0;
1867 }
1868
1869 /*************************************************************************
1870  *      GetCharWidthFloatW [GDI32.@]
1871  */
1872 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
1873                                     UINT iLastChar, PFLOAT pxBuffer)
1874 {
1875        FIXME_(gdi)("GetCharWidthFloatW, stub\n");
1876        return 0;
1877 }
1878  
1879
1880 /***********************************************************************
1881  *                                                                     *
1882  *           Font Resource API                                         *
1883  *                                                                     *
1884  ***********************************************************************/
1885 /***********************************************************************
1886  *           AddFontResource16    (GDI.119)
1887  *
1888  *  Can be either .FON, or .FNT, or .TTF, or .FOT font file.
1889  *
1890  *  FIXME: Load header and find the best-matching font in the fontList;
1891  *         fixup dfPoints if all metrics are identical, otherwise create
1892  *         new fontAlias. When soft font support is ready this will
1893  *         simply create a new fontResource ('filename' will go into
1894  *         the pfr->resource field) with FR_SOFTFONT/FR_SOFTRESOURCE 
1895  *         flag set. 
1896  */
1897 INT16 WINAPI AddFontResource16( LPCSTR filename )
1898 {
1899     return AddFontResourceA( filename );
1900 }
1901
1902
1903 /***********************************************************************
1904  *           AddFontResourceA    (GDI32.@)
1905  */
1906 INT WINAPI AddFontResourceA( LPCSTR str )
1907 {
1908     FIXME("(%s): stub! Read the Wine User Guide on how to install "
1909             "this font manually.\n", debugres_a(str));
1910     return 1;
1911 }
1912
1913
1914 /***********************************************************************
1915  *           AddFontResourceW    (GDI32.@)
1916  */
1917 INT WINAPI AddFontResourceW( LPCWSTR str )
1918 {
1919     FIXME("(%s): stub! Read the Wine User Guide on how to install "
1920             "this font manually.\n", debugres_w(str));
1921     return 1;
1922 }
1923
1924 /***********************************************************************
1925  *           RemoveFontResource16    (GDI.136)
1926  */
1927 BOOL16 WINAPI RemoveFontResource16( LPCSTR str )
1928 {
1929     FIXME("(%s): stub\n", debugres_a(str));
1930     return TRUE;
1931 }
1932
1933
1934 /***********************************************************************
1935  *           RemoveFontResourceA    (GDI32.@)
1936  */
1937 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
1938 {
1939 /*  This is how it should look like */
1940 /*
1941     fontResource** ppfr;
1942     BOOL32 retVal = FALSE;
1943
1944     EnterCriticalSection( &crtsc_fonts_X11 );
1945     for( ppfr = &fontList; *ppfr; ppfr = &(*ppfr)->next )
1946          if( !strcasecmp( (*ppfr)->lfFaceName, str ) )
1947          {
1948              if(((*ppfr)->fr_flags & (FR_SOFTFONT | FR_SOFTRESOURCE)) &&
1949                  (*ppfr)->hOwnerProcess == GetCurrentProcess() )
1950              {
1951                  if( (*ppfr)->fo_count )
1952                      (*ppfr)->fr_flags |= FR_REMOVED;
1953                  else
1954                      XFONT_RemoveFontResource( ppfr );
1955              }
1956              retVal = TRUE;
1957          }
1958     LeaveCriticalSection( &crtsc_fonts_X11 );
1959     return retVal;
1960  */
1961     FIXME("(%s): stub\n", debugres_a(str));
1962     return TRUE;
1963 }
1964
1965
1966 /***********************************************************************
1967  *           RemoveFontResourceW    (GDI32.@)
1968  */
1969 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
1970 {
1971     FIXME("(%s): stub\n", debugres_w(str) );
1972     return TRUE;
1973 }