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