LPARAM in find dialog wm_initdialog is the find/replace structure, not
[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->ntmetm.ntmFlags = ptmW->ntmetm.ntmFlags;
384     ptm16->ntmetm.ntmSizeEM = ptmW->ntmetm.ntmSizeEM;
385     ptm16->ntmetm.ntmCellHeight = ptmW->ntmetm.ntmCellHeight;
386     ptm16->ntmetm.ntmAvgWidth = ptmW->ntmetm.ntmAvgWidth;
387     memcpy(&ptm16->ntmeFontSignature, &ptmW->ntmeFontSignature,
388            sizeof(FONTSIGNATURE));
389 }
390
391 void FONT_NewTextMetricExWToA(const NEWTEXTMETRICEXW *ptmW, LPNEWTEXTMETRICEXA ptmA )
392 {
393     FONT_TextMetricWToA((LPTEXTMETRICW)ptmW, (LPTEXTMETRICA)ptmA);
394     ptmA->ntmetm.ntmFlags = ptmW->ntmetm.ntmFlags;
395     ptmA->ntmetm.ntmSizeEM = ptmW->ntmetm.ntmSizeEM;
396     ptmA->ntmetm.ntmCellHeight = ptmW->ntmetm.ntmCellHeight;
397     ptmA->ntmetm.ntmAvgWidth = ptmW->ntmetm.ntmAvgWidth;
398     memcpy(&ptmA->ntmeFontSignature, &ptmW->ntmeFontSignature,
399            sizeof(FONTSIGNATURE));
400 }
401
402 void FONT_NewTextMetricEx16ToW(const NEWTEXTMETRICEX16 *ptm16, LPNEWTEXTMETRICEXW ptmW )
403 {
404     FONT_TextMetric16ToW((LPTEXTMETRIC16)ptm16, (LPTEXTMETRICW)ptmW);
405     ptmW->ntmetm.ntmFlags = ptm16->ntmetm.ntmFlags;
406     ptmW->ntmetm.ntmSizeEM = ptm16->ntmetm.ntmSizeEM;
407     ptmW->ntmetm.ntmCellHeight = ptm16->ntmetm.ntmCellHeight;
408     ptmW->ntmetm.ntmAvgWidth = ptm16->ntmetm.ntmAvgWidth;
409     memcpy(&ptmW->ntmeFontSignature, &ptm16->ntmeFontSignature,
410            sizeof(FONTSIGNATURE));
411 }
412
413
414 /***********************************************************************
415  *           CreateFontIndirect16   (GDI.57)
416  */
417 HFONT16 WINAPI CreateFontIndirect16( const LOGFONT16 *plf16 )
418 {
419     LOGFONTW lfW;
420
421     if(plf16) {
422         FONT_LogFont16ToW( plf16, &lfW );
423         return CreateFontIndirectW( &lfW );
424     } else {
425         return CreateFontIndirectW( NULL );
426     }
427 }
428
429
430 /***********************************************************************
431  *           CreateFontIndirectA   (GDI32.@)
432  */
433 HFONT WINAPI CreateFontIndirectA( const LOGFONTA *plfA )
434 {
435     LOGFONTW lfW;
436
437     if (plfA) {
438         FONT_LogFontAToW( plfA, &lfW );
439         return CreateFontIndirectW( &lfW );
440      } else
441         return CreateFontIndirectW( NULL );
442
443 }
444
445 /***********************************************************************
446  *           CreateFontIndirectW   (GDI32.@)
447  */
448 HFONT WINAPI CreateFontIndirectW( const LOGFONTW *plf )
449 {
450     HFONT hFont = 0;
451
452     if (plf)
453     {
454         FONTOBJ* fontPtr;
455         if ((fontPtr = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC, &hFont )))
456         {
457             memcpy( &fontPtr->logfont, plf, sizeof(LOGFONTW) );
458
459             TRACE("(%ld %ld %ld %ld) '%s' %s %s => %04x\n",
460                   plf->lfHeight, plf->lfWidth, 
461                   plf->lfEscapement, plf->lfOrientation,
462                   debugstr_w(plf->lfFaceName),
463                   plf->lfWeight > 400 ? "Bold" : "",
464                   plf->lfItalic ? "Italic" : "", hFont);
465
466             if (plf->lfEscapement != plf->lfOrientation) {
467               /* this should really depend on whether GM_ADVANCED is set */
468               fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
469               WARN("orientation angle %f set to "
470                    "escapement angle %f for new font %04x\n", 
471                    plf->lfOrientation/10., plf->lfEscapement/10., hFont);
472             }
473             GDI_ReleaseObj( hFont );
474         }
475     }
476     else WARN("(NULL) => NULL\n");
477
478     return hFont;
479 }
480
481 /***********************************************************************
482  *           CreateFont16    (GDI.56)
483  */
484 HFONT16 WINAPI CreateFont16(INT16 height, INT16 width, INT16 esc, INT16 orient,
485                             INT16 weight, BYTE italic, BYTE underline,
486                             BYTE strikeout, BYTE charset, BYTE outpres,
487                             BYTE clippres, BYTE quality, BYTE pitch,
488                             LPCSTR name )
489 {
490     LOGFONT16 logfont;
491
492     logfont.lfHeight = height;
493     logfont.lfWidth = width;
494     logfont.lfEscapement = esc;
495     logfont.lfOrientation = orient;
496     logfont.lfWeight = weight;
497     logfont.lfItalic = italic;
498     logfont.lfUnderline = underline;
499     logfont.lfStrikeOut = strikeout;
500     logfont.lfCharSet = charset;
501     logfont.lfOutPrecision = outpres;
502     logfont.lfClipPrecision = clippres;
503     logfont.lfQuality = quality;
504     logfont.lfPitchAndFamily = pitch;
505    
506     if (name) 
507         lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
508     else 
509         logfont.lfFaceName[0] = '\0';
510
511     return CreateFontIndirect16( &logfont );
512 }
513
514 /*************************************************************************
515  *           CreateFontA    (GDI32.@)
516  */
517 HFONT WINAPI CreateFontA( INT height, INT width, INT esc,
518                               INT orient, INT weight, DWORD italic,
519                               DWORD underline, DWORD strikeout, DWORD charset,
520                               DWORD outpres, DWORD clippres, DWORD quality,
521                               DWORD pitch, LPCSTR name )
522 {
523     LOGFONTA logfont;
524
525     logfont.lfHeight = height;
526     logfont.lfWidth = width;
527     logfont.lfEscapement = esc;
528     logfont.lfOrientation = orient;
529     logfont.lfWeight = weight;
530     logfont.lfItalic = italic;
531     logfont.lfUnderline = underline;
532     logfont.lfStrikeOut = strikeout;
533     logfont.lfCharSet = charset;
534     logfont.lfOutPrecision = outpres;
535     logfont.lfClipPrecision = clippres;
536     logfont.lfQuality = quality;
537     logfont.lfPitchAndFamily = pitch;
538    
539     if (name) 
540         lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
541     else 
542         logfont.lfFaceName[0] = '\0';
543
544     return CreateFontIndirectA( &logfont );
545 }
546
547 /*************************************************************************
548  *           CreateFontW    (GDI32.@)
549  */
550 HFONT WINAPI CreateFontW( INT height, INT width, INT esc,
551                               INT orient, INT weight, DWORD italic,
552                               DWORD underline, DWORD strikeout, DWORD charset,
553                               DWORD outpres, DWORD clippres, DWORD quality,
554                               DWORD pitch, LPCWSTR name )
555 {
556     LOGFONTW logfont;
557
558     logfont.lfHeight = height;
559     logfont.lfWidth = width;
560     logfont.lfEscapement = esc;
561     logfont.lfOrientation = orient;
562     logfont.lfWeight = weight;
563     logfont.lfItalic = italic;
564     logfont.lfUnderline = underline;
565     logfont.lfStrikeOut = strikeout;
566     logfont.lfCharSet = charset;
567     logfont.lfOutPrecision = outpres;
568     logfont.lfClipPrecision = clippres;
569     logfont.lfQuality = quality;
570     logfont.lfPitchAndFamily = pitch;
571    
572     if (name) 
573         lstrcpynW(logfont.lfFaceName, name, 
574                   sizeof(logfont.lfFaceName) / sizeof(WCHAR));
575     else 
576         logfont.lfFaceName[0] = '\0';
577
578     return CreateFontIndirectW( &logfont );
579 }
580
581
582 /***********************************************************************
583  *           FONT_GetObject16
584  */
585 INT16 FONT_GetObject16( FONTOBJ * font, INT16 count, LPSTR buffer )
586 {
587     LOGFONT16 lf16;
588
589     FONT_LogFontWTo16( &font->logfont, &lf16 );
590
591     if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
592     memcpy( buffer, &lf16, count );
593     return count;
594 }
595
596 /***********************************************************************
597  *           FONT_GetObjectA
598  */
599 INT FONT_GetObjectA( FONTOBJ *font, INT count, LPSTR buffer )
600 {
601     LOGFONTA lfA;
602
603     FONT_LogFontWToA( &font->logfont, &lfA );
604
605     if (count > sizeof(lfA)) count = sizeof(lfA);
606     memcpy( buffer, &lfA, count );
607     return count;
608 }
609 /***********************************************************************
610  *           FONT_GetObjectW
611  */
612 INT FONT_GetObjectW( FONTOBJ *font, INT count, LPSTR buffer )
613 {
614     if (count > sizeof(LOGFONTW)) count = sizeof(LOGFONTW);
615     memcpy( buffer, &font->logfont, count );
616     return count;
617 }
618
619
620 /***********************************************************************
621  *              FONT_EnumInstance16
622  *
623  * Called by the device driver layer to pass font info
624  * down to the application.
625  */
626 static INT FONT_EnumInstance16( LPENUMLOGFONTEXW plf, LPNEWTEXTMETRICEXW ptm,
627                                 DWORD fType, LPARAM lp )
628 {
629 #define pfe ((fontEnum16*)lp)
630     if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET || 
631         pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
632     {
633         FONT_EnumLogFontExWTo16(plf, pfe->lpLogFont);
634         FONT_NewTextMetricExWTo16(ptm, pfe->lpTextMetric);
635         return pfe->lpEnumFunc( pfe->segLogFont, pfe->segTextMetric,
636                                 (UINT16)fType, (LPARAM)(pfe->lpData) );
637     }
638 #undef pfe
639     return 1;
640 }
641
642 /***********************************************************************
643  *              FONT_EnumInstance
644  */
645 static INT FONT_EnumInstance( LPENUMLOGFONTEXW plf, LPNEWTEXTMETRICEXW ptm,
646                               DWORD fType, LPARAM lp )
647 {
648     /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
649
650 #define pfe ((fontEnum32*)lp)
651     if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET || 
652         pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
653     {
654         /* convert font metrics */
655
656         if( pfe->dwFlags & ENUM_UNICODE )
657         {
658             return pfe->lpEnumFunc( plf, ptm, fType, pfe->lpData );
659         }
660         else
661         {
662             ENUMLOGFONTEXA logfont;
663             NEWTEXTMETRICEXA tmA;
664
665             FONT_EnumLogFontExWToA( plf, &logfont);
666             FONT_NewTextMetricExWToA( ptm, &tmA );
667
668             return pfe->lpEnumFunc( (LPENUMLOGFONTEXW)&logfont, 
669                                     (LPNEWTEXTMETRICEXW)&tmA, fType,
670                                     pfe->lpData );
671         }
672     }
673 #undef pfe
674     return 1;
675 }
676
677 /***********************************************************************
678  *              EnumFontFamiliesEx16    (GDI.613)
679  */
680 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
681                                    FONTENUMPROCEX16 efproc, LPARAM lParam,
682                                    DWORD dwFlags)
683 {
684     BOOL (*enum_func)(HDC,LPLOGFONTW,DEVICEFONTENUMPROC,LPARAM);
685     INT16       retVal = 0;
686     DC*         dc = DC_GetDCPtr( hDC );
687
688     if (!dc) return 0;
689     enum_func = dc->funcs->pEnumDeviceFonts;
690     GDI_ReleaseObj( hDC );
691
692     if (enum_func)
693     {
694         LPNEWTEXTMETRICEX16 lptm16 = SEGPTR_ALLOC( sizeof(NEWTEXTMETRICEX16) );
695         if( lptm16 )
696         {
697             LPENUMLOGFONTEX16 lplf16 = SEGPTR_ALLOC( sizeof(ENUMLOGFONTEX16) );
698             if( lplf16 )
699             {
700                 fontEnum16      fe16;
701                 LOGFONTW        lfW;
702                 FONT_LogFont16ToW(plf, &lfW);
703
704                 fe16.lpLogFontParam = plf;
705                 fe16.lpEnumFunc = efproc;
706                 fe16.lpData = lParam;
707                 
708                 fe16.lpTextMetric = lptm16;
709                 fe16.lpLogFont = lplf16;
710                 fe16.segTextMetric = SEGPTR_GET(lptm16);
711                 fe16.segLogFont = SEGPTR_GET(lplf16);
712
713                 retVal = enum_func( hDC, &lfW, FONT_EnumInstance16,
714                                     (LPARAM)&fe16 );
715                 SEGPTR_FREE(lplf16);
716             }
717             SEGPTR_FREE(lptm16);
718         }
719     }
720     return retVal;
721 }
722
723 /***********************************************************************
724  *              FONT_EnumFontFamiliesEx
725  */
726 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf,
727                                     FONTENUMPROCEXW efproc, 
728                                     LPARAM lParam, DWORD dwUnicode)
729 {
730     BOOL (*enum_func)(HDC,LPLOGFONTW,DEVICEFONTENUMPROC,LPARAM);
731     INT ret = 0;
732     DC *dc = DC_GetDCPtr( hDC );
733
734     if (!dc) return 0;
735     enum_func = dc->funcs->pEnumDeviceFonts;
736     GDI_ReleaseObj( hDC );
737
738     if (enum_func)
739     {
740         fontEnum32 fe32;
741
742         fe32.lpLogFontParam = plf;
743         fe32.lpEnumFunc = efproc;
744         fe32.lpData = lParam;
745         
746         fe32.dwFlags = dwUnicode;
747
748         ret = enum_func( hDC, plf, FONT_EnumInstance, (LPARAM)&fe32 );
749     }
750     return ret;
751 }
752
753 /***********************************************************************
754  *              EnumFontFamiliesExW     (GDI32.@)
755  */
756 INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
757                                     FONTENUMPROCEXW efproc, 
758                                     LPARAM lParam, DWORD dwFlags )
759 {
760     return  FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam, ENUM_UNICODE );
761 }
762
763 /***********************************************************************
764  *              EnumFontFamiliesExA     (GDI32.@)
765  */
766 INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf,
767                                     FONTENUMPROCEXA efproc, 
768                                     LPARAM lParam, DWORD dwFlags)
769 {
770     LOGFONTW lfW;
771     FONT_LogFontAToW( plf, &lfW );
772
773     return  FONT_EnumFontFamiliesEx( hDC, &lfW,
774                                      (FONTENUMPROCEXW)efproc, lParam, 0);
775 }
776
777 /***********************************************************************
778  *              EnumFontFamilies16      (GDI.330)
779  */
780 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
781                                  FONTENUMPROC16 efproc, LPARAM lpData )
782 {
783     LOGFONT16   lf;
784
785     lf.lfCharSet = DEFAULT_CHARSET;
786     if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
787     else lf.lfFaceName[0] = '\0';
788
789     return EnumFontFamiliesEx16( hDC, &lf, (FONTENUMPROCEX16)efproc, lpData, 0 );
790 }
791
792 /***********************************************************************
793  *              EnumFontFamiliesA       (GDI32.@)
794  */
795 INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
796                                   FONTENUMPROCA efproc, LPARAM lpData )
797 {
798     LOGFONTA    lf;
799
800     lf.lfCharSet = DEFAULT_CHARSET;
801     if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
802     else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
803
804     return EnumFontFamiliesExA( hDC, &lf, (FONTENUMPROCEXA)efproc, lpData, 0 );
805 }
806
807 /***********************************************************************
808  *              EnumFontFamiliesW       (GDI32.@)
809  */
810 INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
811                                   FONTENUMPROCW efproc, LPARAM lpData )
812 {
813     LOGFONTW  lf;
814
815     lf.lfCharSet = DEFAULT_CHARSET;
816     if( lpFamily ) lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
817     else lf.lfFaceName[0] = 0;
818
819     return EnumFontFamiliesExW( hDC, &lf, (FONTENUMPROCEXW)efproc, lpData, 0 );
820 }
821
822 /***********************************************************************
823  *              EnumFonts16             (GDI.70)
824  */
825 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
826                           LPARAM lpData )
827 {
828     return EnumFontFamilies16( hDC, lpName, (FONTENUMPROCEX16)efproc, lpData );
829 }
830
831 /***********************************************************************
832  *              EnumFontsA              (GDI32.@)
833  */
834 INT WINAPI EnumFontsA( HDC hDC, LPCSTR lpName, FONTENUMPROCA efproc,
835                            LPARAM lpData )
836 {
837     return EnumFontFamiliesA( hDC, lpName, efproc, lpData );
838 }
839
840 /***********************************************************************
841  *              EnumFontsW              (GDI32.@)
842  */
843 INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
844                            LPARAM lpData )
845 {
846     return EnumFontFamiliesW( hDC, lpName, efproc, lpData );
847 }
848
849
850 /***********************************************************************
851  *           GetTextCharacterExtra16    (GDI.89)
852  */
853 INT16 WINAPI GetTextCharacterExtra16( HDC16 hdc )
854 {
855     return (INT16)GetTextCharacterExtra( hdc );
856 }
857
858
859 /***********************************************************************
860  *           GetTextCharacterExtra    (GDI32.@)
861  */
862 INT WINAPI GetTextCharacterExtra( HDC hdc )
863 {
864     INT ret;
865     DC *dc = DC_GetDCPtr( hdc );
866     if (!dc) return 0;
867     ret = abs( (dc->charExtra * dc->wndExtX + dc->vportExtX / 2)
868                  / dc->vportExtX );
869     GDI_ReleaseObj( hdc );
870     return ret;
871 }
872
873
874 /***********************************************************************
875  *           SetTextCharacterExtra16    (GDI.8)
876  */
877 INT16 WINAPI SetTextCharacterExtra16( HDC16 hdc, INT16 extra )
878 {
879     return (INT16)SetTextCharacterExtra( hdc, extra );
880 }
881
882
883 /***********************************************************************
884  *           SetTextCharacterExtra    (GDI32.@)
885  */
886 INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
887 {
888     INT prev;
889     DC * dc = DC_GetDCPtr( hdc );
890     if (!dc) return 0;
891     if (dc->funcs->pSetTextCharacterExtra)
892         prev = dc->funcs->pSetTextCharacterExtra( dc, extra );
893     else
894     {
895         extra = (extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX;
896         prev = (dc->charExtra * dc->wndExtX + dc->vportExtX / 2) / dc->vportExtX;
897         dc->charExtra = abs(extra);
898     }
899     GDI_ReleaseObj( hdc );
900     return prev;
901 }
902
903
904 /***********************************************************************
905  *           SetTextJustification16    (GDI.10)
906  */
907 INT16 WINAPI SetTextJustification16( HDC16 hdc, INT16 extra, INT16 breaks )
908 {
909     return SetTextJustification( hdc, extra, breaks );
910 }
911
912
913 /***********************************************************************
914  *           SetTextJustification    (GDI32.@)
915  */
916 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
917 {
918     BOOL ret = TRUE;
919     DC * dc = DC_GetDCPtr( hdc );
920     if (!dc) return FALSE;
921     if (dc->funcs->pSetTextJustification)
922         ret = dc->funcs->pSetTextJustification( dc, extra, breaks );
923     else
924     {
925         extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
926         if (!extra) breaks = 0;
927         dc->breakTotalExtra = extra;
928         dc->breakCount = breaks;
929         if (breaks)
930         {
931             dc->breakExtra = extra / breaks;
932             dc->breakRem   = extra - (dc->breakCount * dc->breakExtra);
933         }
934         else
935         {
936             dc->breakExtra = 0;
937             dc->breakRem   = 0;
938         }
939     }
940     GDI_ReleaseObj( hdc );
941     return ret;
942 }
943
944
945 /***********************************************************************
946  *           GetTextFace16    (GDI.92)
947  */
948 INT16 WINAPI GetTextFace16( HDC16 hdc, INT16 count, LPSTR name )
949 {
950         return GetTextFaceA(hdc,count,name);
951 }
952
953 /***********************************************************************
954  *           GetTextFaceA    (GDI32.@)
955  */
956 INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
957 {
958     INT res = GetTextFaceW(hdc, 0, NULL);
959     LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
960     GetTextFaceW( hdc, res, nameW );
961     
962     if (name)
963         res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, name, count,
964                                    NULL, NULL);
965     else
966         res = WideCharToMultiByte( CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL);
967     HeapFree( GetProcessHeap(), 0, nameW );
968     return res;
969 }
970
971 /***********************************************************************
972  *           GetTextFaceW    (GDI32.@)
973  */
974 INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
975 {
976     FONTOBJ *font;
977     INT     ret = 0;
978
979     DC * dc = DC_GetDCPtr( hdc );
980     if (!dc) return 0;
981
982     if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
983     {
984         if (name)
985         {
986             lstrcpynW( name, font->logfont.lfFaceName, count );
987             ret = strlenW(name);
988         }
989         else ret = strlenW(font->logfont.lfFaceName) + 1;
990         GDI_ReleaseObj( dc->hFont );
991     }
992     GDI_ReleaseObj( hdc );
993     return ret;
994 }
995
996
997 /***********************************************************************
998  *           GetTextExtent16    (GDI.91)
999  */
1000 DWORD WINAPI GetTextExtent16( HDC16 hdc, LPCSTR str, INT16 count )
1001 {
1002     SIZE16 size;
1003     if (!GetTextExtentPoint16( hdc, str, count, &size )) return 0;
1004     return MAKELONG( size.cx, size.cy );
1005 }
1006
1007
1008 /***********************************************************************
1009  *           GetTextExtentPoint16    (GDI.471)
1010  *
1011  * FIXME: Should this have a bug for compatibility?
1012  * Original Windows versions of GetTextExtentPoint{A,W} have documented
1013  * bugs (-> MSDN KB q147647.txt).
1014  */
1015 BOOL16 WINAPI GetTextExtentPoint16( HDC16 hdc, LPCSTR str, INT16 count,
1016                                     LPSIZE16 size )
1017 {
1018     SIZE size32;
1019     BOOL ret;
1020     TRACE("%04x, %p (%s), %d, %p\n", hdc, str, debugstr_an(str, count), count, size);
1021     ret = GetTextExtentPoint32A( hdc, str, count, &size32 );
1022     size->cx = size32.cx;
1023     size->cy = size32.cy;
1024     return (BOOL16)ret;
1025 }
1026
1027
1028 /***********************************************************************
1029  *           GetTextExtentPoint32A    (GDI32.@)
1030  */
1031 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
1032                                      LPSIZE size )
1033 {
1034     BOOL ret = FALSE;
1035     UINT codepage = CP_ACP; /* FIXME: get codepage of font charset */
1036     DC * dc = DC_GetDCPtr( hdc );
1037
1038     if (!dc) return FALSE;
1039
1040     if (dc->funcs->pGetTextExtentPoint)
1041     {
1042         /* str may not be 0 terminated so we can't use HEAP_strdupWtoA.
1043          * So we use MultiByteToWideChar.
1044          */
1045         UINT wlen = MultiByteToWideChar(codepage,0,str,count,NULL,0);
1046         LPWSTR p = HeapAlloc( GetProcessHeap(), 0, wlen * sizeof(WCHAR) );
1047         if (p)
1048         {
1049             wlen = MultiByteToWideChar(codepage,0,str,count,p,wlen);
1050             ret = dc->funcs->pGetTextExtentPoint( dc, p, wlen, size );
1051             HeapFree( GetProcessHeap(), 0, p );
1052         }
1053     }
1054     GDI_ReleaseObj( hdc );
1055     TRACE("(%08x %s %d %p): returning %ld x %ld\n",
1056           hdc, debugstr_an (str, count), count, size, size->cx, size->cy );
1057     return ret;
1058 }
1059
1060
1061 /***********************************************************************
1062  * GetTextExtentPoint32W [GDI32.@]  Computes width/height for a string
1063  *
1064  * Computes width and height of the specified string.
1065  *
1066  * RETURNS
1067  *    Success: TRUE
1068  *    Failure: FALSE
1069  */
1070 BOOL WINAPI GetTextExtentPoint32W(
1071     HDC hdc,     /* [in]  Handle of device context */
1072     LPCWSTR str,   /* [in]  Address of text string */
1073     INT count,   /* [in]  Number of characters in string */
1074     LPSIZE size) /* [out] Address of structure for string size */
1075 {
1076     BOOL ret = FALSE;
1077     DC * dc = DC_GetDCPtr( hdc );
1078     if (dc)
1079     {
1080         if(dc->funcs->pGetTextExtentPoint)
1081             ret = dc->funcs->pGetTextExtentPoint( dc, str, count, size );
1082         GDI_ReleaseObj( hdc );
1083     }
1084     TRACE("(%08x %s %d %p): returning %ld x %ld\n",
1085           hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
1086     return ret;
1087 }
1088
1089
1090 /***********************************************************************
1091  *           GetTextExtentPointA    (GDI32.@)
1092  */
1093 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
1094                                           LPSIZE size )
1095 {
1096     TRACE("not bug compatible.\n");
1097     return GetTextExtentPoint32A( hdc, str, count, size );
1098 }
1099
1100 /***********************************************************************
1101  *           GetTextExtentPointW   (GDI32.@)
1102  */
1103 BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
1104                                           LPSIZE size )
1105 {
1106     TRACE("not bug compatible.\n");
1107     return GetTextExtentPoint32W( hdc, str, count, size );
1108 }
1109
1110
1111 /***********************************************************************
1112  *           GetTextExtentExPointA    (GDI32.@)
1113  */
1114 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
1115                                    INT maxExt, LPINT lpnFit,
1116                                    LPINT alpDx, LPSIZE size )
1117 {
1118     BOOL ret;
1119
1120     DWORD len = MultiByteToWideChar( CP_ACP, 0, str, count, NULL, 0 );
1121     LPWSTR p = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
1122     MultiByteToWideChar( CP_ACP, 0, str, count, p, len );
1123     ret = GetTextExtentExPointW( hdc, p, len, maxExt, lpnFit, alpDx, size);
1124     HeapFree( GetProcessHeap(), 0, p );
1125     return ret;
1126 }
1127
1128
1129 /***********************************************************************
1130  *           GetTextExtentExPointW    (GDI32.@)
1131  */
1132
1133 BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
1134                                    INT maxExt, LPINT lpnFit,
1135                                    LPINT alpDx, LPSIZE size )
1136 {
1137     int index, nFit, extent;
1138     SIZE tSize;
1139     BOOL ret = FALSE;
1140     DC * dc = DC_GetDCPtr( hdc );
1141     if (!dc) return FALSE;
1142
1143     if (!dc->funcs->pGetTextExtentPoint) goto done;
1144
1145     size->cx = size->cy = nFit = extent = 0;
1146     for(index = 0; index < count; index++)
1147     {
1148         if(!dc->funcs->pGetTextExtentPoint( dc, str, 1, &tSize )) goto done;
1149         if( extent+tSize.cx < maxExt )
1150         {
1151             extent+=tSize.cx;
1152             nFit++;
1153             str++;
1154             if( alpDx ) alpDx[index] = extent;
1155             if( tSize.cy > size->cy ) size->cy = tSize.cy;
1156         }
1157         else break;
1158     }
1159     size->cx = extent;
1160     *lpnFit = nFit;
1161     ret = TRUE;
1162
1163     TRACE("(%08x %s %d) returning %d %ld x %ld\n",
1164           hdc,debugstr_wn(str,count),maxExt,nFit, size->cx,size->cy);
1165
1166 done:
1167     GDI_ReleaseObj( hdc );
1168     return ret;
1169 }
1170
1171 /***********************************************************************
1172  *           GetTextMetrics16    (GDI.93)
1173  */
1174 BOOL16 WINAPI GetTextMetrics16( HDC16 hdc, TEXTMETRIC16 *metrics )
1175 {
1176     TEXTMETRICA tm32;
1177
1178     if (!GetTextMetricsA( (HDC)hdc, &tm32 )) return FALSE;
1179     FONT_TextMetricATo16( &tm32, metrics );
1180     return TRUE;
1181 }
1182
1183
1184 /***********************************************************************
1185  *           GetTextMetricsA    (GDI32.@)
1186  */
1187 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1188     {
1189     BOOL ret = FALSE;
1190     DC * dc = DC_GetDCPtr( hdc );
1191     if (!dc) return FALSE;
1192
1193     if (dc->funcs->pGetTextMetrics && dc->funcs->pGetTextMetrics( dc, metrics ))
1194     {
1195     /* device layer returns values in device units
1196      * therefore we have to convert them to logical */
1197
1198 #define WDPTOLP(x) ((x<0)?                                      \
1199                 (-abs((x)*dc->wndExtX/dc->vportExtX)):          \
1200                 (abs((x)*dc->wndExtX/dc->vportExtX)))
1201 #define HDPTOLP(y) ((y<0)?                                      \
1202                 (-abs((y)*dc->wndExtY/dc->vportExtY)):          \
1203                 (abs((y)*dc->wndExtY/dc->vportExtY)))
1204         
1205     metrics->tmHeight           = HDPTOLP(metrics->tmHeight);
1206     metrics->tmAscent           = HDPTOLP(metrics->tmAscent);
1207     metrics->tmDescent          = HDPTOLP(metrics->tmDescent);
1208     metrics->tmInternalLeading  = HDPTOLP(metrics->tmInternalLeading);
1209     metrics->tmExternalLeading  = HDPTOLP(metrics->tmExternalLeading);
1210     metrics->tmAveCharWidth     = WDPTOLP(metrics->tmAveCharWidth);
1211     metrics->tmMaxCharWidth     = WDPTOLP(metrics->tmMaxCharWidth);
1212     metrics->tmOverhang         = WDPTOLP(metrics->tmOverhang);
1213         ret = TRUE;
1214
1215     TRACE("text metrics:\n"
1216           "    Weight = %03li\t FirstChar = %03i\t AveCharWidth = %li\n"
1217           "    Italic = % 3i\t LastChar = %03i\t\t MaxCharWidth = %li\n"
1218           "    UnderLined = %01i\t DefaultChar = %03i\t Overhang = %li\n"
1219           "    StruckOut = %01i\t BreakChar = %03i\t CharSet = %i\n"
1220           "    PitchAndFamily = %02x\n"
1221           "    --------------------\n"
1222           "    InternalLeading = %li\n"
1223           "    Ascent = %li\n"
1224           "    Descent = %li\n"
1225           "    Height = %li\n",
1226           metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1227           metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1228           metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1229           metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1230           metrics->tmPitchAndFamily,
1231           metrics->tmInternalLeading,
1232           metrics->tmAscent,
1233           metrics->tmDescent,
1234           metrics->tmHeight );
1235     }
1236     GDI_ReleaseObj( hdc );
1237     return ret;
1238 }
1239
1240
1241 /***********************************************************************
1242  *           GetTextMetricsW    (GDI32.@)
1243  */
1244 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1245 {
1246     TEXTMETRICA tm;
1247     if (!GetTextMetricsA( (HDC16)hdc, &tm )) return FALSE;
1248     FONT_TextMetricAToW( &tm, metrics );
1249     return TRUE;
1250 }
1251
1252
1253 /***********************************************************************
1254  * GetOutlineTextMetrics16 [GDI.308]  Gets metrics for TrueType fonts.
1255  *
1256  * NOTES
1257  *    lpOTM should be LPOUTLINETEXTMETRIC
1258  *
1259  * RETURNS
1260  *    Success: Non-zero or size of required buffer
1261  *    Failure: 0
1262  */
1263 UINT16 WINAPI GetOutlineTextMetrics16(
1264     HDC16 hdc,    /* [in]  Handle of device context */
1265     UINT16 cbData, /* [in]  Size of metric data array */
1266     LPOUTLINETEXTMETRIC16 lpOTM)  /* [out] Address of metric data array */
1267 {
1268     FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
1269     return 0;
1270 }
1271
1272
1273 /***********************************************************************
1274  *              GetOutlineTextMetrics (GDI.207)
1275  *              GetOutlineTextMetricsA (GDI32.@)
1276  * Gets metrics for TrueType fonts.
1277  *
1278  *
1279  * RETURNS
1280  *    Success: Non-zero or size of required buffer
1281  *    Failure: 0
1282  */
1283 UINT WINAPI GetOutlineTextMetricsA(
1284     HDC hdc,    /* [in]  Handle of device context */
1285     UINT cbData, /* [in]  Size of metric data array */
1286     LPOUTLINETEXTMETRICA lpOTM)  /* [out] Address of metric data array */
1287 {
1288
1289
1290     UINT rtn = FALSE;
1291     LPTEXTMETRICA lptxtMetr;
1292
1293
1294
1295     if (lpOTM == 0)
1296     {
1297         
1298         lpOTM = (LPOUTLINETEXTMETRICA)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(OUTLINETEXTMETRICA));
1299         rtn = sizeof(OUTLINETEXTMETRICA);
1300         cbData = rtn;
1301     } else
1302     {
1303         cbData = sizeof(*lpOTM);
1304         rtn = cbData;
1305     };
1306
1307     lpOTM->otmSize = cbData;
1308
1309     lptxtMetr =HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(TEXTMETRICA));
1310     
1311     if (!GetTextMetricsA(hdc,lptxtMetr))
1312     {
1313         return 0;
1314     } else
1315     {
1316        memcpy(&(lpOTM->otmTextMetrics),lptxtMetr,sizeof(TEXTMETRICA));
1317     };
1318
1319     HeapFree(GetProcessHeap(),HEAP_ZERO_MEMORY,lptxtMetr);
1320     
1321     lpOTM->otmFilter = 0;
1322
1323     lpOTM->otmPanoseNumber.bFamilyType  = 0;
1324     lpOTM->otmPanoseNumber.bSerifStyle  = 0;
1325     lpOTM->otmPanoseNumber.bWeight      = 0;
1326     lpOTM->otmPanoseNumber.bProportion  = 0;
1327     lpOTM->otmPanoseNumber.bContrast    = 0;
1328     lpOTM->otmPanoseNumber.bStrokeVariation = 0;
1329     lpOTM->otmPanoseNumber.bArmStyle    = 0;
1330     lpOTM->otmPanoseNumber.bLetterform  = 0;
1331     lpOTM->otmPanoseNumber.bMidline     = 0;
1332     lpOTM->otmPanoseNumber.bXHeight     = 0;
1333
1334     lpOTM->otmfsSelection     = 0;
1335     lpOTM->otmfsType          = 0;
1336
1337     /*
1338      Further fill of the structure not implemented,
1339      Needs real values for the structure members
1340      */
1341     
1342     return rtn;
1343 }
1344
1345 /***********************************************************************
1346  *           GetOutlineTextMetricsW [GDI32.@]
1347  */
1348 UINT WINAPI GetOutlineTextMetricsW(
1349     HDC hdc,    /* [in]  Handle of device context */
1350     UINT cbData, /* [in]  Size of metric data array */
1351     LPOUTLINETEXTMETRICW lpOTM)  /* [out] Address of metric data array */
1352 {
1353     FIXME("(%d,%d,%p): stub\n", hdc, cbData, lpOTM);
1354     return 0; 
1355 }
1356
1357 /***********************************************************************
1358  *           GetCharWidth16    (GDI.350)
1359  *           GetCharWidth16    (DISPLAY.350)
1360  */
1361 BOOL16 WINAPI GetCharWidth16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1362                               LPINT16 buffer )
1363 {
1364     BOOL        retVal = FALSE;
1365
1366     if( firstChar != lastChar )
1367     {
1368         LPINT   buf32 = (LPINT)HeapAlloc(GetProcessHeap(), 0,
1369                                  sizeof(INT)*(1 + (lastChar - firstChar)));
1370         if( buf32 )
1371         {
1372             LPINT       obuf32 = buf32;
1373             int         i;
1374
1375             retVal = GetCharWidth32A(hdc, firstChar, lastChar, buf32);
1376             if (retVal)
1377             {
1378                 for (i = firstChar; i <= lastChar; i++)
1379                     *buffer++ = *buf32++;
1380             }
1381             HeapFree(GetProcessHeap(), 0, obuf32);
1382         }
1383     }
1384     else /* happens quite often to warrant a special treatment */
1385     {
1386         INT chWidth;
1387         retVal = GetCharWidth32A(hdc, firstChar, lastChar, &chWidth );
1388        *buffer = chWidth;
1389     }
1390     return retVal;
1391 }
1392
1393
1394 /***********************************************************************
1395  *           GetCharWidth32A    (GDI32.@)
1396  */
1397 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1398                                LPINT buffer )
1399 {
1400     UINT i, extra;
1401     BOOL ret = FALSE;
1402     DC * dc = DC_GetDCPtr( hdc );
1403     if (!dc) return FALSE;
1404
1405     if (dc->funcs->pGetCharWidth && dc->funcs->pGetCharWidth( dc, firstChar, lastChar, buffer))
1406     {
1407         /* convert device units to logical */
1408
1409         extra = dc->vportExtX >> 1;
1410         for( i = firstChar; i <= lastChar; i++, buffer++ )
1411             *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX;
1412         ret = TRUE;
1413     }
1414     GDI_ReleaseObj( hdc );
1415     return ret;
1416 }
1417
1418
1419 /***********************************************************************
1420  *           GetCharWidth32W    (GDI32.@)
1421  */
1422 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1423                                LPINT buffer )
1424 {
1425     return GetCharWidth32A( hdc, firstChar, lastChar, buffer );
1426 }
1427
1428
1429 /* FIXME: all following APIs ******************************************/
1430  
1431
1432 /***********************************************************************
1433  *           SetMapperFlags16    (GDI.349)
1434  */
1435 DWORD WINAPI SetMapperFlags16( HDC16 hDC, DWORD dwFlag )
1436 {
1437     return SetMapperFlags( hDC, dwFlag );
1438 }
1439
1440
1441 /***********************************************************************
1442  *           SetMapperFlags    (GDI32.@)
1443  */
1444 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1445 {
1446     DC *dc = DC_GetDCPtr( hDC );
1447     DWORD ret = 0; 
1448     if(!dc) return 0;
1449     if(dc->funcs->pSetMapperFlags)
1450         ret = dc->funcs->pSetMapperFlags( dc, dwFlag );
1451     else
1452         FIXME("(0x%04x, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1453     GDI_ReleaseObj( hDC );
1454     return ret;
1455 }
1456
1457 /***********************************************************************
1458  *          GetAspectRatioFilterEx16  (GDI.486)
1459  */
1460 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1461 {
1462   FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1463   return FALSE;
1464 }
1465
1466 /***********************************************************************
1467  *          GetAspectRatioFilterEx  (GDI32.@)
1468  */
1469 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1470 {
1471   FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1472   return FALSE;
1473 }
1474
1475 /***********************************************************************
1476  *           GetCharABCWidths16   (GDI.307)
1477  */
1478 BOOL16 WINAPI GetCharABCWidths16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1479                                   LPABC16 abc )
1480 {
1481     ABC abc32;
1482     if (!GetCharABCWidthsA( hdc, firstChar, lastChar, &abc32 )) return FALSE;
1483     abc->abcA = abc32.abcA;
1484     abc->abcB = abc32.abcB;
1485     abc->abcC = abc32.abcC;
1486     return TRUE;
1487 }
1488
1489
1490 /***********************************************************************
1491  *           GetCharABCWidthsA   (GDI32.@)
1492  */
1493 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1494                                   LPABC abc )
1495 {
1496     return GetCharABCWidthsW( hdc, firstChar, lastChar, abc );
1497 }
1498
1499
1500 /******************************************************************************
1501  * GetCharABCWidthsW [GDI32.@]  Retrieves widths of characters in range
1502  *
1503  * PARAMS
1504  *    hdc       [I] Handle of device context
1505  *    firstChar [I] First character in range to query
1506  *    lastChar  [I] Last character in range to query
1507  *    abc       [O] Address of character-width structure
1508  *
1509  * NOTES
1510  *    Only works with TrueType fonts
1511  *
1512  * RETURNS
1513  *    Success: TRUE
1514  *    Failure: FALSE
1515  */
1516 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1517                                    LPABC abc )
1518 {
1519     /* No TrueType fonts in Wine so far */
1520     FIXME("(%04x,%04x,%04x,%p): stub\n", hdc, firstChar, lastChar, abc);
1521     return FALSE;
1522 }
1523
1524
1525 /***********************************************************************
1526  *           GetGlyphOutline16    (GDI.309)
1527  */
1528 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1529                                 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1530                                 LPVOID lpBuffer, const MAT2 *lpmat2 )
1531 {
1532     FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1533           hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1534     return (DWORD)-1; /* failure */
1535 }
1536
1537
1538 /***********************************************************************
1539  *           GetGlyphOutlineA    (GDI32.@)
1540  */
1541 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1542                                  LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1543                                  LPVOID lpBuffer, const MAT2 *lpmat2 )
1544 {
1545     FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1546           hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1547     return (DWORD)-1; /* failure */
1548 }
1549
1550 /***********************************************************************
1551  *           GetGlyphOutlineW    (GDI32.@)
1552  */
1553 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1554                                  LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1555                                  LPVOID lpBuffer, const MAT2 *lpmat2 )
1556 {
1557     FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1558           hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1559     return (DWORD)-1; /* failure */
1560 }
1561
1562 /***********************************************************************
1563  *           CreateScalableFontResource16   (GDI.310)
1564  */
1565 BOOL16 WINAPI CreateScalableFontResource16( UINT16 fHidden,
1566                                             LPCSTR lpszResourceFile,
1567                                             LPCSTR fontFile, LPCSTR path )
1568 {
1569     return CreateScalableFontResourceA( fHidden, lpszResourceFile,
1570                                           fontFile, path );
1571 }
1572
1573 /***********************************************************************
1574  *           CreateScalableFontResourceA   (GDI32.@)
1575  */
1576 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1577                                              LPCSTR lpszResourceFile,
1578                                              LPCSTR lpszFontFile,
1579                                              LPCSTR lpszCurrentPath )
1580 {
1581     /* fHidden=1 - only visible for the calling app, read-only, not
1582      * enumbered with EnumFonts/EnumFontFamilies
1583      * lpszCurrentPath can be NULL
1584      */
1585     FIXME("(%ld,%s,%s,%s): stub\n",
1586           fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1587     return FALSE; /* create failed */
1588 }
1589
1590 /***********************************************************************
1591  *           CreateScalableFontResourceW   (GDI32.@)
1592  */
1593 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1594                                              LPCWSTR lpszResourceFile,
1595                                              LPCWSTR lpszFontFile,
1596                                              LPCWSTR lpszCurrentPath )
1597 {
1598     FIXME("(%ld,%p,%p,%p): stub\n",
1599           fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1600     return FALSE; /* create failed */
1601 }
1602
1603
1604 /*************************************************************************
1605  *             GetRasterizerCaps16   (GDI.313)
1606  */
1607 BOOL16 WINAPI GetRasterizerCaps16( LPRASTERIZER_STATUS lprs, UINT16 cbNumBytes)
1608 {
1609     return GetRasterizerCaps( lprs, cbNumBytes );
1610 }
1611
1612
1613 /*************************************************************************
1614  *             GetRasterizerCaps   (GDI32.@)
1615  */
1616 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
1617 {
1618   lprs->nSize = sizeof(RASTERIZER_STATUS);
1619   lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
1620   lprs->nLanguageID = 0;
1621   return TRUE;
1622 }
1623
1624
1625 /*************************************************************************
1626  *             GetKerningPairs16   (GDI.332)
1627  */
1628 INT16 WINAPI GetKerningPairs16( HDC16 hDC, INT16 cPairs,
1629                                 LPKERNINGPAIR16 lpKerningPairs )
1630 {
1631     /* At this time kerning is ignored (set to 0) */
1632     int i;
1633     FIXME("(%x,%d,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1634     for (i = 0; i < cPairs; i++) 
1635         lpKerningPairs[i].iKernAmount = 0;
1636     return 0;
1637 }
1638
1639
1640
1641 /*************************************************************************
1642  *             GetKerningPairsA   (GDI32.@)
1643  */
1644 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs,
1645                                  LPKERNINGPAIR lpKerningPairs )
1646 {
1647     int i;
1648     FIXME("(%x,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1649     for (i = 0; i < cPairs; i++) 
1650         lpKerningPairs[i].iKernAmount = 0;
1651     return 0;
1652 }
1653
1654
1655 /*************************************************************************
1656  *             GetKerningPairsW   (GDI32.@)
1657  */
1658 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
1659                                  LPKERNINGPAIR lpKerningPairs )
1660 {
1661     return GetKerningPairsA( hDC, cPairs, lpKerningPairs );
1662 }
1663
1664 /*************************************************************************
1665  * TranslateCharsetInfo [GDI32.@]
1666  *
1667  * Fills a CHARSETINFO structure for a character set, code page, or
1668  * font. This allows making the correspondance between different labelings
1669  * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges) 
1670  * of the same encoding.
1671  *
1672  * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
1673  * only one codepage should be set in *lpSrc.
1674  *
1675  * RETURNS
1676  *   TRUE on success, FALSE on failure.
1677  *
1678  */
1679 BOOL WINAPI TranslateCharsetInfo(
1680   LPDWORD lpSrc, /* [in]
1681        if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
1682        if flags == TCI_SRCCHARSET: a character set value
1683        if flags == TCI_SRCCODEPAGE: a code page value
1684                  */
1685   LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
1686   DWORD flags /* [in] determines interpretation of lpSrc */
1687 ) {
1688     int index = 0;
1689     switch (flags) {
1690     case TCI_SRCFONTSIG:
1691         while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
1692       break;
1693     case TCI_SRCCODEPAGE:
1694       while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
1695       break;
1696     case TCI_SRCCHARSET:
1697       while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
1698       break;
1699     default:
1700       return FALSE;
1701     }
1702     if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
1703     memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
1704     return TRUE;
1705 }
1706
1707 /*************************************************************************
1708  *             GetFontLanguageInfo   (GDI32.@)
1709  */
1710 DWORD WINAPI GetFontLanguageInfo(HDC hdc) {
1711         /* return value 0 is correct for most cases anyway */
1712         FIXME("(%x):stub!\n", hdc);
1713         return 0;
1714 }
1715
1716 /*************************************************************************
1717  *             GetFontLanguageInfo   (GDI.616)
1718  */
1719 DWORD WINAPI GetFontLanguageInfo16(HDC16 hdc) {
1720         /* return value 0 is correct for most cases anyway */
1721         FIXME("(%x):stub!\n",hdc);
1722         return 0;
1723 }
1724
1725 /*************************************************************************
1726  * GetFontData [GDI32.@] Retrieve data for TrueType font
1727  *
1728  * RETURNS
1729  *
1730  * success: Number of bytes returned 
1731  * failure: GDI_ERROR
1732  *
1733  * NOTES
1734  *
1735  * Calls SetLastError()  
1736  *
1737  * BUGS
1738  *
1739  * Unimplemented
1740  */
1741 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset, 
1742     LPVOID buffer, DWORD length)
1743 {
1744     FIXME("(%x,%ld,%ld,%p,%ld): stub\n", hdc, table, offset, buffer, length);
1745     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1746     return GDI_ERROR;
1747 }
1748
1749 /*************************************************************************
1750  * GetFontData16 [GDI.311]
1751  *
1752  */
1753 DWORD WINAPI GetFontData16(HDC16 hdc, DWORD dwTable, DWORD dwOffset,
1754                             LPVOID lpvBuffer, DWORD cbData)
1755 {
1756     return GetFontData(hdc, dwTable, dwOffset, lpvBuffer, cbData);
1757 }
1758
1759 /*************************************************************************
1760  * GetCharacterPlacementA [GDI32.@]
1761  *
1762  * NOTES:
1763  *  the web browser control of ie4 calls this with dwFlags=0
1764  */
1765 DWORD WINAPI
1766 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
1767                          INT nMaxExtent, GCP_RESULTSA *lpResults,
1768                          DWORD dwFlags)
1769 {
1770     DWORD ret=0;
1771     SIZE size;
1772
1773     TRACE("%s 0x%08x 0x%08x 0x%08lx:stub!\n",
1774           debugstr_a(lpString), uCount, nMaxExtent, dwFlags);
1775
1776     TRACE("lpOrder=%p lpDx=%p lpCaretPos=%p lpClass=%p "
1777           "lpOutString=%p lpGlyphs=%p\n",
1778           lpResults->lpOrder, lpResults->lpDx, lpResults->lpCaretPos,
1779           lpResults->lpClass, lpResults->lpOutString, lpResults->lpGlyphs);
1780
1781     if(dwFlags)                 FIXME("flags 0x%08lx ignored\n", dwFlags);
1782     if(lpResults->lpOrder)      FIXME("reordering not implemented\n");
1783     if(lpResults->lpCaretPos)   FIXME("caret positions not implemented\n");
1784     if(lpResults->lpClass)      FIXME("classes not implemented\n");
1785     if(lpResults->lpGlyphs)     FIXME("glyphs not implemented\n");
1786
1787     /* copy will do if the GCP_REORDER flag is not set */
1788     if(lpResults->lpOutString)
1789     {
1790       lstrcpynA(lpResults->lpOutString, lpString, uCount);
1791     }
1792
1793     if (lpResults->lpDx)
1794     {
1795       int i, c;
1796       for (i=0; i<uCount;i++)
1797       { 
1798         if (GetCharWidth32A(hdc, lpString[i], lpString[i], &c))
1799           lpResults->lpDx[i]= c;
1800       }
1801     }
1802
1803     if (GetTextExtentPoint32A(hdc, lpString, uCount, &size))
1804       ret = MAKELONG(size.cx, size.cy);
1805
1806     return ret;
1807 }
1808
1809 /*************************************************************************
1810  * GetCharacterPlacementW [GDI32.@]
1811  */
1812 DWORD WINAPI
1813 GetCharacterPlacementW(HDC hdc, LPCWSTR lpString, INT uCount,
1814                          INT nMaxExtent, GCP_RESULTSW *lpResults,
1815                          DWORD dwFlags)
1816 {
1817     /* return value 0 is correct for most cases anyway */
1818     FIXME(":stub!\n");
1819     return 0;
1820 }
1821
1822 /*************************************************************************
1823  *      GetCharABCWidthsFloatA [GDI32.@]
1824  */
1825 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
1826                                         LPABCFLOAT lpABCF)
1827 {
1828        FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
1829        return 0;
1830 }
1831
1832 /*************************************************************************
1833  *      GetCharABCWidthsFloatW [GDI32.@]
1834  */
1835 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
1836                                         UINT iLastChar, LPABCFLOAT lpABCF)
1837 {
1838        FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
1839        return 0;
1840 }
1841
1842 /*************************************************************************
1843  *      GetCharWidthFloatA [GDI32.@]
1844  */
1845 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
1846                                     UINT iLastChar, PFLOAT pxBuffer)
1847 {
1848        FIXME_(gdi)("GetCharWidthFloatA, stub\n");
1849        return 0;
1850 }
1851
1852 /*************************************************************************
1853  *      GetCharWidthFloatW [GDI32.@]
1854  */
1855 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
1856                                     UINT iLastChar, PFLOAT pxBuffer)
1857 {
1858        FIXME_(gdi)("GetCharWidthFloatW, stub\n");
1859        return 0;
1860 }
1861  
1862
1863 /***********************************************************************
1864  *                                                                     *
1865  *           Font Resource API                                         *
1866  *                                                                     *
1867  ***********************************************************************/
1868 /***********************************************************************
1869  *           AddFontResource16    (GDI.119)
1870  *
1871  *  Can be either .FON, or .FNT, or .TTF, or .FOT font file.
1872  *
1873  *  FIXME: Load header and find the best-matching font in the fontList;
1874  *         fixup dfPoints if all metrics are identical, otherwise create
1875  *         new fontAlias. When soft font support is ready this will
1876  *         simply create a new fontResource ('filename' will go into
1877  *         the pfr->resource field) with FR_SOFTFONT/FR_SOFTRESOURCE 
1878  *         flag set. 
1879  */
1880 INT16 WINAPI AddFontResource16( LPCSTR filename )
1881 {
1882     return AddFontResourceA( filename );
1883 }
1884
1885
1886 /***********************************************************************
1887  *           AddFontResourceA    (GDI32.@)
1888  */
1889 INT WINAPI AddFontResourceA( LPCSTR str )
1890 {
1891     FIXME("(%s): stub! Read the Wine User Guide on how to install "
1892             "this font manually.\n", debugres_a(str));
1893     return 1;
1894 }
1895
1896
1897 /***********************************************************************
1898  *           AddFontResourceW    (GDI32.@)
1899  */
1900 INT WINAPI AddFontResourceW( LPCWSTR str )
1901 {
1902     FIXME("(%s): stub! Read the Wine User Guide on how to install "
1903             "this font manually.\n", debugres_w(str));
1904     return 1;
1905 }
1906
1907 /***********************************************************************
1908  *           RemoveFontResource16    (GDI.136)
1909  */
1910 BOOL16 WINAPI RemoveFontResource16( LPCSTR str )
1911 {
1912     FIXME("(%s): stub\n", debugres_a(str));
1913     return TRUE;
1914 }
1915
1916
1917 /***********************************************************************
1918  *           RemoveFontResourceA    (GDI32.@)
1919  */
1920 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
1921 {
1922 /*  This is how it should look like */
1923 /*
1924     fontResource** ppfr;
1925     BOOL32 retVal = FALSE;
1926
1927     EnterCriticalSection( &crtsc_fonts_X11 );
1928     for( ppfr = &fontList; *ppfr; ppfr = &(*ppfr)->next )
1929          if( !strcasecmp( (*ppfr)->lfFaceName, str ) )
1930          {
1931              if(((*ppfr)->fr_flags & (FR_SOFTFONT | FR_SOFTRESOURCE)) &&
1932                  (*ppfr)->hOwnerProcess == GetCurrentProcess() )
1933              {
1934                  if( (*ppfr)->fo_count )
1935                      (*ppfr)->fr_flags |= FR_REMOVED;
1936                  else
1937                      XFONT_RemoveFontResource( ppfr );
1938              }
1939              retVal = TRUE;
1940          }
1941     LeaveCriticalSection( &crtsc_fonts_X11 );
1942     return retVal;
1943  */
1944     FIXME("(%s): stub\n", debugres_a(str));
1945     return TRUE;
1946 }
1947
1948
1949 /***********************************************************************
1950  *           RemoveFontResourceW    (GDI32.@)
1951  */
1952 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
1953 {
1954     FIXME("(%s): stub\n", debugres_w(str) );
1955     return TRUE;
1956 }