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