Removed unnecessary SetWindowPos call in SetWindowRgn.
[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  *           CreateFontIndirect   (GDI.57)
413  */
414 HFONT16 WINAPI CreateFontIndirect16( const LOGFONT16 *plf16 )
415 {
416     LOGFONTW lfW;
417
418     if(plf16) {
419         FONT_LogFont16ToW( plf16, &lfW );
420         return CreateFontIndirectW( &lfW );
421     } else {
422         return CreateFontIndirectW( NULL );
423     }
424 }
425
426
427 /***********************************************************************
428  *           CreateFontIndirectA   (GDI32.@)
429  */
430 HFONT WINAPI CreateFontIndirectA( const LOGFONTA *plfA )
431 {
432     LOGFONTW lfW;
433
434     if (plfA) {
435         FONT_LogFontAToW( plfA, &lfW );
436         return CreateFontIndirectW( &lfW );
437      } else
438         return CreateFontIndirectW( NULL );
439
440 }
441
442 /***********************************************************************
443  *           CreateFontIndirectW   (GDI32.@)
444  */
445 HFONT WINAPI CreateFontIndirectW( const LOGFONTW *plf )
446 {
447     HFONT hFont = 0;
448
449     if (plf)
450     {
451         FONTOBJ* fontPtr;
452         if ((fontPtr = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC, &hFont )))
453         {
454             memcpy( &fontPtr->logfont, plf, sizeof(LOGFONTW) );
455
456             TRACE("(%ld %ld %ld %ld) %s %s %s => %04x\n",
457                   plf->lfHeight, plf->lfWidth, 
458                   plf->lfEscapement, plf->lfOrientation,
459                   debugstr_w(plf->lfFaceName),
460                   plf->lfWeight > 400 ? "Bold" : "",
461                   plf->lfItalic ? "Italic" : "", hFont);
462
463             if (plf->lfEscapement != plf->lfOrientation) {
464               /* this should really depend on whether GM_ADVANCED is set */
465               fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
466               WARN("orientation angle %f set to "
467                    "escapement angle %f for new font %04x\n", 
468                    plf->lfOrientation/10., plf->lfEscapement/10., hFont);
469             }
470             GDI_ReleaseObj( hFont );
471         }
472     }
473     else WARN("(NULL) => NULL\n");
474
475     return hFont;
476 }
477
478 /***********************************************************************
479  *           CreateFont    (GDI.56)
480  */
481 HFONT16 WINAPI CreateFont16(INT16 height, INT16 width, INT16 esc, INT16 orient,
482                             INT16 weight, BYTE italic, BYTE underline,
483                             BYTE strikeout, BYTE charset, BYTE outpres,
484                             BYTE clippres, BYTE quality, BYTE pitch,
485                             LPCSTR name )
486 {
487     LOGFONT16 logfont;
488
489     logfont.lfHeight = height;
490     logfont.lfWidth = width;
491     logfont.lfEscapement = esc;
492     logfont.lfOrientation = orient;
493     logfont.lfWeight = weight;
494     logfont.lfItalic = italic;
495     logfont.lfUnderline = underline;
496     logfont.lfStrikeOut = strikeout;
497     logfont.lfCharSet = charset;
498     logfont.lfOutPrecision = outpres;
499     logfont.lfClipPrecision = clippres;
500     logfont.lfQuality = quality;
501     logfont.lfPitchAndFamily = pitch;
502    
503     if (name) 
504         lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
505     else 
506         logfont.lfFaceName[0] = '\0';
507
508     return CreateFontIndirect16( &logfont );
509 }
510
511 /*************************************************************************
512  *           CreateFontA    (GDI32.@)
513  */
514 HFONT WINAPI CreateFontA( INT height, INT width, INT esc,
515                               INT orient, INT weight, DWORD italic,
516                               DWORD underline, DWORD strikeout, DWORD charset,
517                               DWORD outpres, DWORD clippres, DWORD quality,
518                               DWORD pitch, LPCSTR name )
519 {
520     LOGFONTA logfont;
521
522     logfont.lfHeight = height;
523     logfont.lfWidth = width;
524     logfont.lfEscapement = esc;
525     logfont.lfOrientation = orient;
526     logfont.lfWeight = weight;
527     logfont.lfItalic = italic;
528     logfont.lfUnderline = underline;
529     logfont.lfStrikeOut = strikeout;
530     logfont.lfCharSet = charset;
531     logfont.lfOutPrecision = outpres;
532     logfont.lfClipPrecision = clippres;
533     logfont.lfQuality = quality;
534     logfont.lfPitchAndFamily = pitch;
535    
536     if (name) 
537         lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
538     else 
539         logfont.lfFaceName[0] = '\0';
540
541     return CreateFontIndirectA( &logfont );
542 }
543
544 /*************************************************************************
545  *           CreateFontW    (GDI32.@)
546  */
547 HFONT WINAPI CreateFontW( INT height, INT width, INT esc,
548                               INT orient, INT weight, DWORD italic,
549                               DWORD underline, DWORD strikeout, DWORD charset,
550                               DWORD outpres, DWORD clippres, DWORD quality,
551                               DWORD pitch, LPCWSTR name )
552 {
553     LOGFONTW logfont;
554
555     logfont.lfHeight = height;
556     logfont.lfWidth = width;
557     logfont.lfEscapement = esc;
558     logfont.lfOrientation = orient;
559     logfont.lfWeight = weight;
560     logfont.lfItalic = italic;
561     logfont.lfUnderline = underline;
562     logfont.lfStrikeOut = strikeout;
563     logfont.lfCharSet = charset;
564     logfont.lfOutPrecision = outpres;
565     logfont.lfClipPrecision = clippres;
566     logfont.lfQuality = quality;
567     logfont.lfPitchAndFamily = pitch;
568    
569     if (name) 
570         lstrcpynW(logfont.lfFaceName, name, 
571                   sizeof(logfont.lfFaceName) / sizeof(WCHAR));
572     else 
573         logfont.lfFaceName[0] = '\0';
574
575     return CreateFontIndirectW( &logfont );
576 }
577
578
579 /***********************************************************************
580  *           FONT_GetObject16
581  */
582 INT16 FONT_GetObject16( FONTOBJ * font, INT16 count, LPSTR buffer )
583 {
584     LOGFONT16 lf16;
585
586     FONT_LogFontWTo16( &font->logfont, &lf16 );
587
588     if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
589     memcpy( buffer, &lf16, count );
590     return count;
591 }
592
593 /***********************************************************************
594  *           FONT_GetObjectA
595  */
596 INT FONT_GetObjectA( FONTOBJ *font, INT count, LPSTR buffer )
597 {
598     LOGFONTA lfA;
599
600     FONT_LogFontWToA( &font->logfont, &lfA );
601
602     if (count > sizeof(lfA)) count = sizeof(lfA);
603     memcpy( buffer, &lfA, count );
604     return count;
605 }
606 /***********************************************************************
607  *           FONT_GetObjectW
608  */
609 INT FONT_GetObjectW( FONTOBJ *font, INT count, LPSTR buffer )
610 {
611     if (count > sizeof(LOGFONTW)) count = sizeof(LOGFONTW);
612     memcpy( buffer, &font->logfont, count );
613     return count;
614 }
615
616
617 /***********************************************************************
618  *              FONT_EnumInstance16
619  *
620  * Called by the device driver layer to pass font info
621  * down to the application.
622  */
623 static INT FONT_EnumInstance16( LPENUMLOGFONTEXW plf, LPNEWTEXTMETRICEXW ptm,
624                                 DWORD fType, LPARAM lp )
625 {
626 #define pfe ((fontEnum16*)lp)
627     if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET || 
628         pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
629     {
630         FONT_EnumLogFontExWTo16(plf, pfe->lpLogFont);
631         FONT_NewTextMetricExWTo16(ptm, pfe->lpTextMetric);
632         return pfe->lpEnumFunc( pfe->segLogFont, pfe->segTextMetric,
633                                 (UINT16)fType, (LPARAM)(pfe->lpData) );
634     }
635 #undef pfe
636     return 1;
637 }
638
639 /***********************************************************************
640  *              FONT_EnumInstance
641  */
642 static INT FONT_EnumInstance( LPENUMLOGFONTEXW plf, LPNEWTEXTMETRICEXW ptm,
643                               DWORD fType, LPARAM lp )
644 {
645     /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
646
647 #define pfe ((fontEnum32*)lp)
648     if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET || 
649         pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
650     {
651         /* convert font metrics */
652
653         if( pfe->dwFlags & ENUM_UNICODE )
654         {
655             return pfe->lpEnumFunc( plf, ptm, fType, pfe->lpData );
656         }
657         else
658         {
659             ENUMLOGFONTEXA logfont;
660             NEWTEXTMETRICEXA tmA;
661
662             FONT_EnumLogFontExWToA( plf, &logfont);
663             FONT_NewTextMetricExWToA( ptm, &tmA );
664
665             return pfe->lpEnumFunc( (LPENUMLOGFONTEXW)&logfont, 
666                                     (LPNEWTEXTMETRICEXW)&tmA, fType,
667                                     pfe->lpData );
668         }
669     }
670 #undef pfe
671     return 1;
672 }
673
674 /***********************************************************************
675  *              EnumFontFamiliesEx16    (GDI.613)
676  */
677 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
678                                    FONTENUMPROCEX16 efproc, LPARAM lParam,
679                                    DWORD dwFlags)
680 {
681     BOOL (*enum_func)(HDC,LPLOGFONTW,DEVICEFONTENUMPROC,LPARAM);
682     INT16       retVal = 0;
683     DC*         dc = DC_GetDCPtr( hDC );
684
685     if (!dc) return 0;
686     enum_func = dc->funcs->pEnumDeviceFonts;
687     GDI_ReleaseObj( hDC );
688
689     if (enum_func)
690     {
691         LPNEWTEXTMETRICEX16 lptm16 = SEGPTR_ALLOC( sizeof(NEWTEXTMETRICEX16) );
692         if( lptm16 )
693         {
694             LPENUMLOGFONTEX16 lplf16 = SEGPTR_ALLOC( sizeof(ENUMLOGFONTEX16) );
695             if( lplf16 )
696             {
697                 fontEnum16      fe16;
698                 LOGFONTW        lfW;
699                 FONT_LogFont16ToW(plf, &lfW);
700
701                 fe16.lpLogFontParam = plf;
702                 fe16.lpEnumFunc = efproc;
703                 fe16.lpData = lParam;
704                 
705                 fe16.lpTextMetric = lptm16;
706                 fe16.lpLogFont = lplf16;
707                 fe16.segTextMetric = SEGPTR_GET(lptm16);
708                 fe16.segLogFont = SEGPTR_GET(lplf16);
709
710                 retVal = enum_func( hDC, &lfW, FONT_EnumInstance16,
711                                     (LPARAM)&fe16 );
712                 SEGPTR_FREE(lplf16);
713             }
714             SEGPTR_FREE(lptm16);
715         }
716     }
717     return retVal;
718 }
719
720 /***********************************************************************
721  *              FONT_EnumFontFamiliesEx
722  */
723 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf,
724                                     FONTENUMPROCEXW efproc, 
725                                     LPARAM lParam, DWORD dwUnicode)
726 {
727     BOOL (*enum_func)(HDC,LPLOGFONTW,DEVICEFONTENUMPROC,LPARAM);
728     INT ret = 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  *           GetTextCharacterExtra    (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  *           SetTextCharacterExtra    (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  *           SetTextJustification    (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  *           GetTextFace    (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  *           GetTextExtent    (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  *           GetTextExtentPoint    (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  *           GetTextMetrics    (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  * GetOutlineTextMetrics [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.308)
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  *           GetCharWidth    (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  *           GetCharWidthA      (GDI32.@)
1393  *           GetCharWidth32A    (GDI32.@)
1394  */
1395 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1396                                LPINT buffer )
1397 {
1398     UINT i, extra;
1399     BOOL ret = FALSE;
1400     DC * dc = DC_GetDCPtr( hdc );
1401     if (!dc) return FALSE;
1402
1403     if (dc->funcs->pGetCharWidth && dc->funcs->pGetCharWidth( dc, firstChar, lastChar, buffer))
1404     {
1405         /* convert device units to logical */
1406
1407         extra = dc->vportExtX >> 1;
1408         for( i = firstChar; i <= lastChar; i++, buffer++ )
1409             *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX;
1410         ret = TRUE;
1411     }
1412     GDI_ReleaseObj( hdc );
1413     return ret;
1414 }
1415
1416
1417 /***********************************************************************
1418  *           GetCharWidthW      (GDI32.@)
1419  *           GetCharWidth32W    (GDI32.@)
1420  */
1421 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1422                                LPINT buffer )
1423 {
1424     return GetCharWidth32A( hdc, firstChar, lastChar, buffer );
1425 }
1426
1427
1428 /* FIXME: all following APIs ******************************************/
1429  
1430
1431 /***********************************************************************
1432  *           SetMapperFlags    (GDI.349)
1433  */
1434 DWORD WINAPI SetMapperFlags16( HDC16 hDC, DWORD dwFlag )
1435 {
1436     return SetMapperFlags( hDC, dwFlag );
1437 }
1438
1439
1440 /***********************************************************************
1441  *           SetMapperFlags    (GDI32.@)
1442  */
1443 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1444 {
1445     DC *dc = DC_GetDCPtr( hDC );
1446     DWORD ret = 0; 
1447     if(!dc) return 0;
1448     if(dc->funcs->pSetMapperFlags)
1449         ret = dc->funcs->pSetMapperFlags( dc, dwFlag );
1450     else
1451         FIXME("(0x%04x, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1452     GDI_ReleaseObj( hDC );
1453     return ret;
1454 }
1455
1456 /***********************************************************************
1457  *          GetAspectRatioFilterEx  (GDI.486)
1458  */
1459 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1460 {
1461   FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1462   return FALSE;
1463 }
1464
1465 /***********************************************************************
1466  *          GetAspectRatioFilterEx  (GDI32.@)
1467  */
1468 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1469 {
1470   FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1471   return FALSE;
1472 }
1473
1474 /***********************************************************************
1475  *           GetCharABCWidths   (GDI.307)
1476  */
1477 BOOL16 WINAPI GetCharABCWidths16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1478                                   LPABC16 abc )
1479 {
1480     LPABC       abc32 = HeapAlloc(GetProcessHeap(),0,sizeof(ABC)*(lastChar-firstChar+1));
1481     int         i;
1482
1483     if (!GetCharABCWidthsA( hdc, firstChar, lastChar, abc32 )) {
1484         HeapFree(GetProcessHeap(),0,abc32);
1485         return FALSE;
1486     }
1487
1488     for (i=firstChar;i<=lastChar;i++) {
1489         abc[i-firstChar].abcA = abc32[i-firstChar].abcA;
1490         abc[i-firstChar].abcB = abc32[i-firstChar].abcB;
1491         abc[i-firstChar].abcC = abc32[i-firstChar].abcC;
1492     }
1493     HeapFree(GetProcessHeap(),0,abc32);
1494     return TRUE;
1495 }
1496
1497
1498 /***********************************************************************
1499  *           GetCharABCWidthsA   (GDI32.@)
1500  */
1501 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1502                                   LPABC abc )
1503 {
1504     return GetCharABCWidthsW( hdc, firstChar, lastChar, abc );
1505 }
1506
1507
1508 /******************************************************************************
1509  * GetCharABCWidthsW [GDI32.@]  Retrieves widths of characters in range
1510  *
1511  * PARAMS
1512  *    hdc       [I] Handle of device context
1513  *    firstChar [I] First character in range to query
1514  *    lastChar  [I] Last character in range to query
1515  *    abc       [O] Address of character-width structure
1516  *
1517  * NOTES
1518  *    Only works with TrueType fonts
1519  *
1520  * RETURNS
1521  *    Success: TRUE
1522  *    Failure: FALSE
1523  */
1524 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1525                                    LPABC abc )
1526 {
1527     int         i;
1528     LPINT       widths = HeapAlloc(GetProcessHeap(),0,(lastChar-firstChar+1)*sizeof(INT));
1529
1530     FIXME("(%04x,%04x,%04x,%p), returns slightly bogus values.\n", hdc, firstChar, lastChar, abc);
1531
1532     GetCharWidth32A(hdc,firstChar,lastChar,widths);
1533
1534     for (i=firstChar;i<=lastChar;i++) {
1535         abc[i-firstChar].abcA = 0;      /* left distance */
1536         abc[i-firstChar].abcB = widths[i-firstChar];/* width */
1537         abc[i-firstChar].abcC = 0;      /* right distance */
1538     }
1539     HeapFree(GetProcessHeap(),0,widths);
1540     return TRUE;
1541 }
1542
1543
1544 /***********************************************************************
1545  *           GetGlyphOutline    (GDI.309)
1546  */
1547 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1548                                 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1549                                 LPVOID lpBuffer, const MAT2 *lpmat2 )
1550 {
1551     FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1552           hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1553     return (DWORD)-1; /* failure */
1554 }
1555
1556
1557 /***********************************************************************
1558  *           GetGlyphOutlineA    (GDI32.@)
1559  */
1560 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1561                                  LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1562                                  LPVOID lpBuffer, const MAT2 *lpmat2 )
1563 {
1564     FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1565           hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1566     return (DWORD)-1; /* failure */
1567 }
1568
1569 /***********************************************************************
1570  *           GetGlyphOutlineW    (GDI32.@)
1571  */
1572 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1573                                  LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1574                                  LPVOID lpBuffer, const MAT2 *lpmat2 )
1575 {
1576     FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1577           hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1578     return (DWORD)-1; /* failure */
1579 }
1580
1581 /***********************************************************************
1582  *           CreateScalableFontResource   (GDI.310)
1583  */
1584 BOOL16 WINAPI CreateScalableFontResource16( UINT16 fHidden,
1585                                             LPCSTR lpszResourceFile,
1586                                             LPCSTR fontFile, LPCSTR path )
1587 {
1588     return CreateScalableFontResourceA( fHidden, lpszResourceFile,
1589                                           fontFile, path );
1590 }
1591
1592 /***********************************************************************
1593  *           CreateScalableFontResourceA   (GDI32.@)
1594  */
1595 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1596                                              LPCSTR lpszResourceFile,
1597                                              LPCSTR lpszFontFile,
1598                                              LPCSTR lpszCurrentPath )
1599 {
1600     /* fHidden=1 - only visible for the calling app, read-only, not
1601      * enumbered with EnumFonts/EnumFontFamilies
1602      * lpszCurrentPath can be NULL
1603      */
1604     FIXME("(%ld,%s,%s,%s): stub\n",
1605           fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1606     return FALSE; /* create failed */
1607 }
1608
1609 /***********************************************************************
1610  *           CreateScalableFontResourceW   (GDI32.@)
1611  */
1612 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1613                                              LPCWSTR lpszResourceFile,
1614                                              LPCWSTR lpszFontFile,
1615                                              LPCWSTR lpszCurrentPath )
1616 {
1617     FIXME("(%ld,%p,%p,%p): stub\n",
1618           fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1619     return FALSE; /* create failed */
1620 }
1621
1622
1623 /*************************************************************************
1624  *             GetRasterizerCaps   (GDI.313)
1625  */
1626 BOOL16 WINAPI GetRasterizerCaps16( LPRASTERIZER_STATUS lprs, UINT16 cbNumBytes)
1627 {
1628     return GetRasterizerCaps( lprs, cbNumBytes );
1629 }
1630
1631
1632 /*************************************************************************
1633  *             GetRasterizerCaps   (GDI32.@)
1634  */
1635 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
1636 {
1637   lprs->nSize = sizeof(RASTERIZER_STATUS);
1638   lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
1639   lprs->nLanguageID = 0;
1640   return TRUE;
1641 }
1642
1643
1644 /*************************************************************************
1645  *             GetKerningPairs   (GDI.332)
1646  */
1647 INT16 WINAPI GetKerningPairs16( HDC16 hDC, INT16 cPairs,
1648                                 LPKERNINGPAIR16 lpKerningPairs )
1649 {
1650     /* At this time kerning is ignored (set to 0) */
1651     int i;
1652     FIXME("(%x,%d,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1653     for (i = 0; i < cPairs; i++) 
1654         lpKerningPairs[i].iKernAmount = 0;
1655     return 0;
1656 }
1657
1658
1659
1660 /*************************************************************************
1661  *             GetKerningPairsA   (GDI32.@)
1662  */
1663 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs,
1664                                  LPKERNINGPAIR lpKerningPairs )
1665 {
1666     int i;
1667     FIXME("(%x,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1668     for (i = 0; i < cPairs; i++) 
1669         lpKerningPairs[i].iKernAmount = 0;
1670     return 0;
1671 }
1672
1673
1674 /*************************************************************************
1675  *             GetKerningPairsW   (GDI32.@)
1676  */
1677 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
1678                                  LPKERNINGPAIR lpKerningPairs )
1679 {
1680     return GetKerningPairsA( hDC, cPairs, lpKerningPairs );
1681 }
1682
1683 /*************************************************************************
1684  * TranslateCharsetInfo [GDI32.@]
1685  *
1686  * Fills a CHARSETINFO structure for a character set, code page, or
1687  * font. This allows making the correspondance between different labelings
1688  * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges) 
1689  * of the same encoding.
1690  *
1691  * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
1692  * only one codepage should be set in *lpSrc.
1693  *
1694  * RETURNS
1695  *   TRUE on success, FALSE on failure.
1696  *
1697  */
1698 BOOL WINAPI TranslateCharsetInfo(
1699   LPDWORD lpSrc, /* [in]
1700        if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
1701        if flags == TCI_SRCCHARSET: a character set value
1702        if flags == TCI_SRCCODEPAGE: a code page value
1703                  */
1704   LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
1705   DWORD flags /* [in] determines interpretation of lpSrc */
1706 ) {
1707     int index = 0;
1708     switch (flags) {
1709     case TCI_SRCFONTSIG:
1710         while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
1711       break;
1712     case TCI_SRCCODEPAGE:
1713       while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
1714       break;
1715     case TCI_SRCCHARSET:
1716       while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
1717       break;
1718     default:
1719       return FALSE;
1720     }
1721     if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
1722     memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
1723     return TRUE;
1724 }
1725
1726 /*************************************************************************
1727  *             GetFontLanguageInfo   (GDI32.@)
1728  */
1729 DWORD WINAPI GetFontLanguageInfo(HDC hdc) {
1730         /* return value 0 is correct for most cases anyway */
1731         FIXME("(%x):stub!\n", hdc);
1732         return 0;
1733 }
1734
1735 /*************************************************************************
1736  *             GetFontLanguageInfo   (GDI.616)
1737  */
1738 DWORD WINAPI GetFontLanguageInfo16(HDC16 hdc) {
1739         /* return value 0 is correct for most cases anyway */
1740         FIXME("(%x):stub!\n",hdc);
1741         return 0;
1742 }
1743
1744 /*************************************************************************
1745  * GetFontData [GDI32.@] Retrieve data for TrueType font
1746  *
1747  * RETURNS
1748  *
1749  * success: Number of bytes returned 
1750  * failure: GDI_ERROR
1751  *
1752  * NOTES
1753  *
1754  * Calls SetLastError()  
1755  *
1756  * BUGS
1757  *
1758  * Unimplemented
1759  */
1760 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset, 
1761     LPVOID buffer, DWORD length)
1762 {
1763     FIXME("(%x,%ld,%ld,%p,%ld): stub\n", hdc, table, offset, buffer, length);
1764     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1765     return GDI_ERROR;
1766 }
1767
1768 /*************************************************************************
1769  * GetFontData [GDI.311]
1770  *
1771  */
1772 DWORD WINAPI GetFontData16(HDC16 hdc, DWORD dwTable, DWORD dwOffset,
1773                             LPVOID lpvBuffer, DWORD cbData)
1774 {
1775     return GetFontData(hdc, dwTable, dwOffset, lpvBuffer, cbData);
1776 }
1777
1778 /*************************************************************************
1779  * GetCharacterPlacementA [GDI32.@]
1780  *
1781  * NOTES:
1782  *  the web browser control of ie4 calls this with dwFlags=0
1783  */
1784 DWORD WINAPI
1785 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
1786                          INT nMaxExtent, GCP_RESULTSA *lpResults,
1787                          DWORD dwFlags)
1788 {
1789     DWORD ret=0;
1790     SIZE size;
1791
1792     TRACE("%s 0x%08x 0x%08x 0x%08lx:stub!\n",
1793           debugstr_a(lpString), uCount, nMaxExtent, dwFlags);
1794
1795     TRACE("lpOrder=%p lpDx=%p lpCaretPos=%p lpClass=%p "
1796           "lpOutString=%p lpGlyphs=%p\n",
1797           lpResults->lpOrder, lpResults->lpDx, lpResults->lpCaretPos,
1798           lpResults->lpClass, lpResults->lpOutString, lpResults->lpGlyphs);
1799
1800     if(dwFlags)                 FIXME("flags 0x%08lx ignored\n", dwFlags);
1801     if(lpResults->lpOrder)      FIXME("reordering not implemented\n");
1802     if(lpResults->lpCaretPos)   FIXME("caret positions not implemented\n");
1803     if(lpResults->lpClass)      FIXME("classes not implemented\n");
1804     if(lpResults->lpGlyphs)     FIXME("glyphs not implemented\n");
1805
1806     /* copy will do if the GCP_REORDER flag is not set */
1807     if(lpResults->lpOutString)
1808     {
1809       lstrcpynA(lpResults->lpOutString, lpString, uCount);
1810     }
1811
1812     if (lpResults->lpDx)
1813     {
1814       int i, c;
1815       for (i=0; i<uCount;i++)
1816       { 
1817         if (GetCharWidth32A(hdc, lpString[i], lpString[i], &c))
1818           lpResults->lpDx[i]= c;
1819       }
1820     }
1821
1822     if (GetTextExtentPoint32A(hdc, lpString, uCount, &size))
1823       ret = MAKELONG(size.cx, size.cy);
1824
1825     return ret;
1826 }
1827
1828 /*************************************************************************
1829  * GetCharacterPlacementW [GDI32.@]
1830  */
1831 DWORD WINAPI
1832 GetCharacterPlacementW(HDC hdc, LPCWSTR lpString, INT uCount,
1833                          INT nMaxExtent, GCP_RESULTSW *lpResults,
1834                          DWORD dwFlags)
1835 {
1836     /* return value 0 is correct for most cases anyway */
1837     FIXME(":stub!\n");
1838     return 0;
1839 }
1840
1841 /*************************************************************************
1842  *      GetCharABCWidthsFloatA [GDI32.@]
1843  */
1844 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
1845                                         LPABCFLOAT lpABCF)
1846 {
1847        FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
1848        return 0;
1849 }
1850
1851 /*************************************************************************
1852  *      GetCharABCWidthsFloatW [GDI32.@]
1853  */
1854 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
1855                                         UINT iLastChar, LPABCFLOAT lpABCF)
1856 {
1857        FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
1858        return 0;
1859 }
1860
1861 /*************************************************************************
1862  *      GetCharWidthFloatA [GDI32.@]
1863  */
1864 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
1865                                     UINT iLastChar, PFLOAT pxBuffer)
1866 {
1867        FIXME_(gdi)("GetCharWidthFloatA, stub\n");
1868        return 0;
1869 }
1870
1871 /*************************************************************************
1872  *      GetCharWidthFloatW [GDI32.@]
1873  */
1874 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
1875                                     UINT iLastChar, PFLOAT pxBuffer)
1876 {
1877        FIXME_(gdi)("GetCharWidthFloatW, stub\n");
1878        return 0;
1879 }
1880  
1881
1882 /***********************************************************************
1883  *                                                                     *
1884  *           Font Resource API                                         *
1885  *                                                                     *
1886  ***********************************************************************/
1887 /***********************************************************************
1888  *           AddFontResource    (GDI.119)
1889  *
1890  *  Can be either .FON, or .FNT, or .TTF, or .FOT font file.
1891  *
1892  *  FIXME: Load header and find the best-matching font in the fontList;
1893  *         fixup dfPoints if all metrics are identical, otherwise create
1894  *         new fontAlias. When soft font support is ready this will
1895  *         simply create a new fontResource ('filename' will go into
1896  *         the pfr->resource field) with FR_SOFTFONT/FR_SOFTRESOURCE 
1897  *         flag set. 
1898  */
1899 INT16 WINAPI AddFontResource16( LPCSTR filename )
1900 {
1901     return AddFontResourceA( filename );
1902 }
1903
1904
1905 /***********************************************************************
1906  *           AddFontResourceA    (GDI32.@)
1907  */
1908 INT WINAPI AddFontResourceA( LPCSTR str )
1909 {
1910     FIXME("(%s): stub! Read the Wine User Guide on how to install "
1911             "this font manually.\n", debugres_a(str));
1912     return 1;
1913 }
1914
1915
1916 /***********************************************************************
1917  *           AddFontResourceW    (GDI32.@)
1918  */
1919 INT WINAPI AddFontResourceW( LPCWSTR str )
1920 {
1921     FIXME("(%s): stub! Read the Wine User Guide on how to install "
1922             "this font manually.\n", debugres_w(str));
1923     return 1;
1924 }
1925
1926 /***********************************************************************
1927  *           RemoveFontResource    (GDI.136)
1928  */
1929 BOOL16 WINAPI RemoveFontResource16( LPCSTR str )
1930 {
1931     FIXME("(%s): stub\n", debugres_a(str));
1932     return TRUE;
1933 }
1934
1935
1936 /***********************************************************************
1937  *           RemoveFontResourceA    (GDI32.@)
1938  */
1939 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
1940 {
1941 /*  This is how it should look like */
1942 /*
1943     fontResource** ppfr;
1944     BOOL32 retVal = FALSE;
1945
1946     EnterCriticalSection( &crtsc_fonts_X11 );
1947     for( ppfr = &fontList; *ppfr; ppfr = &(*ppfr)->next )
1948          if( !strcasecmp( (*ppfr)->lfFaceName, str ) )
1949          {
1950              if(((*ppfr)->fr_flags & (FR_SOFTFONT | FR_SOFTRESOURCE)) &&
1951                  (*ppfr)->hOwnerProcess == GetCurrentProcess() )
1952              {
1953                  if( (*ppfr)->fo_count )
1954                      (*ppfr)->fr_flags |= FR_REMOVED;
1955                  else
1956                      XFONT_RemoveFontResource( ppfr );
1957              }
1958              retVal = TRUE;
1959          }
1960     LeaveCriticalSection( &crtsc_fonts_X11 );
1961     return retVal;
1962  */
1963     FIXME("(%s): stub\n", debugres_a(str));
1964     return TRUE;
1965 }
1966
1967
1968 /***********************************************************************
1969  *           RemoveFontResourceW    (GDI32.@)
1970  */
1971 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
1972 {
1973     FIXME("(%s): stub\n", debugres_w(str) );
1974     return TRUE;
1975 }