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