Release 970928
[wine] / objects / font.c
1 /*
2  * GDI font objects
3  *
4  * Copyright 1993 Alexandre Julliard
5  *           1997 Alex Korobka
6  */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include "font.h"
12 #include "heap.h"
13 #include "metafile.h"
14 #include "options.h"
15 #include "stddebug.h"
16 #include "debug.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   LPLOGFONT32W          lpLogFontParam;
35   FONTENUMPROC32W       lpEnumFunc;
36   LPARAM                lpData;
37
38   LPNEWTEXTMETRICEX32W  lpTextMetric;
39   LPENUMLOGFONTEX32W    lpLogFont;
40   DWORD                 dwFlags;
41 } fontEnum32;
42  
43 /***********************************************************************
44  *              LOGFONT conversion functions.
45  */
46 static void __logfont32to16( INT16* plf16, INT32* plf32 )
47 {
48     int  i;
49     for( i = 0; i < 5; i++ ) *plf16++ = *plf32++;
50    *((INT32*)plf16)++ = *plf32++;
51    *((INT32*)plf16)   = *plf32;
52 }
53
54 static void __logfont16to32( INT32* plf32, INT16* plf16 )
55 {
56     int i;
57     for( i = 0; i < 5; i++ ) *plf32++ = *plf16++;
58    *plf32++ = *((INT32*)plf16)++;
59    *plf32   = *((INT32*)plf16);
60 }
61
62 void FONT_LogFont32ATo16( const LOGFONT32A* font32, LPLOGFONT16 font16 )
63 {
64   __logfont32to16( (INT16*)font16, (INT32*)font32 );
65     lstrcpyn32A( font16->lfFaceName, font32->lfFaceName, LF_FACESIZE );
66 }
67
68 void FONT_LogFont32WTo16( const LOGFONT32W* font32, LPLOGFONT16 font16 )
69 {
70   __logfont32to16( (INT16*)font16, (INT32*)font32 );
71     lstrcpynWtoA( font16->lfFaceName, font32->lfFaceName, LF_FACESIZE );
72 }
73
74 void FONT_LogFont16To32A( LPLOGFONT16 font16, LPLOGFONT32A font32 )
75 {
76   __logfont16to32( (INT32*)font32, (INT16*)font16 );
77     lstrcpyn32A( font32->lfFaceName, font16->lfFaceName, LF_FACESIZE );
78 }
79
80 void FONT_LogFont16To32W( LPLOGFONT16 font16, LPLOGFONT32W font32 )
81 {
82   __logfont16to32( (INT32*)font32, (INT16*)font16 );
83     lstrcpynAtoW( font32->lfFaceName, font16->lfFaceName, LF_FACESIZE );
84 }
85
86 /***********************************************************************
87  *              TEXTMETRIC conversion functions.
88  */
89 void FONT_TextMetric32Ato16( LPTEXTMETRIC32A ptm32, LPTEXTMETRIC16 ptm16 )
90 {
91     int         i;
92     INT16*      pi16 = (INT16*)ptm16;
93
94    *(INT32*)&ptm16->tmFirstChar = *(INT32*)&ptm32->tmFirstChar;
95    *(INT32*)&ptm16->tmItalic = *(INT32*)&ptm32->tmItalic;
96    *(INT16*)&ptm16->tmPitchAndFamily = *(INT16*)&ptm32->tmPitchAndFamily;
97 #define pi32 ((INT32*)ptm32)
98     for( i = 0; i < 8; i++ ) *pi16++ = *pi32++;
99     ptm16->tmOverhang = pi32[0];
100     ptm16->tmDigitizedAspectX = pi32[1];
101     ptm16->tmDigitizedAspectY = pi32[2];
102 #undef  pi32
103 }
104
105 void FONT_TextMetric32Wto16( LPTEXTMETRIC32W ptm32, LPTEXTMETRIC16 ptm16 )
106 {
107     int         i;
108     INT16*      pi16 = (INT16*)ptm16;
109
110     ptm16->tmFirstChar = ptm32->tmFirstChar;
111     ptm16->tmLastChar = ptm32->tmLastChar;
112     ptm16->tmDefaultChar = ptm32->tmDefaultChar;
113     ptm16->tmBreakChar = ptm32->tmBreakChar;
114    *(INT32*)&ptm16->tmItalic = *(INT32*)&ptm32->tmItalic;
115    *(INT16*)&ptm16->tmPitchAndFamily = *(INT16*)&ptm32->tmPitchAndFamily;
116 #define pi32 ((INT32*)ptm32)
117     for( i = 0; i < 8; i++ ) *pi16++ = *pi32++;
118     ptm16->tmOverhang = pi32[0];
119     ptm16->tmDigitizedAspectX = pi32[1];
120     ptm16->tmDigitizedAspectY = pi32[2];
121 #undef  pi32
122 }
123
124 void FONT_TextMetric16to32A( LPTEXTMETRIC16 ptm16, LPTEXTMETRIC32A ptm32 )
125 {
126     int         i;
127     INT16*      pi16 = (INT16*)ptm16;
128
129    *(INT32*)&ptm32->tmFirstChar = *(INT32*)&ptm16->tmFirstChar;
130    *(INT32*)&ptm32->tmItalic = *(INT32*)&ptm16->tmItalic;
131    *(INT16*)&ptm32->tmPitchAndFamily = *(INT16*)&ptm16->tmPitchAndFamily;
132 #define pi32 ((INT32*)ptm32)
133     for( i = 0; i < 8; i++ ) *pi32++ = *pi16++;
134     pi32[0] = ptm16->tmOverhang;
135     pi32[1] = ptm16->tmDigitizedAspectX;
136     pi32[2] = ptm16->tmDigitizedAspectY;
137 #undef  pi32
138 }
139
140 void FONT_TextMetric16to32W( LPTEXTMETRIC16 ptm16, LPTEXTMETRIC32W ptm32 )
141 {
142     int         i;
143     INT16*      pi16 = (INT16*)ptm16;
144
145     ptm32->tmFirstChar = ptm16->tmFirstChar;
146     ptm32->tmLastChar = ptm16->tmLastChar;
147     ptm32->tmDefaultChar = ptm16->tmDefaultChar;
148     ptm32->tmBreakChar = ptm16->tmBreakChar;
149    *(INT32*)&ptm32->tmItalic = *(INT32*)&ptm16->tmItalic;
150    *(INT16*)&ptm32->tmPitchAndFamily = *(INT16*)&ptm16->tmPitchAndFamily;
151 #define pi32 ((INT32*)ptm32)
152     for( i = 0; i < 8; i++ ) *pi32++ = *pi16++;
153     pi32[0] = ptm16->tmOverhang;
154     pi32[1] = ptm16->tmDigitizedAspectX;
155     pi32[2] = ptm16->tmDigitizedAspectY;
156 #undef  pi32
157 }
158
159 void FONT_TextMetric32Ato32W( LPTEXTMETRIC32A ptm32A, LPTEXTMETRIC32W ptm32W )
160 {
161     int         i;
162 #define pi32A ((INT32*)ptm32A)
163 #define pi32W ((INT32*)ptm32W)
164     for( i = 0; i < 8; i++ ) *pi32W++ = *pi32A++;
165 #undef pi32W
166 #undef pi32A
167 #define pch32A ((BYTE*)ptm32A)
168 #define pch32W ((WCHAR*)ptm32W)
169    for( i = 0; i < 4; i++ ) *pch32W++ = *pch32A++;
170 #undef pch32W
171 #define pch32W ((BYTE*)ptm32W)
172    for( i = 0; i < 5; i++ ) *pch32W++ = *pch32A++;
173 #undef pch32W
174 #undef pch32A
175 }
176
177 /***********************************************************************
178  *           CreateFontIndirect16   (GDI.57)
179  */
180 HFONT16 WINAPI CreateFontIndirect16( const LOGFONT16 *font )
181 {
182     HFONT16 hFont = 0;
183
184     if (font)
185     {
186         hFont = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC );
187         if( hFont )
188         {
189             FONTOBJ* fontPtr;
190             fontPtr = (FONTOBJ *) GDI_HEAP_LOCK( hFont );
191             memcpy( &fontPtr->logfont, font, sizeof(LOGFONT16) );
192
193             dprintf_font(stddeb,"CreateFontIndirect(%i %i) '%s' %s %s => %04x\n",
194                                  font->lfHeight, font->lfWidth, 
195                                  font->lfFaceName ? font->lfFaceName : "NULL",
196                                  font->lfWeight > 400 ? "Bold" : "",
197                                  font->lfItalic ? "Italic" : "",
198                                  hFont);
199             GDI_HEAP_UNLOCK( hFont );
200         }
201     }
202     else fprintf(stderr,"CreateFontIndirect(NULL) => NULL\n");
203
204     return hFont;
205 }
206
207 /***********************************************************************
208  *           CreateFontIndirect32A   (GDI32.44)
209  */
210 HFONT32 WINAPI CreateFontIndirect32A( const LOGFONT32A *font )
211 {
212     LOGFONT16 font16;
213
214     FONT_LogFont32ATo16( font, &font16 );
215     return CreateFontIndirect16( &font16 );
216 }
217
218 /***********************************************************************
219  *           CreateFontIndirect32W   (GDI32.45)
220  */
221 HFONT32 WINAPI CreateFontIndirect32W( const LOGFONT32W *font )
222 {
223     LOGFONT16 font16;
224
225     FONT_LogFont32WTo16( font, &font16 );
226     return CreateFontIndirect16( &font16 );
227 }
228
229 /***********************************************************************
230  *           CreateFont16    (GDI.56)
231  */
232 HFONT16 WINAPI CreateFont16(INT16 height, INT16 width, INT16 esc, INT16 orient,
233                             INT16 weight, BYTE italic, BYTE underline,
234                             BYTE strikeout, BYTE charset, BYTE outpres,
235                             BYTE clippres, BYTE quality, BYTE pitch,
236                             LPCSTR name )
237 {
238     LOGFONT16 logfont = { height, width, esc, orient, weight, italic, underline,
239                           strikeout, charset, outpres, clippres, quality, pitch, };
240
241     dprintf_font(stddeb,"CreateFont16('%s',%d,%d)\n", name, height, width);
242     if (name) 
243         lstrcpyn32A(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
244     else 
245         logfont.lfFaceName[0] = '\0';
246     return CreateFontIndirect16( &logfont );
247 }
248
249 /*************************************************************************
250  *           CreateFont32A    (GDI32.43)
251  */
252 HFONT32 WINAPI CreateFont32A( INT32 height, INT32 width, INT32 esc,
253                               INT32 orient, INT32 weight, DWORD italic,
254                               DWORD underline, DWORD strikeout, DWORD charset,
255                               DWORD outpres, DWORD clippres, DWORD quality,
256                               DWORD pitch, LPCSTR name )
257 {
258     return (HFONT32)CreateFont16( height, width, esc, orient, weight, italic,
259                                   underline, strikeout, charset, outpres,
260                                   clippres, quality, pitch, name );
261 }
262
263 /*************************************************************************
264  *           CreateFont32W    (GDI32.46)
265  */
266 HFONT32 WINAPI CreateFont32W( INT32 height, INT32 width, INT32 esc,
267                               INT32 orient, INT32 weight, DWORD italic,
268                               DWORD underline, DWORD strikeout, DWORD charset,
269                               DWORD outpres, DWORD clippres, DWORD quality,
270                               DWORD pitch, LPCWSTR name )
271 {
272     LPSTR namea = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
273     HFONT32 ret = (HFONT32)CreateFont16( height, width, esc, orient, weight,
274                                          italic, underline, strikeout, charset,
275                                          outpres, clippres, quality, pitch,
276                                          namea );
277     HeapFree( GetProcessHeap(), 0, namea );
278     return ret;
279 }
280
281
282 /***********************************************************************
283  *           FONT_GetObject16
284  */
285 INT16 FONT_GetObject16( FONTOBJ * font, INT16 count, LPSTR buffer )
286 {
287     if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
288     memcpy( buffer, &font->logfont, count );
289     return count;
290 }
291
292 /***********************************************************************
293  *           FONT_GetObject32A
294  */
295 INT32 FONT_GetObject32A( FONTOBJ *font, INT32 count, LPSTR buffer )
296 {
297     LOGFONT32A fnt32;
298
299     FONT_LogFont16To32A( &font->logfont, &fnt32 );
300
301     if (count > sizeof(fnt32)) count = sizeof(fnt32);
302     memcpy( buffer, &fnt32, count );
303     return count;
304 }
305
306
307 /***********************************************************************
308  *              FONT_EnumInstance16
309  *
310  * Called by the device driver layer to pass font info
311  * down to the application.
312  */
313 static INT32 FONT_EnumInstance16( LPENUMLOGFONT16 plf, 
314                                   LPNEWTEXTMETRIC16 ptm, UINT16 fType, LPARAM lp )
315 {
316 #define pfe ((fontEnum16*)lp)
317     if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET || 
318         pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
319     {
320         memcpy( pfe->lpLogFont, plf, sizeof(ENUMLOGFONT16) );
321         memcpy( pfe->lpTextMetric, ptm, sizeof(NEWTEXTMETRIC16) );
322
323         return pfe->lpEnumFunc( pfe->segLogFont, pfe->segTextMetric, fType, (LPARAM)(pfe->lpData) );
324     }
325 #undef pfe
326     return 1;
327 }
328
329 /***********************************************************************
330  *              FONT_EnumInstance32
331  */
332 static INT32 FONT_EnumInstance32( LPENUMLOGFONT16 plf,
333                                   LPNEWTEXTMETRIC16 ptm, UINT16 fType, LPARAM lp )
334 {
335     /* lfCharSet is at the same offset in both LOGFONT32A and LOGFONT32W */
336
337 #define pfe ((fontEnum32*)lp)
338     if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET || 
339         pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
340     {
341         /* convert font metrics */
342
343         if( pfe->dwFlags & ENUM_UNICODE )
344         {
345             FONT_LogFont16To32W( &plf->elfLogFont, (LPLOGFONT32W)(pfe->lpLogFont) );
346             FONT_TextMetric16to32W( (LPTEXTMETRIC16)ptm, (LPTEXTMETRIC32W)(pfe->lpTextMetric) );
347         }
348         else
349         {
350             FONT_LogFont16To32A( &plf->elfLogFont, (LPLOGFONT32A)pfe->lpLogFont );
351             FONT_TextMetric16to32A( (LPTEXTMETRIC16)ptm, (LPTEXTMETRIC32A)pfe->lpTextMetric );
352         }
353
354         return pfe->lpEnumFunc( (LPENUMLOGFONT32W)pfe->lpLogFont, 
355                                 (LPNEWTEXTMETRIC32W)pfe->lpTextMetric, fType, pfe->lpData );
356     }
357 #undef pfe
358     return 1;
359 }
360
361 /***********************************************************************
362  *              EnumFontFamiliesEx16    (GDI.613)
363  */
364 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
365                                    FONTENUMPROCEX16 efproc, LPARAM lParam,
366                                    DWORD dwFlags)
367 {
368     INT16       retVal = 0;
369     DC*         dc = (DC*) GDI_GetObjPtr( hDC, DC_MAGIC );
370
371     if( dc && dc->funcs->pEnumDeviceFonts )
372     {
373         LPNEWTEXTMETRICEX16     lptm16 = SEGPTR_ALLOC( sizeof(NEWTEXTMETRICEX16) );
374         if( lptm16 )
375         {
376             LPENUMLOGFONTEX16   lplf16 = SEGPTR_ALLOC( sizeof(ENUMLOGFONTEX16) );
377             if( lplf16 )
378             {
379                 fontEnum16      fe16 = { plf, efproc, lParam, lptm16, lplf16, 
380                                          SEGPTR_GET(lptm16), SEGPTR_GET(lplf16) };
381
382                 retVal = dc->funcs->pEnumDeviceFonts( dc, plf, FONT_EnumInstance16, (LPARAM)&fe16 );
383
384                 SEGPTR_FREE(lplf16);
385             }
386             SEGPTR_FREE(lptm16);
387         }
388     }
389     return retVal;
390 }
391
392 /***********************************************************************
393  *              FONT_EnumFontFamiliesEx32
394  */
395 static INT32 FONT_EnumFontFamiliesEx32( HDC32 hDC, LPLOGFONT32W plf, FONTENUMPROC32W efproc, 
396                                                    LPARAM lParam, DWORD dwUnicode)
397 {
398     DC*         dc = (DC*) GDI_GetObjPtr( hDC, DC_MAGIC );
399
400     if( dc && dc->funcs->pEnumDeviceFonts )
401     {
402         LOGFONT16               lf16;
403         NEWTEXTMETRICEX32W      tm32w;
404         ENUMLOGFONTEX32W        lf32w;
405         fontEnum32              fe32 = { plf, efproc, lParam, &tm32w, &lf32w, dwUnicode }; 
406
407         /* the only difference between LOGFONT32A and LOGFONT32W is in the lfFaceName */
408
409         if( plf->lfFaceName[0] )
410         {
411             if( dwUnicode )
412                 lstrcpynWtoA( lf16.lfFaceName, plf->lfFaceName, LF_FACESIZE );
413             else
414                 lstrcpyn32A( lf16.lfFaceName, (LPCSTR)plf->lfFaceName, LF_FACESIZE );
415         }
416         else lf16.lfFaceName[0] = '\0';
417         lf16.lfCharSet = plf->lfCharSet;
418
419         return dc->funcs->pEnumDeviceFonts( dc, &lf16, FONT_EnumInstance32, (LPARAM)&fe32 );
420     }
421     return 0;
422 }
423
424 /***********************************************************************
425  *              EnumFontFamiliesEx32W   (GDI32.82)
426  */
427 INT32 WINAPI EnumFontFamiliesEx32W( HDC32 hDC, LPLOGFONT32W plf,
428                                     FONTENUMPROCEX32W efproc, 
429                                     LPARAM lParam, DWORD dwFlags )
430 {
431     return  FONT_EnumFontFamiliesEx32( hDC, plf, (FONTENUMPROC32W)efproc, 
432                                                   lParam, ENUM_UNICODE );
433 }
434
435 /***********************************************************************
436  *              EnumFontFamiliesEx32A   (GDI32.81)
437  */
438 INT32 WINAPI EnumFontFamiliesEx32A( HDC32 hDC, LPLOGFONT32A plf,
439                                     FONTENUMPROCEX32A efproc, 
440                                     LPARAM lParam, DWORD dwFlags)
441 {
442     return  FONT_EnumFontFamiliesEx32( hDC, (LPLOGFONT32W)plf, 
443                                       (FONTENUMPROC32W)efproc, lParam, 0);
444 }
445
446 /***********************************************************************
447  *              EnumFontFamilies16      (GDI.330)
448  */
449 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
450                                  FONTENUMPROC16 efproc, LPARAM lpData )
451 {
452     LOGFONT16   lf;
453
454     lf.lfCharSet = DEFAULT_CHARSET;
455     if( lpFamily ) lstrcpyn32A( lf.lfFaceName, lpFamily, LF_FACESIZE );
456     else lf.lfFaceName[0] = '\0';
457
458     return EnumFontFamiliesEx16( hDC, &lf, (FONTENUMPROCEX16)efproc, lpData, 0 );
459 }
460
461 /***********************************************************************
462  *              EnumFontFamilies32A     (GDI32.80)
463  */
464 INT32 WINAPI EnumFontFamilies32A( HDC32 hDC, LPCSTR lpFamily,
465                                   FONTENUMPROC32A efproc, LPARAM lpData )
466 {
467     LOGFONT32A  lf;
468
469     lf.lfCharSet = DEFAULT_CHARSET;
470     if( lpFamily ) lstrcpyn32A( lf.lfFaceName, lpFamily, LF_FACESIZE );
471     else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
472
473     return FONT_EnumFontFamiliesEx32( hDC, (LPLOGFONT32W)&lf, 
474                                            (FONTENUMPROC32W)efproc, lpData, 0 );
475 }
476
477 /***********************************************************************
478  *              EnumFontFamilies32W     (GDI32.83)
479  */
480 INT32 WINAPI EnumFontFamilies32W( HDC32 hDC, LPCWSTR lpFamily,
481                                   FONTENUMPROC32W efproc, LPARAM lpData )
482 {
483     LOGFONT32W  lf;
484
485     lf.lfCharSet = DEFAULT_CHARSET;
486     if( lpFamily ) lstrcpyn32W( lf.lfFaceName, lpFamily, LF_FACESIZE );
487     else lf.lfFaceName[0] = 0;
488
489     return FONT_EnumFontFamiliesEx32( hDC, &lf, efproc, lpData, ENUM_UNICODE );
490 }
491
492 /***********************************************************************
493  *              EnumFonts16             (GDI.70)
494  */
495 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
496                           LPARAM lpData )
497 {
498     return EnumFontFamilies16( hDC, lpName, (FONTENUMPROCEX16)efproc, lpData );
499 }
500
501 /***********************************************************************
502  *              EnumFonts32A            (GDI32.84)
503  */
504 INT32 WINAPI EnumFonts32A( HDC32 hDC, LPCSTR lpName, FONTENUMPROC32A efproc,
505                            LPARAM lpData )
506 {
507     return EnumFontFamilies32A( hDC, lpName, efproc, lpData );
508 }
509
510 /***********************************************************************
511  *              EnumFonts32W            (GDI32.85)
512  */
513 INT32 WINAPI EnumFonts32W( HDC32 hDC, LPCWSTR lpName, FONTENUMPROC32W efproc,
514                            LPARAM lpData )
515 {
516     return EnumFontFamilies32W( hDC, lpName, efproc, lpData );
517 }
518
519
520 /***********************************************************************
521  *           GetTextCharacterExtra16    (GDI.89)
522  */
523 INT16 WINAPI GetTextCharacterExtra16( HDC16 hdc )
524 {
525     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
526     if (!dc) return 0;
527     return abs( (dc->w.charExtra * dc->wndExtX + dc->vportExtX / 2)
528                  / dc->vportExtX );
529 }
530
531
532 /***********************************************************************
533  *           GetTextCharacterExtra32    (GDI32.225)
534  */
535 INT32 WINAPI GetTextCharacterExtra32( HDC32 hdc )
536 {
537     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
538     if (!dc) return 0;
539     return abs( (dc->w.charExtra * dc->wndExtX + dc->vportExtX / 2)
540                  / dc->vportExtX );
541 }
542
543
544 /***********************************************************************
545  *           SetTextCharacterExtra16    (GDI.8)
546  */
547 INT16 WINAPI SetTextCharacterExtra16( HDC16 hdc, INT16 extra )
548 {
549     return (INT16)SetTextCharacterExtra32( hdc, extra );
550 }
551
552
553 /***********************************************************************
554  *           SetTextCharacterExtra32    (GDI32.337)
555  */
556 INT32 WINAPI SetTextCharacterExtra32( HDC32 hdc, INT32 extra )
557 {
558     INT32 prev;
559     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
560     if (!dc) return 0;
561     extra = (extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX;
562     prev = dc->w.charExtra;
563     dc->w.charExtra = abs(extra);
564     return (prev * dc->wndExtX + dc->vportExtX / 2) / dc->vportExtX;
565 }
566
567
568 /***********************************************************************
569  *           SetTextJustification16    (GDI.10)
570  */
571 INT16 WINAPI SetTextJustification16( HDC16 hdc, INT16 extra, INT16 breaks )
572 {
573     return SetTextJustification32( hdc, extra, breaks );
574 }
575
576
577 /***********************************************************************
578  *           SetTextJustification32    (GDI32.339)
579  */
580 BOOL32 WINAPI SetTextJustification32( HDC32 hdc, INT32 extra, INT32 breaks )
581 {
582     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
583     if (!dc) return 0;
584
585     extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
586     if (!extra) breaks = 0;
587     dc->w.breakTotalExtra = extra;
588     dc->w.breakCount = breaks;
589     if (breaks)
590     {
591         dc->w.breakExtra = extra / breaks;
592         dc->w.breakRem   = extra - (dc->w.breakCount * dc->w.breakExtra);
593     }
594     else
595     {
596         dc->w.breakExtra = 0;
597         dc->w.breakRem   = 0;
598     }
599     return 1;
600 }
601
602
603 /***********************************************************************
604  *           GetTextFace16    (GDI.92)
605  */
606 INT16 WINAPI GetTextFace16( HDC16 hdc, INT16 count, LPSTR name )
607 {
608         return GetTextFace32A(hdc,count,name);
609 }
610
611 /***********************************************************************
612  *           GetTextFace32A    (GDI32.234)
613  */
614 INT32 WINAPI GetTextFace32A( HDC32 hdc, INT32 count, LPSTR name )
615 {
616     FONTOBJ *font;
617
618     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
619     if (!dc) return 0;
620     if (!(font = (FONTOBJ *) GDI_GetObjPtr( dc->w.hFont, FONT_MAGIC )))
621         return 0;
622     lstrcpyn32A( name, font->logfont.lfFaceName, count );
623     GDI_HEAP_UNLOCK( dc->w.hFont );
624     return strlen(name);
625 }
626
627 /***********************************************************************
628  *           GetTextFace32W    (GDI32.235)
629  */
630 INT32 WINAPI GetTextFace32W( HDC32 hdc, INT32 count, LPWSTR name )
631 {
632     LPSTR nameA = HeapAlloc( GetProcessHeap(), 0, count );
633     INT32 res = GetTextFace32A(hdc,count,nameA);
634     lstrcpyAtoW( name, nameA );
635     HeapFree( GetProcessHeap(), 0, nameA );
636     return res;
637 }
638
639
640 /***********************************************************************
641  *           GetTextExtent    (GDI.91)
642  */
643 DWORD WINAPI GetTextExtent( HDC16 hdc, LPCSTR str, INT16 count )
644 {
645     SIZE16 size;
646     if (!GetTextExtentPoint16( hdc, str, count, &size )) return 0;
647     return MAKELONG( size.cx, size.cy );
648 }
649
650
651 /***********************************************************************
652  *           GetTextExtentPoint16    (GDI.471)
653  *
654  * FIXME: Should this have a bug for compatibility?
655  * Original Windows versions of GetTextExtentPoint{A,W} have documented
656  * bugs.
657  */
658 BOOL16 WINAPI GetTextExtentPoint16( HDC16 hdc, LPCSTR str, INT16 count,
659                                     LPSIZE16 size )
660 {
661     SIZE32 size32;
662     BOOL32 ret = GetTextExtentPoint32A( hdc, str, count, &size32 );
663     CONV_SIZE32TO16( &size32, size );
664     return (BOOL16)ret;
665 }
666
667
668 /***********************************************************************
669  *           GetTextExtentPoint32A    (GDI32.230)
670  */
671 BOOL32 WINAPI GetTextExtentPoint32A( HDC32 hdc, LPCSTR str, INT32 count,
672                                      LPSIZE32 size )
673 {
674     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
675     if (!dc)
676     {
677         if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
678             return FALSE;
679     }
680
681     if (!dc->funcs->pGetTextExtentPoint ||
682         !dc->funcs->pGetTextExtentPoint( dc, str, count, size ))
683         return FALSE;
684
685     dprintf_font(stddeb,"GetTextExtentPoint(%08x '%.*s' %d %p): returning %d,%d\n",
686                  hdc, count, str, count, size, size->cx, size->cy );
687     return TRUE;
688 }
689
690
691 /***********************************************************************
692  *           GetTextExtentPoint32W    (GDI32.231)
693  */
694 BOOL32 WINAPI GetTextExtentPoint32W( HDC32 hdc, LPCWSTR str, INT32 count,
695                                      LPSIZE32 size )
696 {
697     LPSTR p = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
698     BOOL32 ret = GetTextExtentPoint32A( hdc, p, count, size );
699     HeapFree( GetProcessHeap(), 0, p );
700     return ret;
701 }
702
703
704 /***********************************************************************
705  *           GetTextExtentPoint32ABuggy    (GDI32.232)
706  */
707 BOOL32 WINAPI GetTextExtentPoint32ABuggy( HDC32 hdc, LPCSTR str, INT32 count,
708                                           LPSIZE32 size )
709 {
710     dprintf_font( stddeb, "GetTextExtentPoint32ABuggy: not bug compatible.\n");
711     return GetTextExtentPoint32A( hdc, str, count, size );
712 }
713
714 /***********************************************************************
715  *           GetTextExtentPoint32WBuggy    (GDI32.233)
716  */
717 BOOL32 WINAPI GetTextExtentPoint32WBuggy( HDC32 hdc, LPCWSTR str, INT32 count,
718                                           LPSIZE32 size )
719 {
720     dprintf_font( stddeb, "GetTextExtentPoint32WBuggy: not bug compatible.\n");
721     return GetTextExtentPoint32W( hdc, str, count, size );
722 }
723
724
725 /***********************************************************************
726  *           GetTextExtentExPoint32A    (GDI32.228)
727  */
728 BOOL32 WINAPI GetTextExtentExPoint32A( HDC32 hdc, LPCSTR str, INT32 count,
729                                        INT32 maxExt, LPINT32 lpnFit,
730                                        LPINT32 alpDx, LPSIZE32 size )
731 {
732     int index, nFit, extent;
733     SIZE32 tSize;
734     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
735
736     if (!dc)
737     {
738         if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
739             return FALSE;
740     }
741     if (!dc->funcs->pGetTextExtentPoint) return FALSE;
742
743     size->cx = size->cy = nFit = extent = 0;
744     for(index = 0; index < count; index++)
745     {
746         if(!dc->funcs->pGetTextExtentPoint( dc, str, 1, &tSize )) return FALSE;
747         if( extent+tSize.cx < maxExt )
748         {
749             extent+=tSize.cx;
750             nFit++;
751             str++;
752             if( alpDx ) alpDx[index] = extent;
753             if( tSize.cy > size->cy ) size->cy = tSize.cy;
754         }
755         else break;
756     }
757     size->cx = extent;
758    *lpnFit = nFit;
759
760     dprintf_font(stddeb,"GetTextExtentExPoint32A(%08x '%.*s' %d) returning %d %d %d\n",
761                hdc,count,str,maxExt,nFit, size->cx,size->cy);
762     return TRUE;
763 }
764
765
766 /***********************************************************************
767  *           GetTextExtentExPoint32W    (GDI32.229)
768  */
769
770 BOOL32 WINAPI GetTextExtentExPoint32W( HDC32 hdc, LPCWSTR str, INT32 count,
771                                        INT32 maxExt, LPINT32 lpnFit,
772                                        LPINT32 alpDx, LPSIZE32 size )
773 {
774     LPSTR p = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
775     BOOL32 ret = GetTextExtentExPoint32A( hdc, p, count, maxExt,
776                                         lpnFit, alpDx, size);
777     HeapFree( GetProcessHeap(), 0, p );
778     return ret;
779 }
780
781 /***********************************************************************
782  *           GetTextMetrics16    (GDI.93)
783  */
784 BOOL16 WINAPI GetTextMetrics16( HDC16 hdc, TEXTMETRIC16 *metrics )
785 {
786     TEXTMETRIC32A tm32;
787
788     if (!GetTextMetrics32A( (HDC32)hdc, &tm32 )) return FALSE;
789     FONT_TextMetric32Ato16( &tm32, metrics );
790     return TRUE;
791 }
792
793
794 /***********************************************************************
795  *           GetTextMetrics32A    (GDI32.236)
796  */
797 BOOL32 WINAPI GetTextMetrics32A( HDC32 hdc, TEXTMETRIC32A *metrics )
798 {
799     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
800     if (!dc)
801     {
802         if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
803             return FALSE;
804     }
805
806     if (!dc->funcs->pGetTextMetrics ||
807         !dc->funcs->pGetTextMetrics( dc, metrics ))
808         return FALSE;
809
810     /* device layer returns values in device units
811      * therefore we have to convert them to logical */
812
813 #define WDPTOLP(x) ((x<0)?                                      \
814                 (-abs((x)*dc->wndExtX/dc->vportExtX)):          \
815                 (abs((x)*dc->wndExtX/dc->vportExtX)))
816 #define HDPTOLP(y) ((y<0)?                                      \
817                 (-abs((y)*dc->wndExtY/dc->vportExtY)):          \
818                 (abs((y)*dc->wndExtY/dc->vportExtY)))
819         
820     metrics->tmHeight           = HDPTOLP(metrics->tmHeight);
821     metrics->tmAscent           = HDPTOLP(metrics->tmAscent);
822     metrics->tmDescent          = HDPTOLP(metrics->tmDescent);
823     metrics->tmInternalLeading  = HDPTOLP(metrics->tmInternalLeading);
824     metrics->tmExternalLeading  = HDPTOLP(metrics->tmExternalLeading);
825     metrics->tmAveCharWidth     = WDPTOLP(metrics->tmAveCharWidth);
826     metrics->tmMaxCharWidth     = WDPTOLP(metrics->tmMaxCharWidth);
827     metrics->tmOverhang         = WDPTOLP(metrics->tmOverhang);
828
829     dprintf_font(stddeb,"text metrics:
830     Weight = %03i\t FirstChar = %03i\t AveCharWidth = %i
831     Italic = % 3i\t LastChar = %03i\t\t MaxCharWidth = %i
832     UnderLined = %01i\t DefaultChar = %03i\t Overhang = %i
833     StruckOut = %01i\t BreakChar = %03i\t CharSet = %i
834     PitchAndFamily = %02x
835     --------------------
836     InternalLeading = %i
837     Ascent = %i
838     Descent = %i
839     Height = %i\n",
840     metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
841     metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
842     metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
843     metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
844     metrics->tmPitchAndFamily,
845     metrics->tmInternalLeading,
846     metrics->tmAscent,
847     metrics->tmDescent,
848     metrics->tmHeight );
849     return TRUE;
850 }
851
852
853 /***********************************************************************
854  *           GetTextMetrics32W    (GDI32.237)
855  */
856 BOOL32 WINAPI GetTextMetrics32W( HDC32 hdc, TEXTMETRIC32W *metrics )
857 {
858     TEXTMETRIC32A tm;
859     if (!GetTextMetrics32A( (HDC16)hdc, &tm )) return FALSE;
860     FONT_TextMetric32Ato32W( &tm, metrics );
861     return TRUE;
862 }
863
864
865 /***********************************************************************
866  *           GetCharWidth16    (GDI.350)
867  */
868 BOOL16 WINAPI GetCharWidth16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
869                               LPINT16 buffer )
870 {
871     BOOL32      retVal = FALSE;
872
873     if( firstChar != lastChar )
874     {
875         LPINT32 buf32 = (LPINT32)HeapAlloc(GetProcessHeap(), 0,
876                                  sizeof(INT32)*(1 + (lastChar - firstChar)));
877         if( buf32 )
878         {
879             LPINT32     obuf32 = buf32;
880             int         i;
881
882             retVal = GetCharWidth32A(hdc, firstChar, lastChar, buf32);
883             if (retVal)
884             {
885                 for (i = firstChar; i <= lastChar; i++)
886                     *buffer++ = *buf32++;
887             }
888             HeapFree(GetProcessHeap(), 0, obuf32);
889         }
890     }
891     else /* happens quite often to warrant a special treatment */
892     {
893         INT32 chWidth;
894         retVal = GetCharWidth32A(hdc, firstChar, lastChar, &chWidth );
895        *buffer = chWidth;
896     }
897     return retVal;
898 }
899
900
901 /***********************************************************************
902  *           GetCharWidth32A    (GDI32.155)
903  */
904 BOOL32 WINAPI GetCharWidth32A( HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
905                                LPINT32 buffer )
906 {
907     UINT32 i, extra;
908     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
909     if (!dc)
910     {
911         if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
912             return FALSE;
913     }
914
915     if (!dc->funcs->pGetCharWidth ||
916         !dc->funcs->pGetCharWidth( dc, firstChar, lastChar, buffer))
917         return FALSE;
918
919     /* convert device units to logical */
920
921     extra = dc->vportExtX >> 1;
922     for( i = firstChar; i <= lastChar; i++, buffer++ )
923          *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX;
924
925     return TRUE;
926 }
927
928
929 /***********************************************************************
930  *           GetCharWidth32W    (GDI32.158)
931  */
932 BOOL32 WINAPI GetCharWidth32W( HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
933                                LPINT32 buffer )
934 {
935     return GetCharWidth32A( hdc, firstChar, lastChar, buffer );
936 }
937
938
939
940 /* FIXME: all following APIs *******************************************
941  *
942  *
943  *           SetMapperFlags16    (GDI.349)
944  */
945 DWORD WINAPI SetMapperFlags16( HDC16 hDC, DWORD dwFlag )
946 {
947     return SetMapperFlags32( hDC, dwFlag );
948 }
949
950
951 /***********************************************************************
952  *           SetMapperFlags32    (GDI32.322)
953  */
954 DWORD WINAPI SetMapperFlags32( HDC32 hDC, DWORD dwFlag )
955 {
956     dprintf_font(stdnimp,"SetmapperFlags(%04x, %08lX) // Empty Stub !\n",
957                  hDC, dwFlag);
958     return 0L;
959 }
960
961 /***********************************************************************
962  *          GetAspectRatioFilterEx16  (GDI.486)
963  */
964 BOOL16 GetAspectRatioFilterEx16( HDC16 hdc, LPVOID pAspectRatio )
965 {
966   dprintf_font(stdnimp, 
967       "GetAspectRatioFilterEx(%04x, %p): // Empty Stub !\n",
968                hdc, pAspectRatio);
969   return FALSE;
970 }
971
972
973 /***********************************************************************
974  *           GetCharABCWidths16   (GDI.307)
975  */
976 BOOL16 WINAPI GetCharABCWidths16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
977                                   LPABC16 abc )
978 {
979     ABC32 abc32;
980     if (!GetCharABCWidths32A( hdc, firstChar, lastChar, &abc32 )) return FALSE;
981     abc->abcA = abc32.abcA;
982     abc->abcB = abc32.abcB;
983     abc->abcC = abc32.abcC;
984     return TRUE;
985 }
986
987
988 /***********************************************************************
989  *           GetCharABCWidths32A   (GDI32.149)
990  */
991 BOOL32 WINAPI GetCharABCWidths32A(HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
992                                   LPABC32 abc )
993 {
994     /* No TrueType fonts in Wine so far */
995     fprintf( stdnimp, "STUB: GetCharABCWidths(%04x,%04x,%04x,%p)\n",
996              hdc, firstChar, lastChar, abc );
997     return FALSE;
998 }
999
1000
1001 /***********************************************************************
1002  *           GetCharABCWidths32W   (GDI32.152)
1003  */
1004 BOOL32 WINAPI GetCharABCWidths32W(HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
1005                                   LPABC32 abc )
1006 {
1007     return GetCharABCWidths32A( hdc, firstChar, lastChar, abc );
1008 }
1009
1010
1011 /***********************************************************************
1012  *           GetGlyphOutline16    (GDI.309)
1013  */
1014 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1015                                 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1016                                 LPVOID lpBuffer, const MAT2 *lpmat2 )
1017 {
1018     fprintf( stdnimp,"GetGlyphOutLine16(%04x, '%c', %04x, %p, %ld, %p, %p) // - empty stub!\n",
1019              hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1020     return (DWORD)-1; /* failure */
1021 }
1022
1023
1024 /***********************************************************************
1025  *           GetGlyphOutline32A    (GDI32.186)
1026  */
1027 DWORD WINAPI GetGlyphOutline32A( HDC32 hdc, UINT32 uChar, UINT32 fuFormat,
1028                                  LPGLYPHMETRICS32 lpgm, DWORD cbBuffer,
1029                                  LPVOID lpBuffer, const MAT2 *lpmat2 )
1030 {
1031     fprintf( stdnimp,"GetGlyphOutLine32A(%04x, '%c', %04x, %p, %ld, %p, %p) // - empty stub!\n",
1032              hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1033     return (DWORD)-1; /* failure */
1034 }
1035
1036 /***********************************************************************
1037  *           GetGlyphOutline32W    (GDI32.187)
1038  */
1039 DWORD WINAPI GetGlyphOutline32W( HDC32 hdc, UINT32 uChar, UINT32 fuFormat,
1040                                  LPGLYPHMETRICS32 lpgm, DWORD cbBuffer,
1041                                  LPVOID lpBuffer, const MAT2 *lpmat2 )
1042 {
1043     fprintf( stdnimp,"GetGlyphOutLine32W(%04x, '%c', %04x, %p, %ld, %p, %p) // - empty stub!\n",
1044              hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1045     return (DWORD)-1; /* failure */
1046 }
1047
1048 /***********************************************************************
1049  *           CreateScalableFontResource16   (GDI.310)
1050  */
1051 BOOL16 WINAPI CreateScalableFontResource16( UINT16 fHidden,
1052                                             LPCSTR lpszResourceFile,
1053                                             LPCSTR fontFile, LPCSTR path )
1054 {
1055     return CreateScalableFontResource32A( fHidden, lpszResourceFile,
1056                                           fontFile, path );
1057 }
1058
1059 /***********************************************************************
1060  *           CreateScalableFontResource32A   (GDI32.62)
1061  */
1062 BOOL32 WINAPI CreateScalableFontResource32A( DWORD fHidden,
1063                                              LPCSTR lpszResourceFile,
1064                                              LPCSTR lpszFontFile,
1065                                              LPCSTR lpszCurrentPath )
1066 {
1067     /* fHidden=1 - only visible for the calling app, read-only, not
1068      * enumbered with EnumFonts/EnumFontFamilies
1069      * lpszCurrentPath can be NULL
1070      */
1071     fprintf(stdnimp,"CreateScalableFontResource(%ld,%s,%s,%s) // empty stub\n",
1072             fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1073     return FALSE; /* create failed */
1074 }
1075
1076 /***********************************************************************
1077  *           CreateScalableFontResource32W   (GDI32.63)
1078  */
1079 BOOL32 WINAPI CreateScalableFontResource32W( DWORD fHidden,
1080                                              LPCWSTR lpszResourceFile,
1081                                              LPCWSTR lpszFontFile,
1082                                              LPCWSTR lpszCurrentPath )
1083 {
1084     fprintf(stdnimp,"CreateScalableFontResource32W(%ld,%p,%p,%p) // empty stub\n",
1085             fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1086     return FALSE; /* create failed */
1087 }
1088
1089
1090 /*************************************************************************
1091  *             GetRasterizerCaps16   (GDI.313)
1092  */
1093 BOOL16 WINAPI GetRasterizerCaps16( LPRASTERIZER_STATUS lprs, UINT16 cbNumBytes)
1094 {
1095     return GetRasterizerCaps32( lprs, cbNumBytes );
1096 }
1097
1098
1099 /*************************************************************************
1100  *             GetRasterizerCaps32   (GDI32.216)
1101  */
1102 BOOL32 WINAPI GetRasterizerCaps32( LPRASTERIZER_STATUS lprs, UINT32 cbNumBytes)
1103 {
1104   RASTERIZER_STATUS rs;
1105
1106   rs.nSize = sizeof(rs);
1107   rs.wFlags = 0;
1108   rs.nLanguageID = 0;
1109   return TRUE;
1110 }
1111
1112
1113 /*************************************************************************
1114  *             GetKerningPairs16   (GDI.332)
1115  */
1116 INT16 WINAPI GetKerningPairs16( HDC16 hDC, INT16 cPairs,
1117                                 LPKERNINGPAIR16 lpKerningPairs )
1118 {
1119     /* At this time kerning is ignored (set to 0) */
1120     int i;
1121     fprintf(stdnimp,"GetKerningPairs16: almost empty stub!\n");
1122     for (i = 0; i < cPairs; i++) lpKerningPairs[i].iKernAmount = 0;
1123     return 0;
1124 }
1125
1126
1127
1128 /*************************************************************************
1129  *             GetKerningPairs32A   (GDI32.192)
1130  */
1131 DWORD WINAPI GetKerningPairs32A( HDC32 hDC, DWORD cPairs,
1132                                  LPKERNINGPAIR32 lpKerningPairs )
1133 {
1134     int i;
1135     fprintf(stdnimp,"GetKerningPairs32: almost empty stub!\n");
1136     for (i = 0; i < cPairs; i++) lpKerningPairs[i].iKernAmount = 0;
1137     return 0;
1138 }
1139
1140
1141 /*************************************************************************
1142  *             GetKerningPairs32W   (GDI32.193)
1143  */
1144 DWORD WINAPI GetKerningPairs32W( HDC32 hDC, DWORD cPairs,
1145                                  LPKERNINGPAIR32 lpKerningPairs )
1146 {
1147     return GetKerningPairs32A( hDC, cPairs, lpKerningPairs );
1148 }
1149
1150 BOOL32 WINAPI TranslateCharSetInfo(LPDWORD lpSrc,LPCHARSETINFO lpCs,DWORD dwFlags) {
1151     fprintf(stderr,"TranslateCharSetInfo(%p,%p,0x%08lx), stub.\n",
1152         lpSrc,lpCs,dwFlags
1153     );
1154     return TRUE;
1155 }
1156