Release 970305
[wine/multimedia.git] / objects / font.c
blob7912362485ec90e85d7e5fce74157fa19d985669
1 /*
2 * GDI font objects
4 * Copyright 1993 Alexandre Julliard
6 * Enhacements by Juergen Marquardt 1996
8 * Implementation of a second font cache which
9 * will be updated dynamically
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <X11/Xatom.h>
16 #include "font.h"
17 #include "heap.h"
18 #include "metafile.h"
19 #include "options.h"
20 #include "xmalloc.h"
21 #include "stddebug.h"
22 #include "debug.h"
24 LPLOGFONT16 lpLogFontList[MAX_FONTS+1];
27 #define CI_NONEXISTCHAR(cs) (((cs)->width == 0) && \
28 (((cs)->rbearing|(cs)->lbearing| \
29 (cs)->ascent|(cs)->descent) == 0))
31 /*
32 * CI_GET_CHAR_INFO - return the charinfo struct for the indicated 8bit
33 * character. If the character is in the column and exists, then return the
34 * appropriate metrics (note that fonts with common per-character metrics will
35 * return min_bounds). If none of these hold true, try again with the default
36 * char.
38 #define CI_GET_CHAR_INFO(fs,col,def,cs) \
39 { \
40 cs = def; \
41 if (col >= fs->min_char_or_byte2 && col <= fs->max_char_or_byte2) { \
42 if (fs->per_char == NULL) { \
43 cs = &fs->min_bounds; \
44 } else { \
45 cs = &fs->per_char[(col - fs->min_char_or_byte2)]; \
46 if (CI_NONEXISTCHAR(cs)) cs = def; \
47 } \
48 } \
51 #define CI_GET_DEFAULT_INFO(fs,cs) \
52 CI_GET_CHAR_INFO(fs, fs->default_char, NULL, cs)
57 /***********************************************************************
58 * FONT_LOGFONT32AToLOGFONT16
60 static void FONT_LOGFONT32AToLOGFONT16( const LOGFONT32A *font,
61 LPLOGFONT16 font16 )
63 font16->lfHeight = (INT16)font->lfHeight;
64 font16->lfWidth = (INT16)font->lfWidth;
65 font16->lfEscapement = (INT16)font->lfEscapement;
66 font16->lfOrientation = (INT16)font->lfOrientation;
67 font16->lfWeight = (INT16)font->lfWeight;
68 font16->lfItalic = font->lfItalic;
69 font16->lfUnderline = font->lfUnderline;
70 font16->lfStrikeOut = font->lfStrikeOut;
71 font16->lfCharSet = font->lfCharSet;
72 font16->lfOutPrecision = font->lfOutPrecision;
73 font16->lfClipPrecision = font->lfClipPrecision;
74 font16->lfQuality = font->lfQuality;
75 font16->lfPitchAndFamily = font->lfPitchAndFamily;
76 lstrcpyn32A( font16->lfFaceName, font->lfFaceName, LF_FACESIZE );
80 /***********************************************************************
81 * FONT_LOGFONT32WToLOGFONT16
83 static void FONT_LOGFONT32WToLOGFONT16( const LOGFONT32W *font,
84 LPLOGFONT16 font16 )
86 font16->lfHeight = (INT16)font->lfHeight;
87 font16->lfWidth = (INT16)font->lfWidth;
88 font16->lfEscapement = (INT16)font->lfEscapement;
89 font16->lfOrientation = (INT16)font->lfOrientation;
90 font16->lfWeight = (INT16)font->lfWeight;
91 font16->lfItalic = font->lfItalic;
92 font16->lfUnderline = font->lfUnderline;
93 font16->lfStrikeOut = font->lfStrikeOut;
94 font16->lfCharSet = font->lfCharSet;
95 font16->lfOutPrecision = font->lfOutPrecision;
96 font16->lfClipPrecision = font->lfClipPrecision;
97 font16->lfQuality = font->lfQuality;
98 font16->lfPitchAndFamily = font->lfPitchAndFamily;
99 lstrcpynWtoA( font16->lfFaceName, font->lfFaceName, LF_FACESIZE );
103 /***********************************************************************
104 * FONT_LOGFONT16ToLOGFONT32A
106 static void FONT_LOGFONT16ToLOGFONT32A( LPLOGFONT16 font,
107 LPLOGFONT32A font32A )
109 font32A->lfHeight = (INT32)font->lfHeight;
110 font32A->lfWidth = (INT32)font->lfWidth;
111 font32A->lfEscapement = (INT32)font->lfEscapement;
112 font32A->lfOrientation = (INT32)font->lfOrientation;
113 font32A->lfWeight = (INT32)font->lfWeight;
114 font32A->lfItalic = font->lfItalic;
115 font32A->lfUnderline = font->lfUnderline;
116 font32A->lfStrikeOut = font->lfStrikeOut;
117 font32A->lfCharSet = font->lfCharSet;
118 font32A->lfOutPrecision = font->lfOutPrecision;
119 font32A->lfClipPrecision = font->lfClipPrecision;
120 font32A->lfQuality = font->lfQuality;
121 font32A->lfPitchAndFamily = font->lfPitchAndFamily;
122 lstrcpyn32A( font32A->lfFaceName, font->lfFaceName, LF_FACESIZE );
126 /***********************************************************************
127 * FONT_LOGFONT16ToLOGFONT32W
129 static void FONT_LOGFONT16ToLOGFONT32W( LPLOGFONT16 font,
130 LPLOGFONT32W font32W )
132 font32W->lfHeight = (INT32)font->lfHeight;
133 font32W->lfWidth = (INT32)font->lfWidth;
134 font32W->lfEscapement = (INT32)font->lfEscapement;
135 font32W->lfOrientation = (INT32)font->lfOrientation;
136 font32W->lfWeight = (INT32)font->lfWeight;
137 font32W->lfItalic = font->lfItalic;
138 font32W->lfUnderline = font->lfUnderline;
139 font32W->lfStrikeOut = font->lfStrikeOut;
140 font32W->lfCharSet = font->lfCharSet;
141 font32W->lfOutPrecision = font->lfOutPrecision;
142 font32W->lfClipPrecision = font->lfClipPrecision;
143 font32W->lfQuality = font->lfQuality;
144 font32W->lfPitchAndFamily = font->lfPitchAndFamily;
145 lstrcpynAtoW( font32W->lfFaceName, font->lfFaceName, LF_FACESIZE );
149 /***********************************************************************
150 * FONT_GetMetrics
152 void FONT_GetMetrics( LOGFONT16 * logfont, XFontStruct * xfont,
153 TEXTMETRIC16 * metrics )
155 int average, i, count;
156 unsigned long prop;
158 metrics->tmAscent = xfont->ascent;
159 metrics->tmDescent = xfont->descent;
160 metrics->tmHeight = xfont->ascent + xfont->descent;
162 metrics->tmInternalLeading = 0;
163 if (XGetFontProperty( xfont, XA_CAP_HEIGHT, &prop ))
164 metrics->tmInternalLeading = xfont->ascent+xfont->descent-(INT16)prop;
166 metrics->tmExternalLeading = 0;
167 metrics->tmMaxCharWidth = xfont->max_bounds.width;
168 metrics->tmWeight = logfont->lfWeight;
169 metrics->tmItalic = logfont->lfItalic;
170 metrics->tmUnderlined = logfont->lfUnderline;
171 metrics->tmStruckOut = logfont->lfStrikeOut;
172 metrics->tmFirstChar = xfont->min_char_or_byte2;
173 metrics->tmLastChar = xfont->max_char_or_byte2;
174 metrics->tmDefaultChar = xfont->default_char;
175 metrics->tmBreakChar = ' ';
176 metrics->tmCharSet = logfont->lfCharSet;
177 metrics->tmOverhang = 0;
178 metrics->tmDigitizedAspectX = 1;
179 metrics->tmDigitizedAspectY = 1;
180 metrics->tmPitchAndFamily = (logfont->lfPitchAndFamily&0xf0)|TMPF_DEVICE;
182 /* TMPF_FIXED_PITCH bit means variable pitch...Don't you love Microsoft? */
183 if (xfont->min_bounds.width != xfont->max_bounds.width)
184 metrics->tmPitchAndFamily |= TMPF_FIXED_PITCH;
186 if (!xfont->per_char) average = metrics->tmMaxCharWidth;
187 else
189 XCharStruct * charPtr = xfont->per_char;
190 average = count = 0;
191 for (i = metrics->tmFirstChar; i <= metrics->tmLastChar; i++)
193 if (!CI_NONEXISTCHAR( charPtr ))
195 average += charPtr->width;
196 count++;
198 charPtr++;
200 if (count) average = (average + count/2) / count;
202 metrics->tmAveCharWidth = average;
206 /***********************************************************************
207 * GetGlyphOutline16 (GDI.309)
209 DWORD GetGlyphOutline16( HDC16 hdc, UINT16 uChar, UINT16 fuFormat,
210 LPGLYPHMETRICS16 lpgm, DWORD cbBuffer,
211 LPVOID lpBuffer, const MAT2 *lpmat2 )
213 fprintf( stdnimp,"GetGlyphOutLine16(%04x, '%c', %04x, %p, %ld, %p, %p) // - empty stub!\n",
214 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
215 return (DWORD)-1; /* failure */
219 /***********************************************************************
220 * GetGlyphOutline32A (GDI32.186)
222 DWORD GetGlyphOutline32A( HDC32 hdc, UINT32 uChar, UINT32 fuFormat,
223 LPGLYPHMETRICS32 lpgm, DWORD cbBuffer,
224 LPVOID lpBuffer, const MAT2 *lpmat2 )
226 fprintf( stdnimp,"GetGlyphOutLine32A(%04x, '%c', %04x, %p, %ld, %p, %p) // - empty stub!\n",
227 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
228 return (DWORD)-1; /* failure */
232 /***********************************************************************
233 * GetGlyphOutline32W (GDI32.187)
235 DWORD GetGlyphOutline32W( HDC32 hdc, UINT32 uChar, UINT32 fuFormat,
236 LPGLYPHMETRICS32 lpgm, DWORD cbBuffer,
237 LPVOID lpBuffer, const MAT2 *lpmat2 )
239 fprintf( stdnimp,"GetGlyphOutLine32W(%04x, '%c', %04x, %p, %ld, %p, %p) // - empty stub!\n",
240 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
241 return (DWORD)-1; /* failure */
245 /***********************************************************************
246 * CreateScalableFontResource16 (GDI.310)
248 BOOL16 CreateScalableFontResource16( UINT16 fHidden, LPCSTR lpszResourceFile,
249 LPCSTR fontFile, LPCSTR path )
251 return CreateScalableFontResource32A( fHidden, lpszResourceFile,
252 fontFile, path );
255 /***********************************************************************
256 * CreateScalableFontResource32A (GDI32.62)
258 BOOL32 CreateScalableFontResource32A( DWORD fHidden, LPCSTR lpszResourceFile,
259 LPCSTR lpszFontFile,
260 LPCSTR lpszCurrentPath )
262 /* fHidden=1 - only visible for the calling app, read-only, not
263 * enumbered with EnumFonts/EnumFontFamilies
264 * lpszCurrentPath can be NULL
266 fprintf(stdnimp,"CreateScalableFontResource(%ld,%s,%s,%s) // empty stub\n",
267 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
268 return FALSE; /* create failed */
272 /***********************************************************************
273 * CreateScalableFontResource32W (GDI32.63)
275 BOOL32 CreateScalableFontResource32W( DWORD fHidden, LPCWSTR lpszResourceFile,
276 LPCWSTR lpszFontFile,
277 LPCWSTR lpszCurrentPath )
279 fprintf(stdnimp,"CreateScalableFontResource32W(%ld,%p,%p,%p) // empty stub\n",
280 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
281 return FALSE; /* create failed */
285 /***********************************************************************
286 * CreateFontIndirect16 (GDI.57)
288 HFONT16 CreateFontIndirect16( const LOGFONT16 *font )
290 FONTOBJ * fontPtr;
291 HFONT16 hfont;
293 if (!font)
295 fprintf(stderr,"CreateFontIndirect: font is NULL : returning NULL\n");
296 return 0;
298 hfont = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC );
299 if (!hfont) return 0;
300 fontPtr = (FONTOBJ *) GDI_HEAP_LIN_ADDR( hfont );
301 memcpy( &fontPtr->logfont, font, sizeof(LOGFONT16) );
302 dprintf_font(stddeb,"CreateFontIndirect(%p (%d,%d)); return %04x\n",
303 font, font->lfHeight, font->lfWidth, hfont);
304 return hfont;
308 /***********************************************************************
309 * CreateFontIndirect32A (GDI32.44)
311 HFONT32 CreateFontIndirect32A( const LOGFONT32A *font )
313 LOGFONT16 font16;
315 FONT_LOGFONT32AToLOGFONT16(font,&font16);
317 return CreateFontIndirect16( &font16 );
321 /***********************************************************************
322 * CreateFontIndirect32W (GDI32.45)
324 HFONT32 CreateFontIndirect32W( const LOGFONT32W *font )
326 LOGFONT16 font16;
328 FONT_LOGFONT32WToLOGFONT16(font,&font16);
329 return CreateFontIndirect16( &font16 );
333 /***********************************************************************
334 * CreateFont16 (GDI.56)
336 HFONT16 CreateFont16( INT16 height, INT16 width, INT16 esc, INT16 orient,
337 INT16 weight, BYTE italic, BYTE underline,
338 BYTE strikeout, BYTE charset, BYTE outpres,
339 BYTE clippres, BYTE quality, BYTE pitch, LPCSTR name )
341 LOGFONT16 logfont = {height, width, esc, orient, weight, italic, underline,
342 strikeout, charset, outpres, clippres, quality, pitch, };
343 dprintf_font(stddeb,"CreateFont16(%d,%d)\n", height, width);
344 if (name) lstrcpyn32A(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
345 else logfont.lfFaceName[0] = '\0';
346 return CreateFontIndirect16( &logfont );
351 /*************************************************************************
352 * CreateFont32A (GDI32.43)
354 HFONT32 CreateFont32A( INT32 height, INT32 width, INT32 esc, INT32 orient,
355 INT32 weight, DWORD italic, DWORD underline,
356 DWORD strikeout, DWORD charset, DWORD outpres,
357 DWORD clippres, DWORD quality, DWORD pitch, LPCSTR name)
359 return (HFONT32)CreateFont16( height, width, esc, orient, weight, italic,
360 underline, strikeout, charset, outpres,
361 clippres, quality, pitch, name );
365 /*************************************************************************
366 * CreateFont32W (GDI32.46)
368 HFONT32 CreateFont32W( INT32 height, INT32 width, INT32 esc, INT32 orient,
369 INT32 weight, DWORD italic, DWORD underline,
370 DWORD strikeout, DWORD charset, DWORD outpres,
371 DWORD clippres, DWORD quality, DWORD pitch,
372 LPCWSTR name )
374 LPSTR namea = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
375 HFONT32 ret = (HFONT32)CreateFont16( height, width, esc, orient, weight,
376 italic, underline, strikeout, charset,
377 outpres, clippres, quality, pitch,
378 namea );
379 HeapFree( GetProcessHeap(), 0, namea );
380 return ret;
384 /***********************************************************************
385 * FONT_GetObject16
387 INT16 FONT_GetObject16( FONTOBJ * font, INT16 count, LPSTR buffer )
389 if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
390 memcpy( buffer, &font->logfont, count );
391 return count;
395 /***********************************************************************
396 * FONT_GetObject32A
398 INT32 FONT_GetObject32A( FONTOBJ *font, INT32 count, LPSTR buffer )
400 LOGFONT32A fnt32;
402 memset(&fnt32, 0, sizeof(fnt32));
403 fnt32.lfHeight = font->logfont.lfHeight;
404 fnt32.lfWidth = font->logfont.lfWidth;
405 fnt32.lfEscapement = font->logfont.lfEscapement;
406 fnt32.lfOrientation = font->logfont.lfOrientation;
407 fnt32.lfWeight = font->logfont.lfWeight;
408 fnt32.lfItalic = font->logfont.lfItalic;
409 fnt32.lfUnderline = font->logfont.lfUnderline;
410 fnt32.lfStrikeOut = font->logfont.lfStrikeOut;
411 fnt32.lfCharSet = font->logfont.lfCharSet;
412 fnt32.lfOutPrecision = font->logfont.lfOutPrecision;
413 fnt32.lfClipPrecision = font->logfont.lfClipPrecision;
414 fnt32.lfQuality = font->logfont.lfQuality;
415 fnt32.lfPitchAndFamily = font->logfont.lfPitchAndFamily;
416 strncpy( fnt32.lfFaceName, font->logfont.lfFaceName,
417 sizeof(fnt32.lfFaceName) );
419 if (count > sizeof(fnt32)) count = sizeof(fnt32);
420 memcpy( buffer, &fnt32, count );
421 return count;
427 /***********************************************************************
428 * GetTextCharacterExtra16 (GDI.89)
430 INT16 GetTextCharacterExtra16( HDC16 hdc )
432 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
433 if (!dc) return 0;
434 return abs( (dc->w.charExtra * dc->wndExtX + dc->vportExtX / 2)
435 / dc->vportExtX );
439 /***********************************************************************
440 * GetTextCharacterExtra32 (GDI32.225)
442 INT32 GetTextCharacterExtra32( HDC32 hdc )
444 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
445 if (!dc) return 0;
446 return abs( (dc->w.charExtra * dc->wndExtX + dc->vportExtX / 2)
447 / dc->vportExtX );
451 /***********************************************************************
452 * SetTextCharacterExtra16 (GDI.8)
454 INT16 SetTextCharacterExtra16( HDC16 hdc, INT16 extra )
456 return (INT16)SetTextCharacterExtra32( hdc, extra );
460 /***********************************************************************
461 * SetTextCharacterExtra32 (GDI32.337)
463 INT32 SetTextCharacterExtra32( HDC32 hdc, INT32 extra )
465 INT32 prev;
466 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
467 if (!dc) return 0;
468 extra = (extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX;
469 prev = dc->w.charExtra;
470 dc->w.charExtra = abs(extra);
471 return (prev * dc->wndExtX + dc->vportExtX / 2) / dc->vportExtX;
475 /***********************************************************************
476 * SetTextJustification16 (GDI.10)
478 INT16 SetTextJustification16( HDC16 hdc, INT16 extra, INT16 breaks )
480 return SetTextJustification32( hdc, extra, breaks );
484 /***********************************************************************
485 * SetTextJustification32 (GDI32.339)
487 BOOL32 SetTextJustification32( HDC32 hdc, INT32 extra, INT32 breaks )
489 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
490 if (!dc) return 0;
492 extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
493 if (!extra) breaks = 0;
494 dc->w.breakTotalExtra = extra;
495 dc->w.breakCount = breaks;
496 if (breaks)
498 dc->w.breakExtra = extra / breaks;
499 dc->w.breakRem = extra - (dc->w.breakCount * dc->w.breakExtra);
501 else
503 dc->w.breakExtra = 0;
504 dc->w.breakRem = 0;
506 return 1;
510 /***********************************************************************
511 * GetTextFace16 (GDI.92)
513 INT16 GetTextFace16( HDC16 hdc, INT16 count, LPSTR name )
515 return GetTextFace32A(hdc,count,name);
518 /***********************************************************************
519 * GetTextFace32A (GDI32.234)
521 INT32 GetTextFace32A( HDC32 hdc, INT32 count, LPSTR name )
523 FONTOBJ *font;
525 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
526 if (!dc) return 0;
527 if (!(font = (FONTOBJ *) GDI_GetObjPtr( dc->w.hFont, FONT_MAGIC )))
528 return 0;
529 lstrcpyn32A( name, font->logfont.lfFaceName, count );
530 return strlen(name);
533 /***********************************************************************
534 * GetTextFace32W (GDI32.235)
536 INT32 GetTextFace32W( HDC32 hdc, INT32 count, LPWSTR name )
538 LPSTR nameA = HeapAlloc( GetProcessHeap(), 0, count );
539 INT32 res = GetTextFace32A(hdc,count,nameA);
540 lstrcpyAtoW( name, nameA );
541 HeapFree( GetProcessHeap(), 0, nameA );
542 return res;
546 /***********************************************************************
547 * GetTextExtent (GDI.91)
549 DWORD GetTextExtent( HDC16 hdc, LPCSTR str, INT16 count )
551 SIZE16 size;
552 if (!GetTextExtentPoint16( hdc, str, count, &size )) return 0;
553 return MAKELONG( size.cx, size.cy );
557 /***********************************************************************
558 * GetTextExtentPoint16 (GDI.471)
560 * FIXME: Should this have a bug for compatibility?
561 * Original Windows versions of GetTextExtentPoint{A,W} have documented
562 * bugs.
564 BOOL16 GetTextExtentPoint16( HDC16 hdc, LPCSTR str, INT16 count, LPSIZE16 size)
566 SIZE32 size32;
567 BOOL32 ret = GetTextExtentPoint32A( hdc, str, count, &size32 );
568 CONV_SIZE32TO16( &size32, size );
569 return (BOOL16)ret;
573 /***********************************************************************
574 * GetTextExtentPoint32A (GDI32.230)
576 BOOL32 GetTextExtentPoint32A( HDC32 hdc, LPCSTR str, INT32 count,
577 LPSIZE32 size )
579 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
580 if (!dc)
582 if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
583 return FALSE;
586 if (!dc->funcs->pGetTextExtentPoint ||
587 !dc->funcs->pGetTextExtentPoint( dc, str, count, size ))
588 return FALSE;
590 dprintf_font(stddeb,"GetTextExtentPoint(%08x '%.*s' %d %p): returning %d,%d\n",
591 hdc, count, str, count, size, size->cx, size->cy );
592 return TRUE;
596 /***********************************************************************
597 * GetTextExtentPoint32W (GDI32.231)
599 BOOL32 GetTextExtentPoint32W( HDC32 hdc, LPCWSTR str, INT32 count,
600 LPSIZE32 size )
602 LPSTR p = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
603 BOOL32 ret = GetTextExtentPoint32A( hdc, p, count, size );
604 HeapFree( GetProcessHeap(), 0, p );
605 return ret;
608 /***********************************************************************
609 * GetTextExtentPoint32ABuggy (GDI32.232)
611 BOOL32 GetTextExtentPoint32ABuggy( HDC32 hdc, LPCSTR str, INT32 count,
612 LPSIZE32 size )
614 dprintf_font( stddeb, "GetTextExtentPoint32ABuggy: not bug compatible.\n");
615 return GetTextExtentPoint32A( hdc, str, count, size );
618 /***********************************************************************
619 * GetTextExtentPoint32WBuggy (GDI32.233)
621 BOOL32 GetTextExtentPoint32WBuggy( HDC32 hdc, LPCWSTR str, INT32 count,
622 LPSIZE32 size )
624 dprintf_font( stddeb, "GetTextExtentPoint32WBuggy: not bug compatible.\n");
625 return GetTextExtentPoint32W( hdc, str, count, size );
629 /***********************************************************************
630 * GetTextExtentExPoint32A (GDI32.228)
632 BOOL32 GetTextExtentExPoint32A( HDC32 hdc, LPCSTR str, INT32 count,
633 INT32 maxExt,LPINT32 lpnFit, LPINT32 alpDx,
634 LPSIZE32 size )
636 int index;
637 SIZE32 tSize;
638 int nFit=0;
639 int extent=0;
640 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
641 if (!dc)
643 if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
644 return FALSE;
646 if (!dc->funcs->pGetTextExtentPoint) return FALSE;
648 size->cx=0; size->cy=0;
649 for(index=0;index<count;index++)
651 if(!dc->funcs->pGetTextExtentPoint( dc, str, 1, &tSize )) return FALSE;
652 if(extent+tSize.cx<maxExt)
654 extent+=tSize.cx;
655 nFit++;
656 str++;
657 if(alpDx) alpDx[index]=extent;
658 if(tSize.cy > size->cy) size->cy=tSize.cy;
660 else break;
662 size->cx=extent;
663 *lpnFit=nFit;
664 dprintf_font(stddeb,"GetTextExtentExPoint32A(%08x '%.*s' %d) returning %d %d %d\n",
665 hdc,count,str,maxExt,nFit, size->cx,size->cy);
666 return TRUE;
669 /***********************************************************************
670 * GetTextExtentExPoint32W (GDI32.229)
673 BOOL32 GetTextExtentExPoint32W( HDC32 hdc, LPCWSTR str, INT32 count,
674 INT32 maxExt, LPINT32 lpnFit, LPINT32 alpDx,
675 LPSIZE32 size )
677 LPSTR p = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
678 BOOL32 ret = GetTextExtentExPoint32A( hdc, p, count, maxExt,
679 lpnFit, alpDx, size);
680 HeapFree( GetProcessHeap(), 0, p );
681 return ret;
684 /***********************************************************************
685 * GetTextMetrics16 (GDI.93)
687 BOOL16 GetTextMetrics16( HDC16 hdc, TEXTMETRIC16 *metrics )
689 TEXTMETRIC32A tm;
691 if (!GetTextMetrics32A( (HDC32)hdc, &tm )) return FALSE;
692 metrics->tmHeight = tm.tmHeight;
693 metrics->tmAscent = tm.tmAscent;
694 metrics->tmDescent = tm.tmDescent;
695 metrics->tmInternalLeading = tm.tmInternalLeading;
696 metrics->tmExternalLeading = tm.tmExternalLeading;
697 metrics->tmAveCharWidth = tm.tmAveCharWidth;
698 metrics->tmMaxCharWidth = tm.tmMaxCharWidth;
699 metrics->tmWeight = tm.tmWeight;
700 metrics->tmOverhang = tm.tmOverhang;
701 metrics->tmDigitizedAspectX = tm.tmDigitizedAspectX;
702 metrics->tmDigitizedAspectY = tm.tmDigitizedAspectY;
703 metrics->tmFirstChar = tm.tmFirstChar;
704 metrics->tmLastChar = tm.tmLastChar;
705 metrics->tmDefaultChar = tm.tmDefaultChar;
706 metrics->tmBreakChar = tm.tmBreakChar;
707 metrics->tmItalic = tm.tmItalic;
708 metrics->tmUnderlined = tm.tmUnderlined;
709 metrics->tmStruckOut = tm.tmStruckOut;
710 metrics->tmPitchAndFamily = tm.tmPitchAndFamily;
711 metrics->tmCharSet = tm.tmCharSet;
712 return TRUE;
716 /***********************************************************************
717 * GetTextMetrics32A (GDI32.236)
719 BOOL32 GetTextMetrics32A( HDC32 hdc, TEXTMETRIC32A *metrics )
721 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
722 if (!dc)
724 if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
725 return FALSE;
728 if (!dc->funcs->pGetTextMetrics ||
729 !dc->funcs->pGetTextMetrics( dc,metrics ))
730 return FALSE;
731 dprintf_font(stdnimp,"text metrics:\n
732 InternalLeading = %i
733 ExternalLeading = %i
734 MaxCharWidth = %i
735 Weight = %i
736 Italic = %i
737 Underlined = %i
738 StruckOut = %i
739 FirstChar = %i
740 LastChar = %i
741 DefaultChar = %i
742 BreakChar = %i
743 CharSet = %i
744 Overhang = %i
745 DigitizedAspectX = %i
746 DigitizedAspectY = %i
747 AveCharWidth = %i
748 MaxCharWidth = %i
749 Ascent = %i
750 Descent = %i
751 Height = %i\n",
752 metrics->tmInternalLeading,
753 metrics->tmExternalLeading,
754 metrics->tmMaxCharWidth,
755 metrics->tmWeight,
756 metrics->tmItalic,
757 metrics->tmUnderlined,
758 metrics->tmStruckOut,
759 metrics->tmFirstChar,
760 metrics->tmLastChar,
761 metrics->tmDefaultChar,
762 metrics->tmBreakChar,
763 metrics->tmCharSet,
764 metrics->tmOverhang,
765 metrics->tmDigitizedAspectX,
766 metrics->tmDigitizedAspectY,
767 metrics->tmAveCharWidth,
768 metrics->tmMaxCharWidth,
769 metrics->tmAscent,
770 metrics->tmDescent,
771 metrics->tmHeight);
772 return TRUE;
776 /***********************************************************************
777 * GetTextMetrics32W (GDI32.237)
779 BOOL32 GetTextMetrics32W( HDC32 hdc, TEXTMETRIC32W *metrics )
781 TEXTMETRIC32A tm;
782 if (!GetTextMetrics32A( (HDC16)hdc, &tm )) return FALSE;
783 metrics->tmHeight = tm.tmHeight;
784 metrics->tmAscent = tm.tmAscent;
785 metrics->tmDescent = tm.tmDescent;
786 metrics->tmInternalLeading = tm.tmInternalLeading;
787 metrics->tmExternalLeading = tm.tmExternalLeading;
788 metrics->tmAveCharWidth = tm.tmAveCharWidth;
789 metrics->tmMaxCharWidth = tm.tmMaxCharWidth;
790 metrics->tmWeight = tm.tmWeight;
791 metrics->tmOverhang = tm.tmOverhang;
792 metrics->tmDigitizedAspectX = tm.tmDigitizedAspectX;
793 metrics->tmDigitizedAspectY = tm.tmDigitizedAspectY;
794 metrics->tmFirstChar = tm.tmFirstChar;
795 metrics->tmLastChar = tm.tmLastChar;
796 metrics->tmDefaultChar = tm.tmDefaultChar;
797 metrics->tmBreakChar = tm.tmBreakChar;
798 metrics->tmItalic = tm.tmItalic;
799 metrics->tmUnderlined = tm.tmUnderlined;
800 metrics->tmStruckOut = tm.tmStruckOut;
801 metrics->tmPitchAndFamily = tm.tmPitchAndFamily;
802 metrics->tmCharSet = tm.tmCharSet;
803 return TRUE;
807 /***********************************************************************
808 * SetMapperFlags16 (GDI.349)
810 DWORD SetMapperFlags16( HDC16 hDC, DWORD dwFlag )
812 return SetMapperFlags32( hDC, dwFlag );
816 /***********************************************************************
817 * SetMapperFlags32 (GDI32.322)
819 DWORD SetMapperFlags32( HDC32 hDC, DWORD dwFlag )
821 dprintf_font(stdnimp,"SetmapperFlags(%04x, %08lX) // Empty Stub !\n",
822 hDC, dwFlag);
823 return 0L;
827 /***********************************************************************
828 * GetCharABCWidths16 (GDI.307)
830 BOOL16 GetCharABCWidths16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
831 LPABC16 abc )
833 ABC32 abc32;
834 if (!GetCharABCWidths32A( hdc, firstChar, lastChar, &abc32 )) return FALSE;
835 abc->abcA = abc32.abcA;
836 abc->abcB = abc32.abcB;
837 abc->abcC = abc32.abcC;
838 return TRUE;
842 /***********************************************************************
843 * GetCharABCWidths32A (GDI32.149)
845 BOOL32 GetCharABCWidths32A( HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
846 LPABC32 abc )
848 /* No TrueType fonts in Wine so far */
849 fprintf( stdnimp, "STUB: GetCharABCWidths(%04x,%04x,%04x,%p)\n",
850 hdc, firstChar, lastChar, abc );
851 return FALSE;
855 /***********************************************************************
856 * GetCharABCWidths32W (GDI32.152)
858 BOOL32 GetCharABCWidths32W( HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
859 LPABC32 abc )
861 return GetCharABCWidths32A( hdc, firstChar, lastChar, abc );
865 /***********************************************************************
866 * GetCharWidth16 (GDI.350)
868 BOOL16 GetCharWidth16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
869 LPINT16 buffer )
871 int i, width;
872 XFontStruct *xfont;
873 XCharStruct *cs, *def;
875 DC *dc = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC);
876 if (!dc) return FALSE;
877 xfont = dc->u.x.font.fstruct;
879 /* fixed font? */
880 if (xfont->per_char == NULL)
882 for (i = firstChar; i <= lastChar; i++)
883 *buffer++ = xfont->max_bounds.width;
884 return TRUE;
887 CI_GET_DEFAULT_INFO(xfont, def);
889 for (i = firstChar; i <= lastChar; i++)
891 CI_GET_CHAR_INFO( xfont, i, def, cs );
892 width = cs ? cs->width : xfont->max_bounds.width;
893 *buffer++ = MAX( width, 0 );
895 return TRUE;
899 /***********************************************************************
900 * GetCharWidth32A (GDI32.155)
902 BOOL32 GetCharWidth32A( HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
903 LPINT32 buffer )
905 int i, width;
906 XFontStruct *xfont;
907 XCharStruct *cs, *def;
909 DC *dc = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC);
910 if (!dc) return FALSE;
911 xfont = dc->u.x.font.fstruct;
913 /* fixed font? */
914 if (xfont->per_char == NULL)
916 for (i = firstChar; i <= lastChar; i++)
917 *buffer++ = xfont->max_bounds.width;
918 return TRUE;
921 CI_GET_DEFAULT_INFO(xfont, def);
923 for (i = firstChar; i <= lastChar; i++)
925 CI_GET_CHAR_INFO( xfont, i, def, cs );
926 width = cs ? cs->width : xfont->max_bounds.width;
927 *buffer++ = MAX( width, 0 );
929 return TRUE;
933 /***********************************************************************
934 * GetCharWidth32W (GDI32.158)
936 BOOL32 GetCharWidth32W( HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
937 LPINT32 buffer )
939 return GetCharWidth32A( hdc, firstChar, lastChar, buffer );
943 /***********************************************************************
944 * AddFontResource16 (GDI.119)
946 INT16 AddFontResource16( LPCSTR str )
948 return AddFontResource32A( str );
952 /***********************************************************************
953 * AddFontResource32A (GDI32.2)
955 INT32 AddFontResource32A( LPCSTR str )
957 if (HIWORD(str))
958 fprintf( stdnimp, "STUB: AddFontResource('%s')\n", str );
959 else
960 fprintf( stdnimp, "STUB: AddFontResource(%04x)\n", LOWORD(str) );
961 return 1;
965 /***********************************************************************
966 * AddFontResource32W (GDI32.4)
968 INT32 AddFontResource32W( LPCWSTR str )
970 fprintf( stdnimp, "STUB: AddFontResource32W(%p)\n", str );
971 return 1;
975 /***********************************************************************
976 * RemoveFontResource16 (GDI.136)
978 BOOL16 RemoveFontResource16( LPCSTR str )
980 return RemoveFontResource32A( str );
984 /***********************************************************************
985 * RemoveFontResource32A (GDI32.284)
987 BOOL32 RemoveFontResource32A( LPCSTR str )
989 if (HIWORD(str))
990 fprintf( stdnimp, "STUB: RemoveFontResource('%s')\n", str );
991 else
992 fprintf( stdnimp, "STUB: RemoveFontResource(%04x)\n", LOWORD(str) );
993 return TRUE;
997 /***********************************************************************
998 * RemoveFontResource32W (GDI32.286)
1000 BOOL32 RemoveFontResource32W( LPCWSTR str )
1002 fprintf( stdnimp, "STUB: RemoveFontResource32W(%p)\n", str );
1003 return TRUE;
1007 /*************************************************************************
1008 * FONT_ParseFontParms [internal]
1010 int FONT_ParseFontParms(LPSTR lpFont, WORD wParmsNo, LPSTR lpRetStr, WORD wMaxSiz)
1012 int i;
1013 if (lpFont == NULL) return 0;
1014 if (lpRetStr == NULL) return 0;
1015 for (i = 0; (*lpFont != '\0' && i != wParmsNo); ) {
1016 if (*lpFont == '-') i++;
1017 lpFont++;
1019 if (i == wParmsNo) {
1020 if (*lpFont == '-') lpFont++;
1021 wMaxSiz--;
1022 for (i = 0; (*lpFont != '\0' && *lpFont != '-' && i < wMaxSiz); i++)
1023 *(lpRetStr + i) = *lpFont++;
1024 *(lpRetStr + i) = '\0';
1025 return i;
1027 else
1028 lpRetStr[0] = '\0';
1029 return 0;
1034 /*************************************************************************
1035 * InitFontsList [internal]
1038 static int logfcmp(const void *a,const void *b)
1040 return lstrcmpi32A( (*(LPLOGFONT16 *)a)->lfFaceName,
1041 (*(LPLOGFONT16 *)b)->lfFaceName );
1044 void InitFontsList(void)
1046 char str[32];
1047 char pattern[100];
1048 char *family, *weight, *charset;
1049 char **names;
1050 char slant, spacing;
1051 int i, count;
1052 LPLOGFONT16 lpNewFont;
1054 dprintf_font(stddeb,"InitFontsList !\n");
1056 weight = "medium";
1057 slant = 'r';
1058 spacing = '*';
1059 charset = "*";
1060 family = "*-*";
1062 sprintf( pattern, "-%s-%s-%c-normal-*-*-*-*-*-%c-*-%s",
1063 family, weight, slant, spacing, charset);
1064 names = XListFonts( display, pattern, MAX_FONTS, &count );
1065 dprintf_font(stddeb,"InitFontsList // count=%d \n", count);
1067 lpNewFont = malloc((sizeof(LOGFONT16)+LF_FACESIZE)*count);
1068 if (lpNewFont == NULL) {
1069 dprintf_font(stddeb,
1070 "InitFontsList // Error alloc new font structure !\n");
1071 XFreeFontNames(names);
1072 return;
1075 for (i = 0; i < count; i++) {
1076 dprintf_font(stddeb,"InitFontsList // names[%d]='%s' \n", i, names[i]);
1078 FONT_ParseFontParms(names[i], 2, str, sizeof(str));
1079 strcpy(lpNewFont->lfFaceName, str);
1080 FONT_ParseFontParms(names[i], 8, str, sizeof(str));
1081 lpNewFont->lfHeight = atoi(str) / 10;
1082 FONT_ParseFontParms(names[i], 12, str, sizeof(str));
1083 lpNewFont->lfWidth = atoi(str) / 10;
1084 lpNewFont->lfEscapement = 0;
1085 lpNewFont->lfOrientation = 0;
1086 lpNewFont->lfWeight = FW_REGULAR;
1087 lpNewFont->lfItalic = 0;
1088 lpNewFont->lfUnderline = 0;
1089 lpNewFont->lfStrikeOut = 0;
1090 FONT_ParseFontParms(names[i], 13, str, sizeof(str));
1091 if (strcmp(str, "iso8859") == 0) {
1092 lpNewFont->lfCharSet = ANSI_CHARSET;
1093 } else {
1094 lpNewFont->lfCharSet = OEM_CHARSET;
1096 lpNewFont->lfOutPrecision = OUT_DEFAULT_PRECIS;
1097 lpNewFont->lfClipPrecision = CLIP_DEFAULT_PRECIS;
1098 lpNewFont->lfQuality = DEFAULT_QUALITY;
1099 FONT_ParseFontParms(names[i], 11, str, sizeof(str));
1100 switch(str[0]) {
1101 case 'p':
1102 lpNewFont->lfPitchAndFamily = VARIABLE_PITCH | FF_SWISS;
1103 break;
1104 case 'm':
1105 case 'c':
1106 lpNewFont->lfPitchAndFamily = FIXED_PITCH | FF_MODERN;
1107 break;
1108 default:
1109 lpNewFont->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
1110 break;
1112 dprintf_font( stddeb,
1113 "InitFontsList // lpNewFont->lfHeight=%d\n",
1114 lpNewFont->lfHeight );
1115 dprintf_font( stddeb,
1116 "InitFontsList // lpNewFont->lfWidth=%d\n",
1117 lpNewFont->lfWidth );
1118 dprintf_font( stddeb,
1119 "InitFontsList // lfFaceName='%s'\n",
1120 lpNewFont->lfFaceName );
1121 lpLogFontList[i] = lpNewFont;
1122 lpNewFont = (LPLOGFONT16)
1123 ((char *)lpNewFont + sizeof(LOGFONT16)+LF_FACESIZE);
1125 lpLogFontList[i] = NULL;
1127 qsort(lpLogFontList,count,sizeof(*lpLogFontList),logfcmp);
1128 XFreeFontNames(names);
1131 /*************************************************************************
1132 * EnumFonts [GDI.70]
1133 * We reuse EnumFontFamilies* for the callback function get the same
1134 * structs (+ extra stuff at the end which will be ignored by the enum funcs)
1136 INT16 EnumFonts16(HDC16 hDC, LPCSTR lpFaceName, FONTENUMPROC16 lpEnumFunc, LPARAM lpData)
1138 return EnumFontFamilies16(hDC,lpFaceName,lpEnumFunc,lpData);
1141 /*************************************************************************
1142 * EnumFontsA [GDI32.84]
1144 INT32 EnumFonts32A(HDC32 hDC, LPCSTR lpFaceName, FONTENUMPROC32A lpEnumFunc, LPARAM lpData)
1146 return EnumFontFamilies32A(hDC,lpFaceName,lpEnumFunc,lpData);
1149 /*************************************************************************
1150 * EnumFontsA [GDI32.84]
1152 INT32 EnumFonts32W(HDC32 hDC, LPCWSTR lpFaceName, FONTENUMPROC32W lpEnumFunc, LPARAM lpData)
1154 return EnumFontFamilies32W(hDC,lpFaceName,lpEnumFunc,lpData);
1157 /*************************************************************************
1158 * EnumFontFamilies [GDI.330]
1160 INT16 EnumFontFamilies16(HDC16 hDC, LPCSTR lpszFamily, FONTENUMPROC16 lpEnumFunc, LPARAM lpData)
1162 LOGFONT16 LF;
1164 if (lpszFamily)
1165 strcpy(LF.lfFaceName,lpszFamily);
1166 else
1167 LF.lfFaceName[0]='\0';
1168 LF.lfCharSet = DEFAULT_CHARSET;
1170 return EnumFontFamiliesEx16(hDC,&LF,(FONTENUMPROCEX16)lpEnumFunc,lpData,0);
1173 /*************************************************************************
1174 * EnumFontFamiliesA [GDI32.80]
1176 INT32 EnumFontFamilies32A(HDC32 hDC, LPCSTR lpszFamily, FONTENUMPROC32A lpEnumFunc, LPARAM lpData)
1178 LOGFONT32A LF;
1180 if (lpszFamily)
1181 strcpy(LF.lfFaceName,lpszFamily);
1182 else
1183 LF.lfFaceName[0]='\0';
1184 LF.lfCharSet = DEFAULT_CHARSET;
1186 return EnumFontFamiliesEx32A(hDC,&LF,(FONTENUMPROCEX32A)lpEnumFunc,lpData,0);
1189 /*************************************************************************
1190 * EnumFontFamiliesW [GDI32.83]
1192 INT32 EnumFontFamilies32W(HDC32 hDC, LPCWSTR lpszFamilyW, FONTENUMPROC32W lpEnumFunc, LPARAM lpData)
1194 LOGFONT32W LF;
1196 if (lpszFamilyW)
1197 lstrcpy32W(LF.lfFaceName,lpszFamilyW);
1198 else
1199 LF.lfFaceName[0]=0;
1200 LF.lfCharSet = DEFAULT_CHARSET;
1201 return EnumFontFamiliesEx32W(hDC,&LF,(FONTENUMPROCEX32W)lpEnumFunc,lpData,0);
1204 /*************************************************************************
1205 * EnumFontFamiliesEx [GDI.618]
1206 * FIXME: fill the rest of the NEWTEXTMETRICEX and ENUMLOGFONTEX structures.
1207 * (applies to all EnumFontFamiliesEx*)
1208 * winelib/16 support.
1210 INT16 EnumFontFamiliesEx16(HDC16 hDC, LPLOGFONT16 lpLF, FONTENUMPROCEX16 lpEnumFunc, LPARAM lpData,DWORD reserved)
1212 HLOCAL16 hLog;
1213 HLOCAL16 hMet;
1214 HFONT16 hFont;
1215 HFONT16 hOldFont;
1216 LPENUMLOGFONTEX16 lpEnumLogFont;
1217 LPNEWTEXTMETRICEX16 lptm;
1218 LPSTR lpOldName;
1219 char FaceName[LF_FACESIZE];
1220 int nRet = 0;
1221 int i;
1223 dprintf_font(stddeb,"EnumFontFamiliesEx(%04x, '%s', %08lx, %08lx, %08lx)\n",
1224 hDC, lpLF->lfFaceName, (DWORD)lpEnumFunc, lpData, reserved);
1225 if (lpEnumFunc == 0) return 0;
1226 hLog = GDI_HEAP_ALLOC( sizeof(ENUMLOGFONTEX16) );
1227 lpEnumLogFont = (LPENUMLOGFONTEX16) GDI_HEAP_LIN_ADDR(hLog);
1228 if (lpEnumLogFont == NULL) {
1229 fprintf(stderr,"EnumFontFamiliesEx // can't alloc LOGFONT struct !\n");
1230 return 0;
1232 hMet = GDI_HEAP_ALLOC( sizeof(NEWTEXTMETRICEX16) );
1233 lptm = (LPNEWTEXTMETRICEX16) GDI_HEAP_LIN_ADDR(hMet);
1234 if (lptm == NULL) {
1235 GDI_HEAP_FREE(hLog);
1236 fprintf(stderr,"EnumFontFamiliesEx // can't alloc TEXTMETRIC struct !\n");
1237 return 0;
1239 lpOldName = NULL;
1240 strcpy(FaceName,lpLF->lfFaceName);
1242 if (lpLogFontList[0] == NULL) InitFontsList();
1243 for(i = 0; lpLogFontList[i] != NULL; i++) {
1244 /* lfCharSet */
1245 if (lpLF->lfCharSet!=DEFAULT_CHARSET)
1246 if (lpLogFontList[i]->lfCharSet != lpLF->lfCharSet)
1247 continue;
1249 /* lfPitchAndFamily only of importance in Hebrew and Arabic versions. */
1250 /* lfFaceName */
1251 if (FaceName[0])
1253 if (lstrcmpi32A(FaceName,lpLogFontList[i]->lfFaceName))
1254 continue;
1256 else
1258 if ((lpOldName!=NULL) &&
1259 !lstrcmpi32A(lpOldName,lpLogFontList[i]->lfFaceName))
1260 continue;
1261 lpOldName=lpLogFontList[i]->lfFaceName;
1264 memcpy(lpEnumLogFont, lpLogFontList[i], sizeof(LOGFONT16));
1265 strcpy(lpEnumLogFont->elfFullName,"");
1266 strcpy(lpEnumLogFont->elfStyle,"");
1267 hFont = CreateFontIndirect16((LPLOGFONT16)lpEnumLogFont);
1268 hOldFont = SelectObject32(hDC, hFont);
1269 GetTextMetrics16(hDC, (LPTEXTMETRIC16)lptm);
1270 SelectObject32(hDC, hOldFont);
1271 DeleteObject32(hFont);
1272 dprintf_font(stddeb, "EnumFontFamiliesEx // i=%d lpLogFont=%p lptm=%p\n", i, lpEnumLogFont, lptm);
1274 nRet = lpEnumFunc( GDI_HEAP_SEG_ADDR(hLog), GDI_HEAP_SEG_ADDR(hMet),
1275 0, lpData );
1276 if (nRet == 0) {
1277 dprintf_font(stddeb,"EnumFontFamilies // EnumEnd requested by application !\n");
1278 break;
1281 GDI_HEAP_FREE(hMet);
1282 GDI_HEAP_FREE(hLog);
1283 return nRet;
1287 /*************************************************************************
1288 * EnumFontFamiliesExA [GDI32.81]
1289 * FIXME: Don't use 16 bit GDI heap functions (applies to EnumFontFamiliesEx32*)
1291 INT32 EnumFontFamiliesEx32A(HDC32 hDC, LPLOGFONT32A lpLF,FONTENUMPROCEX32A lpEnumFunc, LPARAM lpData,DWORD reserved)
1293 HLOCAL16 hLog;
1294 HLOCAL16 hMet;
1295 HFONT32 hFont;
1296 HFONT32 hOldFont;
1297 LPENUMLOGFONTEX32A lpEnumLogFont;
1298 LPNEWTEXTMETRICEX32A lptm;
1299 LPSTR lpOldName;
1300 char FaceName[LF_FACESIZE];
1301 int nRet = 0;
1302 int i;
1304 dprintf_font(stddeb,"EnumFontFamilies32A(%04x, %p, %08lx, %08lx, %08lx)\n",
1305 hDC, lpLF->lfFaceName, (DWORD)lpEnumFunc, lpData,reserved);
1306 if (lpEnumFunc == 0) return 0;
1307 hLog = GDI_HEAP_ALLOC( sizeof(ENUMLOGFONTEX32A) );
1308 lpEnumLogFont = (LPENUMLOGFONTEX32A) GDI_HEAP_LIN_ADDR(hLog);
1309 if (lpEnumLogFont == NULL) {
1310 fprintf(stderr,"EnumFontFamilies // can't alloc LOGFONT struct !\n");
1311 return 0;
1313 hMet = GDI_HEAP_ALLOC( sizeof(NEWTEXTMETRICEX32A) );
1314 lptm = (LPNEWTEXTMETRICEX32A) GDI_HEAP_LIN_ADDR(hMet);
1315 if (lptm == NULL) {
1316 GDI_HEAP_FREE(hLog);
1317 fprintf(stderr,"EnumFontFamilies32A // can't alloc TEXTMETRIC struct !\n");
1318 return 0;
1320 lpOldName = NULL;
1321 strcpy(FaceName,lpLF->lfFaceName);
1323 if (lpLogFontList[0] == NULL) InitFontsList();
1324 for(i = 0; lpLogFontList[i] != NULL; i++) {
1325 /* lfCharSet */
1326 if (lpLF->lfCharSet!=DEFAULT_CHARSET)
1327 if (lpLogFontList[i]->lfCharSet != lpLF->lfCharSet)
1328 continue;
1330 /* lfPitchAndFamily only of importance in Hebrew and Arabic versions. */
1331 /* lfFaceName */
1332 if (FaceName[0]) {
1333 if (lstrcmpi32A(FaceName,lpLogFontList[i]->lfFaceName))
1334 continue;
1335 } else {
1336 if ((lpOldName!=NULL) &&
1337 !lstrcmpi32A(lpOldName,lpLogFontList[i]->lfFaceName))
1338 continue;
1339 lpOldName=lpLogFontList[i]->lfFaceName;
1342 FONT_LOGFONT16ToLOGFONT32A(lpLogFontList[i],&(lpEnumLogFont->elfLogFont));
1343 strcpy(lpEnumLogFont->elfFullName,"");
1344 strcpy(lpEnumLogFont->elfStyle,"");
1345 strcpy(lpEnumLogFont->elfScript,"");
1346 hFont = CreateFontIndirect32A((LPLOGFONT32A)lpEnumLogFont);
1347 hOldFont = SelectObject32(hDC, hFont);
1348 GetTextMetrics32A(hDC, (LPTEXTMETRIC32A)lptm);
1349 SelectObject32(hDC, hOldFont);
1350 DeleteObject32(hFont);
1351 dprintf_font(stddeb, "EnumFontFamiliesEx32A // i=%d lpLogFont=%p lptm=%p\n", i, lpEnumLogFont, lptm);
1353 nRet = lpEnumFunc(lpEnumLogFont,lptm,0,lpData);
1354 if (nRet == 0) {
1355 dprintf_font(stddeb,"EnumFontFamiliesEx32A // EnumEnd requested by application !\n");
1356 break;
1359 GDI_HEAP_FREE(hMet);
1360 GDI_HEAP_FREE(hLog);
1361 return nRet;
1365 /*************************************************************************
1366 * EnumFontFamiliesW [GDI32.82]
1368 INT32 EnumFontFamiliesEx32W(HDC32 hDC, LPLOGFONT32W lpLF, FONTENUMPROCEX32W lpEnumFunc, LPARAM lpData, DWORD reserved)
1370 HLOCAL16 hLog;
1371 HLOCAL16 hMet;
1372 HFONT32 hFont;
1373 HFONT32 hOldFont;
1374 LPENUMLOGFONTEX32W lpEnumLogFont;
1375 LPNEWTEXTMETRICEX32W lptm;
1376 LPSTR lpOldName;
1377 int nRet = 0;
1378 int i;
1379 LPSTR lpszFamily;
1381 dprintf_font(stddeb,"EnumFontFamiliesEx32W(%04x, %p, %08lx, %08lx, %08lx)\n",
1382 hDC, lpLF, (DWORD)lpEnumFunc, lpData,reserved);
1383 if (lpEnumFunc == 0) return 0;
1384 hLog = GDI_HEAP_ALLOC( sizeof(ENUMLOGFONTEX32W) );
1385 lpEnumLogFont = (LPENUMLOGFONTEX32W) GDI_HEAP_LIN_ADDR(hLog);
1386 if (lpEnumLogFont == NULL) {
1387 fprintf(stderr,"EnumFontFamilies32W // can't alloc LOGFONT struct !\n");
1388 return 0;
1390 hMet = GDI_HEAP_ALLOC( sizeof(NEWTEXTMETRICEX32W) );
1391 lptm = (LPNEWTEXTMETRICEX32W) GDI_HEAP_LIN_ADDR(hMet);
1392 if (lptm == NULL) {
1393 GDI_HEAP_FREE(hLog);
1394 fprintf(stderr,"EnumFontFamilies32W // can't alloc TEXTMETRIC struct !\n");
1395 return 0;
1397 lpOldName = NULL;
1398 lpszFamily = HEAP_strdupWtoA( GetProcessHeap(), 0, lpLF->lfFaceName );
1399 if (lpLogFontList[0] == NULL) InitFontsList();
1400 for(i = 0; lpLogFontList[i] != NULL; i++) {
1401 /* lfCharSet */
1402 if (lpLF->lfCharSet!=DEFAULT_CHARSET)
1403 if (lpLogFontList[i]->lfCharSet != lpLF->lfCharSet)
1404 continue;
1406 /* lfPitchAndFamily only of importance in Hebrew and Arabic versions. */
1407 /* lfFaceName */
1408 if (lpszFamily[0]) {
1409 if (lstrcmpi32A(lpszFamily,lpLogFontList[i]->lfFaceName))
1410 continue;
1411 } else {
1412 if ((lpOldName!=NULL) &&
1413 !lstrcmpi32A(lpOldName,lpLogFontList[i]->lfFaceName))
1414 continue;
1415 lpOldName=lpLogFontList[i]->lfFaceName;
1418 FONT_LOGFONT16ToLOGFONT32W(lpLogFontList[i],&(lpEnumLogFont->elfLogFont));
1419 lpEnumLogFont->elfFullName[0] = 0;
1420 lpEnumLogFont->elfStyle[0] = 0;
1421 lpEnumLogFont->elfScript[0] = 0;
1422 hFont = CreateFontIndirect32W((LPLOGFONT32W)lpEnumLogFont);
1423 hOldFont = SelectObject32(hDC, hFont);
1424 GetTextMetrics32W(hDC, (LPTEXTMETRIC32W)lptm);
1425 SelectObject32(hDC, hOldFont);
1426 DeleteObject32(hFont);
1427 dprintf_font(stddeb, "EnumFontFamilies32W // i=%d lpLogFont=%p lptm=%p\n", i, lpEnumLogFont, lptm);
1429 nRet = lpEnumFunc(lpEnumLogFont,lptm,0,lpData);
1430 if (nRet == 0) {
1431 dprintf_font(stddeb,"EnumFontFamilies32W // EnumEnd requested by application !\n");
1432 break;
1435 GDI_HEAP_FREE(hMet);
1436 GDI_HEAP_FREE(hLog);
1437 HeapFree( GetProcessHeap(), 0, lpszFamily );
1438 return nRet;
1442 /*************************************************************************
1443 * GetRasterizerCaps16 (GDI.313)
1445 BOOL16 GetRasterizerCaps16( LPRASTERIZER_STATUS lprs, UINT16 cbNumBytes )
1447 return GetRasterizerCaps32( lprs, cbNumBytes );
1451 /*************************************************************************
1452 * GetRasterizerCaps32 (GDI32.216)
1454 BOOL32 GetRasterizerCaps32( LPRASTERIZER_STATUS lprs, UINT32 cbNumBytes )
1456 /* This is not much more than a dummy */
1457 RASTERIZER_STATUS rs;
1459 rs.nSize = sizeof(rs);
1460 rs.wFlags = 0;
1461 rs.nLanguageID = 0;
1462 return TRUE;
1466 /*************************************************************************
1467 * GetKerningPairs16 (GDI.332)
1469 INT16 GetKerningPairs16( HDC16 hDC, INT16 cPairs,
1470 LPKERNINGPAIR16 lpKerningPairs )
1472 /* This has to be dealt with when proper font handling is in place
1474 * At this time kerning is ignored (set to 0)
1476 int i;
1477 fprintf(stdnimp,"GetKerningPairs16: almost empty stub!\n");
1478 for (i = 0; i < cPairs; i++) lpKerningPairs[i].iKernAmount = 0;
1479 return 0;
1483 /*************************************************************************
1484 * GetKerningPairs32A (GDI32.192)
1486 DWORD GetKerningPairs32A( HDC32 hDC, DWORD cPairs,
1487 LPKERNINGPAIR32 lpKerningPairs )
1489 /* This has to be dealt with when proper font handling is in place
1491 * At this time kerning is ignored (set to 0)
1493 int i;
1494 fprintf(stdnimp,"GetKerningPairs32: almost empty stub!\n");
1495 for (i = 0; i < cPairs; i++) lpKerningPairs[i].iKernAmount = 0;
1496 return 0;
1500 /*************************************************************************
1501 * GetKerningPairs32W (GDI32.193)
1503 DWORD GetKerningPairs32W( HDC32 hDC, DWORD cPairs,
1504 LPKERNINGPAIR32 lpKerningPairs )
1506 return GetKerningPairs32A( hDC, cPairs, lpKerningPairs );