Documentation update.
[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   LPNEWTEXTMETRICEXW  lpTextMetric;
43   LPENUMLOGFONTEXW    lpLogFont;
44   DWORD                 dwFlags;
45 } fontEnum32;
46  
47 /*
48  *  For TranslateCharsetInfo
49  */
50 #define FS(x) {{0,0,0,0},{0x1<<(x),0}}
51 #define MAXTCIINDEX 32
52 static CHARSETINFO FONT_tci[MAXTCIINDEX] = {
53   /* ANSI */
54   { ANSI_CHARSET, 1252, FS(0)},
55   { EASTEUROPE_CHARSET, 1250, FS(1)},
56   { RUSSIAN_CHARSET, 1251, FS(2)},
57   { GREEK_CHARSET, 1253, FS(3)},
58   { TURKISH_CHARSET, 1254, FS(4)},
59   { HEBREW_CHARSET, 1255, FS(5)},
60   { ARABIC_CHARSET, 1256, FS(6)},
61   { BALTIC_CHARSET, 1257, FS(7)},
62   /* reserved by ANSI */
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   { DEFAULT_CHARSET, 0, FS(0)},
70   { DEFAULT_CHARSET, 0, FS(0)},
71   /* ANSI and OEM */
72   { THAI_CHARSET,  874,  FS(16)},
73   { SHIFTJIS_CHARSET, 932, FS(17)},
74   { GB2312_CHARSET, 936, FS(18)},
75   { HANGEUL_CHARSET, 949, FS(19)},
76   { CHINESEBIG5_CHARSET, 950, FS(20)},
77   { JOHAB_CHARSET, 1361, FS(21)}, 
78   /* reserved for alternate ANSI and OEM */
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   { DEFAULT_CHARSET, 0, FS(0)},
86   { DEFAULT_CHARSET, 0, FS(0)},
87   /* reserved for system */
88   { DEFAULT_CHARSET, 0, FS(0)},
89   { DEFAULT_CHARSET, 0, FS(0)},
90 };
91
92 /***********************************************************************
93  *              LOGFONT conversion functions.
94  */
95 void FONT_LogFont32ATo16( const LOGFONTA* font32, LPLOGFONT16 font16 )
96 {
97     font16->lfHeight = font32->lfHeight;
98     font16->lfWidth = font32->lfWidth;
99     font16->lfEscapement = font32->lfEscapement;
100     font16->lfOrientation = font32->lfOrientation;
101     font16->lfWeight = font32->lfWeight;
102     font16->lfItalic = font32->lfItalic;
103     font16->lfUnderline = font32->lfUnderline;
104     font16->lfStrikeOut = font32->lfStrikeOut;
105     font16->lfCharSet = font32->lfCharSet;
106     font16->lfOutPrecision = font32->lfOutPrecision;
107     font16->lfClipPrecision = font32->lfClipPrecision;
108     font16->lfQuality = font32->lfQuality;
109     font16->lfPitchAndFamily = font32->lfPitchAndFamily;
110     lstrcpynA( font16->lfFaceName, font32->lfFaceName, LF_FACESIZE );
111 }
112
113 void FONT_LogFont32WTo16( const LOGFONTW* font32, LPLOGFONT16 font16 )
114 {
115     font16->lfHeight = font32->lfHeight;
116     font16->lfWidth = font32->lfWidth;
117     font16->lfEscapement = font32->lfEscapement;
118     font16->lfOrientation = font32->lfOrientation;
119     font16->lfWeight = font32->lfWeight;
120     font16->lfItalic = font32->lfItalic;
121     font16->lfUnderline = font32->lfUnderline;
122     font16->lfStrikeOut = font32->lfStrikeOut;
123     font16->lfCharSet = font32->lfCharSet;
124     font16->lfOutPrecision = font32->lfOutPrecision;
125     font16->lfClipPrecision = font32->lfClipPrecision;
126     font16->lfQuality = font32->lfQuality;
127     font16->lfPitchAndFamily = font32->lfPitchAndFamily;
128     WideCharToMultiByte( CP_ACP, 0, font32->lfFaceName, -1,
129                          font16->lfFaceName, LF_FACESIZE, NULL, NULL );
130     font16->lfFaceName[LF_FACESIZE-1] = 0;
131 }
132
133 void FONT_LogFont16To32A( const LPLOGFONT16 font16, LPLOGFONTA font32 )
134 {
135     font32->lfHeight = font16->lfHeight;
136     font32->lfWidth = font16->lfWidth;
137     font32->lfEscapement = font16->lfEscapement;
138     font32->lfOrientation = font16->lfOrientation;
139     font32->lfWeight = font16->lfWeight;
140     font32->lfItalic = font16->lfItalic;
141     font32->lfUnderline = font16->lfUnderline;
142     font32->lfStrikeOut = font16->lfStrikeOut;
143     font32->lfCharSet = font16->lfCharSet;
144     font32->lfOutPrecision = font16->lfOutPrecision;
145     font32->lfClipPrecision = font16->lfClipPrecision;
146     font32->lfQuality = font16->lfQuality;
147     font32->lfPitchAndFamily = font16->lfPitchAndFamily;
148     lstrcpynA( font32->lfFaceName, font16->lfFaceName, LF_FACESIZE );
149 }
150
151 void FONT_LogFont16To32W( const LPLOGFONT16 font16, LPLOGFONTW font32 )
152 {
153     font32->lfHeight = font16->lfHeight;
154     font32->lfWidth = font16->lfWidth;
155     font32->lfEscapement = font16->lfEscapement;
156     font32->lfOrientation = font16->lfOrientation;
157     font32->lfWeight = font16->lfWeight;
158     font32->lfItalic = font16->lfItalic;
159     font32->lfUnderline = font16->lfUnderline;
160     font32->lfStrikeOut = font16->lfStrikeOut;
161     font32->lfCharSet = font16->lfCharSet;
162     font32->lfOutPrecision = font16->lfOutPrecision;
163     font32->lfClipPrecision = font16->lfClipPrecision;
164     font32->lfQuality = font16->lfQuality;
165     font32->lfPitchAndFamily = font16->lfPitchAndFamily;
166     MultiByteToWideChar( CP_ACP, 0, font16->lfFaceName, -1, font32->lfFaceName, LF_FACESIZE );
167     font32->lfFaceName[LF_FACESIZE-1] = 0;
168 }
169
170 void FONT_EnumLogFontEx16To32A( const LPENUMLOGFONTEX16 font16, LPENUMLOGFONTEXA font32 )
171 {
172     FONT_LogFont16To32A( (LPLOGFONT16)font16, (LPLOGFONTA)font32);
173     lstrcpynA( font32->elfFullName, font16->elfFullName, LF_FULLFACESIZE );
174     lstrcpynA( font32->elfStyle, font16->elfStyle, LF_FACESIZE );
175     lstrcpynA( font32->elfScript, font16->elfScript, LF_FACESIZE );
176 }
177
178 void FONT_EnumLogFontEx16To32W( const LPENUMLOGFONTEX16 font16, LPENUMLOGFONTEXW font32 )
179 {
180     FONT_LogFont16To32W( (LPLOGFONT16)font16, (LPLOGFONTW)font32);
181
182     MultiByteToWideChar( CP_ACP, 0, font16->elfFullName, -1, font32->elfFullName, LF_FULLFACESIZE );
183     font32->elfFullName[LF_FULLFACESIZE-1] = 0;
184     MultiByteToWideChar( CP_ACP, 0, font16->elfStyle, -1, font32->elfStyle, LF_FACESIZE );
185     font32->elfStyle[LF_FACESIZE-1] = 0;
186     MultiByteToWideChar( CP_ACP, 0, font16->elfScript, -1, font32->elfScript, LF_FACESIZE );
187     font32->elfScript[LF_FACESIZE-1] = 0;
188 }
189
190 /***********************************************************************
191  *              TEXTMETRIC conversion functions.
192  */
193 void FONT_TextMetric32Ato16(const LPTEXTMETRICA ptm32, LPTEXTMETRIC16 ptm16 )
194 {
195     ptm16->tmHeight = ptm32->tmHeight;
196     ptm16->tmAscent = ptm32->tmAscent;
197     ptm16->tmDescent = ptm32->tmDescent;
198     ptm16->tmInternalLeading = ptm32->tmInternalLeading;
199     ptm16->tmExternalLeading = ptm32->tmExternalLeading;
200     ptm16->tmAveCharWidth = ptm32->tmAveCharWidth;
201     ptm16->tmMaxCharWidth = ptm32->tmMaxCharWidth;
202     ptm16->tmWeight = ptm32->tmWeight;
203     ptm16->tmOverhang = ptm32->tmOverhang;
204     ptm16->tmDigitizedAspectX = ptm32->tmDigitizedAspectX;
205     ptm16->tmDigitizedAspectY = ptm32->tmDigitizedAspectY;
206     ptm16->tmFirstChar = ptm32->tmFirstChar;
207     ptm16->tmLastChar = ptm32->tmLastChar;
208     ptm16->tmDefaultChar = ptm32->tmDefaultChar;
209     ptm16->tmBreakChar = ptm32->tmBreakChar;
210     ptm16->tmItalic = ptm32->tmItalic;
211     ptm16->tmUnderlined = ptm32->tmUnderlined;
212     ptm16->tmStruckOut = ptm32->tmStruckOut;
213     ptm16->tmPitchAndFamily = ptm32->tmPitchAndFamily;
214     ptm16->tmCharSet = ptm32->tmCharSet;
215 }
216
217 void FONT_TextMetric32Wto16(const LPTEXTMETRICW ptm32, LPTEXTMETRIC16 ptm16 )
218 {
219     ptm16->tmHeight = ptm32->tmHeight;
220     ptm16->tmAscent = ptm32->tmAscent;
221     ptm16->tmDescent = ptm32->tmDescent;
222     ptm16->tmInternalLeading = ptm32->tmInternalLeading;
223     ptm16->tmExternalLeading = ptm32->tmExternalLeading;
224     ptm16->tmAveCharWidth = ptm32->tmAveCharWidth;
225     ptm16->tmMaxCharWidth = ptm32->tmMaxCharWidth;
226     ptm16->tmWeight = ptm32->tmWeight;
227     ptm16->tmOverhang = ptm32->tmOverhang;
228     ptm16->tmDigitizedAspectX = ptm32->tmDigitizedAspectX;
229     ptm16->tmDigitizedAspectY = ptm32->tmDigitizedAspectY;
230     ptm16->tmFirstChar = ptm32->tmFirstChar;
231     ptm16->tmLastChar = ptm32->tmLastChar;
232     ptm16->tmDefaultChar = ptm32->tmDefaultChar;
233     ptm16->tmBreakChar = ptm32->tmBreakChar;
234     ptm16->tmItalic = ptm32->tmItalic;
235     ptm16->tmUnderlined = ptm32->tmUnderlined;
236     ptm16->tmStruckOut = ptm32->tmStruckOut;
237     ptm16->tmPitchAndFamily = ptm32->tmPitchAndFamily;
238     ptm16->tmCharSet = ptm32->tmCharSet;
239 }
240
241 void FONT_TextMetric16to32A(const LPTEXTMETRIC16 ptm16, LPTEXTMETRICA ptm32 )
242 {
243     ptm32->tmHeight = ptm16->tmHeight;
244     ptm32->tmAscent = ptm16->tmAscent;
245     ptm32->tmDescent = ptm16->tmDescent;
246     ptm32->tmInternalLeading = ptm16->tmInternalLeading;
247     ptm32->tmExternalLeading = ptm16->tmExternalLeading;
248     ptm32->tmAveCharWidth = ptm16->tmAveCharWidth;
249     ptm32->tmMaxCharWidth = ptm16->tmMaxCharWidth;
250     ptm32->tmWeight = ptm16->tmWeight;
251     ptm32->tmOverhang = ptm16->tmOverhang;
252     ptm32->tmDigitizedAspectX = ptm16->tmDigitizedAspectX;
253     ptm32->tmDigitizedAspectY = ptm16->tmDigitizedAspectY;
254     ptm32->tmFirstChar = ptm16->tmFirstChar;
255     ptm32->tmLastChar = ptm16->tmLastChar;
256     ptm32->tmDefaultChar = ptm16->tmDefaultChar;
257     ptm32->tmBreakChar = ptm16->tmBreakChar;
258     ptm32->tmItalic = ptm16->tmItalic;
259     ptm32->tmUnderlined = ptm16->tmUnderlined;
260     ptm32->tmStruckOut = ptm16->tmStruckOut;
261     ptm32->tmPitchAndFamily = ptm16->tmPitchAndFamily;
262     ptm32->tmCharSet = ptm16->tmCharSet;
263 }
264
265 void FONT_TextMetric16to32W(const LPTEXTMETRIC16 ptm16, LPTEXTMETRICW ptm32 )
266 {
267     ptm32->tmHeight = ptm16->tmHeight;
268     ptm32->tmAscent = ptm16->tmAscent;
269     ptm32->tmDescent = ptm16->tmDescent;
270     ptm32->tmInternalLeading = ptm16->tmInternalLeading;
271     ptm32->tmExternalLeading = ptm16->tmExternalLeading;
272     ptm32->tmAveCharWidth = ptm16->tmAveCharWidth;
273     ptm32->tmMaxCharWidth = ptm16->tmMaxCharWidth;
274     ptm32->tmWeight = ptm16->tmWeight;
275     ptm32->tmOverhang = ptm16->tmOverhang;
276     ptm32->tmDigitizedAspectX = ptm16->tmDigitizedAspectX;
277     ptm32->tmDigitizedAspectY = ptm16->tmDigitizedAspectY;
278     ptm32->tmFirstChar = ptm16->tmFirstChar;
279     ptm32->tmLastChar = ptm16->tmLastChar;
280     ptm32->tmDefaultChar = ptm16->tmDefaultChar;
281     ptm32->tmBreakChar = ptm16->tmBreakChar;
282     ptm32->tmItalic = ptm16->tmItalic;
283     ptm32->tmUnderlined = ptm16->tmUnderlined;
284     ptm32->tmStruckOut = ptm16->tmStruckOut;
285     ptm32->tmPitchAndFamily = ptm16->tmPitchAndFamily;
286     ptm32->tmCharSet = ptm16->tmCharSet;
287 }
288
289 void FONT_TextMetric32Ato32W(const LPTEXTMETRICA ptm32A, LPTEXTMETRICW ptm32W )
290 {
291     ptm32W->tmHeight = ptm32A->tmHeight;
292     ptm32W->tmAscent = ptm32A->tmAscent;
293     ptm32W->tmDescent = ptm32A->tmDescent;
294     ptm32W->tmInternalLeading = ptm32A->tmInternalLeading;
295     ptm32W->tmExternalLeading = ptm32A->tmExternalLeading;
296     ptm32W->tmAveCharWidth = ptm32A->tmAveCharWidth;
297     ptm32W->tmMaxCharWidth = ptm32A->tmMaxCharWidth;
298     ptm32W->tmWeight = ptm32A->tmWeight;
299     ptm32W->tmOverhang = ptm32A->tmOverhang;
300     ptm32W->tmDigitizedAspectX = ptm32A->tmDigitizedAspectX;
301     ptm32W->tmDigitizedAspectY = ptm32A->tmDigitizedAspectY;
302     ptm32W->tmFirstChar = ptm32A->tmFirstChar;
303     ptm32W->tmLastChar = ptm32A->tmLastChar;
304     ptm32W->tmDefaultChar = ptm32A->tmDefaultChar;
305     ptm32W->tmBreakChar = ptm32A->tmBreakChar;
306     ptm32W->tmItalic = ptm32A->tmItalic;
307     ptm32W->tmUnderlined = ptm32A->tmUnderlined;
308     ptm32W->tmStruckOut = ptm32A->tmStruckOut;
309     ptm32W->tmPitchAndFamily = ptm32A->tmPitchAndFamily;
310     ptm32W->tmCharSet = ptm32A->tmCharSet;
311 }
312
313 /***********************************************************************
314  *           CreateFontIndirect16   (GDI.57)
315  */
316 HFONT16 WINAPI CreateFontIndirect16( const LOGFONT16 *font )
317 {
318     HFONT hFont = 0;
319
320     if (font)
321     {
322             FONTOBJ* fontPtr;
323         if ((fontPtr = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC, &hFont )))
324         {
325             memcpy( &fontPtr->logfont, font, sizeof(LOGFONT16) );
326
327             TRACE("(%i %i %i %i) '%s' %s %s => %04x\n",
328                   font->lfHeight, font->lfWidth, 
329                   font->lfEscapement, font->lfOrientation,
330                   font->lfFaceName ? font->lfFaceName : "NULL",
331                   font->lfWeight > 400 ? "Bold" : "",
332                   font->lfItalic ? "Italic" : "", hFont);
333
334             if (font->lfEscapement != font->lfOrientation) {
335               /* this should really depend on whether GM_ADVANCED is set */
336               fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
337               WARN("orientation angle %f set to "
338                    "escapement angle %f for new font %04x\n", 
339                    font->lfOrientation/10., font->lfEscapement/10., hFont);
340             }
341             GDI_ReleaseObj( hFont );
342         }
343     }
344     else WARN("(NULL) => NULL\n");
345
346     return hFont;
347 }
348
349 /***********************************************************************
350  *           CreateFontIndirectA   (GDI32.44)
351  */
352 HFONT WINAPI CreateFontIndirectA( const LOGFONTA *font )
353 {
354     LOGFONT16 font16;
355
356     FONT_LogFont32ATo16( font, &font16 );
357     return CreateFontIndirect16( &font16 );
358 }
359
360 /***********************************************************************
361  *           CreateFontIndirectW   (GDI32.45)
362  */
363 HFONT WINAPI CreateFontIndirectW( const LOGFONTW *font )
364 {
365     LOGFONT16 font16;
366
367     FONT_LogFont32WTo16( font, &font16 );
368     return CreateFontIndirect16( &font16 );
369 }
370
371 /***********************************************************************
372  *           CreateFont16    (GDI.56)
373  */
374 HFONT16 WINAPI CreateFont16(INT16 height, INT16 width, INT16 esc, INT16 orient,
375                             INT16 weight, BYTE italic, BYTE underline,
376                             BYTE strikeout, BYTE charset, BYTE outpres,
377                             BYTE clippres, BYTE quality, BYTE pitch,
378                             LPCSTR name )
379 {
380     LOGFONT16 logfont;
381
382     TRACE("('%s',%d,%d)\n", (name ? name : "(null)") , height, width);
383
384     logfont.lfHeight = height;
385     logfont.lfWidth = width;
386     logfont.lfEscapement = esc;
387     logfont.lfOrientation = orient;
388     logfont.lfWeight = weight;
389     logfont.lfItalic = italic;
390     logfont.lfUnderline = underline;
391     logfont.lfStrikeOut = strikeout;
392     logfont.lfCharSet = charset;
393     logfont.lfOutPrecision = outpres;
394     logfont.lfClipPrecision = clippres;
395     logfont.lfQuality = quality;
396     logfont.lfPitchAndFamily = pitch;
397    
398     if (name) 
399         lstrcpynA(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
400     else 
401         logfont.lfFaceName[0] = '\0';
402
403     return CreateFontIndirect16( &logfont );
404 }
405
406 /*************************************************************************
407  *           CreateFontA    (GDI32.43)
408  */
409 HFONT WINAPI CreateFontA( INT height, INT width, INT esc,
410                               INT orient, INT weight, DWORD italic,
411                               DWORD underline, DWORD strikeout, DWORD charset,
412                               DWORD outpres, DWORD clippres, DWORD quality,
413                               DWORD pitch, LPCSTR name )
414 {
415     return (HFONT)CreateFont16( height, width, esc, orient, weight, italic,
416                                   underline, strikeout, charset, outpres,
417                                   clippres, quality, pitch, name );
418 }
419
420 /*************************************************************************
421  *           CreateFontW    (GDI32.46)
422  */
423 HFONT WINAPI CreateFontW( INT height, INT width, INT esc,
424                               INT orient, INT weight, DWORD italic,
425                               DWORD underline, DWORD strikeout, DWORD charset,
426                               DWORD outpres, DWORD clippres, DWORD quality,
427                               DWORD pitch, LPCWSTR name )
428 {
429     LPSTR namea = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
430     HFONT ret = (HFONT)CreateFont16( height, width, esc, orient, weight,
431                                          italic, underline, strikeout, charset,
432                                          outpres, clippres, quality, pitch,
433                                          namea );
434     if (namea) HeapFree( GetProcessHeap(), 0, namea );
435     return ret;
436 }
437
438
439 /***********************************************************************
440  *           FONT_GetObject16
441  */
442 INT16 FONT_GetObject16( FONTOBJ * font, INT16 count, LPSTR buffer )
443 {
444     if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
445     memcpy( buffer, &font->logfont, count );
446     return count;
447 }
448
449 /***********************************************************************
450  *           FONT_GetObjectA
451  */
452 INT FONT_GetObjectA( FONTOBJ *font, INT count, LPSTR buffer )
453 {
454     LOGFONTA fnt32;
455
456     FONT_LogFont16To32A( &font->logfont, &fnt32 );
457
458     if (count > sizeof(fnt32)) count = sizeof(fnt32);
459     memcpy( buffer, &fnt32, count );
460     return count;
461 }
462 /***********************************************************************
463  *           FONT_GetObjectW
464  */
465 INT FONT_GetObjectW( FONTOBJ *font, INT count, LPSTR buffer )
466 {
467     LOGFONTW fnt32;
468
469     FONT_LogFont16To32W( &font->logfont, &fnt32 );
470
471     if (count > sizeof(fnt32)) count = sizeof(fnt32);
472     memcpy( buffer, &fnt32, count );
473     return count;
474 }
475
476
477 /***********************************************************************
478  *              FONT_EnumInstance16
479  *
480  * Called by the device driver layer to pass font info
481  * down to the application.
482  */
483 static INT FONT_EnumInstance16( LPENUMLOGFONTEX16 plf, 
484                                   LPNEWTEXTMETRIC16 ptm, UINT16 fType, LPARAM lp )
485 {
486 #define pfe ((fontEnum16*)lp)
487     if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET || 
488         pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
489     {
490         memcpy( pfe->lpLogFont, plf, sizeof(ENUMLOGFONT16) );
491         memcpy( pfe->lpTextMetric, ptm, sizeof(NEWTEXTMETRIC16) );
492
493         return pfe->lpEnumFunc( pfe->segLogFont, pfe->segTextMetric, fType, (LPARAM)(pfe->lpData) );
494     }
495 #undef pfe
496     return 1;
497 }
498
499 /***********************************************************************
500  *              FONT_EnumInstance
501  */
502 static INT FONT_EnumInstance( LPENUMLOGFONTEX16 plf,
503                                   LPNEWTEXTMETRIC16 ptm, UINT16 fType, LPARAM lp )
504 {
505     /* lfCharSet is at the same offset in both LOGFONTA and LOGFONTW */
506
507 #define pfe ((fontEnum32*)lp)
508     if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET || 
509         pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
510     {
511         /* convert font metrics */
512
513         if( pfe->dwFlags & ENUM_UNICODE )
514         {
515             FONT_EnumLogFontEx16To32W( plf, pfe->lpLogFont );
516             FONT_TextMetric16to32W( (LPTEXTMETRIC16)ptm, (LPTEXTMETRICW)(pfe->lpTextMetric) );
517         
518             return pfe->lpEnumFunc( pfe->lpLogFont, pfe->lpTextMetric, fType, pfe->lpData );
519         }
520         else
521         {
522             ENUMLOGFONTEXA logfont;
523
524             FONT_EnumLogFontEx16To32A( plf, &logfont);
525             FONT_TextMetric16to32A( (LPTEXTMETRIC16)ptm, (LPTEXTMETRICA)pfe->lpTextMetric );
526
527             return pfe->lpEnumFunc( (LPENUMLOGFONTEXW)&logfont, 
528                                 pfe->lpTextMetric, fType, pfe->lpData );
529         }
530     }
531 #undef pfe
532     return 1;
533 }
534
535 /***********************************************************************
536  *              EnumFontFamiliesEx16    (GDI.613)
537  */
538 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
539                                    FONTENUMPROCEX16 efproc, LPARAM lParam,
540                                    DWORD dwFlags)
541 {
542     BOOL (*enum_func)(HDC,LPLOGFONT16,DEVICEFONTENUMPROC,LPARAM);
543     INT16       retVal = 0;
544     DC*         dc = DC_GetDCPtr( hDC );
545
546     if (!dc) return 0;
547     enum_func = dc->funcs->pEnumDeviceFonts;
548     GDI_ReleaseObj( hDC );
549
550     if (enum_func)
551     {
552         LPNEWTEXTMETRICEX16     lptm16 = SEGPTR_ALLOC( sizeof(NEWTEXTMETRICEX16) );
553         if( lptm16 )
554         {
555             LPENUMLOGFONTEX16   lplf16 = SEGPTR_ALLOC( sizeof(ENUMLOGFONTEX16) );
556             if( lplf16 )
557             {
558                 fontEnum16      fe16;
559
560                 fe16.lpLogFontParam = plf;
561                 fe16.lpEnumFunc = efproc;
562                 fe16.lpData = lParam;
563                 
564                 fe16.lpTextMetric = lptm16;
565                 fe16.lpLogFont = lplf16;
566                 fe16.segTextMetric = SEGPTR_GET(lptm16);
567                 fe16.segLogFont = SEGPTR_GET(lplf16);
568
569                 retVal = enum_func( hDC, plf, FONT_EnumInstance16, (LPARAM)&fe16 );
570                 SEGPTR_FREE(lplf16);
571             }
572             SEGPTR_FREE(lptm16);
573         }
574     }
575     return retVal;
576 }
577
578 /***********************************************************************
579  *              FONT_EnumFontFamiliesEx
580  */
581 static INT FONT_EnumFontFamiliesEx( HDC hDC, LPLOGFONTW plf, FONTENUMPROCEXW efproc, 
582                                                    LPARAM lParam, DWORD dwUnicode)
583 {
584     BOOL (*enum_func)(HDC,LPLOGFONT16,DEVICEFONTENUMPROC,LPARAM);
585     INT ret = 0;
586     DC *dc = DC_GetDCPtr( hDC );
587
588     if (!dc) return 0;
589     enum_func = dc->funcs->pEnumDeviceFonts;
590     GDI_ReleaseObj( hDC );
591
592     if (enum_func)
593     {
594         LOGFONT16               lf16;
595         NEWTEXTMETRICEXW        tm32w;
596         ENUMLOGFONTEXW  lf32w;
597         fontEnum32              fe32;
598
599         fe32.lpLogFontParam = plf;
600         fe32.lpEnumFunc = efproc;
601         fe32.lpData = lParam;
602         
603         fe32.lpTextMetric = &tm32w;
604         fe32.lpLogFont = &lf32w;
605         fe32.dwFlags = dwUnicode;
606
607         /* the only difference between LOGFONT32A and LOGFONT32W is in the lfFaceName */
608
609         if( plf->lfFaceName[0] )
610         {
611             if( dwUnicode )
612             {
613                 WideCharToMultiByte( CP_ACP, 0, plf->lfFaceName, -1,
614                                      lf16.lfFaceName, LF_FACESIZE, NULL, NULL );
615                 lf16.lfFaceName[LF_FACESIZE-1] = 0;
616             }
617             else
618                 lstrcpynA( lf16.lfFaceName, (LPCSTR)plf->lfFaceName, LF_FACESIZE );
619         }
620         else lf16.lfFaceName[0] = '\0';
621         lf16.lfCharSet = plf->lfCharSet;
622
623         ret = enum_func( hDC, &lf16, FONT_EnumInstance, (LPARAM)&fe32 );
624     }
625     return ret;
626 }
627
628 /***********************************************************************
629  *              EnumFontFamiliesExW     (GDI32.82)
630  */
631 INT WINAPI EnumFontFamiliesExW( HDC hDC, LPLOGFONTW plf,
632                                     FONTENUMPROCEXW efproc, 
633                                     LPARAM lParam, DWORD dwFlags )
634 {
635     return  FONT_EnumFontFamiliesEx( hDC, plf, efproc, lParam, ENUM_UNICODE );
636 }
637
638 /***********************************************************************
639  *              EnumFontFamiliesExA     (GDI32.81)
640  */
641 INT WINAPI EnumFontFamiliesExA( HDC hDC, LPLOGFONTA plf,
642                                     FONTENUMPROCEXA efproc, 
643                                     LPARAM lParam, DWORD dwFlags)
644 {
645     return  FONT_EnumFontFamiliesEx( hDC, (LPLOGFONTW)plf, 
646                                       (FONTENUMPROCEXW)efproc, lParam, 0);
647 }
648
649 /***********************************************************************
650  *              EnumFontFamilies16      (GDI.330)
651  */
652 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
653                                  FONTENUMPROC16 efproc, LPARAM lpData )
654 {
655     LOGFONT16   lf;
656
657     lf.lfCharSet = DEFAULT_CHARSET;
658     if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
659     else lf.lfFaceName[0] = '\0';
660
661     return EnumFontFamiliesEx16( hDC, &lf, (FONTENUMPROCEX16)efproc, lpData, 0 );
662 }
663
664 /***********************************************************************
665  *              EnumFontFamiliesA       (GDI32.80)
666  */
667 INT WINAPI EnumFontFamiliesA( HDC hDC, LPCSTR lpFamily,
668                                   FONTENUMPROCA efproc, LPARAM lpData )
669 {
670     LOGFONTA    lf;
671
672     lf.lfCharSet = DEFAULT_CHARSET;
673     if( lpFamily ) lstrcpynA( lf.lfFaceName, lpFamily, LF_FACESIZE );
674     else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
675
676     return FONT_EnumFontFamiliesEx( hDC, (LPLOGFONTW)&lf, 
677                                            (FONTENUMPROCEXW)efproc, lpData, 0 );
678 }
679
680 /***********************************************************************
681  *              EnumFontFamiliesW       (GDI32.83)
682  */
683 INT WINAPI EnumFontFamiliesW( HDC hDC, LPCWSTR lpFamily,
684                                   FONTENUMPROCW efproc, LPARAM lpData )
685 {
686     LOGFONTW  lf;
687
688     lf.lfCharSet = DEFAULT_CHARSET;
689     if( lpFamily ) lstrcpynW( lf.lfFaceName, lpFamily, LF_FACESIZE );
690     else lf.lfFaceName[0] = 0;
691
692     return FONT_EnumFontFamiliesEx( hDC, &lf, (FONTENUMPROCEXW)efproc, 
693                                                 lpData, ENUM_UNICODE );
694 }
695
696 /***********************************************************************
697  *              EnumFonts16             (GDI.70)
698  */
699 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
700                           LPARAM lpData )
701 {
702     return EnumFontFamilies16( hDC, lpName, (FONTENUMPROCEX16)efproc, lpData );
703 }
704
705 /***********************************************************************
706  *              EnumFontsA              (GDI32.84)
707  */
708 INT WINAPI EnumFontsA( HDC hDC, LPCSTR lpName, FONTENUMPROCA efproc,
709                            LPARAM lpData )
710 {
711     return EnumFontFamiliesA( hDC, lpName, efproc, lpData );
712 }
713
714 /***********************************************************************
715  *              EnumFontsW              (GDI32.85)
716  */
717 INT WINAPI EnumFontsW( HDC hDC, LPCWSTR lpName, FONTENUMPROCW efproc,
718                            LPARAM lpData )
719 {
720     return EnumFontFamiliesW( hDC, lpName, efproc, lpData );
721 }
722
723
724 /***********************************************************************
725  *           GetTextCharacterExtra16    (GDI.89)
726  */
727 INT16 WINAPI GetTextCharacterExtra16( HDC16 hdc )
728 {
729     return (INT16)GetTextCharacterExtra( hdc );
730 }
731
732
733 /***********************************************************************
734  *           GetTextCharacterExtra    (GDI32.225)
735  */
736 INT WINAPI GetTextCharacterExtra( HDC hdc )
737 {
738     INT ret;
739     DC *dc = DC_GetDCPtr( hdc );
740     if (!dc) return 0;
741     ret = abs( (dc->charExtra * dc->wndExtX + dc->vportExtX / 2)
742                  / dc->vportExtX );
743     GDI_ReleaseObj( hdc );
744     return ret;
745 }
746
747
748 /***********************************************************************
749  *           SetTextCharacterExtra16    (GDI.8)
750  */
751 INT16 WINAPI SetTextCharacterExtra16( HDC16 hdc, INT16 extra )
752 {
753     return (INT16)SetTextCharacterExtra( hdc, extra );
754 }
755
756
757 /***********************************************************************
758  *           SetTextCharacterExtra    (GDI32.337)
759  */
760 INT WINAPI SetTextCharacterExtra( HDC hdc, INT extra )
761 {
762     INT prev;
763     DC * dc = DC_GetDCPtr( hdc );
764     if (!dc) return 0;
765     if (dc->funcs->pSetTextCharacterExtra)
766         prev = dc->funcs->pSetTextCharacterExtra( dc, extra );
767     else
768     {
769         extra = (extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX;
770         prev = (dc->charExtra * dc->wndExtX + dc->vportExtX / 2) / dc->vportExtX;
771         dc->charExtra = abs(extra);
772     }
773     GDI_ReleaseObj( hdc );
774     return prev;
775 }
776
777
778 /***********************************************************************
779  *           SetTextJustification16    (GDI.10)
780  */
781 INT16 WINAPI SetTextJustification16( HDC16 hdc, INT16 extra, INT16 breaks )
782 {
783     return SetTextJustification( hdc, extra, breaks );
784 }
785
786
787 /***********************************************************************
788  *           SetTextJustification    (GDI32.339)
789  */
790 BOOL WINAPI SetTextJustification( HDC hdc, INT extra, INT breaks )
791 {
792     BOOL ret = TRUE;
793     DC * dc = DC_GetDCPtr( hdc );
794     if (!dc) return FALSE;
795     if (dc->funcs->pSetTextJustification)
796         ret = dc->funcs->pSetTextJustification( dc, extra, breaks );
797     else
798     {
799         extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
800         if (!extra) breaks = 0;
801         dc->breakTotalExtra = extra;
802         dc->breakCount = breaks;
803         if (breaks)
804         {
805             dc->breakExtra = extra / breaks;
806             dc->breakRem   = extra - (dc->breakCount * dc->breakExtra);
807         }
808         else
809         {
810             dc->breakExtra = 0;
811             dc->breakRem   = 0;
812         }
813     }
814     GDI_ReleaseObj( hdc );
815     return ret;
816 }
817
818
819 /***********************************************************************
820  *           GetTextFace16    (GDI.92)
821  */
822 INT16 WINAPI GetTextFace16( HDC16 hdc, INT16 count, LPSTR name )
823 {
824         return GetTextFaceA(hdc,count,name);
825 }
826
827 /***********************************************************************
828  *           GetTextFaceA    (GDI32.234)
829  */
830 INT WINAPI GetTextFaceA( HDC hdc, INT count, LPSTR name )
831 {
832     FONTOBJ *font;
833     INT     ret = 0;
834
835     DC * dc = DC_GetDCPtr( hdc );
836     if (!dc) return 0;
837
838     if ((font = (FONTOBJ *) GDI_GetObjPtr( dc->hFont, FONT_MAGIC )))
839     {
840         if (name)
841         {
842             lstrcpynA( name, font->logfont.lfFaceName, count );
843             ret = strlen(name);
844         }
845         else ret = strlen(font->logfont.lfFaceName) + 1;
846         GDI_ReleaseObj( dc->hFont );
847     }
848     GDI_ReleaseObj( hdc );
849     return ret;
850 }
851
852 /***********************************************************************
853  *           GetTextFaceW    (GDI32.235)
854  */
855 INT WINAPI GetTextFaceW( HDC hdc, INT count, LPWSTR name )
856 {
857     LPSTR nameA = HeapAlloc( GetProcessHeap(), 0, count );
858     INT res = GetTextFaceA(hdc,count,nameA);
859     if (name) res = MultiByteToWideChar( CP_ACP, 0, nameA, -1, name, count );
860     HeapFree( GetProcessHeap(), 0, nameA );
861     return res;
862 }
863
864
865 /***********************************************************************
866  *           GetTextExtent16    (GDI.91)
867  */
868 DWORD WINAPI GetTextExtent16( HDC16 hdc, LPCSTR str, INT16 count )
869 {
870     SIZE16 size;
871     if (!GetTextExtentPoint16( hdc, str, count, &size )) return 0;
872     return MAKELONG( size.cx, size.cy );
873 }
874
875
876 /***********************************************************************
877  *           GetTextExtentPoint16    (GDI.471)
878  *
879  * FIXME: Should this have a bug for compatibility?
880  * Original Windows versions of GetTextExtentPoint{A,W} have documented
881  * bugs (-> MSDN KB q147647.txt).
882  */
883 BOOL16 WINAPI GetTextExtentPoint16( HDC16 hdc, LPCSTR str, INT16 count,
884                                     LPSIZE16 size )
885 {
886     SIZE size32;
887     BOOL ret;
888     TRACE("%04x, %p (%s), %d, %p\n", hdc, str, debugstr_an(str, count), count, size);
889     ret = GetTextExtentPoint32A( hdc, str, count, &size32 );
890     size->cx = size32.cx;
891     size->cy = size32.cy;
892     return (BOOL16)ret;
893 }
894
895
896 /***********************************************************************
897  *           GetTextExtentPoint32A    (GDI32.230)
898  */
899 BOOL WINAPI GetTextExtentPoint32A( HDC hdc, LPCSTR str, INT count,
900                                      LPSIZE size )
901 {
902     BOOL ret = FALSE;
903     UINT codepage = CP_ACP; /* FIXME: get codepage of font charset */
904     DC * dc = DC_GetDCPtr( hdc );
905
906     if (!dc) return FALSE;
907
908     if (dc->funcs->pGetTextExtentPoint)
909     {
910         /* str may not be 0 terminated so we can't use HEAP_strdupWtoA.
911          * So we use MultiByteToWideChar.
912          */
913         UINT wlen = MultiByteToWideChar(codepage,0,str,count,NULL,0);
914         LPWSTR p = HeapAlloc( GetProcessHeap(), 0, wlen * sizeof(WCHAR) );
915         if (p)
916         {
917             wlen = MultiByteToWideChar(codepage,0,str,count,p,wlen);
918             ret = dc->funcs->pGetTextExtentPoint( dc, p, wlen, size );
919             HeapFree( GetProcessHeap(), 0, p );
920         }
921     }
922     GDI_ReleaseObj( hdc );
923     TRACE("(%08x %s %d %p): returning %ld x %ld\n",
924           hdc, debugstr_an (str, count), count, size, size->cx, size->cy );
925     return ret;
926 }
927
928
929 /***********************************************************************
930  * GetTextExtentPoint32W [GDI32.231]  Computes width/height for a string
931  *
932  * Computes width and height of the specified string.
933  *
934  * RETURNS
935  *    Success: TRUE
936  *    Failure: FALSE
937  */
938 BOOL WINAPI GetTextExtentPoint32W(
939     HDC hdc,     /* [in]  Handle of device context */
940     LPCWSTR str,   /* [in]  Address of text string */
941     INT count,   /* [in]  Number of characters in string */
942     LPSIZE size) /* [out] Address of structure for string size */
943 {
944     BOOL ret = FALSE;
945     DC * dc = DC_GetDCPtr( hdc );
946     if (dc)
947     {
948         if(dc->funcs->pGetTextExtentPoint)
949             ret = dc->funcs->pGetTextExtentPoint( dc, str, count, size );
950         GDI_ReleaseObj( hdc );
951     }
952     TRACE("(%08x %s %d %p): returning %ld x %ld\n",
953           hdc, debugstr_wn (str, count), count, size, size->cx, size->cy );
954     return ret;
955 }
956
957
958 /***********************************************************************
959  *           GetTextExtentPointA    (GDI32.232)
960  */
961 BOOL WINAPI GetTextExtentPointA( HDC hdc, LPCSTR str, INT count,
962                                           LPSIZE size )
963 {
964     TRACE("not bug compatible.\n");
965     return GetTextExtentPoint32A( hdc, str, count, size );
966 }
967
968 /***********************************************************************
969  *           GetTextExtentPointW   (GDI32.233)
970  */
971 BOOL WINAPI GetTextExtentPointW( HDC hdc, LPCWSTR str, INT count,
972                                           LPSIZE size )
973 {
974     TRACE("not bug compatible.\n");
975     return GetTextExtentPoint32W( hdc, str, count, size );
976 }
977
978
979 /***********************************************************************
980  *           GetTextExtentExPointA    (GDI32.228)
981  */
982 BOOL WINAPI GetTextExtentExPointA( HDC hdc, LPCSTR str, INT count,
983                                    INT maxExt, LPINT lpnFit,
984                                    LPINT alpDx, LPSIZE size )
985 {
986     BOOL ret;
987
988     DWORD len = MultiByteToWideChar( CP_ACP, 0, str, count, NULL, 0 );
989     LPWSTR p = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
990     MultiByteToWideChar( CP_ACP, 0, str, count, p, len );
991     ret = GetTextExtentExPointW( hdc, p, len, maxExt, lpnFit, alpDx, size);
992     HeapFree( GetProcessHeap(), 0, p );
993     return ret;
994 }
995
996
997 /***********************************************************************
998  *           GetTextExtentExPointW    (GDI32.229)
999  */
1000
1001 BOOL WINAPI GetTextExtentExPointW( HDC hdc, LPCWSTR str, INT count,
1002                                    INT maxExt, LPINT lpnFit,
1003                                    LPINT alpDx, LPSIZE size )
1004 {
1005     int index, nFit, extent;
1006     SIZE tSize;
1007     BOOL ret = FALSE;
1008     DC * dc = DC_GetDCPtr( hdc );
1009     if (!dc) return FALSE;
1010
1011     if (!dc->funcs->pGetTextExtentPoint) goto done;
1012
1013     size->cx = size->cy = nFit = extent = 0;
1014     for(index = 0; index < count; index++)
1015     {
1016         if(!dc->funcs->pGetTextExtentPoint( dc, str, 1, &tSize )) goto done;
1017         if( extent+tSize.cx < maxExt )
1018         {
1019             extent+=tSize.cx;
1020             nFit++;
1021             str++;
1022             if( alpDx ) alpDx[index] = extent;
1023             if( tSize.cy > size->cy ) size->cy = tSize.cy;
1024         }
1025         else break;
1026     }
1027     size->cx = extent;
1028     *lpnFit = nFit;
1029     ret = TRUE;
1030
1031     TRACE("(%08x %s %d) returning %d %ld x %ld\n",
1032           hdc,debugstr_wn(str,count),maxExt,nFit, size->cx,size->cy);
1033
1034 done:
1035     GDI_ReleaseObj( hdc );
1036     return ret;
1037 }
1038
1039 /***********************************************************************
1040  *           GetTextMetrics16    (GDI.93)
1041  */
1042 BOOL16 WINAPI GetTextMetrics16( HDC16 hdc, TEXTMETRIC16 *metrics )
1043 {
1044     TEXTMETRICA tm32;
1045
1046     if (!GetTextMetricsA( (HDC)hdc, &tm32 )) return FALSE;
1047     FONT_TextMetric32Ato16( &tm32, metrics );
1048     return TRUE;
1049 }
1050
1051
1052 /***********************************************************************
1053  *           GetTextMetricsA    (GDI32.236)
1054  */
1055 BOOL WINAPI GetTextMetricsA( HDC hdc, TEXTMETRICA *metrics )
1056     {
1057     BOOL ret = FALSE;
1058     DC * dc = DC_GetDCPtr( hdc );
1059     if (!dc) return FALSE;
1060
1061     if (dc->funcs->pGetTextMetrics && dc->funcs->pGetTextMetrics( dc, metrics ))
1062     {
1063     /* device layer returns values in device units
1064      * therefore we have to convert them to logical */
1065
1066 #define WDPTOLP(x) ((x<0)?                                      \
1067                 (-abs((x)*dc->wndExtX/dc->vportExtX)):          \
1068                 (abs((x)*dc->wndExtX/dc->vportExtX)))
1069 #define HDPTOLP(y) ((y<0)?                                      \
1070                 (-abs((y)*dc->wndExtY/dc->vportExtY)):          \
1071                 (abs((y)*dc->wndExtY/dc->vportExtY)))
1072         
1073     metrics->tmHeight           = HDPTOLP(metrics->tmHeight);
1074     metrics->tmAscent           = HDPTOLP(metrics->tmAscent);
1075     metrics->tmDescent          = HDPTOLP(metrics->tmDescent);
1076     metrics->tmInternalLeading  = HDPTOLP(metrics->tmInternalLeading);
1077     metrics->tmExternalLeading  = HDPTOLP(metrics->tmExternalLeading);
1078     metrics->tmAveCharWidth     = WDPTOLP(metrics->tmAveCharWidth);
1079     metrics->tmMaxCharWidth     = WDPTOLP(metrics->tmMaxCharWidth);
1080     metrics->tmOverhang         = WDPTOLP(metrics->tmOverhang);
1081         ret = TRUE;
1082
1083     TRACE("text metrics:\n"
1084           "    Weight = %03li\t FirstChar = %03i\t AveCharWidth = %li\n"
1085           "    Italic = % 3i\t LastChar = %03i\t\t MaxCharWidth = %li\n"
1086           "    UnderLined = %01i\t DefaultChar = %03i\t Overhang = %li\n"
1087           "    StruckOut = %01i\t BreakChar = %03i\t CharSet = %i\n"
1088           "    PitchAndFamily = %02x\n"
1089           "    --------------------\n"
1090           "    InternalLeading = %li\n"
1091           "    Ascent = %li\n"
1092           "    Descent = %li\n"
1093           "    Height = %li\n",
1094           metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
1095           metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
1096           metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
1097           metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
1098           metrics->tmPitchAndFamily,
1099           metrics->tmInternalLeading,
1100           metrics->tmAscent,
1101           metrics->tmDescent,
1102           metrics->tmHeight );
1103     }
1104     GDI_ReleaseObj( hdc );
1105     return ret;
1106 }
1107
1108
1109 /***********************************************************************
1110  *           GetTextMetricsW    (GDI32.237)
1111  */
1112 BOOL WINAPI GetTextMetricsW( HDC hdc, TEXTMETRICW *metrics )
1113 {
1114     TEXTMETRICA tm;
1115     if (!GetTextMetricsA( (HDC16)hdc, &tm )) return FALSE;
1116     FONT_TextMetric32Ato32W( &tm, metrics );
1117     return TRUE;
1118 }
1119
1120
1121 /***********************************************************************
1122  * GetOutlineTextMetrics16 [GDI.308]  Gets metrics for TrueType fonts.
1123  *
1124  * NOTES
1125  *    lpOTM should be LPOUTLINETEXTMETRIC
1126  *
1127  * RETURNS
1128  *    Success: Non-zero or size of required buffer
1129  *    Failure: 0
1130  */
1131 UINT16 WINAPI GetOutlineTextMetrics16(
1132     HDC16 hdc,    /* [in]  Handle of device context */
1133     UINT16 cbData, /* [in]  Size of metric data array */
1134     LPOUTLINETEXTMETRIC16 lpOTM)  /* [out] Address of metric data array */
1135 {
1136     FIXME("(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
1137     return 0;
1138 }
1139
1140
1141 /***********************************************************************
1142  * GetOutlineTextMetricsA [GDI.207]  Gets metrics for TrueType fonts.
1143  *
1144  *
1145  * RETURNS
1146  *    Success: Non-zero or size of required buffer
1147  *    Failure: 0
1148  */
1149 UINT WINAPI GetOutlineTextMetricsA(
1150     HDC hdc,    /* [in]  Handle of device context */
1151     UINT cbData, /* [in]  Size of metric data array */
1152     LPOUTLINETEXTMETRICA lpOTM)  /* [out] Address of metric data array */
1153 {
1154
1155
1156     UINT rtn = FALSE;
1157     LPTEXTMETRICA lptxtMetr;
1158
1159
1160
1161     if (lpOTM == 0)
1162     {
1163         
1164         lpOTM = (LPOUTLINETEXTMETRICA)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(OUTLINETEXTMETRICA));
1165         rtn = sizeof(OUTLINETEXTMETRICA);
1166         cbData = rtn;
1167     } else
1168     {
1169         cbData = sizeof(*lpOTM);
1170         rtn = cbData;
1171     };
1172
1173     lpOTM->otmSize = cbData;
1174
1175     lptxtMetr =HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(TEXTMETRICA));
1176     
1177     if (!GetTextMetricsA(hdc,lptxtMetr))
1178     {
1179         return 0;
1180     } else
1181     {
1182        memcpy(&(lpOTM->otmTextMetrics),lptxtMetr,sizeof(TEXTMETRICA));
1183     };
1184
1185     HeapFree(GetProcessHeap(),HEAP_ZERO_MEMORY,lptxtMetr);
1186     
1187     lpOTM->otmFilter = 0;
1188
1189     lpOTM->otmPanoseNumber.bFamilyType  = 0;
1190     lpOTM->otmPanoseNumber.bSerifStyle  = 0;
1191     lpOTM->otmPanoseNumber.bWeight      = 0;
1192     lpOTM->otmPanoseNumber.bProportion  = 0;
1193     lpOTM->otmPanoseNumber.bContrast    = 0;
1194     lpOTM->otmPanoseNumber.bStrokeVariation = 0;
1195     lpOTM->otmPanoseNumber.bArmStyle    = 0;
1196     lpOTM->otmPanoseNumber.bLetterform  = 0;
1197     lpOTM->otmPanoseNumber.bMidline     = 0;
1198     lpOTM->otmPanoseNumber.bXHeight     = 0;
1199
1200     lpOTM->otmfsSelection     = 0;
1201     lpOTM->otmfsType          = 0;
1202
1203     /*
1204      Further fill of the structure not implemented,
1205      Needs real values for the structure members
1206      */
1207     
1208     return rtn;
1209 }
1210
1211 /***********************************************************************
1212  *           GetOutlineTextMetricsW [GDI32.208]
1213  */
1214 UINT WINAPI GetOutlineTextMetricsW(
1215     HDC hdc,    /* [in]  Handle of device context */
1216     UINT cbData, /* [in]  Size of metric data array */
1217     LPOUTLINETEXTMETRICW lpOTM)  /* [out] Address of metric data array */
1218 {
1219     FIXME("(%d,%d,%p): stub\n", hdc, cbData, lpOTM);
1220     return 0; 
1221 }
1222
1223 /***********************************************************************
1224  *           GetCharWidth16    (GDI.350)
1225  */
1226 BOOL16 WINAPI GetCharWidth16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1227                               LPINT16 buffer )
1228 {
1229     BOOL        retVal = FALSE;
1230
1231     if( firstChar != lastChar )
1232     {
1233         LPINT   buf32 = (LPINT)HeapAlloc(GetProcessHeap(), 0,
1234                                  sizeof(INT)*(1 + (lastChar - firstChar)));
1235         if( buf32 )
1236         {
1237             LPINT       obuf32 = buf32;
1238             int         i;
1239
1240             retVal = GetCharWidth32A(hdc, firstChar, lastChar, buf32);
1241             if (retVal)
1242             {
1243                 for (i = firstChar; i <= lastChar; i++)
1244                     *buffer++ = *buf32++;
1245             }
1246             HeapFree(GetProcessHeap(), 0, obuf32);
1247         }
1248     }
1249     else /* happens quite often to warrant a special treatment */
1250     {
1251         INT chWidth;
1252         retVal = GetCharWidth32A(hdc, firstChar, lastChar, &chWidth );
1253        *buffer = chWidth;
1254     }
1255     return retVal;
1256 }
1257
1258
1259 /***********************************************************************
1260  *           GetCharWidth32A    (GDI32.155)
1261  */
1262 BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
1263                                LPINT buffer )
1264 {
1265     UINT i, extra;
1266     BOOL ret = FALSE;
1267     DC * dc = DC_GetDCPtr( hdc );
1268     if (!dc) return FALSE;
1269
1270     if (dc->funcs->pGetCharWidth && dc->funcs->pGetCharWidth( dc, firstChar, lastChar, buffer))
1271     {
1272         /* convert device units to logical */
1273
1274         extra = dc->vportExtX >> 1;
1275         for( i = firstChar; i <= lastChar; i++, buffer++ )
1276             *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX;
1277         ret = TRUE;
1278     }
1279     GDI_ReleaseObj( hdc );
1280     return ret;
1281 }
1282
1283
1284 /***********************************************************************
1285  *           GetCharWidth32W    (GDI32.158)
1286  */
1287 BOOL WINAPI GetCharWidth32W( HDC hdc, UINT firstChar, UINT lastChar,
1288                                LPINT buffer )
1289 {
1290     return GetCharWidth32A( hdc, firstChar, lastChar, buffer );
1291 }
1292
1293
1294 /* FIXME: all following APIs ******************************************/
1295  
1296
1297 /***********************************************************************
1298  *           SetMapperFlags16    (GDI.349)
1299  */
1300 DWORD WINAPI SetMapperFlags16( HDC16 hDC, DWORD dwFlag )
1301 {
1302     return SetMapperFlags( hDC, dwFlag );
1303 }
1304
1305
1306 /***********************************************************************
1307  *           SetMapperFlags    (GDI32.322)
1308  */
1309 DWORD WINAPI SetMapperFlags( HDC hDC, DWORD dwFlag )
1310 {
1311     DC *dc = DC_GetDCPtr( hDC );
1312     DWORD ret = 0; 
1313     if(!dc) return 0;
1314     if(dc->funcs->pSetMapperFlags)
1315         ret = dc->funcs->pSetMapperFlags( dc, dwFlag );
1316     else
1317         FIXME("(0x%04x, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1318     GDI_ReleaseObj( hDC );
1319     return ret;
1320 }
1321
1322 /***********************************************************************
1323  *          GetAspectRatioFilterEx16  (GDI.486)
1324  */
1325 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1326 {
1327   FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1328   return FALSE;
1329 }
1330
1331 /***********************************************************************
1332  *          GetAspectRatioFilterEx  (GDI32.142)
1333  */
1334 BOOL WINAPI GetAspectRatioFilterEx( HDC hdc, LPSIZE pAspectRatio )
1335 {
1336   FIXME("(%04x, %p): -- Empty Stub !\n", hdc, pAspectRatio);
1337   return FALSE;
1338 }
1339
1340 /***********************************************************************
1341  *           GetCharABCWidths16   (GDI.307)
1342  */
1343 BOOL16 WINAPI GetCharABCWidths16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1344                                   LPABC16 abc )
1345 {
1346     ABC abc32;
1347     if (!GetCharABCWidthsA( hdc, firstChar, lastChar, &abc32 )) return FALSE;
1348     abc->abcA = abc32.abcA;
1349     abc->abcB = abc32.abcB;
1350     abc->abcC = abc32.abcC;
1351     return TRUE;
1352 }
1353
1354
1355 /***********************************************************************
1356  *           GetCharABCWidthsA   (GDI32.149)
1357  */
1358 BOOL WINAPI GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar,
1359                                   LPABC abc )
1360 {
1361     return GetCharABCWidthsW( hdc, firstChar, lastChar, abc );
1362 }
1363
1364
1365 /******************************************************************************
1366  * GetCharABCWidthsW [GDI32.152]  Retrieves widths of characters in range
1367  *
1368  * PARAMS
1369  *    hdc       [I] Handle of device context
1370  *    firstChar [I] First character in range to query
1371  *    lastChar  [I] Last character in range to query
1372  *    abc       [O] Address of character-width structure
1373  *
1374  * NOTES
1375  *    Only works with TrueType fonts
1376  *
1377  * RETURNS
1378  *    Success: TRUE
1379  *    Failure: FALSE
1380  */
1381 BOOL WINAPI GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar,
1382                                    LPABC abc )
1383 {
1384     /* No TrueType fonts in Wine so far */
1385     FIXME("(%04x,%04x,%04x,%p): stub\n", hdc, firstChar, lastChar, abc);
1386     return FALSE;
1387 }
1388
1389
1390 /***********************************************************************
1391  *           GetGlyphOutline16    (GDI.309)
1392  */
1393 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1394                                 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1395                                 LPVOID lpBuffer, const MAT2 *lpmat2 )
1396 {
1397     FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1398           hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1399     return (DWORD)-1; /* failure */
1400 }
1401
1402
1403 /***********************************************************************
1404  *           GetGlyphOutlineA    (GDI32.186)
1405  */
1406 DWORD WINAPI GetGlyphOutlineA( HDC hdc, UINT uChar, UINT fuFormat,
1407                                  LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1408                                  LPVOID lpBuffer, const MAT2 *lpmat2 )
1409 {
1410     FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1411           hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1412     return (DWORD)-1; /* failure */
1413 }
1414
1415 /***********************************************************************
1416  *           GetGlyphOutlineW    (GDI32.187)
1417  */
1418 DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat,
1419                                  LPGLYPHMETRICS lpgm, DWORD cbBuffer,
1420                                  LPVOID lpBuffer, const MAT2 *lpmat2 )
1421 {
1422     FIXME("(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1423           hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1424     return (DWORD)-1; /* failure */
1425 }
1426
1427 /***********************************************************************
1428  *           CreateScalableFontResource16   (GDI.310)
1429  */
1430 BOOL16 WINAPI CreateScalableFontResource16( UINT16 fHidden,
1431                                             LPCSTR lpszResourceFile,
1432                                             LPCSTR fontFile, LPCSTR path )
1433 {
1434     return CreateScalableFontResourceA( fHidden, lpszResourceFile,
1435                                           fontFile, path );
1436 }
1437
1438 /***********************************************************************
1439  *           CreateScalableFontResourceA   (GDI32.62)
1440  */
1441 BOOL WINAPI CreateScalableFontResourceA( DWORD fHidden,
1442                                              LPCSTR lpszResourceFile,
1443                                              LPCSTR lpszFontFile,
1444                                              LPCSTR lpszCurrentPath )
1445 {
1446     /* fHidden=1 - only visible for the calling app, read-only, not
1447      * enumbered with EnumFonts/EnumFontFamilies
1448      * lpszCurrentPath can be NULL
1449      */
1450     FIXME("(%ld,%s,%s,%s): stub\n",
1451           fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1452     return FALSE; /* create failed */
1453 }
1454
1455 /***********************************************************************
1456  *           CreateScalableFontResourceW   (GDI32.63)
1457  */
1458 BOOL WINAPI CreateScalableFontResourceW( DWORD fHidden,
1459                                              LPCWSTR lpszResourceFile,
1460                                              LPCWSTR lpszFontFile,
1461                                              LPCWSTR lpszCurrentPath )
1462 {
1463     FIXME("(%ld,%p,%p,%p): stub\n",
1464           fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1465     return FALSE; /* create failed */
1466 }
1467
1468
1469 /*************************************************************************
1470  *             GetRasterizerCaps16   (GDI.313)
1471  */
1472 BOOL16 WINAPI GetRasterizerCaps16( LPRASTERIZER_STATUS lprs, UINT16 cbNumBytes)
1473 {
1474     return GetRasterizerCaps( lprs, cbNumBytes );
1475 }
1476
1477
1478 /*************************************************************************
1479  *             GetRasterizerCaps   (GDI32.216)
1480  */
1481 BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
1482 {
1483   lprs->nSize = sizeof(RASTERIZER_STATUS);
1484   lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
1485   lprs->nLanguageID = 0;
1486   return TRUE;
1487 }
1488
1489
1490 /*************************************************************************
1491  *             GetKerningPairs16   (GDI.332)
1492  */
1493 INT16 WINAPI GetKerningPairs16( HDC16 hDC, INT16 cPairs,
1494                                 LPKERNINGPAIR16 lpKerningPairs )
1495 {
1496     /* At this time kerning is ignored (set to 0) */
1497     int i;
1498     FIXME("(%x,%d,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1499     for (i = 0; i < cPairs; i++) 
1500         lpKerningPairs[i].iKernAmount = 0;
1501     return 0;
1502 }
1503
1504
1505
1506 /*************************************************************************
1507  *             GetKerningPairsA   (GDI32.192)
1508  */
1509 DWORD WINAPI GetKerningPairsA( HDC hDC, DWORD cPairs,
1510                                  LPKERNINGPAIR lpKerningPairs )
1511 {
1512     int i;
1513     FIXME("(%x,%ld,%p): almost empty stub!\n", hDC, cPairs, lpKerningPairs);
1514     for (i = 0; i < cPairs; i++) 
1515         lpKerningPairs[i].iKernAmount = 0;
1516     return 0;
1517 }
1518
1519
1520 /*************************************************************************
1521  *             GetKerningPairsW   (GDI32.193)
1522  */
1523 DWORD WINAPI GetKerningPairsW( HDC hDC, DWORD cPairs,
1524                                  LPKERNINGPAIR lpKerningPairs )
1525 {
1526     return GetKerningPairsA( hDC, cPairs, lpKerningPairs );
1527 }
1528
1529 /*************************************************************************
1530  * TranslateCharsetInfo [GDI32.382]
1531  *
1532  * Fills a CHARSETINFO structure for a character set, code page, or
1533  * font. This allows making the correspondance between different labelings
1534  * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges) 
1535  * of the same encoding.
1536  *
1537  * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
1538  * only one codepage should be set in *lpSrc.
1539  *
1540  * RETURNS
1541  *   TRUE on success, FALSE on failure.
1542  *
1543  */
1544 BOOL WINAPI TranslateCharsetInfo(
1545   LPDWORD lpSrc, /* [in]
1546        if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
1547        if flags == TCI_SRCCHARSET: a character set value
1548        if flags == TCI_SRCCODEPAGE: a code page value
1549                  */
1550   LPCHARSETINFO lpCs, /* [out] structure to receive charset information */
1551   DWORD flags /* [in] determines interpretation of lpSrc */
1552 ) {
1553     int index = 0;
1554     switch (flags) {
1555     case TCI_SRCFONTSIG:
1556         while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
1557       break;
1558     case TCI_SRCCODEPAGE:
1559       while ((UINT) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
1560       break;
1561     case TCI_SRCCHARSET:
1562       while ((UINT) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
1563       break;
1564     default:
1565       return FALSE;
1566     }
1567     if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
1568     memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
1569     return TRUE;
1570 }
1571
1572 /*************************************************************************
1573  *             GetFontLanguageInfo   (GDI32.182)
1574  */
1575 DWORD WINAPI GetFontLanguageInfo(HDC hdc) {
1576         /* return value 0 is correct for most cases anyway */
1577         FIXME("(%x):stub!\n", hdc);
1578         return 0;
1579 }
1580
1581 /*************************************************************************
1582  *             GetFontLanguageInfo   (GDI.616)
1583  */
1584 DWORD WINAPI GetFontLanguageInfo16(HDC16 hdc) {
1585         /* return value 0 is correct for most cases anyway */
1586         FIXME("(%x):stub!\n",hdc);
1587         return 0;
1588 }
1589
1590 /*************************************************************************
1591  * GetFontData [GDI32.181] Retrieve data for TrueType font
1592  *
1593  * RETURNS
1594  *
1595  * success: Number of bytes returned 
1596  * failure: GDI_ERROR
1597  *
1598  * NOTES
1599  *
1600  * Calls SetLastError()  
1601  *
1602  * BUGS
1603  *
1604  * Unimplemented
1605  */
1606 DWORD WINAPI GetFontData(HDC hdc, DWORD table, DWORD offset, 
1607     LPVOID buffer, DWORD length)
1608 {
1609     FIXME("(%x,%ld,%ld,%p,%ld): stub\n", hdc, table, offset, buffer, length);
1610     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1611     return GDI_ERROR;
1612 }
1613
1614 /*************************************************************************
1615  * GetFontData16 [GDI.311]
1616  *
1617  */
1618 DWORD WINAPI GetFontData16(HDC16 hdc, DWORD dwTable, DWORD dwOffset,
1619                             LPVOID lpvBuffer, DWORD cbData)
1620 {
1621     return GetFontData(hdc, dwTable, dwOffset, lpvBuffer, cbData);
1622 }
1623
1624 /*************************************************************************
1625  * GetCharacterPlacementA [GDI32.160]
1626  *
1627  * NOTES:
1628  *  the web browser control of ie4 calls this with dwFlags=0
1629  */
1630 DWORD WINAPI
1631 GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
1632                          INT nMaxExtent, GCP_RESULTSA *lpResults,
1633                          DWORD dwFlags)
1634 {
1635     DWORD ret=0;
1636     SIZE size;
1637
1638     TRACE("%s 0x%08x 0x%08x 0x%08lx:stub!\n",
1639           debugstr_a(lpString), uCount, nMaxExtent, dwFlags);
1640
1641     TRACE("lpOrder=%p lpDx=%p lpCaretPos=%p lpClass=%p "
1642           "lpOutString=%p lpGlyphs=%p\n",
1643           lpResults->lpOrder, lpResults->lpDx, lpResults->lpCaretPos,
1644           lpResults->lpClass, lpResults->lpOutString, lpResults->lpGlyphs);
1645
1646     if(dwFlags)                 FIXME("flags 0x%08lx ignored\n", dwFlags);
1647     if(lpResults->lpOrder)      FIXME("reordering not implemented\n");
1648     if(lpResults->lpCaretPos)   FIXME("caret positions not implemented\n");
1649     if(lpResults->lpClass)      FIXME("classes not implemented\n");
1650     if(lpResults->lpGlyphs)     FIXME("glyphs not implemented\n");
1651
1652     /* copy will do if the GCP_REORDER flag is not set */
1653     if(lpResults->lpOutString)
1654     {
1655       lstrcpynA(lpResults->lpOutString, lpString, uCount);
1656     }
1657
1658     if (lpResults->lpDx)
1659     {
1660       int i, c;
1661       for (i=0; i<uCount;i++)
1662       { 
1663         if (GetCharWidth32A(hdc, lpString[i], lpString[i], &c))
1664           lpResults->lpDx[i]= c;
1665       }
1666     }
1667
1668     if (GetTextExtentPoint32A(hdc, lpString, uCount, &size))
1669       ret = MAKELONG(size.cx, size.cy);
1670
1671     return ret;
1672 }
1673
1674 /*************************************************************************
1675  * GetCharacterPlacementW [GDI32.161]
1676  */
1677 DWORD WINAPI
1678 GetCharacterPlacementW(HDC hdc, LPCWSTR lpString, INT uCount,
1679                          INT nMaxExtent, GCP_RESULTSW *lpResults,
1680                          DWORD dwFlags)
1681 {
1682     /* return value 0 is correct for most cases anyway */
1683     FIXME(":stub!\n");
1684     return 0;
1685 }
1686
1687 /*************************************************************************
1688  *      GetCharABCWidthsFloatA [GDI32.150]
1689  */
1690 BOOL WINAPI GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar,
1691                                         LPABCFLOAT lpABCF)
1692 {
1693        FIXME_(gdi)("GetCharABCWidthsFloatA, stub\n");
1694        return 0;
1695 }
1696
1697 /*************************************************************************
1698  *      GetCharABCWidthsFloatW [GDI32.151]
1699  */
1700 BOOL WINAPI GetCharABCWidthsFloatW(HDC hdc, UINT iFirstChar,
1701                                         UINT iLastChar, LPABCFLOAT lpABCF)
1702 {
1703        FIXME_(gdi)("GetCharABCWidthsFloatW, stub\n");
1704        return 0;
1705 }
1706
1707 /*************************************************************************
1708  *      GetCharWidthFloatA [GDI32.156]
1709  */
1710 BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
1711                                     UINT iLastChar, PFLOAT pxBuffer)
1712 {
1713        FIXME_(gdi)("GetCharWidthFloatA, stub\n");
1714        return 0;
1715 }
1716
1717 /*************************************************************************
1718  *      GetCharWidthFloatW [GDI32.157]
1719  */
1720 BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
1721                                     UINT iLastChar, PFLOAT pxBuffer)
1722 {
1723        FIXME_(gdi)("GetCharWidthFloatW, stub\n");
1724        return 0;
1725 }
1726  
1727
1728 /***********************************************************************
1729  *                                                                     *
1730  *           Font Resource API                                         *
1731  *                                                                     *
1732  ***********************************************************************/
1733 /***********************************************************************
1734  *           AddFontResource16    (GDI.119)
1735  *
1736  *  Can be either .FON, or .FNT, or .TTF, or .FOT font file.
1737  *
1738  *  FIXME: Load header and find the best-matching font in the fontList;
1739  *         fixup dfPoints if all metrics are identical, otherwise create
1740  *         new fontAlias. When soft font support is ready this will
1741  *         simply create a new fontResource ('filename' will go into
1742  *         the pfr->resource field) with FR_SOFTFONT/FR_SOFTRESOURCE 
1743  *         flag set. 
1744  */
1745 INT16 WINAPI AddFontResource16( LPCSTR filename )
1746 {
1747     return AddFontResourceA( filename );
1748 }
1749
1750
1751 /***********************************************************************
1752  *           AddFontResourceA    (GDI32.2)
1753  */
1754 INT WINAPI AddFontResourceA( LPCSTR str )
1755 {
1756     FIXME("(%s): stub! Read \"documentation/fonts\" how to install "
1757             "this font manually.\n", debugres_a(str));
1758     return 1;
1759 }
1760
1761
1762 /***********************************************************************
1763  *           AddFontResourceW    (GDI32.4)
1764  */
1765 INT WINAPI AddFontResourceW( LPCWSTR str )
1766 {
1767     FIXME("(%s): stub! Read \"documentation/fonts\" how to install "
1768             "this font manually.\n", debugres_w(str));
1769     return 1;
1770 }
1771
1772 /***********************************************************************
1773  *           RemoveFontResource16    (GDI.136)
1774  */
1775 BOOL16 WINAPI RemoveFontResource16( LPCSTR str )
1776 {
1777     FIXME("(%s): stub\n",       debugres_a(str));
1778     return TRUE;
1779 }
1780
1781
1782 /***********************************************************************
1783  *           RemoveFontResourceA    (GDI32.284)
1784  */
1785 BOOL WINAPI RemoveFontResourceA( LPCSTR str )
1786 {
1787 /*  This is how it should look like */
1788 /*
1789     fontResource** ppfr;
1790     BOOL32 retVal = FALSE;
1791
1792     EnterCriticalSection( &crtsc_fonts_X11 );
1793     for( ppfr = &fontList; *ppfr; ppfr = &(*ppfr)->next )
1794          if( !strcasecmp( (*ppfr)->lfFaceName, str ) )
1795          {
1796              if(((*ppfr)->fr_flags & (FR_SOFTFONT | FR_SOFTRESOURCE)) &&
1797                  (*ppfr)->hOwnerProcess == GetCurrentProcess() )
1798              {
1799                  if( (*ppfr)->fo_count )
1800                      (*ppfr)->fr_flags |= FR_REMOVED;
1801                  else
1802                      XFONT_RemoveFontResource( ppfr );
1803              }
1804              retVal = TRUE;
1805          }
1806     LeaveCriticalSection( &crtsc_fonts_X11 );
1807     return retVal;
1808  */
1809     FIXME("(%s): stub\n", debugres_a(str));
1810     return TRUE;
1811 }
1812
1813
1814 /***********************************************************************
1815  *           RemoveFontResourceW    (GDI32.286)
1816  */
1817 BOOL WINAPI RemoveFontResourceW( LPCWSTR str )
1818 {
1819     FIXME("(%s): stub\n", debugres_w(str) );
1820     return TRUE;
1821 }