Release 980329
[wine/multimedia.git] / objects / font.c
blob564a43c5844dcdca536fc0377520a259c1c7bfbf
1 /*
2 * GDI font objects
4 * Copyright 1993 Alexandre Julliard
5 * 1997 Alex Korobka
6 */
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 "debug.h"
17 #define ENUM_UNICODE 0x00000001
19 typedef struct
21 LPLOGFONT16 lpLogFontParam;
22 FONTENUMPROCEX16 lpEnumFunc;
23 LPARAM lpData;
25 LPNEWTEXTMETRICEX16 lpTextMetric;
26 LPENUMLOGFONTEX16 lpLogFont;
27 SEGPTR segTextMetric;
28 SEGPTR segLogFont;
29 } fontEnum16;
31 typedef struct
33 LPLOGFONT32W lpLogFontParam;
34 FONTENUMPROC32W lpEnumFunc;
35 LPARAM lpData;
37 LPNEWTEXTMETRICEX32W lpTextMetric;
38 LPENUMLOGFONTEX32W lpLogFont;
39 DWORD dwFlags;
40 } fontEnum32;
42 /***********************************************************************
43 * LOGFONT conversion functions.
45 static void __logfont32to16( INT16* plf16, const INT32* plf32 )
47 int i;
48 for( i = 0; i < 5; i++ ) *plf16++ = *plf32++;
49 *((INT32*)plf16)++ = *plf32++;
50 *((INT32*)plf16) = *plf32;
53 static void __logfont16to32( INT32* plf32, const INT16* plf16 )
55 int i;
56 for( i = 0; i < 5; i++ ) *plf32++ = *plf16++;
57 *plf32++ = *((INT32*)plf16)++;
58 *plf32 = *((INT32*)plf16);
61 void FONT_LogFont32ATo16( const LOGFONT32A* font32, LPLOGFONT16 font16 )
63 __logfont32to16( (INT16*)font16, (const INT32*)font32 );
64 lstrcpyn32A( font16->lfFaceName, font32->lfFaceName, LF_FACESIZE );
67 void FONT_LogFont32WTo16( const LOGFONT32W* font32, LPLOGFONT16 font16 )
69 __logfont32to16( (INT16*)font16, (const INT32*)font32 );
70 lstrcpynWtoA( font16->lfFaceName, font32->lfFaceName, LF_FACESIZE );
73 void FONT_LogFont16To32A( const LPLOGFONT16 font16, LPLOGFONT32A font32 )
75 __logfont16to32( (INT32*)font32, (const INT16*)font16 );
76 lstrcpyn32A( font32->lfFaceName, font16->lfFaceName, LF_FACESIZE );
79 void FONT_LogFont16To32W( const LPLOGFONT16 font16, LPLOGFONT32W font32 )
81 __logfont16to32( (INT32*)font32, (const INT16*)font16 );
82 lstrcpynAtoW( font32->lfFaceName, font16->lfFaceName, LF_FACESIZE );
85 /***********************************************************************
86 * TEXTMETRIC conversion functions.
88 void FONT_TextMetric32Ato16(const LPTEXTMETRIC32A ptm32, LPTEXTMETRIC16 ptm16 )
90 ptm16->tmHeight = ptm32->tmHeight;
91 ptm16->tmAscent = ptm32->tmAscent;
92 ptm16->tmDescent = ptm32->tmDescent;
93 ptm16->tmInternalLeading = ptm32->tmInternalLeading;
94 ptm16->tmExternalLeading = ptm32->tmExternalLeading;
95 ptm16->tmAveCharWidth = ptm32->tmAveCharWidth;
96 ptm16->tmMaxCharWidth = ptm32->tmMaxCharWidth;
97 ptm16->tmWeight = ptm32->tmWeight;
98 ptm16->tmOverhang = ptm32->tmOverhang;
99 ptm16->tmDigitizedAspectX = ptm32->tmDigitizedAspectX;
100 ptm16->tmDigitizedAspectY = ptm32->tmDigitizedAspectY;
101 ptm16->tmFirstChar = ptm32->tmFirstChar;
102 ptm16->tmLastChar = ptm32->tmLastChar;
103 ptm16->tmDefaultChar = ptm32->tmDefaultChar;
104 ptm16->tmBreakChar = ptm32->tmBreakChar;
105 ptm16->tmItalic = ptm32->tmItalic;
106 ptm16->tmUnderlined = ptm32->tmUnderlined;
107 ptm16->tmStruckOut = ptm32->tmStruckOut;
108 ptm16->tmPitchAndFamily = ptm32->tmPitchAndFamily;
109 ptm16->tmCharSet = ptm32->tmCharSet;
112 void FONT_TextMetric32Wto16(const LPTEXTMETRIC32W ptm32, LPTEXTMETRIC16 ptm16 )
114 ptm16->tmHeight = ptm32->tmHeight;
115 ptm16->tmAscent = ptm32->tmAscent;
116 ptm16->tmDescent = ptm32->tmDescent;
117 ptm16->tmInternalLeading = ptm32->tmInternalLeading;
118 ptm16->tmExternalLeading = ptm32->tmExternalLeading;
119 ptm16->tmAveCharWidth = ptm32->tmAveCharWidth;
120 ptm16->tmMaxCharWidth = ptm32->tmMaxCharWidth;
121 ptm16->tmWeight = ptm32->tmWeight;
122 ptm16->tmOverhang = ptm32->tmOverhang;
123 ptm16->tmDigitizedAspectX = ptm32->tmDigitizedAspectX;
124 ptm16->tmDigitizedAspectY = ptm32->tmDigitizedAspectY;
125 ptm16->tmFirstChar = ptm32->tmFirstChar;
126 ptm16->tmLastChar = ptm32->tmLastChar;
127 ptm16->tmDefaultChar = ptm32->tmDefaultChar;
128 ptm16->tmBreakChar = ptm32->tmBreakChar;
129 ptm16->tmItalic = ptm32->tmItalic;
130 ptm16->tmUnderlined = ptm32->tmUnderlined;
131 ptm16->tmStruckOut = ptm32->tmStruckOut;
132 ptm16->tmPitchAndFamily = ptm32->tmPitchAndFamily;
133 ptm16->tmCharSet = ptm32->tmCharSet;
136 void FONT_TextMetric16to32A(const LPTEXTMETRIC16 ptm16, LPTEXTMETRIC32A ptm32 )
138 ptm32->tmHeight = ptm16->tmHeight;
139 ptm32->tmAscent = ptm16->tmAscent;
140 ptm32->tmDescent = ptm16->tmDescent;
141 ptm32->tmInternalLeading = ptm16->tmInternalLeading;
142 ptm32->tmExternalLeading = ptm16->tmExternalLeading;
143 ptm32->tmAveCharWidth = ptm16->tmAveCharWidth;
144 ptm32->tmMaxCharWidth = ptm16->tmMaxCharWidth;
145 ptm32->tmWeight = ptm16->tmWeight;
146 ptm32->tmOverhang = ptm16->tmOverhang;
147 ptm32->tmDigitizedAspectX = ptm16->tmDigitizedAspectX;
148 ptm32->tmDigitizedAspectY = ptm16->tmDigitizedAspectY;
149 ptm32->tmFirstChar = ptm16->tmFirstChar;
150 ptm32->tmLastChar = ptm16->tmLastChar;
151 ptm32->tmDefaultChar = ptm16->tmDefaultChar;
152 ptm32->tmBreakChar = ptm16->tmBreakChar;
153 ptm32->tmItalic = ptm16->tmItalic;
154 ptm32->tmUnderlined = ptm16->tmUnderlined;
155 ptm32->tmStruckOut = ptm16->tmStruckOut;
156 ptm32->tmPitchAndFamily = ptm16->tmPitchAndFamily;
157 ptm32->tmCharSet = ptm16->tmCharSet;
160 void FONT_TextMetric16to32W(const LPTEXTMETRIC16 ptm16, LPTEXTMETRIC32W ptm32 )
162 ptm32->tmHeight = ptm16->tmHeight;
163 ptm32->tmAscent = ptm16->tmAscent;
164 ptm32->tmDescent = ptm16->tmDescent;
165 ptm32->tmInternalLeading = ptm16->tmInternalLeading;
166 ptm32->tmExternalLeading = ptm16->tmExternalLeading;
167 ptm32->tmAveCharWidth = ptm16->tmAveCharWidth;
168 ptm32->tmMaxCharWidth = ptm16->tmMaxCharWidth;
169 ptm32->tmWeight = ptm16->tmWeight;
170 ptm32->tmOverhang = ptm16->tmOverhang;
171 ptm32->tmDigitizedAspectX = ptm16->tmDigitizedAspectX;
172 ptm32->tmDigitizedAspectY = ptm16->tmDigitizedAspectY;
173 ptm32->tmFirstChar = ptm16->tmFirstChar;
174 ptm32->tmLastChar = ptm16->tmLastChar;
175 ptm32->tmDefaultChar = ptm16->tmDefaultChar;
176 ptm32->tmBreakChar = ptm16->tmBreakChar;
177 ptm32->tmItalic = ptm16->tmItalic;
178 ptm32->tmUnderlined = ptm16->tmUnderlined;
179 ptm32->tmStruckOut = ptm16->tmStruckOut;
180 ptm32->tmPitchAndFamily = ptm16->tmPitchAndFamily;
181 ptm32->tmCharSet = ptm16->tmCharSet;
184 void FONT_TextMetric32Ato32W(const LPTEXTMETRIC32A ptm32A, LPTEXTMETRIC32W ptm32W )
186 ptm32W->tmHeight = ptm32A->tmHeight;
187 ptm32W->tmAscent = ptm32A->tmAscent;
188 ptm32W->tmDescent = ptm32A->tmDescent;
189 ptm32W->tmInternalLeading = ptm32A->tmInternalLeading;
190 ptm32W->tmExternalLeading = ptm32A->tmExternalLeading;
191 ptm32W->tmAveCharWidth = ptm32A->tmAveCharWidth;
192 ptm32W->tmMaxCharWidth = ptm32A->tmMaxCharWidth;
193 ptm32W->tmWeight = ptm32A->tmWeight;
194 ptm32W->tmOverhang = ptm32A->tmOverhang;
195 ptm32W->tmDigitizedAspectX = ptm32A->tmDigitizedAspectX;
196 ptm32W->tmDigitizedAspectY = ptm32A->tmDigitizedAspectY;
197 ptm32W->tmFirstChar = ptm32A->tmFirstChar;
198 ptm32W->tmLastChar = ptm32A->tmLastChar;
199 ptm32W->tmDefaultChar = ptm32A->tmDefaultChar;
200 ptm32W->tmBreakChar = ptm32A->tmBreakChar;
201 ptm32W->tmItalic = ptm32A->tmItalic;
202 ptm32W->tmUnderlined = ptm32A->tmUnderlined;
203 ptm32W->tmStruckOut = ptm32A->tmStruckOut;
204 ptm32W->tmPitchAndFamily = ptm32A->tmPitchAndFamily;
205 ptm32W->tmCharSet = ptm32A->tmCharSet;
208 /***********************************************************************
209 * CreateFontIndirect16 (GDI.57)
211 HFONT16 WINAPI CreateFontIndirect16( const LOGFONT16 *font )
213 HFONT16 hFont = 0;
215 if (font)
217 hFont = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC );
218 if( hFont )
220 FONTOBJ* fontPtr;
221 fontPtr = (FONTOBJ *) GDI_HEAP_LOCK( hFont );
222 memcpy( &fontPtr->logfont, font, sizeof(LOGFONT16) );
224 TRACE(font,"(%i %i) '%s' %s %s => %04x\n",
225 font->lfHeight, font->lfWidth,
226 font->lfFaceName ? font->lfFaceName : "NULL",
227 font->lfWeight > 400 ? "Bold" : "",
228 font->lfItalic ? "Italic" : "",
229 hFont);
230 GDI_HEAP_UNLOCK( hFont );
233 else WARN(font,"(NULL) => NULL\n");
235 return hFont;
238 /***********************************************************************
239 * CreateFontIndirect32A (GDI32.44)
241 HFONT32 WINAPI CreateFontIndirect32A( const LOGFONT32A *font )
243 LOGFONT16 font16;
245 FONT_LogFont32ATo16( font, &font16 );
246 return CreateFontIndirect16( &font16 );
249 /***********************************************************************
250 * CreateFontIndirect32W (GDI32.45)
252 HFONT32 WINAPI CreateFontIndirect32W( const LOGFONT32W *font )
254 LOGFONT16 font16;
256 FONT_LogFont32WTo16( font, &font16 );
257 return CreateFontIndirect16( &font16 );
260 /***********************************************************************
261 * CreateFont16 (GDI.56)
263 HFONT16 WINAPI CreateFont16(INT16 height, INT16 width, INT16 esc, INT16 orient,
264 INT16 weight, BYTE italic, BYTE underline,
265 BYTE strikeout, BYTE charset, BYTE outpres,
266 BYTE clippres, BYTE quality, BYTE pitch,
267 LPCSTR name )
269 LOGFONT16 logfont = { height, width, esc, orient, weight, italic, underline,
270 strikeout, charset, outpres, clippres, quality, pitch, };
272 TRACE(font,"('%s',%d,%d)\n",
273 (name ? name : "(null)") , height, width);
274 if (name)
275 lstrcpyn32A(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
276 else
277 logfont.lfFaceName[0] = '\0';
278 return CreateFontIndirect16( &logfont );
281 /*************************************************************************
282 * CreateFont32A (GDI32.43)
284 HFONT32 WINAPI CreateFont32A( INT32 height, INT32 width, INT32 esc,
285 INT32 orient, INT32 weight, DWORD italic,
286 DWORD underline, DWORD strikeout, DWORD charset,
287 DWORD outpres, DWORD clippres, DWORD quality,
288 DWORD pitch, LPCSTR name )
290 return (HFONT32)CreateFont16( height, width, esc, orient, weight, italic,
291 underline, strikeout, charset, outpres,
292 clippres, quality, pitch, name );
295 /*************************************************************************
296 * CreateFont32W (GDI32.46)
298 HFONT32 WINAPI CreateFont32W( INT32 height, INT32 width, INT32 esc,
299 INT32 orient, INT32 weight, DWORD italic,
300 DWORD underline, DWORD strikeout, DWORD charset,
301 DWORD outpres, DWORD clippres, DWORD quality,
302 DWORD pitch, LPCWSTR name )
304 LPSTR namea = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
305 HFONT32 ret = (HFONT32)CreateFont16( height, width, esc, orient, weight,
306 italic, underline, strikeout, charset,
307 outpres, clippres, quality, pitch,
308 namea );
309 if (namea) HeapFree( GetProcessHeap(), 0, namea );
310 return ret;
314 /***********************************************************************
315 * FONT_GetObject16
317 INT16 FONT_GetObject16( FONTOBJ * font, INT16 count, LPSTR buffer )
319 if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
320 memcpy( buffer, &font->logfont, count );
321 return count;
324 /***********************************************************************
325 * FONT_GetObject32A
327 INT32 FONT_GetObject32A( FONTOBJ *font, INT32 count, LPSTR buffer )
329 LOGFONT32A fnt32;
331 FONT_LogFont16To32A( &font->logfont, &fnt32 );
333 if (count > sizeof(fnt32)) count = sizeof(fnt32);
334 memcpy( buffer, &fnt32, count );
335 return count;
339 /***********************************************************************
340 * FONT_EnumInstance16
342 * Called by the device driver layer to pass font info
343 * down to the application.
345 static INT32 FONT_EnumInstance16( LPENUMLOGFONT16 plf,
346 LPNEWTEXTMETRIC16 ptm, UINT16 fType, LPARAM lp )
348 #define pfe ((fontEnum16*)lp)
349 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
350 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
352 memcpy( pfe->lpLogFont, plf, sizeof(ENUMLOGFONT16) );
353 memcpy( pfe->lpTextMetric, ptm, sizeof(NEWTEXTMETRIC16) );
355 return pfe->lpEnumFunc( pfe->segLogFont, pfe->segTextMetric, fType, (LPARAM)(pfe->lpData) );
357 #undef pfe
358 return 1;
361 /***********************************************************************
362 * FONT_EnumInstance32
364 static INT32 FONT_EnumInstance32( LPENUMLOGFONT16 plf,
365 LPNEWTEXTMETRIC16 ptm, UINT16 fType, LPARAM lp )
367 /* lfCharSet is at the same offset in both LOGFONT32A and LOGFONT32W */
369 #define pfe ((fontEnum32*)lp)
370 if( pfe->lpLogFontParam->lfCharSet == DEFAULT_CHARSET ||
371 pfe->lpLogFontParam->lfCharSet == plf->elfLogFont.lfCharSet )
373 /* convert font metrics */
375 if( pfe->dwFlags & ENUM_UNICODE )
377 FONT_LogFont16To32W( &plf->elfLogFont, (LPLOGFONT32W)(pfe->lpLogFont) );
378 FONT_TextMetric16to32W( (LPTEXTMETRIC16)ptm, (LPTEXTMETRIC32W)(pfe->lpTextMetric) );
380 else
382 FONT_LogFont16To32A( &plf->elfLogFont, (LPLOGFONT32A)pfe->lpLogFont );
383 FONT_TextMetric16to32A( (LPTEXTMETRIC16)ptm, (LPTEXTMETRIC32A)pfe->lpTextMetric );
386 return pfe->lpEnumFunc( (LPENUMLOGFONT32W)pfe->lpLogFont,
387 (LPNEWTEXTMETRIC32W)pfe->lpTextMetric, fType, pfe->lpData );
389 #undef pfe
390 return 1;
393 /***********************************************************************
394 * EnumFontFamiliesEx16 (GDI.613)
396 INT16 WINAPI EnumFontFamiliesEx16( HDC16 hDC, LPLOGFONT16 plf,
397 FONTENUMPROCEX16 efproc, LPARAM lParam,
398 DWORD dwFlags)
400 INT16 retVal = 0;
401 DC* dc = (DC*) GDI_GetObjPtr( hDC, DC_MAGIC );
403 if( dc && dc->funcs->pEnumDeviceFonts )
405 LPNEWTEXTMETRICEX16 lptm16 = SEGPTR_ALLOC( sizeof(NEWTEXTMETRICEX16) );
406 if( lptm16 )
408 LPENUMLOGFONTEX16 lplf16 = SEGPTR_ALLOC( sizeof(ENUMLOGFONTEX16) );
409 if( lplf16 )
411 fontEnum16 fe16 = { plf, efproc, lParam, lptm16, lplf16,
412 SEGPTR_GET(lptm16), SEGPTR_GET(lplf16) };
414 retVal = dc->funcs->pEnumDeviceFonts( dc, plf, FONT_EnumInstance16, (LPARAM)&fe16 );
416 SEGPTR_FREE(lplf16);
418 SEGPTR_FREE(lptm16);
421 return retVal;
424 /***********************************************************************
425 * FONT_EnumFontFamiliesEx32
427 static INT32 FONT_EnumFontFamiliesEx32( HDC32 hDC, LPLOGFONT32W plf, FONTENUMPROC32W efproc,
428 LPARAM lParam, DWORD dwUnicode)
430 DC* dc = (DC*) GDI_GetObjPtr( hDC, DC_MAGIC );
432 if( dc && dc->funcs->pEnumDeviceFonts )
434 LOGFONT16 lf16;
435 NEWTEXTMETRICEX32W tm32w;
436 ENUMLOGFONTEX32W lf32w;
437 fontEnum32 fe32 = { plf, efproc, lParam, &tm32w, &lf32w, dwUnicode };
439 /* the only difference between LOGFONT32A and LOGFONT32W is in the lfFaceName */
441 if( plf->lfFaceName[0] )
443 if( dwUnicode )
444 lstrcpynWtoA( lf16.lfFaceName, plf->lfFaceName, LF_FACESIZE );
445 else
446 lstrcpyn32A( lf16.lfFaceName, (LPCSTR)plf->lfFaceName, LF_FACESIZE );
448 else lf16.lfFaceName[0] = '\0';
449 lf16.lfCharSet = plf->lfCharSet;
451 return dc->funcs->pEnumDeviceFonts( dc, &lf16, FONT_EnumInstance32, (LPARAM)&fe32 );
453 return 0;
456 /***********************************************************************
457 * EnumFontFamiliesEx32W (GDI32.82)
459 INT32 WINAPI EnumFontFamiliesEx32W( HDC32 hDC, LPLOGFONT32W plf,
460 FONTENUMPROCEX32W efproc,
461 LPARAM lParam, DWORD dwFlags )
463 return FONT_EnumFontFamiliesEx32( hDC, plf, (FONTENUMPROC32W)efproc,
464 lParam, ENUM_UNICODE );
467 /***********************************************************************
468 * EnumFontFamiliesEx32A (GDI32.81)
470 INT32 WINAPI EnumFontFamiliesEx32A( HDC32 hDC, LPLOGFONT32A plf,
471 FONTENUMPROCEX32A efproc,
472 LPARAM lParam, DWORD dwFlags)
474 return FONT_EnumFontFamiliesEx32( hDC, (LPLOGFONT32W)plf,
475 (FONTENUMPROC32W)efproc, lParam, 0);
478 /***********************************************************************
479 * EnumFontFamilies16 (GDI.330)
481 INT16 WINAPI EnumFontFamilies16( HDC16 hDC, LPCSTR lpFamily,
482 FONTENUMPROC16 efproc, LPARAM lpData )
484 LOGFONT16 lf;
486 lf.lfCharSet = DEFAULT_CHARSET;
487 if( lpFamily ) lstrcpyn32A( lf.lfFaceName, lpFamily, LF_FACESIZE );
488 else lf.lfFaceName[0] = '\0';
490 return EnumFontFamiliesEx16( hDC, &lf, (FONTENUMPROCEX16)efproc, lpData, 0 );
493 /***********************************************************************
494 * EnumFontFamilies32A (GDI32.80)
496 INT32 WINAPI EnumFontFamilies32A( HDC32 hDC, LPCSTR lpFamily,
497 FONTENUMPROC32A efproc, LPARAM lpData )
499 LOGFONT32A lf;
501 lf.lfCharSet = DEFAULT_CHARSET;
502 if( lpFamily ) lstrcpyn32A( lf.lfFaceName, lpFamily, LF_FACESIZE );
503 else lf.lfFaceName[0] = lf.lfFaceName[1] = '\0';
505 return FONT_EnumFontFamiliesEx32( hDC, (LPLOGFONT32W)&lf,
506 (FONTENUMPROC32W)efproc, lpData, 0 );
509 /***********************************************************************
510 * EnumFontFamilies32W (GDI32.83)
512 INT32 WINAPI EnumFontFamilies32W( HDC32 hDC, LPCWSTR lpFamily,
513 FONTENUMPROC32W efproc, LPARAM lpData )
515 LOGFONT32W lf;
517 lf.lfCharSet = DEFAULT_CHARSET;
518 if( lpFamily ) lstrcpyn32W( lf.lfFaceName, lpFamily, LF_FACESIZE );
519 else lf.lfFaceName[0] = 0;
521 return FONT_EnumFontFamiliesEx32( hDC, &lf, efproc, lpData, ENUM_UNICODE );
524 /***********************************************************************
525 * EnumFonts16 (GDI.70)
527 INT16 WINAPI EnumFonts16( HDC16 hDC, LPCSTR lpName, FONTENUMPROC16 efproc,
528 LPARAM lpData )
530 return EnumFontFamilies16( hDC, lpName, (FONTENUMPROCEX16)efproc, lpData );
533 /***********************************************************************
534 * EnumFonts32A (GDI32.84)
536 INT32 WINAPI EnumFonts32A( HDC32 hDC, LPCSTR lpName, FONTENUMPROC32A efproc,
537 LPARAM lpData )
539 return EnumFontFamilies32A( hDC, lpName, efproc, lpData );
542 /***********************************************************************
543 * EnumFonts32W (GDI32.85)
545 INT32 WINAPI EnumFonts32W( HDC32 hDC, LPCWSTR lpName, FONTENUMPROC32W efproc,
546 LPARAM lpData )
548 return EnumFontFamilies32W( hDC, lpName, efproc, lpData );
552 /***********************************************************************
553 * GetTextCharacterExtra16 (GDI.89)
555 INT16 WINAPI GetTextCharacterExtra16( HDC16 hdc )
557 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
558 if (!dc) return 0;
559 return abs( (dc->w.charExtra * dc->wndExtX + dc->vportExtX / 2)
560 / dc->vportExtX );
564 /***********************************************************************
565 * GetTextCharacterExtra32 (GDI32.225)
567 INT32 WINAPI GetTextCharacterExtra32( HDC32 hdc )
569 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
570 if (!dc) return 0;
571 return abs( (dc->w.charExtra * dc->wndExtX + dc->vportExtX / 2)
572 / dc->vportExtX );
576 /***********************************************************************
577 * SetTextCharacterExtra16 (GDI.8)
579 INT16 WINAPI SetTextCharacterExtra16( HDC16 hdc, INT16 extra )
581 return (INT16)SetTextCharacterExtra32( hdc, extra );
585 /***********************************************************************
586 * SetTextCharacterExtra32 (GDI32.337)
588 INT32 WINAPI SetTextCharacterExtra32( HDC32 hdc, INT32 extra )
590 INT32 prev;
591 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
592 if (!dc) return 0;
593 extra = (extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX;
594 prev = dc->w.charExtra;
595 dc->w.charExtra = abs(extra);
596 return (prev * dc->wndExtX + dc->vportExtX / 2) / dc->vportExtX;
600 /***********************************************************************
601 * SetTextJustification16 (GDI.10)
603 INT16 WINAPI SetTextJustification16( HDC16 hdc, INT16 extra, INT16 breaks )
605 return SetTextJustification32( hdc, extra, breaks );
609 /***********************************************************************
610 * SetTextJustification32 (GDI32.339)
612 BOOL32 WINAPI SetTextJustification32( HDC32 hdc, INT32 extra, INT32 breaks )
614 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
615 if (!dc) return 0;
617 extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
618 if (!extra) breaks = 0;
619 dc->w.breakTotalExtra = extra;
620 dc->w.breakCount = breaks;
621 if (breaks)
623 dc->w.breakExtra = extra / breaks;
624 dc->w.breakRem = extra - (dc->w.breakCount * dc->w.breakExtra);
626 else
628 dc->w.breakExtra = 0;
629 dc->w.breakRem = 0;
631 return 1;
635 /***********************************************************************
636 * GetTextFace16 (GDI.92)
638 INT16 WINAPI GetTextFace16( HDC16 hdc, INT16 count, LPSTR name )
640 return GetTextFace32A(hdc,count,name);
643 /***********************************************************************
644 * GetTextFace32A (GDI32.234)
646 INT32 WINAPI GetTextFace32A( HDC32 hdc, INT32 count, LPSTR name )
648 FONTOBJ *font;
650 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
651 if (!dc) return 0;
652 if (!(font = (FONTOBJ *) GDI_GetObjPtr( dc->w.hFont, FONT_MAGIC )))
653 return 0;
654 lstrcpyn32A( name, font->logfont.lfFaceName, count );
655 GDI_HEAP_UNLOCK( dc->w.hFont );
656 return strlen(name);
659 /***********************************************************************
660 * GetTextFace32W (GDI32.235)
662 INT32 WINAPI GetTextFace32W( HDC32 hdc, INT32 count, LPWSTR name )
664 LPSTR nameA = HeapAlloc( GetProcessHeap(), 0, count );
665 INT32 res = GetTextFace32A(hdc,count,nameA);
666 lstrcpyAtoW( name, nameA );
667 HeapFree( GetProcessHeap(), 0, nameA );
668 return res;
672 /***********************************************************************
673 * GetTextExtent (GDI.91)
675 DWORD WINAPI GetTextExtent( HDC16 hdc, LPCSTR str, INT16 count )
677 SIZE16 size;
678 if (!GetTextExtentPoint16( hdc, str, count, &size )) return 0;
679 return MAKELONG( size.cx, size.cy );
683 /***********************************************************************
684 * GetTextExtentPoint16 (GDI.471)
686 * FIXME: Should this have a bug for compatibility?
687 * Original Windows versions of GetTextExtentPoint{A,W} have documented
688 * bugs.
690 BOOL16 WINAPI GetTextExtentPoint16( HDC16 hdc, LPCSTR str, INT16 count,
691 LPSIZE16 size )
693 SIZE32 size32;
694 BOOL32 ret = GetTextExtentPoint32A( hdc, str, count, &size32 );
695 CONV_SIZE32TO16( &size32, size );
696 return (BOOL16)ret;
700 /***********************************************************************
701 * GetTextExtentPoint32A (GDI32.230)
703 BOOL32 WINAPI GetTextExtentPoint32A( HDC32 hdc, LPCSTR str, INT32 count,
704 LPSIZE32 size )
706 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
707 if (!dc)
709 if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
710 return FALSE;
713 if (!dc->funcs->pGetTextExtentPoint ||
714 !dc->funcs->pGetTextExtentPoint( dc, str, count, size ))
715 return FALSE;
717 TRACE(font,"(%08x %s %d %p): returning %d,%d\n",
718 hdc, debugstr_an (str, count), count,
719 size, size->cx, size->cy );
720 return TRUE;
724 /***********************************************************************
725 * GetTextExtentPoint32W (GDI32.231)
727 BOOL32 WINAPI GetTextExtentPoint32W( HDC32 hdc, LPCWSTR str, INT32 count,
728 LPSIZE32 size )
730 LPSTR p = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
731 BOOL32 ret = GetTextExtentPoint32A( hdc, p, count, size );
732 HeapFree( GetProcessHeap(), 0, p );
733 return ret;
737 /***********************************************************************
738 * GetTextExtentPoint32ABuggy (GDI32.232)
740 BOOL32 WINAPI GetTextExtentPoint32ABuggy( HDC32 hdc, LPCSTR str, INT32 count,
741 LPSIZE32 size )
743 TRACE(font, "not bug compatible.\n");
744 return GetTextExtentPoint32A( hdc, str, count, size );
747 /***********************************************************************
748 * GetTextExtentPoint32WBuggy (GDI32.233)
750 BOOL32 WINAPI GetTextExtentPoint32WBuggy( HDC32 hdc, LPCWSTR str, INT32 count,
751 LPSIZE32 size )
753 TRACE(font, "not bug compatible.\n");
754 return GetTextExtentPoint32W( hdc, str, count, size );
758 /***********************************************************************
759 * GetTextExtentExPoint32A (GDI32.228)
761 BOOL32 WINAPI GetTextExtentExPoint32A( HDC32 hdc, LPCSTR str, INT32 count,
762 INT32 maxExt, LPINT32 lpnFit,
763 LPINT32 alpDx, LPSIZE32 size )
765 int index, nFit, extent;
766 SIZE32 tSize;
767 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
769 if (!dc)
771 if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
772 return FALSE;
774 if (!dc->funcs->pGetTextExtentPoint) return FALSE;
776 size->cx = size->cy = nFit = extent = 0;
777 for(index = 0; index < count; index++)
779 if(!dc->funcs->pGetTextExtentPoint( dc, str, 1, &tSize )) return FALSE;
780 if( extent+tSize.cx < maxExt )
782 extent+=tSize.cx;
783 nFit++;
784 str++;
785 if( alpDx ) alpDx[index] = extent;
786 if( tSize.cy > size->cy ) size->cy = tSize.cy;
788 else break;
790 size->cx = extent;
791 *lpnFit = nFit;
793 TRACE(font,"(%08x '%.*s' %d) returning %d %d %d\n",
794 hdc,count,str,maxExt,nFit, size->cx,size->cy);
795 return TRUE;
799 /***********************************************************************
800 * GetTextExtentExPoint32W (GDI32.229)
803 BOOL32 WINAPI GetTextExtentExPoint32W( HDC32 hdc, LPCWSTR str, INT32 count,
804 INT32 maxExt, LPINT32 lpnFit,
805 LPINT32 alpDx, LPSIZE32 size )
807 LPSTR p = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
808 BOOL32 ret = GetTextExtentExPoint32A( hdc, p, count, maxExt,
809 lpnFit, alpDx, size);
810 HeapFree( GetProcessHeap(), 0, p );
811 return ret;
814 /***********************************************************************
815 * GetTextMetrics16 (GDI.93)
817 BOOL16 WINAPI GetTextMetrics16( HDC16 hdc, TEXTMETRIC16 *metrics )
819 TEXTMETRIC32A tm32;
821 if (!GetTextMetrics32A( (HDC32)hdc, &tm32 )) return FALSE;
822 FONT_TextMetric32Ato16( &tm32, metrics );
823 return TRUE;
827 /***********************************************************************
828 * GetTextMetrics32A (GDI32.236)
830 BOOL32 WINAPI GetTextMetrics32A( HDC32 hdc, TEXTMETRIC32A *metrics )
832 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
833 if (!dc)
835 if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
836 return FALSE;
839 if (!dc->funcs->pGetTextMetrics ||
840 !dc->funcs->pGetTextMetrics( dc, metrics ))
841 return FALSE;
843 /* device layer returns values in device units
844 * therefore we have to convert them to logical */
846 #define WDPTOLP(x) ((x<0)? \
847 (-abs((x)*dc->wndExtX/dc->vportExtX)): \
848 (abs((x)*dc->wndExtX/dc->vportExtX)))
849 #define HDPTOLP(y) ((y<0)? \
850 (-abs((y)*dc->wndExtY/dc->vportExtY)): \
851 (abs((y)*dc->wndExtY/dc->vportExtY)))
853 metrics->tmHeight = HDPTOLP(metrics->tmHeight);
854 metrics->tmAscent = HDPTOLP(metrics->tmAscent);
855 metrics->tmDescent = HDPTOLP(metrics->tmDescent);
856 metrics->tmInternalLeading = HDPTOLP(metrics->tmInternalLeading);
857 metrics->tmExternalLeading = HDPTOLP(metrics->tmExternalLeading);
858 metrics->tmAveCharWidth = WDPTOLP(metrics->tmAveCharWidth);
859 metrics->tmMaxCharWidth = WDPTOLP(metrics->tmMaxCharWidth);
860 metrics->tmOverhang = WDPTOLP(metrics->tmOverhang);
862 TRACE(font,"text metrics:
863 Weight = %03i\t FirstChar = %03i\t AveCharWidth = %i
864 Italic = % 3i\t LastChar = %03i\t\t MaxCharWidth = %i
865 UnderLined = %01i\t DefaultChar = %03i\t Overhang = %i
866 StruckOut = %01i\t BreakChar = %03i\t CharSet = %i
867 PitchAndFamily = %02x
868 --------------------
869 InternalLeading = %i
870 Ascent = %i
871 Descent = %i
872 Height = %i\n",
873 metrics->tmWeight, metrics->tmFirstChar, metrics->tmAveCharWidth,
874 metrics->tmItalic, metrics->tmLastChar, metrics->tmMaxCharWidth,
875 metrics->tmUnderlined, metrics->tmDefaultChar, metrics->tmOverhang,
876 metrics->tmStruckOut, metrics->tmBreakChar, metrics->tmCharSet,
877 metrics->tmPitchAndFamily,
878 metrics->tmInternalLeading,
879 metrics->tmAscent,
880 metrics->tmDescent,
881 metrics->tmHeight );
882 return TRUE;
886 /***********************************************************************
887 * GetTextMetrics32W (GDI32.237)
889 BOOL32 WINAPI GetTextMetrics32W( HDC32 hdc, TEXTMETRIC32W *metrics )
891 TEXTMETRIC32A tm;
892 if (!GetTextMetrics32A( (HDC16)hdc, &tm )) return FALSE;
893 FONT_TextMetric32Ato32W( &tm, metrics );
894 return TRUE;
898 /***********************************************************************
899 * GetCharWidth16 (GDI.350)
901 BOOL16 WINAPI GetCharWidth16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
902 LPINT16 buffer )
904 BOOL32 retVal = FALSE;
906 if( firstChar != lastChar )
908 LPINT32 buf32 = (LPINT32)HeapAlloc(GetProcessHeap(), 0,
909 sizeof(INT32)*(1 + (lastChar - firstChar)));
910 if( buf32 )
912 LPINT32 obuf32 = buf32;
913 int i;
915 retVal = GetCharWidth32A(hdc, firstChar, lastChar, buf32);
916 if (retVal)
918 for (i = firstChar; i <= lastChar; i++)
919 *buffer++ = *buf32++;
921 HeapFree(GetProcessHeap(), 0, obuf32);
924 else /* happens quite often to warrant a special treatment */
926 INT32 chWidth;
927 retVal = GetCharWidth32A(hdc, firstChar, lastChar, &chWidth );
928 *buffer = chWidth;
930 return retVal;
934 /***********************************************************************
935 * GetCharWidth32A (GDI32.155)
937 BOOL32 WINAPI GetCharWidth32A( HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
938 LPINT32 buffer )
940 UINT32 i, extra;
941 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
942 if (!dc)
944 if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
945 return FALSE;
948 if (!dc->funcs->pGetCharWidth ||
949 !dc->funcs->pGetCharWidth( dc, firstChar, lastChar, buffer))
950 return FALSE;
952 /* convert device units to logical */
954 extra = dc->vportExtX >> 1;
955 for( i = firstChar; i <= lastChar; i++, buffer++ )
956 *buffer = (*buffer * dc->wndExtX + extra) / dc->vportExtX;
958 return TRUE;
962 /***********************************************************************
963 * GetCharWidth32W (GDI32.158)
965 BOOL32 WINAPI GetCharWidth32W( HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
966 LPINT32 buffer )
968 return GetCharWidth32A( hdc, firstChar, lastChar, buffer );
973 /* FIXME: all following APIs *******************************************
976 * SetMapperFlags16 (GDI.349)
978 DWORD WINAPI SetMapperFlags16( HDC16 hDC, DWORD dwFlag )
980 return SetMapperFlags32( hDC, dwFlag );
984 /***********************************************************************
985 * SetMapperFlags32 (GDI32.322)
987 DWORD WINAPI SetMapperFlags32( HDC32 hDC, DWORD dwFlag )
989 FIXME(font, "(%04x, %08lX) -- Empty Stub !\n",
990 hDC, dwFlag);
991 return 0L;
994 /***********************************************************************
995 * GetAspectRatioFilterEx16 (GDI.486)
997 BOOL16 GetAspectRatioFilterEx16( HDC16 hdc, LPVOID pAspectRatio )
999 FIXME(font, "(%04x, %p): -- Empty Stub !\n",
1000 hdc, pAspectRatio);
1001 return FALSE;
1005 /***********************************************************************
1006 * GetCharABCWidths16 (GDI.307)
1008 BOOL16 WINAPI GetCharABCWidths16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1009 LPABC16 abc )
1011 ABC32 abc32;
1012 if (!GetCharABCWidths32A( hdc, firstChar, lastChar, &abc32 )) return FALSE;
1013 abc->abcA = abc32.abcA;
1014 abc->abcB = abc32.abcB;
1015 abc->abcC = abc32.abcC;
1016 return TRUE;
1020 /***********************************************************************
1021 * GetCharABCWidths32A (GDI32.149)
1023 BOOL32 WINAPI GetCharABCWidths32A(HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
1024 LPABC32 abc )
1026 /* No TrueType fonts in Wine so far */
1027 FIXME(font, "(%04x,%04x,%04x,%p): stub\n", hdc, firstChar, lastChar, abc );
1028 return FALSE;
1032 /***********************************************************************
1033 * GetCharABCWidths32W (GDI32.152)
1035 BOOL32 WINAPI GetCharABCWidths32W(HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
1036 LPABC32 abc )
1038 return GetCharABCWidths32A( hdc, firstChar, lastChar, abc );
1042 /***********************************************************************
1043 * GetGlyphOutline16 (GDI.309)
1045 DWORD WINAPI GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
1046 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
1047 LPVOID lpBuffer, const MAT2 *lpmat2 )
1049 FIXME(font,"(%04x, '%c', %04x, %p, %ld, %p, %p): empty stub!\n",
1050 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1051 return (DWORD)-1; /* failure */
1055 /***********************************************************************
1056 * GetGlyphOutline32A (GDI32.186)
1058 DWORD WINAPI GetGlyphOutline32A( HDC32 hdc, UINT32 uChar, UINT32 fuFormat,
1059 LPGLYPHMETRICS32 lpgm, DWORD cbBuffer,
1060 LPVOID lpBuffer, const MAT2 *lpmat2 )
1062 FIXME(font,"(%04x, '%c', %04x, %p, %ld, %p, %p): empty stub!\n",
1063 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1064 return (DWORD)-1; /* failure */
1067 /***********************************************************************
1068 * GetGlyphOutline32W (GDI32.187)
1070 DWORD WINAPI GetGlyphOutline32W( HDC32 hdc, UINT32 uChar, UINT32 fuFormat,
1071 LPGLYPHMETRICS32 lpgm, DWORD cbBuffer,
1072 LPVOID lpBuffer, const MAT2 *lpmat2 )
1074 FIXME(font,"(%04x, '%c', %04x, %p, %ld, %p, %p): empty stub!\n",
1075 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
1076 return (DWORD)-1; /* failure */
1079 /***********************************************************************
1080 * CreateScalableFontResource16 (GDI.310)
1082 BOOL16 WINAPI CreateScalableFontResource16( UINT16 fHidden,
1083 LPCSTR lpszResourceFile,
1084 LPCSTR fontFile, LPCSTR path )
1086 return CreateScalableFontResource32A( fHidden, lpszResourceFile,
1087 fontFile, path );
1090 /***********************************************************************
1091 * CreateScalableFontResource32A (GDI32.62)
1093 BOOL32 WINAPI CreateScalableFontResource32A( DWORD fHidden,
1094 LPCSTR lpszResourceFile,
1095 LPCSTR lpszFontFile,
1096 LPCSTR lpszCurrentPath )
1098 /* fHidden=1 - only visible for the calling app, read-only, not
1099 * enumbered with EnumFonts/EnumFontFamilies
1100 * lpszCurrentPath can be NULL
1102 FIXME(font,"(%ld,%s,%s,%s): empty stub\n",
1103 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1104 return FALSE; /* create failed */
1107 /***********************************************************************
1108 * CreateScalableFontResource32W (GDI32.63)
1110 BOOL32 WINAPI CreateScalableFontResource32W( DWORD fHidden,
1111 LPCWSTR lpszResourceFile,
1112 LPCWSTR lpszFontFile,
1113 LPCWSTR lpszCurrentPath )
1115 FIXME(font,"(%ld,%p,%p,%p): empty stub\n",
1116 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
1117 return FALSE; /* create failed */
1121 /*************************************************************************
1122 * GetRasterizerCaps16 (GDI.313)
1124 BOOL16 WINAPI GetRasterizerCaps16( LPRASTERIZER_STATUS lprs, UINT16 cbNumBytes)
1126 return GetRasterizerCaps32( lprs, cbNumBytes );
1130 /*************************************************************************
1131 * GetRasterizerCaps32 (GDI32.216)
1133 BOOL32 WINAPI GetRasterizerCaps32( LPRASTERIZER_STATUS lprs, UINT32 cbNumBytes)
1135 lprs->nSize = sizeof(RASTERIZER_STATUS);
1136 lprs->wFlags = TT_AVAILABLE|TT_ENABLED;
1137 lprs->nLanguageID = 0;
1138 return TRUE;
1142 /*************************************************************************
1143 * GetKerningPairs16 (GDI.332)
1145 INT16 WINAPI GetKerningPairs16( HDC16 hDC, INT16 cPairs,
1146 LPKERNINGPAIR16 lpKerningPairs )
1148 /* At this time kerning is ignored (set to 0) */
1149 int i;
1150 FIXME(font,"(%x,%d,%p): almost empty stub!\n",
1151 hDC, cPairs, lpKerningPairs);
1152 for (i = 0; i < cPairs; i++)
1153 lpKerningPairs[i].iKernAmount = 0;
1154 return 0;
1159 /*************************************************************************
1160 * GetKerningPairs32A (GDI32.192)
1162 DWORD WINAPI GetKerningPairs32A( HDC32 hDC, DWORD cPairs,
1163 LPKERNINGPAIR32 lpKerningPairs )
1165 int i;
1166 FIXME(font,"(%x,%ld,%p): almost empty stub!\n",
1167 hDC, cPairs, lpKerningPairs);
1168 for (i = 0; i < cPairs; i++)
1169 lpKerningPairs[i].iKernAmount = 0;
1170 return 0;
1174 /*************************************************************************
1175 * GetKerningPairs32W (GDI32.193)
1177 DWORD WINAPI GetKerningPairs32W( HDC32 hDC, DWORD cPairs,
1178 LPKERNINGPAIR32 lpKerningPairs )
1180 return GetKerningPairs32A( hDC, cPairs, lpKerningPairs );
1183 BOOL32 WINAPI TranslateCharSetInfo(LPDWORD lpSrc,LPCHARSETINFO lpCs,DWORD dwFlags) {
1184 FIXME(font,"(%p,%p,0x%08lx), stub.\n",lpSrc,lpCs,dwFlags);
1185 return TRUE;
1189 /*************************************************************************
1190 * GetFontLanguageInfo (GDI32.182)
1192 DWORD WINAPI GetFontLanguageInfo32(HDC32 hdc) {
1193 /* return value 0 is correct for most cases anyway */
1194 FIXME(font,"(%x):stub!\n", hdc);
1195 return 0;
1198 /*************************************************************************
1199 * GetFontLanguageInfo (GDI.616)
1201 DWORD WINAPI GetFontLanguageInfo16(HDC16 hdc) {
1202 /* return value 0 is correct for most cases anyway */
1203 FIXME(font,"(%x):stub!\n",hdc);
1204 return 0;