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