Some warnings fixed, one useless VERSION warning removed (winelib).
[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 "font.h"
11 #include "heap.h"
12 #include "metafile.h"
13 #include "options.h"
14 #include "debug.h"
15 #include "winerror.h"
16
17 #define ENUM_UNICODE    0x00000001
18
19 typedef struct
20 {
21   LPLOGFONT16           lpLogFontParam;
22   FONTENUMPROCEX16      lpEnumFunc;
23   LPARAM                lpData;
24
25   LPNEWTEXTMETRICEX16   lpTextMetric;
26   LPENUMLOGFONTEX16     lpLogFont;
27   SEGPTR                segTextMetric;
28   SEGPTR                segLogFont;
29 } fontEnum16;
30
31 typedef struct
32 {
33   LPLOGFONT32W          lpLogFontParam;
34   FONTENUMPROC32W       lpEnumFunc;
35   LPARAM                lpData;
36
37   LPNEWTEXTMETRICEX32W  lpTextMetric;
38   LPENUMLOGFONTEX32W    lpLogFont;
39   DWORD                 dwFlags;
40 } fontEnum32;
41  
42 /*
43  *  For TranslateCharsetInfo
44  */
45 #define FS(x) {{0,0,0,0},{0x1<<(x),0}}
46 #define MAXTCIINDEX 32
47 static CHARSETINFO FONT_tci[MAXTCIINDEX] = {
48   /* ANSI */
49   { ANSI_CHARSET, 1252, FS(0)},
50   { EASTEUROPE_CHARSET, 1250, FS(1)},
51   { RUSSIAN_CHARSET, 1251, FS(2)},
52   { GREEK_CHARSET, 1253, FS(3)},
53   { TURKISH_CHARSET, 1254, FS(4)},
54   { HEBREW_CHARSET, 1255, FS(5)},
55   { ARABIC_CHARSET, 1256, FS(6)},
56   { BALTIC_CHARSET, 1257, FS(7)},
57   /* reserved by ANSI */
58   { DEFAULT_CHARSET, 0, FS(0)},
59   { DEFAULT_CHARSET, 0, FS(0)},
60   { DEFAULT_CHARSET, 0, FS(0)},
61   { DEFAULT_CHARSET, 0, FS(0)},
62   { DEFAULT_CHARSET, 0, FS(0)},
63   { DEFAULT_CHARSET, 0, FS(0)},
64   { DEFAULT_CHARSET, 0, FS(0)},
65   { DEFAULT_CHARSET, 0, FS(0)},
66   /* ANSI and OEM */
67   { THAI_CHARSET,  874,  FS(16)},
68   { SHIFTJIS_CHARSET, 932, FS(17)},
69   { GB2312_CHARSET, 936, FS(18)},
70   { HANGEUL_CHARSET, 949, FS(19)},
71   { CHINESEBIG5_CHARSET, 950, FS(20)},
72   { JOHAB_CHARSET, 1361, FS(21)}, 
73   /* reserved for alternate ANSI and OEM */
74   { DEFAULT_CHARSET, 0, FS(0)},
75   { DEFAULT_CHARSET, 0, FS(0)},
76   { DEFAULT_CHARSET, 0, FS(0)},
77   { DEFAULT_CHARSET, 0, FS(0)},
78   { DEFAULT_CHARSET, 0, FS(0)},
79   { DEFAULT_CHARSET, 0, FS(0)},
80   { DEFAULT_CHARSET, 0, FS(0)},
81   { DEFAULT_CHARSET, 0, FS(0)},
82   /* reserved for system */
83   { DEFAULT_CHARSET, 0, FS(0)},
84   { DEFAULT_CHARSET, 0, FS(0)},
85 };
86
87 /***********************************************************************
88  *              LOGFONT conversion functions.
89  */
90 static void __logfont32to16( INT16* plf16, const INT32* plf32 )
91 {
92     int  i;
93     for( i = 0; i < 5; i++ ) *plf16++ = *plf32++;
94    *((INT32*)plf16)++ = *plf32++;
95    *((INT32*)plf16)   = *plf32;
96 }
97
98 static void __logfont16to32( INT32* plf32, const INT16* plf16 )
99 {
100     int i;
101     for( i = 0; i < 5; i++ ) *plf32++ = *plf16++;
102    *plf32++ = *((INT32*)plf16)++;
103    *plf32   = *((INT32*)plf16);
104 }
105
106 void FONT_LogFont32ATo16( const LOGFONT32A* font32, LPLOGFONT16 font16 )
107 {
108   __logfont32to16( (INT16*)font16, (const INT32*)font32 );
109     lstrcpyn32A( font16->lfFaceName, font32->lfFaceName, LF_FACESIZE );
110 }
111
112 void FONT_LogFont32WTo16( const LOGFONT32W* font32, LPLOGFONT16 font16 )
113 {
114   __logfont32to16( (INT16*)font16, (const INT32*)font32 );
115     lstrcpynWtoA( font16->lfFaceName, font32->lfFaceName, LF_FACESIZE );
116 }
117
118 void FONT_LogFont16To32A( const LPLOGFONT16 font16, LPLOGFONT32A font32 )
119 {
120   __logfont16to32( (INT32*)font32, (const INT16*)font16 );
121     lstrcpyn32A( font32->lfFaceName, font16->lfFaceName, LF_FACESIZE );
122 }
123
124 void FONT_LogFont16To32W( const LPLOGFONT16 font16, LPLOGFONT32W font32 )
125 {
126   __logfont16to32( (INT32*)font32, (const INT16*)font16 );
127     lstrcpynAtoW( font32->lfFaceName, font16->lfFaceName, LF_FACESIZE );
128 }
129
130 /***********************************************************************
131  *              TEXTMETRIC conversion functions.
132  */
133 void FONT_TextMetric32Ato16(const LPTEXTMETRIC32A ptm32, LPTEXTMETRIC16 ptm16 )
134 {
135     ptm16->tmHeight = ptm32->tmHeight;
136     ptm16->tmAscent = ptm32->tmAscent;
137     ptm16->tmDescent = ptm32->tmDescent;
138     ptm16->tmInternalLeading = ptm32->tmInternalLeading;
139     ptm16->tmExternalLeading = ptm32->tmExternalLeading;
140     ptm16->tmAveCharWidth = ptm32->tmAveCharWidth;
141     ptm16->tmMaxCharWidth = ptm32->tmMaxCharWidth;
142     ptm16->tmWeight = ptm32->tmWeight;
143     ptm16->tmOverhang = ptm32->tmOverhang;
144     ptm16->tmDigitizedAspectX = ptm32->tmDigitizedAspectX;
145     ptm16->tmDigitizedAspectY = ptm32->tmDigitizedAspectY;
146     ptm16->tmFirstChar = ptm32->tmFirstChar;
147     ptm16->tmLastChar = ptm32->tmLastChar;
148     ptm16->tmDefaultChar = ptm32->tmDefaultChar;
149     ptm16->tmBreakChar = ptm32->tmBreakChar;
150     ptm16->tmItalic = ptm32->tmItalic;
151     ptm16->tmUnderlined = ptm32->tmUnderlined;
152     ptm16->tmStruckOut = ptm32->tmStruckOut;
153     ptm16->tmPitchAndFamily = ptm32->tmPitchAndFamily;
154     ptm16->tmCharSet = ptm32->tmCharSet;
155 }
156
157 void FONT_TextMetric32Wto16(const LPTEXTMETRIC32W ptm32, LPTEXTMETRIC16 ptm16 )
158 {
159     ptm16->tmHeight = ptm32->tmHeight;
160     ptm16->tmAscent = ptm32->tmAscent;
161     ptm16->tmDescent = ptm32->tmDescent;
162     ptm16->tmInternalLeading = ptm32->tmInternalLeading;
163     ptm16->tmExternalLeading = ptm32->tmExternalLeading;
164     ptm16->tmAveCharWidth = ptm32->tmAveCharWidth;
165     ptm16->tmMaxCharWidth = ptm32->tmMaxCharWidth;
166     ptm16->tmWeight = ptm32->tmWeight;
167     ptm16->tmOverhang = ptm32->tmOverhang;
168     ptm16->tmDigitizedAspectX = ptm32->tmDigitizedAspectX;
169     ptm16->tmDigitizedAspectY = ptm32->tmDigitizedAspectY;
170     ptm16->tmFirstChar = ptm32->tmFirstChar;
171     ptm16->tmLastChar = ptm32->tmLastChar;
172     ptm16->tmDefaultChar = ptm32->tmDefaultChar;
173     ptm16->tmBreakChar = ptm32->tmBreakChar;
174     ptm16->tmItalic = ptm32->tmItalic;
175     ptm16->tmUnderlined = ptm32->tmUnderlined;
176     ptm16->tmStruckOut = ptm32->tmStruckOut;
177     ptm16->tmPitchAndFamily = ptm32->tmPitchAndFamily;
178     ptm16->tmCharSet = ptm32->tmCharSet;
179 }
180
181 void FONT_TextMetric16to32A(const LPTEXTMETRIC16 ptm16, LPTEXTMETRIC32A ptm32 )
182 {
183     ptm32->tmHeight = ptm16->tmHeight;
184     ptm32->tmAscent = ptm16->tmAscent;
185     ptm32->tmDescent = ptm16->tmDescent;
186     ptm32->tmInternalLeading = ptm16->tmInternalLeading;
187     ptm32->tmExternalLeading = ptm16->tmExternalLeading;
188     ptm32->tmAveCharWidth = ptm16->tmAveCharWidth;
189     ptm32->tmMaxCharWidth = ptm16->tmMaxCharWidth;
190     ptm32->tmWeight = ptm16->tmWeight;
191     ptm32->tmOverhang = ptm16->tmOverhang;
192     ptm32->tmDigitizedAspectX = ptm16->tmDigitizedAspectX;
193     ptm32->tmDigitizedAspectY = ptm16->tmDigitizedAspectY;
194     ptm32->tmFirstChar = ptm16->tmFirstChar;
195     ptm32->tmLastChar = ptm16->tmLastChar;
196     ptm32->tmDefaultChar = ptm16->tmDefaultChar;
197     ptm32->tmBreakChar = ptm16->tmBreakChar;
198     ptm32->tmItalic = ptm16->tmItalic;
199     ptm32->tmUnderlined = ptm16->tmUnderlined;
200     ptm32->tmStruckOut = ptm16->tmStruckOut;
201     ptm32->tmPitchAndFamily = ptm16->tmPitchAndFamily;
202     ptm32->tmCharSet = ptm16->tmCharSet;
203 }
204
205 void FONT_TextMetric16to32W(const LPTEXTMETRIC16 ptm16, LPTEXTMETRIC32W ptm32 )
206 {
207     ptm32->tmHeight = ptm16->tmHeight;
208     ptm32->tmAscent = ptm16->tmAscent;
209     ptm32->tmDescent = ptm16->tmDescent;
210     ptm32->tmInternalLeading = ptm16->tmInternalLeading;
211     ptm32->tmExternalLeading = ptm16->tmExternalLeading;
212     ptm32->tmAveCharWidth = ptm16->tmAveCharWidth;
213     ptm32->tmMaxCharWidth = ptm16->tmMaxCharWidth;
214     ptm32->tmWeight = ptm16->tmWeight;
215     ptm32->tmOverhang = ptm16->tmOverhang;
216     ptm32->tmDigitizedAspectX = ptm16->tmDigitizedAspectX;
217     ptm32->tmDigitizedAspectY = ptm16->tmDigitizedAspectY;
218     ptm32->tmFirstChar = ptm16->tmFirstChar;
219     ptm32->tmLastChar = ptm16->tmLastChar;
220     ptm32->tmDefaultChar = ptm16->tmDefaultChar;
221     ptm32->tmBreakChar = ptm16->tmBreakChar;
222     ptm32->tmItalic = ptm16->tmItalic;
223     ptm32->tmUnderlined = ptm16->tmUnderlined;
224     ptm32->tmStruckOut = ptm16->tmStruckOut;
225     ptm32->tmPitchAndFamily = ptm16->tmPitchAndFamily;
226     ptm32->tmCharSet = ptm16->tmCharSet;
227 }
228
229 void FONT_TextMetric32Ato32W(const LPTEXTMETRIC32A ptm32A, LPTEXTMETRIC32W ptm32W )
230 {
231     ptm32W->tmHeight = ptm32A->tmHeight;
232     ptm32W->tmAscent = ptm32A->tmAscent;
233     ptm32W->tmDescent = ptm32A->tmDescent;
234     ptm32W->tmInternalLeading = ptm32A->tmInternalLeading;
235     ptm32W->tmExternalLeading = ptm32A->tmExternalLeading;
236     ptm32W->tmAveCharWidth = ptm32A->tmAveCharWidth;
237     ptm32W->tmMaxCharWidth = ptm32A->tmMaxCharWidth;
238     ptm32W->tmWeight = ptm32A->tmWeight;
239     ptm32W->tmOverhang = ptm32A->tmOverhang;
240     ptm32W->tmDigitizedAspectX = ptm32A->tmDigitizedAspectX;
241     ptm32W->tmDigitizedAspectY = ptm32A->tmDigitizedAspectY;
242     ptm32W->tmFirstChar = ptm32A->tmFirstChar;
243     ptm32W->tmLastChar = ptm32A->tmLastChar;
244     ptm32W->tmDefaultChar = ptm32A->tmDefaultChar;
245     ptm32W->tmBreakChar = ptm32A->tmBreakChar;
246     ptm32W->tmItalic = ptm32A->tmItalic;
247     ptm32W->tmUnderlined = ptm32A->tmUnderlined;
248     ptm32W->tmStruckOut = ptm32A->tmStruckOut;
249     ptm32W->tmPitchAndFamily = ptm32A->tmPitchAndFamily;
250     ptm32W->tmCharSet = ptm32A->tmCharSet;
251 }
252
253 /***********************************************************************
254  *           CreateFontIndirect16   (GDI.57)
255  */
256 HFONT16 WINAPI CreateFontIndirect16( const LOGFONT16 *font )
257 {
258     HFONT16 hFont = 0;
259
260     if (font)
261     {
262         hFont = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC );
263         if( hFont )
264         {
265             FONTOBJ* fontPtr;
266             fontPtr = (FONTOBJ *) GDI_HEAP_LOCK( hFont );
267             memcpy( &fontPtr->logfont, font, sizeof(LOGFONT16) );
268
269             TRACE(font,"(%i %i %i %i) '%s' %s %s => %04x\n",
270                                  font->lfHeight, font->lfWidth, 
271                                  font->lfEscapement, font->lfOrientation,
272                                  font->lfFaceName ? font->lfFaceName : "NULL",
273                                  font->lfWeight > 400 ? "Bold" : "",
274                                  font->lfItalic ? "Italic" : "",
275                                  hFont);
276
277             if (font->lfEscapement != font->lfOrientation) {
278               /* this should really depend on whether GM_ADVANCED is set */
279               fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
280               WARN(font, 
281        "orientation angle %f set to escapement angle %f for new font %04x\n", 
282            font->lfOrientation/10., font->lfEscapement/10., hFont);
283             }
284             GDI_HEAP_UNLOCK( hFont );
285         }
286     }
287     else WARN(font,"(NULL) => NULL\n");
288
289     return hFont;
290 }
291
292 /***********************************************************************
293  *           CreateFontIndirect32A   (GDI32.44)
294  */
295 HFONT32 WINAPI CreateFontIndirect32A( const LOGFONT32A *font )
296 {
297     LOGFONT16 font16;
298
299     FONT_LogFont32ATo16( font, &font16 );
300     return CreateFontIndirect16( &font16 );
301 }
302
303 /***********************************************************************
304  *           CreateFontIndirect32W   (GDI32.45)
305  */
306 HFONT32 WINAPI CreateFontIndirect32W( const LOGFONT32W *font )
307 {
308     LOGFONT16 font16;
309
310     FONT_LogFont32WTo16( font, &font16 );
311     return CreateFontIndirect16( &font16 );
312 }
313
314 /***********************************************************************
315  *           CreateFont16    (GDI.56)
316  */
317 HFONT16 WINAPI CreateFont16(INT16 height, INT16 width, INT16 esc, INT16 orient,
318                             INT16 weight, BYTE italic, BYTE underline,
319                             BYTE strikeout, BYTE charset, BYTE outpres,
320                             BYTE clippres, BYTE quality, BYTE pitch,
321                             LPCSTR name )
322 {
323     LOGFONT16 logfont = { height, width, esc, orient, weight, italic, underline,
324                           strikeout, charset, outpres, clippres, quality, pitch, };
325
326     TRACE(font,"('%s',%d,%d)\n",
327                  (name ? name : "(null)") , height, width);
328     if (name) 
329         lstrcpyn32A(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
330     else 
331         logfont.lfFaceName[0] = '\0';
332     return CreateFontIndirect16( &logfont );
333 }
334
335 /*************************************************************************
336  *           CreateFont32A    (GDI32.43)
337  */
338 HFONT32 WINAPI CreateFont32A( INT32 height, INT32 width, INT32 esc,
339                               INT32 orient, INT32 weight, DWORD italic,
340                               DWORD underline, DWORD strikeout, DWORD charset,
341                               DWORD outpres, DWORD clippres, DWORD quality,
342                               DWORD pitch, LPCSTR name )
343 {
344     return (HFONT32)CreateFont16( height, width, esc, orient, weight, italic,
345                                   underline, strikeout, charset, outpres,
346                                   clippres, quality, pitch, name );
347 }
348
349 /*************************************************************************
350  *           CreateFont32W    (GDI32.46)
351  */
352 HFONT32 WINAPI CreateFont32W( INT32 height, INT32 width, INT32 esc,
353                               INT32 orient, INT32 weight, DWORD italic,
354                               DWORD underline, DWORD strikeout, DWORD charset,
355                               DWORD outpres, DWORD clippres, DWORD quality,
356                               DWORD pitch, LPCWSTR name )
357 {
358     LPSTR namea = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
359     HFONT32 ret = (HFONT32)CreateFont16( height, width, esc, orient, weight,
360                                          italic, underline, strikeout, charset,
361                                          outpres, clippres, quality, pitch,
362                                          namea );
363     if (namea) HeapFree( GetProcessHeap(), 0, namea );
364     return ret;
365 }
366
367
368 /***********************************************************************
369  *           FONT_GetObject16
370  */
371 INT16 FONT_GetObject16( FONTOBJ * font, INT16 count, LPSTR buffer )
372 {
373     if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
374     memcpy( buffer, &font->logfont, count );
375     return count;
376 }
377
378 /***********************************************************************
379  *           FONT_GetObject32A
380  */
381 INT32 FONT_GetObject32A( FONTOBJ *font, INT32 count, LPSTR buffer )
382 {
383     LOGFONT32A fnt32;
384
385     FONT_LogFont16To32A( &font->logfont, &fnt32 );
386
387     if (count > sizeof(fnt32)) count = sizeof(fnt32);
388     memcpy( buffer, &fnt32, count );
389     return count;
390 }
391 /***********************************************************************
392  *           FONT_GetObject32W
393  */
394 INT32 FONT_GetObject32W( FONTOBJ *font, INT32 count, LPSTR buffer )
395 {
396     LOGFONT32W fnt32;
397
398     FONT_LogFont16To32W( &font->logfont, &fnt32 );
399
400     if (count > sizeof(fnt32)) count = sizeof(fnt32);
401     memcpy( buffer, &fnt32, count );
402     return count;
403 }
404
405
406 /***********************************************************************
407  *              FONT_EnumInstance16
408  *
409  * Called by the device driver layer to pass font info
410  * down to the application.
411  */
412 static INT32 FONT_EnumInstance16( LPENUMLOGFONT16 plf, 
413                                   LPNEWTEXTMETRIC16 ptm, UINT16 fType, LPARAM lp )
414 {
415 #define pfe ((fontEnum16*)lp)
416     if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET || 
417         pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
418     {
419         memcpy( pfe->lpLogFont, plf, sizeof(ENUMLOGFONT16) );
420         memcpy( pfe->lpTextMetric, ptm, sizeof(NEWTEXTMETRIC16) );
421
422         return pfe->lpEnumFunc( pfe->segLogFont, pfe->segTextMetric, fType, (LPARAM)(pfe->lpData) );
423     }
424 #undef pfe
425     return 1;
426 }
427
428 /***********************************************************************
429  *              FONT_EnumInstance32
430  */
431 static INT32 FONT_EnumInstance32( LPENUMLOGFONT16 plf,
432                                   LPNEWTEXTMETRIC16 ptm, UINT16 fType, LPARAM lp )
433 {
434     /* lfCharSet is at the same offset in both LOGFONT32A and LOGFONT32W */
435
436 #define pfe ((fontEnum32*)lp)
437     if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET || 
438         pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
439     {
440         /* convert font metrics */
441
442         if( pfe->dwFlags & ENUM_UNICODE )
443         {
444             FONT_LogFont16To32W( &plf->elfLogFont, (LPLOGFONT32W)(pfe->lpLogFont) );
445             FONT_TextMetric16to32W( (LPTEXTMETRIC16)ptm, (LPTEXTMETRIC32W)(pfe->lpTextMetric) );
446         }
447         else
448         {
449             FONT_LogFont16To32A( &plf->elfLogFont, (LPLOGFONT32A)pfe->lpLogFont );
450             FONT_TextMetric16to32A( (LPTEXTMETRIC16)ptm, (LPTEXTMETRIC32A)pfe->lpTextMetric );
451         }
452
453         return pfe->lpEnumFunc( (LPENUMLOGFONT32W)pfe->lpLogFont, 
454                                 (LPNEWTEXTMETRIC32W)pfe->lpTextMetric, fType, pfe->lpData );
455     }
456 #undef pfe
457     return 1;
458 }
459
460 /***********************************************************************
461  *              EnumFontFamiliesEx16    (GDI.613)
462  */
463 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
464                                    FONTENUMPROCEX16 efproc, LPARAM lParam,
465                                    DWORD dwFlags)
466 {
467     INT16       retVal = 0;
468     DC*         dc = (DC*) GDI_GetObjPtr( hDC, DC_MAGIC );
469
470     if( dc && dc->funcs->pEnumDeviceFonts )
471     {
472         LPNEWTEXTMETRICEX16     lptm16 = SEGPTR_ALLOC( sizeof(NEWTEXTMETRICEX16) );
473         if( lptm16 )
474         {
475             LPENUMLOGFONTEX16   lplf16 = SEGPTR_ALLOC( sizeof(ENUMLOGFONTEX16) );
476             if( lplf16 )
477             {
478                 fontEnum16      fe16 = { plf, efproc, lParam, lptm16, lplf16, 
479                                          SEGPTR_GET(lptm16), SEGPTR_GET(lplf16) };
480
481                 retVal = dc->funcs->pEnumDeviceFonts( dc, plf, FONT_EnumInstance16, (LPARAM)&fe16 );
482
483                 SEGPTR_FREE(lplf16);
484             }
485             SEGPTR_FREE(lptm16);
486         }
487     }
488     return retVal;
489 }
490
491 /***********************************************************************
492  *              FONT_EnumFontFamiliesEx32
493  */
494 static INT32 FONT_EnumFontFamiliesEx32( HDC32 hDC, LPLOGFONT32W plf, FONTENUMPROC32W efproc, 
495                                                    LPARAM lParam, DWORD dwUnicode)
496 {
497     DC*         dc = (DC*) GDI_GetObjPtr( hDC, DC_MAGIC );
498
499     if( dc && dc->funcs->pEnumDeviceFonts )
500     {
501         LOGFONT16               lf16;
502         NEWTEXTMETRICEX32W      tm32w;
503         ENUMLOGFONTEX32W        lf32w;
504         fontEnum32              fe32 = { plf, efproc, lParam, &tm32w, &lf32w, dwUnicode }; 
505
506         /* the only difference between LOGFONT32A and LOGFONT32W is in the lfFaceName */
507
508         if( plf->lfFaceName[0] )
509         {
510             if( dwUnicode )
511                 lstrcpynWtoA( lf16.lfFaceName, plf->lfFaceName, LF_FACESIZE );
512             else
513                 lstrcpyn32A( lf16.lfFaceName, (LPCSTR)plf->lfFaceName, LF_FACESIZE );
514         }
515         else lf16.lfFaceName[0] = '\0';
516         lf16.lfCharSet = plf->lfCharSet;
517
518         return dc->funcs->pEnumDeviceFonts( dc, &lf16, FONT_EnumInstance32, (LPARAM)&fe32 );
519     }
520     return 0;
521 }
522
523 /***********************************************************************
524  *              EnumFontFamiliesEx32W   (GDI32.82)
525  */
526 INT32 WINAPI EnumFontFamiliesEx32W( HDC32 hDC, LPLOGFONT32W plf,
527                                     FONTENUMPROCEX32W efproc, 
528                                     LPARAM lParam, DWORD dwFlags )
529 {
530     return  FONT_EnumFontFamiliesEx32( hDC, plf, (FONTENUMPROC32W)efproc, 
531                                                   lParam, ENUM_UNICODE );
532 }
533
534 /***********************************************************************
535  *              EnumFontFamiliesEx32A   (GDI32.81)
536  */
537 INT32 WINAPI EnumFontFamiliesEx32A( HDC32 hDC, LPLOGFONT32A plf,
538                                     FONTENUMPROCEX32A efproc, 
539                                     LPARAM lParam, DWORD dwFlags)
540 {
541     return  FONT_EnumFontFamiliesEx32( hDC, (LPLOGFONT32W)plf, 
542                                       (FONTENUMPROC32W)efproc, lParam, 0);
543 }
544
545 /***********************************************************************
546  *              EnumFontFamilies16      (GDI.330)
547  */
548 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
549                                  FONTENUMPROC16 efproc, LPARAM lpData )
550 {
551     LOGFONT16   lf;
552
553     lf.lfCharSet = DEFAULT_CHARSET;
554     if( lpFamily ) lstrcpyn32A( lf.lfFaceName, lpFamily, LF_FACESIZE );
555     else lf.lfFaceName[0] = '\0';
556
557     return EnumFontFamiliesEx16( hDC, &lf, (FONTENUMPROCEX16)efproc, lpData, 0 );
558 }
559
560 /***********************************************************************
561  *              EnumFontFamilies32A     (GDI32.80)
562  */
563 INT32 WINAPI EnumFontFamilies32A( HDC32 hDC, LPCSTR lpFamily,
564                                   FONTENUMPROC32A efproc, LPARAM lpData )
565 {
566     LOGFONT32A  lf;
567
568     lf.lfCharSet = DEFAULT_CHARSET;
569     if( lpFamily ) lstrcpyn32A( lf.lfFaceName, lpFamily, LF_FACESIZE );
570     else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
571
572     return FONT_EnumFontFamiliesEx32( hDC, (LPLOGFONT32W)&lf, 
573                                            (FONTENUMPROC32W)efproc, lpData, 0 );
574 }
575
576 /***********************************************************************
577  *              EnumFontFamilies32W     (GDI32.83)
578  */
579 INT32 WINAPI EnumFontFamilies32W( HDC32 hDC, LPCWSTR lpFamily,
580                                   FONTENUMPROC32W efproc, LPARAM lpData )
581 {
582     LOGFONT32W  lf;
583
584     lf.lfCharSet = DEFAULT_CHARSET;
585     if( lpFamily ) lstrcpyn32W( lf.lfFaceName, lpFamily, LF_FACESIZE );
586     else lf.lfFaceName[0] = 0;
587
588     return FONT_EnumFontFamiliesEx32( hDC, &lf, efproc, lpData, ENUM_UNICODE );
589 }
590
591 /***********************************************************************
592  *              EnumFonts16             (GDI.70)
593  */
594 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
595                           LPARAM lpData )
596 {
597     return EnumFontFamilies16( hDC, lpName, (FONTENUMPROCEX16)efproc, lpData );
598 }
599
600 /***********************************************************************
601  *              EnumFonts32A            (GDI32.84)
602  */
603 INT32 WINAPI EnumFonts32A( HDC32 hDC, LPCSTR lpName, FONTENUMPROC32A efproc,
604                            LPARAM lpData )
605 {
606     return EnumFontFamilies32A( hDC, lpName, efproc, lpData );
607 }
608
609 /***********************************************************************
610  *              EnumFonts32W            (GDI32.85)
611  */
612 INT32 WINAPI EnumFonts32W( HDC32 hDC, LPCWSTR lpName, FONTENUMPROC32W efproc,
613                            LPARAM lpData )
614 {
615     return EnumFontFamilies32W( hDC, lpName, efproc, lpData );
616 }
617
618
619 /***********************************************************************
620  *           GetTextCharacterExtra16    (GDI.89)
621  */
622 INT16 WINAPI GetTextCharacterExtra16( HDC16 hdc )
623 {
624     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
625     if (!dc) return 0;
626     return abs( (dc->w.charExtra * dc->wndExtX + dc->vportExtX / 2)
627                  / dc->vportExtX );
628 }
629
630
631 /***********************************************************************
632  *           GetTextCharacterExtra32    (GDI32.225)
633  */
634 INT32 WINAPI GetTextCharacterExtra32( HDC32 hdc )
635 {
636     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
637     if (!dc) return 0;
638     return abs( (dc->w.charExtra * dc->wndExtX + dc->vportExtX / 2)
639                  / dc->vportExtX );
640 }
641
642
643 /***********************************************************************
644  *           SetTextCharacterExtra16    (GDI.8)
645  */
646 INT16 WINAPI SetTextCharacterExtra16( HDC16 hdc, INT16 extra )
647 {
648     return (INT16)SetTextCharacterExtra32( hdc, extra );
649 }
650
651
652 /***********************************************************************
653  *           SetTextCharacterExtra32    (GDI32.337)
654  */
655 INT32 WINAPI SetTextCharacterExtra32( HDC32 hdc, INT32 extra )
656 {
657     INT32 prev;
658     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
659     if (!dc) return 0;
660     extra = (extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX;
661     prev = dc->w.charExtra;
662     dc->w.charExtra = abs(extra);
663     return (prev * dc->wndExtX + dc->vportExtX / 2) / dc->vportExtX;
664 }
665
666
667 /***********************************************************************
668  *           SetTextJustification16    (GDI.10)
669  */
670 INT16 WINAPI SetTextJustification16( HDC16 hdc, INT16 extra, INT16 breaks )
671 {
672     return SetTextJustification32( hdc, extra, breaks );
673 }
674
675
676 /***********************************************************************
677  *           SetTextJustification32    (GDI32.339)
678  */
679 BOOL32 WINAPI SetTextJustification32( HDC32 hdc, INT32 extra, INT32 breaks )
680 {
681     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
682     if (!dc) return 0;
683
684     extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
685     if (!extra) breaks = 0;
686     dc->w.breakTotalExtra = extra;
687     dc->w.breakCount = breaks;
688     if (breaks)
689     {
690         dc->w.breakExtra = extra / breaks;
691         dc->w.breakRem   = extra - (dc->w.breakCount * dc->w.breakExtra);
692     }
693     else
694     {
695         dc->w.breakExtra = 0;
696         dc->w.breakRem   = 0;
697     }
698     return 1;
699 }
700
701
702 /***********************************************************************
703  *           GetTextFace16    (GDI.92)
704  */
705 INT16 WINAPI GetTextFace16( HDC16 hdc, INT16 count, LPSTR name )
706 {
707         return GetTextFace32A(hdc,count,name);
708 }
709
710 /***********************************************************************
711  *           GetTextFace32A    (GDI32.234)
712  */
713 INT32 WINAPI GetTextFace32A( HDC32 hdc, INT32 count, LPSTR name )
714 {
715     FONTOBJ *font;
716
717     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
718     if (!dc) return 0;
719     if (!(font = (FONTOBJ *) GDI_GetObjPtr( dc->w.hFont, FONT_MAGIC )))
720         return 0;
721     if (name) 
722         lstrcpyn32A( name, font->logfont.lfFaceName, count );
723     GDI_HEAP_UNLOCK( dc->w.hFont );
724     if (name)
725         return strlen(name);
726     else
727         return strlen(font->logfont.lfFaceName) + 1;
728 }
729
730 /***********************************************************************
731  *           GetTextFace32W    (GDI32.235)
732  */
733 INT32 WINAPI GetTextFace32W( HDC32 hdc, INT32 count, LPWSTR name )
734 {
735     LPSTR nameA = HeapAlloc( GetProcessHeap(), 0, count );
736     INT32 res = GetTextFace32A(hdc,count,nameA);
737     lstrcpyAtoW( name, nameA );
738     HeapFree( GetProcessHeap(), 0, nameA );
739     return res;
740 }
741
742
743 /***********************************************************************
744  *           GetTextExtent    (GDI.91)
745  */
746 DWORD WINAPI GetTextExtent( HDC16 hdc, LPCSTR str, INT16 count )
747 {
748     SIZE16 size;
749     if (!GetTextExtentPoint16( hdc, str, count, &size )) return 0;
750     return MAKELONG( size.cx, size.cy );
751 }
752
753
754 /***********************************************************************
755  *           GetTextExtentPoint16    (GDI.471)
756  *
757  * FIXME: Should this have a bug for compatibility?
758  * Original Windows versions of GetTextExtentPoint{A,W} have documented
759  * bugs (-> MSDN KB q147647.txt).
760  */
761 BOOL16 WINAPI GetTextExtentPoint16( HDC16 hdc, LPCSTR str, INT16 count,
762                                     LPSIZE16 size )
763 {
764     SIZE32 size32;
765     BOOL32 ret = GetTextExtentPoint32A( hdc, str, count, &size32 );
766     CONV_SIZE32TO16( &size32, size );
767     return (BOOL16)ret;
768 }
769
770
771 /***********************************************************************
772  *           GetTextExtentPoint32A    (GDI32.230)
773  */
774 BOOL32 WINAPI GetTextExtentPoint32A( HDC32 hdc, LPCSTR str, INT32 count,
775                                      LPSIZE32 size )
776 {
777     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
778     if (!dc)
779     {
780         if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
781             return FALSE;
782     }
783
784     if (!dc->funcs->pGetTextExtentPoint ||
785         !dc->funcs->pGetTextExtentPoint( dc, str, count, size ))
786         return FALSE;
787
788     TRACE(font,"(%08x %s %d %p): returning %d,%d\n",
789                  hdc, debugstr_an (str, count), count,
790                  size, size->cx, size->cy );
791     return TRUE;
792 }
793
794
795 /***********************************************************************
796  * GetTextExtentPoint32W [GDI32.231]  Computes width/height for a string
797  *
798  * Computes width and height of the specified string.
799  *
800  * RETURNS
801  *    Success: TRUE
802  *    Failure: FALSE
803  */
804 BOOL32 WINAPI GetTextExtentPoint32W(
805     HDC32 hdc,     /* [in]  Handle of device context */
806     LPCWSTR str,   /* [in]  Address of text string */
807     INT32 count,   /* [in]  Number of characters in string */
808     LPSIZE32 size) /* [out] Address of structure for string size */
809 {
810     LPSTR p = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
811     BOOL32 ret = GetTextExtentPoint32A( hdc, p, count, size );
812     HeapFree( GetProcessHeap(), 0, p );
813     return ret;
814 }
815
816
817 /***********************************************************************
818  *           GetTextExtentPoint32ABuggy    (GDI32.232)
819  */
820 BOOL32 WINAPI GetTextExtentPoint32ABuggy( HDC32 hdc, LPCSTR str, INT32 count,
821                                           LPSIZE32 size )
822 {
823     TRACE(font, "not bug compatible.\n");
824     return GetTextExtentPoint32A( hdc, str, count, size );
825 }
826
827 /***********************************************************************
828  *           GetTextExtentPoint32WBuggy    (GDI32.233)
829  */
830 BOOL32 WINAPI GetTextExtentPoint32WBuggy( HDC32 hdc, LPCWSTR str, INT32 count,
831                                           LPSIZE32 size )
832 {
833     TRACE(font, "not bug compatible.\n");
834     return GetTextExtentPoint32W( hdc, str, count, size );
835 }
836
837
838 /***********************************************************************
839  *           GetTextExtentExPoint32A    (GDI32.228)
840  */
841 BOOL32 WINAPI GetTextExtentExPoint32A( HDC32 hdc, LPCSTR str, INT32 count,
842                                        INT32 maxExt, LPINT32 lpnFit,
843                                        LPINT32 alpDx, LPSIZE32 size )
844 {
845     int index, nFit, extent;
846     SIZE32 tSize;
847     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
848
849     if (!dc)
850     {
851         if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
852             return FALSE;
853     }
854     if (!dc->funcs->pGetTextExtentPoint) return FALSE;
855
856     size->cx = size->cy = nFit = extent = 0;
857     for(index = 0; index < count; index++)
858     {
859         if(!dc->funcs->pGetTextExtentPoint( dc, str, 1, &tSize )) return FALSE;
860         if( extent+tSize.cx < maxExt )
861         {
862             extent+=tSize.cx;
863             nFit++;
864             str++;
865             if( alpDx ) alpDx[index] = extent;
866             if( tSize.cy > size->cy ) size->cy = tSize.cy;
867         }
868         else break;
869     }
870     size->cx = extent;
871    *lpnFit = nFit;
872
873     TRACE(font,"(%08x '%.*s' %d) returning %d %d %d\n",
874                hdc,count,str,maxExt,nFit, size->cx,size->cy);
875     return TRUE;
876 }
877
878
879 /***********************************************************************
880  *           GetTextExtentExPoint32W    (GDI32.229)
881  */
882
883 BOOL32 WINAPI GetTextExtentExPoint32W( HDC32 hdc, LPCWSTR str, INT32 count,
884                                        INT32 maxExt, LPINT32 lpnFit,
885                                        LPINT32 alpDx, LPSIZE32 size )
886 {
887     LPSTR p = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
888     BOOL32 ret = GetTextExtentExPoint32A( hdc, p, count, maxExt,
889                                         lpnFit, alpDx, size);
890     HeapFree( GetProcessHeap(), 0, p );
891     return ret;
892 }
893
894 /***********************************************************************
895  *           GetTextMetrics16    (GDI.93)
896  */
897 BOOL16 WINAPI GetTextMetrics16( HDC16 hdc, TEXTMETRIC16 *metrics )
898 {
899     TEXTMETRIC32A tm32;
900
901     if (!GetTextMetrics32A( (HDC32)hdc, &tm32 )) return FALSE;
902     FONT_TextMetric32Ato16( &tm32, metrics );
903     return TRUE;
904 }
905
906
907 /***********************************************************************
908  *           GetTextMetrics32A    (GDI32.236)
909  */
910 BOOL32 WINAPI GetTextMetrics32A( HDC32 hdc, TEXTMETRIC32A *metrics )
911 {
912     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
913     if (!dc)
914     {
915         if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
916             return FALSE;
917     }
918
919     if (!dc->funcs->pGetTextMetrics ||
920         !dc->funcs->pGetTextMetrics( dc, metrics ))
921         return FALSE;
922
923     /* device layer returns values in device units
924      * therefore we have to convert them to logical */
925
926 #define WDPTOLP(x) ((x<0)?                                      \
927                 (-abs((x)*dc->wndExtX/dc->vportExtX)):          \
928                 (abs((x)*dc->wndExtX/dc->vportExtX)))
929 #define HDPTOLP(y) ((y<0)?                                      \
930                 (-abs((y)*dc->wndExtY/dc->vportExtY)):          \
931                 (abs((y)*dc->wndExtY/dc->vportExtY)))
932         
933     metrics->tmHeight           = HDPTOLP(metrics->tmHeight);
934     metrics->tmAscent           = HDPTOLP(metrics->tmAscent);
935     metrics->tmDescent          = HDPTOLP(metrics->tmDescent);
936     metrics->tmInternalLeading  = HDPTOLP(metrics->tmInternalLeading);
937     metrics->tmExternalLeading  = HDPTOLP(metrics->tmExternalLeading);
938     metrics->tmAveCharWidth     = WDPTOLP(metrics->tmAveCharWidth);
939     metrics->tmMaxCharWidth     = WDPTOLP(metrics->tmMaxCharWidth);
940     metrics->tmOverhang         = WDPTOLP(metrics->tmOverhang);
941
942     TRACE(font,"text metrics:
943     Weight = %03i\t FirstChar = %03i\t AveCharWidth = %i
944     Italic = % 3i\t LastChar = %03i\t\t MaxCharWidth = %i
945     UnderLined = %01i\t DefaultChar = %03i\t Overhang = %i
946     StruckOut = %01i\t BreakChar = %03i\t CharSet = %i
947     PitchAndFamily = %02x
948     --------------------
949     InternalLeading = %i
950     Ascent = %i
951     Descent = %i
952     Height = %i\n",
953     metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
954     metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
955     metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
956     metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
957     metrics->tmPitchAndFamily,
958     metrics->tmInternalLeading,
959     metrics->tmAscent,
960     metrics->tmDescent,
961     metrics->tmHeight );
962     return TRUE;
963 }
964
965
966 /***********************************************************************
967  *           GetTextMetrics32W    (GDI32.237)
968  */
969 BOOL32 WINAPI GetTextMetrics32W( HDC32 hdc, TEXTMETRIC32W *metrics )
970 {
971     TEXTMETRIC32A tm;
972     if (!GetTextMetrics32A( (HDC16)hdc, &tm )) return FALSE;
973     FONT_TextMetric32Ato32W( &tm, metrics );
974     return TRUE;
975 }
976
977
978 /***********************************************************************
979  * GetOutlineTextMetrics [GDI.308]  Gets metrics for TrueType fonts.
980  *
981  * NOTES
982  *    lpOTM should be LPOUTLINETEXTMETRIC
983  *
984  * RETURNS
985  *    Success: Non-zero or size of required buffer
986  *    Failure: 0
987  */
988 UINT16 WINAPI GetOutlineTextMetrics16(
989     HDC16 hdc,    /* [in]  Handle of device context */
990     UINT16 cbData, /* [in]  Size of metric data array */
991     LPOUTLINETEXTMETRIC16 lpOTM)  /* [out] Address of metric data array */
992 {
993     FIXME(font, "(%04x,%04x,%p): stub\n", hdc,cbData,lpOTM);
994     return 0;
995 }
996
997
998 /***********************************************************************
999  * GetOutlineTextMetrics [GDI.207]  Gets metrics for TrueType fonts.
1000  *
1001  *
1002  * RETURNS
1003  *    Success: Non-zero or size of required buffer
1004  *    Failure: 0
1005  */
1006 UINT32 WINAPI GetOutlineTextMetrics32A(
1007     HDC32 hdc,    /* [in]  Handle of device context */
1008     UINT32 cbData, /* [in]  Size of metric data array */
1009     LPOUTLINETEXTMETRIC32A lpOTM)  /* [out] Address of metric data array */
1010 {
1011
1012
1013     UINT32 rtn = FALSE;
1014     LPTEXTMETRIC32A lptxtMetr;
1015
1016
1017
1018     if (lpOTM == 0)
1019     {
1020         
1021         lpOTM = (LPOUTLINETEXTMETRIC32A)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(OUTLINETEXTMETRIC32A));
1022         rtn = sizeof(OUTLINETEXTMETRIC32A);
1023         cbData = rtn;
1024     } else
1025     {
1026         cbData = sizeof(*lpOTM);
1027         rtn = cbData;
1028     };
1029
1030     lpOTM->otmSize = cbData;
1031
1032     lptxtMetr =HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(TEXTMETRIC32A));
1033     
1034     if (!GetTextMetrics32A(hdc,lptxtMetr))
1035     {
1036         return 0;
1037     } else
1038     {
1039        memcpy(&(lpOTM->otmTextMetrics),lptxtMetr,sizeof(TEXTMETRIC32A));
1040     };
1041
1042     HeapFree(GetProcessHeap(),HEAP_ZERO_MEMORY,lptxtMetr);
1043     
1044     lpOTM->otmFilter = 0;
1045
1046     lpOTM->otmPanoseNumber.bFamilyType  = 0;
1047     lpOTM->otmPanoseNumber.bSerifStyle  = 0;
1048     lpOTM->otmPanoseNumber.bWeight      = 0;
1049     lpOTM->otmPanoseNumber.bProportion  = 0;
1050     lpOTM->otmPanoseNumber.bContrast    = 0;
1051     lpOTM->otmPanoseNumber.bStrokeVariation = 0;
1052     lpOTM->otmPanoseNumber.bArmStyle    = 0;
1053     lpOTM->otmPanoseNumber.bLetterform  = 0;
1054     lpOTM->otmPanoseNumber.bMidline     = 0;
1055     lpOTM->otmPanoseNumber.bXHeight     = 0;
1056
1057     lpOTM->otmfsSelection     = 0;
1058     lpOTM->otmfsType          = 0;
1059
1060     /*
1061      Further fill of the structure not implemented,
1062      Needs real values for the structure members
1063      */
1064     
1065     return rtn;
1066 }
1067
1068 /***********************************************************************
1069  *           GetOutlineTextMetrics32W [GDI32.208]
1070  */
1071 UINT32 WINAPI GetOutlineTextMetrics32W(
1072     HDC32 hdc,    /* [in]  Handle of device context */
1073     UINT32 cbData, /* [in]  Size of metric data array */
1074     LPOUTLINETEXTMETRIC32W lpOTM)  /* [out] Address of metric data array */
1075 {
1076     FIXME(font, "(%d,%d,%p): stub\n", hdc, cbData, lpOTM);
1077     return 0; 
1078 }
1079
1080 /***********************************************************************
1081  *           GetCharWidth16    (GDI.350)
1082  */
1083 BOOL16 WINAPI GetCharWidth16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1084                               LPINT16 buffer )
1085 {
1086     BOOL32      retVal = FALSE;
1087
1088     if( firstChar != lastChar )
1089     {
1090         LPINT32 buf32 = (LPINT32)HeapAlloc(GetProcessHeap(), 0,
1091                                  sizeof(INT32)*(1 + (lastChar - firstChar)));
1092         if( buf32 )
1093         {
1094             LPINT32     obuf32 = buf32;
1095             int         i;
1096
1097             retVal = GetCharWidth32A(hdc, firstChar, lastChar, buf32);
1098             if (retVal)
1099             {
1100                 for (i = firstChar; i <= lastChar; i++)
1101                     *buffer++ = *buf32++;
1102             }
1103             HeapFree(GetProcessHeap(), 0, obuf32);
1104         }
1105     }
1106     else /* happens quite often to warrant a special treatment */
1107     {
1108         INT32 chWidth;
1109         retVal = GetCharWidth32A(hdc, firstChar, lastChar, &chWidth );
1110        *buffer = chWidth;
1111     }
1112     return retVal;
1113 }
1114
1115
1116 /***********************************************************************
1117  *           GetCharWidth32A    (GDI32.155)
1118  */
1119 BOOL32 WINAPI GetCharWidth32A( HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
1120                                LPINT32 buffer )
1121 {
1122     UINT32 i, extra;
1123     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
1124     if (!dc)
1125     {
1126         if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
1127             return FALSE;
1128     }
1129
1130     if (!dc->funcs->pGetCharWidth ||
1131         !dc->funcs->pGetCharWidth( dc, firstChar, lastChar, buffer))
1132         return FALSE;
1133
1134     /* convert device units to logical */
1135
1136     extra = dc->vportExtX >> 1;
1137     for( i = firstChar; i <= lastChar; i++, buffer++ )
1138          *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX;
1139
1140     return TRUE;
1141 }
1142
1143
1144 /***********************************************************************
1145  *           GetCharWidth32W    (GDI32.158)
1146  */
1147 BOOL32 WINAPI GetCharWidth32W( HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
1148                                LPINT32 buffer )
1149 {
1150     return GetCharWidth32A( hdc, firstChar, lastChar, buffer );
1151 }
1152
1153
1154
1155 /* FIXME: all following APIs *******************************************
1156  *
1157  *
1158  *           SetMapperFlags16    (GDI.349)
1159  */
1160 DWORD WINAPI SetMapperFlags16( HDC16 hDC, DWORD dwFlag )
1161 {
1162     return SetMapperFlags32( hDC, dwFlag );
1163 }
1164
1165
1166 /***********************************************************************
1167  *           SetMapperFlags32    (GDI32.322)
1168  */
1169 DWORD WINAPI SetMapperFlags32( HDC32 hDC, DWORD dwFlag )
1170 {
1171     FIXME(font, "(0x%04x, 0x%08lx): stub - harmless\n", hDC, dwFlag);
1172     return 0;
1173 }
1174
1175 /***********************************************************************
1176  *          GetAspectRatioFilterEx16  (GDI.486)
1177  */
1178 BOOL16 WINAPI GetAspectRatioFilterEx16( HDC16 hdc, LPSIZE16 pAspectRatio )
1179 {
1180   FIXME(font, "(%04x, %p): -- Empty Stub !\n",
1181                 hdc, pAspectRatio);
1182   return FALSE;
1183 }
1184
1185 /***********************************************************************
1186  *          GetAspectRatioFilterEx32  (GDI32.142)
1187  */
1188 BOOL32 WINAPI GetAspectRatioFilterEx32( HDC32 hdc, LPSIZE32 pAspectRatio )
1189 {
1190   FIXME(font, "(%04x, %p): -- Empty Stub !\n",
1191         hdc, pAspectRatio);
1192   return FALSE;
1193 }
1194
1195 /***********************************************************************
1196  *           GetCharABCWidths16   (GDI.307)
1197  */
1198 BOOL16 WINAPI GetCharABCWidths16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1199                                   LPABC16 abc )
1200 {
1201     ABC32 abc32;
1202     if (!GetCharABCWidths32A( hdc, firstChar, lastChar, &abc32 )) return FALSE;
1203     abc->abcA = abc32.abcA;
1204     abc->abcB = abc32.abcB;
1205     abc->abcC = abc32.abcC;
1206     return TRUE;
1207 }
1208
1209
1210 /***********************************************************************
1211  *           GetCharABCWidths32A   (GDI32.149)
1212  */
1213 BOOL32 WINAPI GetCharABCWidths32A(HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
1214                                   LPABC32 abc )
1215 {
1216     return GetCharABCWidths32W( hdc, firstChar, lastChar, abc );
1217 }
1218
1219
1220 /******************************************************************************
1221  * GetCharABCWidths32W [GDI32.152]  Retrieves widths of characters in range
1222  *
1223  * PARAMS
1224  *    hdc       [I] Handle of device context
1225  *    firstChar [I] First character in range to query
1226  *    lastChar  [I] Last character in range to query
1227  *    abc       [O] Address of character-width structure
1228  *
1229  * NOTES
1230  *    Only works with TrueType fonts
1231  *
1232  * RETURNS
1233  *    Success: TRUE
1234  *    Failure: FALSE
1235  */
1236 BOOL32 WINAPI GetCharABCWidths32W( HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
1237                                    LPABC32 abc )
1238 {
1239     /* No TrueType fonts in Wine so far */
1240     FIXME(font, "(%04x,%04x,%04x,%p): stub\n", hdc, firstChar, lastChar, abc);
1241     return FALSE;
1242 }
1243
1244
1245 /***********************************************************************
1246  *           GetGlyphOutline16    (GDI.309)
1247  */
1248 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1249                                 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1250                                 LPVOID lpBuffer, const MAT2 *lpmat2 )
1251 {
1252     FIXME(font,"(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1253           hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1254     return (DWORD)-1; /* failure */
1255 }
1256
1257
1258 /***********************************************************************
1259  *           GetGlyphOutline32A    (GDI32.186)
1260  */
1261 DWORD WINAPI GetGlyphOutline32A( HDC32 hdc, UINT32 uChar, UINT32 fuFormat,
1262                                  LPGLYPHMETRICS32 lpgm, DWORD cbBuffer,
1263                                  LPVOID lpBuffer, const MAT2 *lpmat2 )
1264 {
1265     FIXME(font,"(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1266           hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1267     return (DWORD)-1; /* failure */
1268 }
1269
1270 /***********************************************************************
1271  *           GetGlyphOutline32W    (GDI32.187)
1272  */
1273 DWORD WINAPI GetGlyphOutline32W( HDC32 hdc, UINT32 uChar, UINT32 fuFormat,
1274                                  LPGLYPHMETRICS32 lpgm, DWORD cbBuffer,
1275                                  LPVOID lpBuffer, const MAT2 *lpmat2 )
1276 {
1277     FIXME(font,"(%04x, '%c', %04x, %p, %ld, %p, %p): stub\n",
1278           hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1279     return (DWORD)-1; /* failure */
1280 }
1281
1282 /***********************************************************************
1283  *           CreateScalableFontResource16   (GDI.310)
1284  */
1285 BOOL16 WINAPI CreateScalableFontResource16( UINT16 fHidden,
1286                                             LPCSTR lpszResourceFile,
1287                                             LPCSTR fontFile, LPCSTR path )
1288 {
1289     return CreateScalableFontResource32A( fHidden, lpszResourceFile,
1290                                           fontFile, path );
1291 }
1292
1293 /***********************************************************************
1294  *           CreateScalableFontResource32A   (GDI32.62)
1295  */
1296 BOOL32 WINAPI CreateScalableFontResource32A( DWORD fHidden,
1297                                              LPCSTR lpszResourceFile,
1298                                              LPCSTR lpszFontFile,
1299                                              LPCSTR lpszCurrentPath )
1300 {
1301     /* fHidden=1 - only visible for the calling app, read-only, not
1302      * enumbered with EnumFonts/EnumFontFamilies
1303      * lpszCurrentPath can be NULL
1304      */
1305     FIXME(font,"(%ld,%s,%s,%s): stub\n",
1306           fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1307     return FALSE; /* create failed */
1308 }
1309
1310 /***********************************************************************
1311  *           CreateScalableFontResource32W   (GDI32.63)
1312  */
1313 BOOL32 WINAPI CreateScalableFontResource32W( DWORD fHidden,
1314                                              LPCWSTR lpszResourceFile,
1315                                              LPCWSTR lpszFontFile,
1316                                              LPCWSTR lpszCurrentPath )
1317 {
1318     FIXME(font,"(%ld,%p,%p,%p): stub\n",
1319           fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1320     return FALSE; /* create failed */
1321 }
1322
1323
1324 /*************************************************************************
1325  *             GetRasterizerCaps16   (GDI.313)
1326  */
1327 BOOL16 WINAPI GetRasterizerCaps16( LPRASTERIZER_STATUS lprs, UINT16 cbNumBytes)
1328 {
1329     return GetRasterizerCaps32( lprs, cbNumBytes );
1330 }
1331
1332
1333 /*************************************************************************
1334  *             GetRasterizerCaps32   (GDI32.216)
1335  */
1336 BOOL32 WINAPI GetRasterizerCaps32( LPRASTERIZER_STATUS lprs, UINT32 cbNumBytes)
1337 {
1338   lprs->nSize = sizeof(RASTERIZER_STATUS);
1339   lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
1340   lprs->nLanguageID = 0;
1341   return TRUE;
1342 }
1343
1344
1345 /*************************************************************************
1346  *             GetKerningPairs16   (GDI.332)
1347  */
1348 INT16 WINAPI GetKerningPairs16( HDC16 hDC, INT16 cPairs,
1349                                 LPKERNINGPAIR16 lpKerningPairs )
1350 {
1351     /* At this time kerning is ignored (set to 0) */
1352     int i;
1353     FIXME(font,"(%x,%d,%p): almost empty stub!\n",
1354           hDC, cPairs, lpKerningPairs);
1355     for (i = 0; i < cPairs; i++) 
1356         lpKerningPairs[i].iKernAmount = 0;
1357     return 0;
1358 }
1359
1360
1361
1362 /*************************************************************************
1363  *             GetKerningPairs32A   (GDI32.192)
1364  */
1365 DWORD WINAPI GetKerningPairs32A( HDC32 hDC, DWORD cPairs,
1366                                  LPKERNINGPAIR32 lpKerningPairs )
1367 {
1368     int i;
1369     FIXME(font,"(%x,%ld,%p): almost empty stub!\n",
1370           hDC, cPairs, lpKerningPairs);
1371     for (i = 0; i < cPairs; i++) 
1372         lpKerningPairs[i].iKernAmount = 0;
1373     return 0;
1374 }
1375
1376
1377 /*************************************************************************
1378  *             GetKerningPairs32W   (GDI32.193)
1379  */
1380 DWORD WINAPI GetKerningPairs32W( HDC32 hDC, DWORD cPairs,
1381                                  LPKERNINGPAIR32 lpKerningPairs )
1382 {
1383     return GetKerningPairs32A( hDC, cPairs, lpKerningPairs );
1384 }
1385
1386 /*************************************************************************
1387  * TranslateCharsetInfo [GDI32.382]
1388  *
1389  * Fills a CHARSETINFO structure for a character set, code page, or
1390  * font. This allows making the correspondance between different labelings
1391  * (character set, Windows, ANSI, and OEM codepages, and Unicode ranges) 
1392  * of the same encoding.
1393  *
1394  * Only one codepage will be set in lpCs->fs. If TCI_SRCFONTSIG is used,
1395  * only one codepage should be set in *lpSrc.
1396  *
1397  * RETURNS
1398  *   TRUE on success, FALSE on failure.
1399  *
1400  */
1401 BOOL32 WINAPI TranslateCharsetInfo(
1402   LPDWORD lpSrc, /*
1403        if flags == TCI_SRCFONTSIG: pointer to fsCsb of a FONTSIGNATURE
1404        if flags == TCI_SRCCHARSET: a character set value
1405        if flags == TCI_SRCCODEPAGE: a code page value
1406                  */
1407   LPCHARSETINFO lpCs, /* structure to receive charset information */
1408   DWORD flags /* determines interpretation of lpSrc */
1409 ) {
1410     int index = 0;
1411     switch (flags) {
1412     case TCI_SRCFONTSIG:
1413         while (!(*lpSrc>>index & 0x0001) && index<MAXTCIINDEX) index++;
1414       break;
1415     case TCI_SRCCODEPAGE:
1416       while ((UINT32) (lpSrc) != FONT_tci[index].ciACP && index < MAXTCIINDEX) index++;
1417       break;
1418     case TCI_SRCCHARSET:
1419       while ((UINT32) (lpSrc) != FONT_tci[index].ciCharset && index < MAXTCIINDEX) index++;
1420       break;
1421     default:
1422       return FALSE;
1423     }
1424     if (index >= MAXTCIINDEX || FONT_tci[index].ciCharset == DEFAULT_CHARSET) return FALSE;
1425     memcpy(lpCs, &FONT_tci[index], sizeof(CHARSETINFO));
1426     return TRUE;
1427 }
1428
1429 /*************************************************************************
1430  *             GetFontLanguageInfo   (GDI32.182)
1431  */
1432 DWORD WINAPI GetFontLanguageInfo32(HDC32 hdc) {
1433         /* return value 0 is correct for most cases anyway */
1434         FIXME(font,"(%x):stub!\n", hdc);
1435         return 0;
1436 }
1437
1438 /*************************************************************************
1439  *             GetFontLanguageInfo   (GDI.616)
1440  */
1441 DWORD WINAPI GetFontLanguageInfo16(HDC16 hdc) {
1442         /* return value 0 is correct for most cases anyway */
1443         FIXME(font,"(%x):stub!\n",hdc);
1444         return 0;
1445 }
1446
1447 /*************************************************************************
1448  * GetFontData32 [GDI32.181] Retrieve data for TrueType font
1449  *
1450  * RETURNS
1451  *
1452  * success: Number of bytes returned 
1453  * failure: GDI_ERROR
1454  *
1455  * NOTES
1456  *
1457  * Calls SetLastError()  
1458  *
1459  * BUGS
1460  *
1461  * Unimplemented
1462  */
1463 DWORD WINAPI GetFontData32(HDC32 hdc, DWORD table, DWORD offset, 
1464     LPVOID buffer, DWORD length)
1465 {
1466     FIXME(font, "(%x,%ld,%ld,%p,%ld): stub\n", 
1467         hdc, table, offset, buffer, length);
1468     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1469     return GDI_ERROR;
1470 }
1471
1472 /*************************************************************************
1473  * GetCharacterPlacement32A [GDI32.160]
1474  */
1475 DWORD WINAPI
1476 GetCharacterPlacement32A(HDC32 hdc, LPCSTR lpString, INT32 uCount,
1477                          INT32 nMaxExtent, GCP_RESULTS32A *lpResults,
1478                          DWORD dwFlags)
1479 {
1480     /* return value 0 is correct for most cases anyway */
1481     FIXME(font,":stub!\n");
1482     return 0;
1483 }
1484
1485 /*************************************************************************
1486  * GetCharacterPlacement32W [GDI32.161]
1487  */
1488 DWORD WINAPI
1489 GetCharacterPlacement32W(HDC32 hdc, LPCWSTR lpString, INT32 uCount,
1490                          INT32 nMaxExtent, GCP_RESULTS32W *lpResults,
1491                          DWORD dwFlags)
1492 {
1493     /* return value 0 is correct for most cases anyway */
1494     FIXME(font,":stub!\n");
1495     return 0;
1496 }
1497
1498 /*************************************************************************
1499  *      GetCharABCWidthsFloat32A [GDI32.150]
1500  */
1501 BOOL32 WINAPI GetCharABCWidthsFloat32A(HDC32 hdc, UINT32 iFirstChar, UINT32 iLastChar,
1502                                         LPABCFLOAT lpABCF)
1503 {
1504        FIXME(gdi, "GetCharABCWidthsFloatA, stub\n");
1505        return 0;
1506 }
1507
1508 /*************************************************************************
1509  *      GetCharABCWidthsFloat32W [GDI32.151]
1510  */
1511 BOOL32 WINAPI GetCharABCWidthsFloat32W(HDC32 hdc, UINT32 iFirstChar,
1512                                         UINT32 iLastChar, LPABCFLOAT lpABCF)
1513 {
1514        FIXME(gdi, "GetCharABCWidthsFloatW, stub\n");
1515        return 0;
1516 }
1517
1518 /*************************************************************************
1519  *      GetCharWidthFloat32A [GDI32.156]
1520  */
1521 BOOL32 WINAPI GetCharWidthFloat32A(HDC32 hdc, UINT32 iFirstChar,
1522                                     UINT32 iLastChar, PFLOAT pxBuffer)
1523 {
1524        FIXME(gdi, "GetCharWidthFloatA, stub\n");
1525        return 0;
1526 }
1527
1528 /*************************************************************************
1529  *      GetCharWidthFloat32W [GDI32.157]
1530  */
1531 BOOL32 WINAPI GetCharWidthFloat32W(HDC32 hdc, UINT32 iFirstChar,
1532                                     UINT32 iLastChar, PFLOAT pxBuffer)
1533 {
1534        FIXME(gdi, "GetCharWidthFloatW, stub\n");
1535        return 0;
1536 }
1537