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