Release 970215
[wine/multimedia.git] / objects / font.c
blobedf0266248f1d8928a47244cc9631c23fdfa5084
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;
205 /***********************************************************************
206 * GetGlyphOutLine (GDI.309)
208 DWORD GetGlyphOutLine( HDC16 hdc, UINT uChar, UINT fuFormat,
209 LPGLYPHMETRICS lpgm, DWORD cbBuffer, LPSTR lpBuffer,
210 LPMAT2 lpmat2)
212 fprintf( stdnimp,"GetGlyphOutLine(%04x, '%c', %04x, %p, %ld, %p, %p) // - empty stub!\n",
213 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
214 return (DWORD)-1; /* failure */
218 /***********************************************************************
219 * CreateScalableFontResource (GDI.310)
221 BOOL CreateScalableFontResource( UINT fHidden,LPSTR lpszResourceFile,
222 LPSTR lpszFontFile, LPSTR lpszCurrentPath )
224 /* fHidden=1 - only visible for the calling app, read-only, not
225 * enumbered with EnumFonts/EnumFontFamilies
226 * lpszCurrentPath can be NULL
228 fprintf(stdnimp,"CreateScalableFontResource(%d,%s,%s,%s) // empty stub!\n",
229 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
230 return FALSE; /* create failed */
234 /***********************************************************************
235 * CreateFontIndirect16 (GDI.57)
237 HFONT16 CreateFontIndirect16( const LOGFONT16 *font )
239 FONTOBJ * fontPtr;
240 HFONT16 hfont;
242 if (!font)
244 fprintf(stderr,"CreateFontIndirect: font is NULL : returning NULL\n");
245 return 0;
247 hfont = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC );
248 if (!hfont) return 0;
249 fontPtr = (FONTOBJ *) GDI_HEAP_LIN_ADDR( hfont );
250 memcpy( &fontPtr->logfont, font, sizeof(LOGFONT16) );
251 dprintf_font(stddeb,"CreateFontIndirect(%p (%d,%d)); return %04x\n",
252 font, font->lfHeight, font->lfWidth, hfont);
253 return hfont;
257 /***********************************************************************
258 * CreateFontIndirect32A (GDI32.44)
260 HFONT32 CreateFontIndirect32A( const LOGFONT32A *font )
262 LOGFONT16 font16;
264 FONT_LOGFONT32AToLOGFONT16(font,&font16);
266 return CreateFontIndirect16( &font16 );
270 /***********************************************************************
271 * CreateFontIndirect32W (GDI32.45)
273 HFONT32 CreateFontIndirect32W( const LOGFONT32W *font )
275 LOGFONT16 font16;
277 FONT_LOGFONT32WToLOGFONT16(font,&font16);
278 return CreateFontIndirect16( &font16 );
282 /***********************************************************************
283 * CreateFont16 (GDI.56)
285 HFONT16 CreateFont16( INT16 height, INT16 width, INT16 esc, INT16 orient,
286 INT16 weight, BYTE italic, BYTE underline,
287 BYTE strikeout, BYTE charset, BYTE outpres,
288 BYTE clippres, BYTE quality, BYTE pitch, LPCSTR name )
290 LOGFONT16 logfont = {height, width, esc, orient, weight, italic, underline,
291 strikeout, charset, outpres, clippres, quality, pitch, };
292 dprintf_font(stddeb,"CreateFont16(%d,%d)\n", height, width);
293 if (name) lstrcpyn32A(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
294 else logfont.lfFaceName[0] = '\0';
295 return CreateFontIndirect16( &logfont );
300 /*************************************************************************
301 * CreateFont32A (GDI32.43)
303 HFONT32 CreateFont32A( INT32 height, INT32 width, INT32 esc, INT32 orient,
304 INT32 weight, DWORD italic, DWORD underline,
305 DWORD strikeout, DWORD charset, DWORD outpres,
306 DWORD clippres, DWORD quality, DWORD pitch, LPCSTR name)
308 return (HFONT32)CreateFont16( height, width, esc, orient, weight, italic,
309 underline, strikeout, charset, outpres,
310 clippres, quality, pitch, name );
314 /*************************************************************************
315 * CreateFont32W (GDI32.46)
317 HFONT32 CreateFont32W( INT32 height, INT32 width, INT32 esc, INT32 orient,
318 INT32 weight, DWORD italic, DWORD underline,
319 DWORD strikeout, DWORD charset, DWORD outpres,
320 DWORD clippres, DWORD quality, DWORD pitch,
321 LPCWSTR name )
323 LPSTR namea = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
324 HFONT32 ret = (HFONT32)CreateFont16( height, width, esc, orient, weight,
325 italic, underline, strikeout, charset,
326 outpres, clippres, quality, pitch,
327 namea );
328 HeapFree( GetProcessHeap(), 0, namea );
329 return ret;
333 /***********************************************************************
334 * FONT_GetObject16
336 INT16 FONT_GetObject16( FONTOBJ * font, INT16 count, LPSTR buffer )
338 if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
339 memcpy( buffer, &font->logfont, count );
340 return count;
344 /***********************************************************************
345 * FONT_GetObject32A
347 INT32 FONT_GetObject32A( FONTOBJ *font, INT32 count, LPSTR buffer )
349 LOGFONT32A fnt32;
351 memset(&fnt32, 0, sizeof(fnt32));
352 fnt32.lfHeight = font->logfont.lfHeight;
353 fnt32.lfWidth = font->logfont.lfWidth;
354 fnt32.lfEscapement = font->logfont.lfEscapement;
355 fnt32.lfOrientation = font->logfont.lfOrientation;
356 fnt32.lfWeight = font->logfont.lfWeight;
357 fnt32.lfItalic = font->logfont.lfItalic;
358 fnt32.lfUnderline = font->logfont.lfUnderline;
359 fnt32.lfStrikeOut = font->logfont.lfStrikeOut;
360 fnt32.lfCharSet = font->logfont.lfCharSet;
361 fnt32.lfOutPrecision = font->logfont.lfOutPrecision;
362 fnt32.lfClipPrecision = font->logfont.lfClipPrecision;
363 fnt32.lfQuality = font->logfont.lfQuality;
364 fnt32.lfPitchAndFamily = font->logfont.lfPitchAndFamily;
365 strncpy( fnt32.lfFaceName, font->logfont.lfFaceName,
366 sizeof(fnt32.lfFaceName) );
368 if (count > sizeof(fnt32)) count = sizeof(fnt32);
369 memcpy( buffer, &fnt32, count );
370 return count;
376 /***********************************************************************
377 * GetTextCharacterExtra16 (GDI.89)
379 INT16 GetTextCharacterExtra16( HDC16 hdc )
381 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
382 if (!dc) return 0;
383 return abs( (dc->w.charExtra * dc->wndExtX + dc->vportExtX / 2)
384 / dc->vportExtX );
388 /***********************************************************************
389 * GetTextCharacterExtra32 (GDI32.225)
391 INT32 GetTextCharacterExtra32( HDC32 hdc )
393 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
394 if (!dc) return 0;
395 return abs( (dc->w.charExtra * dc->wndExtX + dc->vportExtX / 2)
396 / dc->vportExtX );
400 /***********************************************************************
401 * SetTextCharacterExtra16 (GDI.8)
403 INT16 SetTextCharacterExtra16( HDC16 hdc, INT16 extra )
405 return (INT16)SetTextCharacterExtra32( hdc, extra );
409 /***********************************************************************
410 * SetTextCharacterExtra32 (GDI32.337)
412 INT32 SetTextCharacterExtra32( HDC32 hdc, INT32 extra )
414 INT32 prev;
415 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
416 if (!dc) return 0;
417 extra = (extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX;
418 prev = dc->w.charExtra;
419 dc->w.charExtra = abs(extra);
420 return (prev * dc->wndExtX + dc->vportExtX / 2) / dc->vportExtX;
424 /***********************************************************************
425 * SetTextJustification16 (GDI.10)
427 INT16 SetTextJustification16( HDC16 hdc, INT16 extra, INT16 breaks )
429 return SetTextJustification32( hdc, extra, breaks );
433 /***********************************************************************
434 * SetTextJustification32 (GDI32.339)
436 BOOL32 SetTextJustification32( HDC32 hdc, INT32 extra, INT32 breaks )
438 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
439 if (!dc) return 0;
441 extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
442 if (!extra) breaks = 0;
443 dc->w.breakTotalExtra = extra;
444 dc->w.breakCount = breaks;
445 if (breaks)
447 dc->w.breakExtra = extra / breaks;
448 dc->w.breakRem = extra - (dc->w.breakCount * dc->w.breakExtra);
450 else
452 dc->w.breakExtra = 0;
453 dc->w.breakRem = 0;
455 return 1;
459 /***********************************************************************
460 * GetTextFace16 (GDI.92)
462 INT16 GetTextFace16( HDC16 hdc, INT16 count, LPSTR name )
464 return GetTextFace32A(hdc,count,name);
467 /***********************************************************************
468 * GetTextFace32A (GDI32.234)
470 INT32 GetTextFace32A( HDC32 hdc, INT32 count, LPSTR name )
472 FONTOBJ *font;
474 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
475 if (!dc) return 0;
476 if (!(font = (FONTOBJ *) GDI_GetObjPtr( dc->w.hFont, FONT_MAGIC )))
477 return 0;
478 lstrcpyn32A( name, font->logfont.lfFaceName, count );
479 return strlen(name);
482 /***********************************************************************
483 * GetTextFace32W (GDI32.235)
485 INT32 GetTextFace32W( HDC32 hdc, INT32 count, LPWSTR name )
487 LPSTR nameA = HeapAlloc( GetProcessHeap(), 0, count );
488 INT32 res = GetTextFace32A(hdc,count,nameA);
489 lstrcpyAtoW( name, nameA );
490 HeapFree( GetProcessHeap(), 0, nameA );
491 return res;
495 /***********************************************************************
496 * GetTextExtent (GDI.91)
498 DWORD GetTextExtent( HDC16 hdc, LPCSTR str, INT16 count )
500 SIZE16 size;
501 if (!GetTextExtentPoint16( hdc, str, count, &size )) return 0;
502 return MAKELONG( size.cx, size.cy );
506 /***********************************************************************
507 * GetTextExtentPoint16 (GDI.471)
509 * FIXME: Should this have a bug for compatibility?
510 * Original Windows versions of GetTextExtentPoint{A,W} have documented
511 * bugs.
513 BOOL16 GetTextExtentPoint16( HDC16 hdc, LPCSTR str, INT16 count, LPSIZE16 size)
515 SIZE32 size32;
516 BOOL32 ret = GetTextExtentPoint32A( hdc, str, count, &size32 );
517 CONV_SIZE32TO16( &size32, size );
518 return (BOOL16)ret;
522 /***********************************************************************
523 * GetTextExtentPoint32A (GDI32.230)
525 BOOL32 GetTextExtentPoint32A( HDC32 hdc, LPCSTR str, INT32 count,
526 LPSIZE32 size )
528 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
529 if (!dc)
531 if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
532 return FALSE;
535 if (!dc->funcs->pGetTextExtentPoint ||
536 !dc->funcs->pGetTextExtentPoint( dc, str, count, size ))
537 return FALSE;
539 dprintf_font(stddeb,"GetTextExtentPoint(%08x '%.*s' %d %p): returning %d,%d\n",
540 hdc, count, str, count, size, size->cx, size->cy );
541 return TRUE;
545 /***********************************************************************
546 * GetTextExtentPoint32W (GDI32.231)
548 BOOL32 GetTextExtentPoint32W( HDC32 hdc, LPCWSTR str, INT32 count,
549 LPSIZE32 size )
551 LPSTR p = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
552 BOOL32 ret = GetTextExtentPoint32A( hdc, p, count, size );
553 HeapFree( GetProcessHeap(), 0, p );
554 return ret;
557 /***********************************************************************
558 * GetTextExtentPoint32ABuggy (GDI32.232)
560 BOOL32 GetTextExtentPoint32ABuggy( HDC32 hdc, LPCSTR str, INT32 count,
561 LPSIZE32 size )
563 dprintf_font( stddeb, "GetTextExtentPoint32ABuggy: not bug compatible.\n");
564 return GetTextExtentPoint32A( hdc, str, count, size );
567 /***********************************************************************
568 * GetTextExtentPoint32WBuggy (GDI32.233)
570 BOOL32 GetTextExtentPoint32WBuggy( HDC32 hdc, LPCWSTR str, INT32 count,
571 LPSIZE32 size )
573 dprintf_font( stddeb, "GetTextExtentPoint32WBuggy: not bug compatible.\n");
574 return GetTextExtentPoint32W( hdc, str, count, size );
578 /***********************************************************************
579 * GetTextExtentExPoint32A (GDI32.228)
581 BOOL32 GetTextExtentExPoint32A( HDC32 hdc, LPCSTR str, INT32 count,
582 INT32 maxExt,LPINT32 lpnFit, LPINT32 alpDx,
583 LPSIZE32 size )
585 int index;
586 SIZE32 tSize;
587 int nFit=0;
588 int extent=0;
589 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
590 if (!dc)
592 if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
593 return FALSE;
595 if (!dc->funcs->pGetTextExtentPoint) return FALSE;
597 size->cx=0; size->cy=0;
598 for(index=0;index<count;index++)
600 if(!dc->funcs->pGetTextExtentPoint( dc, str, 1, &tSize )) return FALSE;
601 if(extent+tSize.cx<maxExt)
603 extent+=tSize.cx;
604 nFit++;
605 str++;
606 if(alpDx) alpDx[index]=extent;
607 if(tSize.cy > size->cy) size->cy=tSize.cy;
609 else break;
611 size->cx=extent;
612 *lpnFit=nFit;
613 dprintf_font(stddeb,"GetTextExtentExPoint32A(%08x '%.*s' %d) returning %d %d %d\n",
614 hdc,count,str,maxExt,nFit, size->cx,size->cy);
615 return TRUE;
618 /***********************************************************************
619 * GetTextExtentExPoint32W (GDI32.229)
622 BOOL32 GetTextExtentExPoint32W( HDC32 hdc, LPCWSTR str, INT32 count,
623 INT32 maxExt, LPINT32 lpnFit, LPINT32 alpDx,
624 LPSIZE32 size )
626 LPSTR p = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
627 BOOL32 ret = GetTextExtentExPoint32A( hdc, p, count, maxExt,
628 lpnFit, alpDx, size);
629 HeapFree( GetProcessHeap(), 0, p );
630 return ret;
633 /***********************************************************************
634 * GetTextMetrics16 (GDI.93)
636 BOOL16 GetTextMetrics16( HDC16 hdc, TEXTMETRIC16 *metrics )
638 TEXTMETRIC32A tm;
640 if (!GetTextMetrics32A( (HDC32)hdc, &tm )) return FALSE;
641 metrics->tmHeight = tm.tmHeight;
642 metrics->tmAscent = tm.tmAscent;
643 metrics->tmDescent = tm.tmDescent;
644 metrics->tmInternalLeading = tm.tmInternalLeading;
645 metrics->tmExternalLeading = tm.tmExternalLeading;
646 metrics->tmAveCharWidth = tm.tmAveCharWidth;
647 metrics->tmMaxCharWidth = tm.tmMaxCharWidth;
648 metrics->tmWeight = tm.tmWeight;
649 metrics->tmOverhang = tm.tmOverhang;
650 metrics->tmDigitizedAspectX = tm.tmDigitizedAspectX;
651 metrics->tmDigitizedAspectY = tm.tmDigitizedAspectY;
652 metrics->tmFirstChar = tm.tmFirstChar;
653 metrics->tmLastChar = tm.tmLastChar;
654 metrics->tmDefaultChar = tm.tmDefaultChar;
655 metrics->tmBreakChar = tm.tmBreakChar;
656 metrics->tmItalic = tm.tmItalic;
657 metrics->tmUnderlined = tm.tmUnderlined;
658 metrics->tmStruckOut = tm.tmStruckOut;
659 metrics->tmPitchAndFamily = tm.tmPitchAndFamily;
660 metrics->tmCharSet = tm.tmCharSet;
661 return TRUE;
665 /***********************************************************************
666 * GetTextMetrics32A (GDI32.236)
668 BOOL32 GetTextMetrics32A( HDC32 hdc, TEXTMETRIC32A *metrics )
670 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
671 if (!dc)
673 if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
674 return FALSE;
677 if (!dc->funcs->pGetTextMetrics ||
678 !dc->funcs->pGetTextMetrics( dc,metrics ))
679 return FALSE;
680 dprintf_font(stdnimp,"text metrics:\n
681 InternalLeading = %i
682 ExternalLeading = %i
683 MaxCharWidth = %i
684 Weight = %i
685 Italic = %i
686 Underlined = %i
687 StruckOut = %i
688 FirstChar = %i
689 LastChar = %i
690 DefaultChar = %i
691 BreakChar = %i
692 CharSet = %i
693 Overhang = %i
694 DigitizedAspectX = %i
695 DigitizedAspectY = %i
696 AveCharWidth = %i
697 MaxCharWidth = %i
698 Ascent = %i
699 Descent = %i
700 Height = %i\n",
701 metrics->tmInternalLeading,
702 metrics->tmExternalLeading,
703 metrics->tmMaxCharWidth,
704 metrics->tmWeight,
705 metrics->tmItalic,
706 metrics->tmUnderlined,
707 metrics->tmStruckOut,
708 metrics->tmFirstChar,
709 metrics->tmLastChar,
710 metrics->tmDefaultChar,
711 metrics->tmBreakChar,
712 metrics->tmCharSet,
713 metrics->tmOverhang,
714 metrics->tmDigitizedAspectX,
715 metrics->tmDigitizedAspectY,
716 metrics->tmAveCharWidth,
717 metrics->tmMaxCharWidth,
718 metrics->tmAscent,
719 metrics->tmDescent,
720 metrics->tmHeight);
721 return TRUE;
725 /***********************************************************************
726 * GetTextMetrics32W (GDI32.237)
728 BOOL32 GetTextMetrics32W( HDC32 hdc, TEXTMETRIC32W *metrics )
730 TEXTMETRIC32A tm;
731 if (!GetTextMetrics32A( (HDC16)hdc, &tm )) return FALSE;
732 metrics->tmHeight = tm.tmHeight;
733 metrics->tmAscent = tm.tmAscent;
734 metrics->tmDescent = tm.tmDescent;
735 metrics->tmInternalLeading = tm.tmInternalLeading;
736 metrics->tmExternalLeading = tm.tmExternalLeading;
737 metrics->tmAveCharWidth = tm.tmAveCharWidth;
738 metrics->tmMaxCharWidth = tm.tmMaxCharWidth;
739 metrics->tmWeight = tm.tmWeight;
740 metrics->tmOverhang = tm.tmOverhang;
741 metrics->tmDigitizedAspectX = tm.tmDigitizedAspectX;
742 metrics->tmDigitizedAspectY = tm.tmDigitizedAspectY;
743 metrics->tmFirstChar = tm.tmFirstChar;
744 metrics->tmLastChar = tm.tmLastChar;
745 metrics->tmDefaultChar = tm.tmDefaultChar;
746 metrics->tmBreakChar = tm.tmBreakChar;
747 metrics->tmItalic = tm.tmItalic;
748 metrics->tmUnderlined = tm.tmUnderlined;
749 metrics->tmStruckOut = tm.tmStruckOut;
750 metrics->tmPitchAndFamily = tm.tmPitchAndFamily;
751 metrics->tmCharSet = tm.tmCharSet;
752 return TRUE;
756 /***********************************************************************
757 * SetMapperFlags16 (GDI.349)
759 DWORD SetMapperFlags16( HDC16 hDC, DWORD dwFlag )
761 return SetMapperFlags32( hDC, dwFlag );
765 /***********************************************************************
766 * SetMapperFlags32 (GDI32.322)
768 DWORD SetMapperFlags32( HDC32 hDC, DWORD dwFlag )
770 dprintf_font(stdnimp,"SetmapperFlags(%04x, %08lX) // Empty Stub !\n",
771 hDC, dwFlag);
772 return 0L;
776 /***********************************************************************
777 * GetCharABCWidths16 (GDI.307)
779 BOOL16 GetCharABCWidths16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
780 LPABC16 abc )
782 ABC32 abc32;
783 if (!GetCharABCWidths32A( hdc, firstChar, lastChar, &abc32 )) return FALSE;
784 abc->abcA = abc32.abcA;
785 abc->abcB = abc32.abcB;
786 abc->abcC = abc32.abcC;
787 return TRUE;
791 /***********************************************************************
792 * GetCharABCWidths32A (GDI32.149)
794 BOOL32 GetCharABCWidths32A( HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
795 LPABC32 abc )
797 /* No TrueType fonts in Wine so far */
798 fprintf( stdnimp, "STUB: GetCharABCWidths(%04x,%04x,%04x,%p)\n",
799 hdc, firstChar, lastChar, abc );
800 return FALSE;
804 /***********************************************************************
805 * GetCharABCWidths32W (GDI32.152)
807 BOOL32 GetCharABCWidths32W( HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
808 LPABC32 abc )
810 return GetCharABCWidths32A( hdc, firstChar, lastChar, abc );
814 /***********************************************************************
815 * GetCharWidth16 (GDI.350)
817 BOOL16 GetCharWidth16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
818 LPINT16 buffer )
820 int i, width;
821 XFontStruct *xfont;
822 XCharStruct *cs, *def;
824 DC *dc = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC);
825 if (!dc) return FALSE;
826 xfont = dc->u.x.font.fstruct;
828 /* fixed font? */
829 if (xfont->per_char == NULL)
831 for (i = firstChar; i <= lastChar; i++)
832 *buffer++ = xfont->max_bounds.width;
833 return TRUE;
836 CI_GET_DEFAULT_INFO(xfont, def);
838 for (i = firstChar; i <= lastChar; i++)
840 CI_GET_CHAR_INFO( xfont, i, def, cs );
841 width = cs ? cs->width : xfont->max_bounds.width;
842 *buffer++ = MAX( width, 0 );
844 return TRUE;
848 /***********************************************************************
849 * GetCharWidth32A (GDI32.155)
851 BOOL32 GetCharWidth32A( HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
852 LPINT32 buffer )
854 int i, width;
855 XFontStruct *xfont;
856 XCharStruct *cs, *def;
858 DC *dc = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC);
859 if (!dc) return FALSE;
860 xfont = dc->u.x.font.fstruct;
862 /* fixed font? */
863 if (xfont->per_char == NULL)
865 for (i = firstChar; i <= lastChar; i++)
866 *buffer++ = xfont->max_bounds.width;
867 return TRUE;
870 CI_GET_DEFAULT_INFO(xfont, def);
872 for (i = firstChar; i <= lastChar; i++)
874 CI_GET_CHAR_INFO( xfont, i, def, cs );
875 width = cs ? cs->width : xfont->max_bounds.width;
876 *buffer++ = MAX( width, 0 );
878 return TRUE;
882 /***********************************************************************
883 * GetCharWidth32W (GDI32.158)
885 BOOL32 GetCharWidth32W( HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
886 LPINT32 buffer )
888 return GetCharWidth32A( hdc, firstChar, lastChar, buffer );
892 /***********************************************************************
893 * AddFontResource (GDI.119)
895 INT AddFontResource( LPCSTR str )
897 if (HIWORD(str))
898 fprintf( stdnimp, "STUB: AddFontResource('%s')\n", str );
899 else
900 fprintf( stdnimp, "STUB: AddFontResource(%04x)\n", LOWORD(str) );
901 return 1;
905 /***********************************************************************
906 * RemoveFontResource (GDI.136)
908 BOOL RemoveFontResource( LPSTR str )
910 if (HIWORD(str))
911 fprintf( stdnimp, "STUB: RemoveFontResource('%s')\n", str );
912 else
913 fprintf( stdnimp, "STUB: RemoveFontResource(%04x)\n", LOWORD(str) );
914 return TRUE;
917 /*************************************************************************
918 * FONT_ParseFontParms [internal]
920 int FONT_ParseFontParms(LPSTR lpFont, WORD wParmsNo, LPSTR lpRetStr, WORD wMaxSiz)
922 int i;
923 if (lpFont == NULL) return 0;
924 if (lpRetStr == NULL) return 0;
925 for (i = 0; (*lpFont != '\0' && i != wParmsNo); ) {
926 if (*lpFont == '-') i++;
927 lpFont++;
929 if (i == wParmsNo) {
930 if (*lpFont == '-') lpFont++;
931 wMaxSiz--;
932 for (i = 0; (*lpFont != '\0' && *lpFont != '-' && i < wMaxSiz); i++)
933 *(lpRetStr + i) = *lpFont++;
934 *(lpRetStr + i) = '\0';
935 return i;
937 else
938 lpRetStr[0] = '\0';
939 return 0;
944 /*************************************************************************
945 * InitFontsList [internal]
948 static int logfcmp(const void *a,const void *b)
950 return lstrcmpi32A( (*(LPLOGFONT16 *)a)->lfFaceName,
951 (*(LPLOGFONT16 *)b)->lfFaceName );
954 void InitFontsList(void)
956 char str[32];
957 char pattern[100];
958 char *family, *weight, *charset;
959 char **names;
960 char slant, spacing;
961 int i, count;
962 LPLOGFONT16 lpNewFont;
964 dprintf_font(stddeb,"InitFontsList !\n");
966 weight = "medium";
967 slant = 'r';
968 spacing = '*';
969 charset = "*";
970 family = "*-*";
972 sprintf( pattern, "-%s-%s-%c-normal-*-*-*-*-*-%c-*-%s",
973 family, weight, slant, spacing, charset);
974 names = XListFonts( display, pattern, MAX_FONTS, &count );
975 dprintf_font(stddeb,"InitFontsList // count=%d \n", count);
977 lpNewFont = malloc((sizeof(LOGFONT16)+LF_FACESIZE)*count);
978 if (lpNewFont == NULL) {
979 dprintf_font(stddeb,
980 "InitFontsList // Error alloc new font structure !\n");
981 XFreeFontNames(names);
982 return;
985 for (i = 0; i < count; i++) {
986 dprintf_font(stddeb,"InitFontsList // names[%d]='%s' \n", i, names[i]);
988 FONT_ParseFontParms(names[i], 2, str, sizeof(str));
989 strcpy(lpNewFont->lfFaceName, str);
990 FONT_ParseFontParms(names[i], 8, str, sizeof(str));
991 lpNewFont->lfHeight = atoi(str) / 10;
992 FONT_ParseFontParms(names[i], 12, str, sizeof(str));
993 lpNewFont->lfWidth = atoi(str) / 10;
994 lpNewFont->lfEscapement = 0;
995 lpNewFont->lfOrientation = 0;
996 lpNewFont->lfWeight = FW_REGULAR;
997 lpNewFont->lfItalic = 0;
998 lpNewFont->lfUnderline = 0;
999 lpNewFont->lfStrikeOut = 0;
1000 FONT_ParseFontParms(names[i], 13, str, sizeof(str));
1001 if (strcmp(str, "iso8859") == 0) {
1002 lpNewFont->lfCharSet = ANSI_CHARSET;
1003 } else {
1004 lpNewFont->lfCharSet = OEM_CHARSET;
1006 lpNewFont->lfOutPrecision = OUT_DEFAULT_PRECIS;
1007 lpNewFont->lfClipPrecision = CLIP_DEFAULT_PRECIS;
1008 lpNewFont->lfQuality = DEFAULT_QUALITY;
1009 FONT_ParseFontParms(names[i], 11, str, sizeof(str));
1010 switch(str[0]) {
1011 case 'p':
1012 lpNewFont->lfPitchAndFamily = VARIABLE_PITCH | FF_SWISS;
1013 break;
1014 case 'm':
1015 case 'c':
1016 lpNewFont->lfPitchAndFamily = FIXED_PITCH | FF_MODERN;
1017 break;
1018 default:
1019 lpNewFont->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
1020 break;
1022 dprintf_font( stddeb,
1023 "InitFontsList // lpNewFont->lfHeight=%d\n",
1024 lpNewFont->lfHeight );
1025 dprintf_font( stddeb,
1026 "InitFontsList // lpNewFont->lfWidth=%d\n",
1027 lpNewFont->lfWidth );
1028 dprintf_font( stddeb,
1029 "InitFontsList // lfFaceName='%s'\n",
1030 lpNewFont->lfFaceName );
1031 lpLogFontList[i] = lpNewFont;
1032 lpNewFont = (LPLOGFONT16)
1033 ((char *)lpNewFont + sizeof(LOGFONT16)+LF_FACESIZE);
1035 lpLogFontList[i] = NULL;
1037 qsort(lpLogFontList,count,sizeof(*lpLogFontList),logfcmp);
1038 XFreeFontNames(names);
1041 /*************************************************************************
1042 * EnumFonts [GDI.70]
1043 * We reuse EnumFontFamilies* for the callback function get the same
1044 * structs (+ extra stuff at the end which will be ignored by the enum funcs)
1046 INT16 EnumFonts16(HDC16 hDC, LPCSTR lpFaceName, FONTENUMPROC16 lpEnumFunc, LPARAM lpData)
1048 return EnumFontFamilies16(hDC,lpFaceName,lpEnumFunc,lpData);
1051 /*************************************************************************
1052 * EnumFontsA [GDI32.84]
1054 INT32 EnumFonts32A(HDC32 hDC, LPCSTR lpFaceName, FONTENUMPROC32A lpEnumFunc, LPARAM lpData)
1056 return EnumFontFamilies32A(hDC,lpFaceName,lpEnumFunc,lpData);
1059 /*************************************************************************
1060 * EnumFontsA [GDI32.84]
1062 INT32 EnumFonts32W(HDC32 hDC, LPCWSTR lpFaceName, FONTENUMPROC32W lpEnumFunc, LPARAM lpData)
1064 return EnumFontFamilies32W(hDC,lpFaceName,lpEnumFunc,lpData);
1067 /*************************************************************************
1068 * EnumFontFamilies [GDI.330]
1070 INT16 EnumFontFamilies16(HDC16 hDC, LPCSTR lpszFamily, FONTENUMPROC16 lpEnumFunc, LPARAM lpData)
1072 LOGFONT16 LF;
1074 if (lpszFamily)
1075 strcpy(LF.lfFaceName,lpszFamily);
1076 else
1077 LF.lfFaceName[0]='\0';
1078 LF.lfCharSet = DEFAULT_CHARSET;
1080 return EnumFontFamiliesEx16(hDC,&LF,(FONTENUMPROCEX16)lpEnumFunc,lpData,0);
1083 /*************************************************************************
1084 * EnumFontFamiliesA [GDI32.80]
1086 INT32 EnumFontFamilies32A(HDC32 hDC, LPCSTR lpszFamily, FONTENUMPROC32A lpEnumFunc, LPARAM lpData)
1088 LOGFONT32A LF;
1090 if (lpszFamily)
1091 strcpy(LF.lfFaceName,lpszFamily);
1092 else
1093 LF.lfFaceName[0]='\0';
1094 LF.lfCharSet = DEFAULT_CHARSET;
1096 return EnumFontFamiliesEx32A(hDC,&LF,(FONTENUMPROCEX32A)lpEnumFunc,lpData,0);
1099 /*************************************************************************
1100 * EnumFontFamiliesW [GDI32.83]
1102 INT32 EnumFontFamilies32W(HDC32 hDC, LPCWSTR lpszFamilyW, FONTENUMPROC32W lpEnumFunc, LPARAM lpData)
1104 LOGFONT32W LF;
1106 if (lpszFamilyW)
1107 lstrcpy32W(LF.lfFaceName,lpszFamilyW);
1108 else
1109 LF.lfFaceName[0]=0;
1110 LF.lfCharSet = DEFAULT_CHARSET;
1111 return EnumFontFamiliesEx32W(hDC,&LF,(FONTENUMPROCEX32W)lpEnumFunc,lpData,0);
1114 /*************************************************************************
1115 * EnumFontFamiliesEx [GDI.618]
1116 * FIXME: fill the rest of the NEWTEXTMETRICEX and ENUMLOGFONTEX structures.
1117 * (applies to all EnumFontFamiliesEx*)
1118 * winelib/16 support.
1120 INT16 EnumFontFamiliesEx16(HDC16 hDC, LPLOGFONT16 lpLF, FONTENUMPROCEX16 lpEnumFunc, LPARAM lpData,DWORD reserved)
1122 HLOCAL16 hLog;
1123 HLOCAL16 hMet;
1124 HFONT16 hFont;
1125 HFONT16 hOldFont;
1126 LPENUMLOGFONTEX16 lpEnumLogFont;
1127 LPNEWTEXTMETRICEX16 lptm;
1128 LPSTR lpOldName;
1129 char FaceName[LF_FACESIZE];
1130 int nRet = 0;
1131 int i;
1133 dprintf_font(stddeb,"EnumFontFamiliesEx(%04x, '%s', %08lx, %08lx, %08lx)\n",
1134 hDC, lpLF->lfFaceName, (DWORD)lpEnumFunc, lpData, reserved);
1135 if (lpEnumFunc == 0) return 0;
1136 hLog = GDI_HEAP_ALLOC( sizeof(ENUMLOGFONTEX16) );
1137 lpEnumLogFont = (LPENUMLOGFONTEX16) GDI_HEAP_LIN_ADDR(hLog);
1138 if (lpEnumLogFont == NULL) {
1139 fprintf(stderr,"EnumFontFamiliesEx // can't alloc LOGFONT struct !\n");
1140 return 0;
1142 hMet = GDI_HEAP_ALLOC( sizeof(NEWTEXTMETRICEX16) );
1143 lptm = (LPNEWTEXTMETRICEX16) GDI_HEAP_LIN_ADDR(hMet);
1144 if (lptm == NULL) {
1145 GDI_HEAP_FREE(hLog);
1146 fprintf(stderr,"EnumFontFamiliesEx // can't alloc TEXTMETRIC struct !\n");
1147 return 0;
1149 lpOldName = NULL;
1150 strcpy(FaceName,lpLF->lfFaceName);
1152 if (lpLogFontList[0] == NULL) InitFontsList();
1153 for(i = 0; lpLogFontList[i] != NULL; i++) {
1154 /* lfCharSet */
1155 if (lpLF->lfCharSet!=DEFAULT_CHARSET)
1156 if (lpLogFontList[i]->lfCharSet != lpLF->lfCharSet)
1157 continue;
1159 /* lfPitchAndFamily only of importance in Hebrew and Arabic versions. */
1160 /* lfFaceName */
1161 if (FaceName[0])
1163 if (lstrcmpi32A(FaceName,lpLogFontList[i]->lfFaceName))
1164 continue;
1166 else
1168 if ((lpOldName!=NULL) &&
1169 !lstrcmpi32A(lpOldName,lpLogFontList[i]->lfFaceName))
1170 continue;
1171 lpOldName=lpLogFontList[i]->lfFaceName;
1174 memcpy(lpEnumLogFont, lpLogFontList[i], sizeof(LOGFONT16));
1175 strcpy(lpEnumLogFont->elfFullName,"");
1176 strcpy(lpEnumLogFont->elfStyle,"");
1177 hFont = CreateFontIndirect16((LPLOGFONT16)lpEnumLogFont);
1178 hOldFont = SelectObject32(hDC, hFont);
1179 GetTextMetrics16(hDC, (LPTEXTMETRIC16)lptm);
1180 SelectObject32(hDC, hOldFont);
1181 DeleteObject32(hFont);
1182 dprintf_font(stddeb, "EnumFontFamiliesEx // i=%d lpLogFont=%p lptm=%p\n", i, lpEnumLogFont, lptm);
1184 nRet = lpEnumFunc( GDI_HEAP_SEG_ADDR(hLog), GDI_HEAP_SEG_ADDR(hMet),
1185 0, lpData );
1186 if (nRet == 0) {
1187 dprintf_font(stddeb,"EnumFontFamilies // EnumEnd requested by application !\n");
1188 break;
1191 GDI_HEAP_FREE(hMet);
1192 GDI_HEAP_FREE(hLog);
1193 return nRet;
1197 /*************************************************************************
1198 * EnumFontFamiliesExA [GDI32.81]
1199 * FIXME: Don't use 16 bit GDI heap functions (applies to EnumFontFamiliesEx32*)
1201 INT32 EnumFontFamiliesEx32A(HDC32 hDC, LPLOGFONT32A lpLF,FONTENUMPROCEX32A lpEnumFunc, LPARAM lpData,DWORD reserved)
1203 HLOCAL16 hLog;
1204 HLOCAL16 hMet;
1205 HFONT32 hFont;
1206 HFONT32 hOldFont;
1207 LPENUMLOGFONTEX32A lpEnumLogFont;
1208 LPNEWTEXTMETRICEX32A lptm;
1209 LPSTR lpOldName;
1210 char FaceName[LF_FACESIZE];
1211 int nRet = 0;
1212 int i;
1214 dprintf_font(stddeb,"EnumFontFamilies32A(%04x, %p, %08lx, %08lx, %08lx)\n",
1215 hDC, lpLF->lfFaceName, (DWORD)lpEnumFunc, lpData,reserved);
1216 if (lpEnumFunc == 0) return 0;
1217 hLog = GDI_HEAP_ALLOC( sizeof(ENUMLOGFONTEX32A) );
1218 lpEnumLogFont = (LPENUMLOGFONTEX32A) GDI_HEAP_LIN_ADDR(hLog);
1219 if (lpEnumLogFont == NULL) {
1220 fprintf(stderr,"EnumFontFamilies // can't alloc LOGFONT struct !\n");
1221 return 0;
1223 hMet = GDI_HEAP_ALLOC( sizeof(NEWTEXTMETRICEX32A) );
1224 lptm = (LPNEWTEXTMETRICEX32A) GDI_HEAP_LIN_ADDR(hMet);
1225 if (lptm == NULL) {
1226 GDI_HEAP_FREE(hLog);
1227 fprintf(stderr,"EnumFontFamilies32A // can't alloc TEXTMETRIC struct !\n");
1228 return 0;
1230 lpOldName = NULL;
1231 strcpy(FaceName,lpLF->lfFaceName);
1233 if (lpLogFontList[0] == NULL) InitFontsList();
1234 for(i = 0; lpLogFontList[i] != NULL; i++) {
1235 /* lfCharSet */
1236 if (lpLF->lfCharSet!=DEFAULT_CHARSET)
1237 if (lpLogFontList[i]->lfCharSet != lpLF->lfCharSet)
1238 continue;
1240 /* lfPitchAndFamily only of importance in Hebrew and Arabic versions. */
1241 /* lfFaceName */
1242 if (FaceName[0]) {
1243 if (lstrcmpi32A(FaceName,lpLogFontList[i]->lfFaceName))
1244 continue;
1245 } else {
1246 if ((lpOldName!=NULL) &&
1247 !lstrcmpi32A(lpOldName,lpLogFontList[i]->lfFaceName))
1248 continue;
1249 lpOldName=lpLogFontList[i]->lfFaceName;
1252 FONT_LOGFONT16ToLOGFONT32A(lpLogFontList[i],&(lpEnumLogFont->elfLogFont));
1253 strcpy(lpEnumLogFont->elfFullName,"");
1254 strcpy(lpEnumLogFont->elfStyle,"");
1255 strcpy(lpEnumLogFont->elfScript,"");
1256 hFont = CreateFontIndirect32A((LPLOGFONT32A)lpEnumLogFont);
1257 hOldFont = SelectObject32(hDC, hFont);
1258 GetTextMetrics32A(hDC, (LPTEXTMETRIC32A)lptm);
1259 SelectObject32(hDC, hOldFont);
1260 DeleteObject32(hFont);
1261 dprintf_font(stddeb, "EnumFontFamiliesEx32A // i=%d lpLogFont=%p lptm=%p\n", i, lpEnumLogFont, lptm);
1263 nRet = lpEnumFunc(lpEnumLogFont,lptm,0,lpData);
1264 if (nRet == 0) {
1265 dprintf_font(stddeb,"EnumFontFamiliesEx32A // EnumEnd requested by application !\n");
1266 break;
1269 GDI_HEAP_FREE(hMet);
1270 GDI_HEAP_FREE(hLog);
1271 return nRet;
1275 /*************************************************************************
1276 * EnumFontFamiliesW [GDI32.82]
1278 INT32 EnumFontFamiliesEx32W(HDC32 hDC, LPLOGFONT32W lpLF, FONTENUMPROCEX32W lpEnumFunc, LPARAM lpData, DWORD reserved)
1280 HLOCAL16 hLog;
1281 HLOCAL16 hMet;
1282 HFONT32 hFont;
1283 HFONT32 hOldFont;
1284 LPENUMLOGFONTEX32W lpEnumLogFont;
1285 LPNEWTEXTMETRICEX32W lptm;
1286 LPSTR lpOldName;
1287 int nRet = 0;
1288 int i;
1289 LPSTR lpszFamily;
1291 dprintf_font(stddeb,"EnumFontFamiliesEx32W(%04x, %p, %08lx, %08lx, %08lx)\n",
1292 hDC, lpLF, (DWORD)lpEnumFunc, lpData,reserved);
1293 if (lpEnumFunc == 0) return 0;
1294 hLog = GDI_HEAP_ALLOC( sizeof(ENUMLOGFONTEX32W) );
1295 lpEnumLogFont = (LPENUMLOGFONTEX32W) GDI_HEAP_LIN_ADDR(hLog);
1296 if (lpEnumLogFont == NULL) {
1297 fprintf(stderr,"EnumFontFamilies32W // can't alloc LOGFONT struct !\n");
1298 return 0;
1300 hMet = GDI_HEAP_ALLOC( sizeof(NEWTEXTMETRICEX32W) );
1301 lptm = (LPNEWTEXTMETRICEX32W) GDI_HEAP_LIN_ADDR(hMet);
1302 if (lptm == NULL) {
1303 GDI_HEAP_FREE(hLog);
1304 fprintf(stderr,"EnumFontFamilies32W // can't alloc TEXTMETRIC struct !\n");
1305 return 0;
1307 lpOldName = NULL;
1308 lpszFamily = HEAP_strdupWtoA( GetProcessHeap(), 0, lpLF->lfFaceName );
1309 if (lpLogFontList[0] == NULL) InitFontsList();
1310 for(i = 0; lpLogFontList[i] != NULL; i++) {
1311 /* lfCharSet */
1312 if (lpLF->lfCharSet!=DEFAULT_CHARSET)
1313 if (lpLogFontList[i]->lfCharSet != lpLF->lfCharSet)
1314 continue;
1316 /* lfPitchAndFamily only of importance in Hebrew and Arabic versions. */
1317 /* lfFaceName */
1318 if (lpszFamily[0]) {
1319 if (lstrcmpi32A(lpszFamily,lpLogFontList[i]->lfFaceName))
1320 continue;
1321 } else {
1322 if ((lpOldName!=NULL) &&
1323 !lstrcmpi32A(lpOldName,lpLogFontList[i]->lfFaceName))
1324 continue;
1325 lpOldName=lpLogFontList[i]->lfFaceName;
1328 FONT_LOGFONT16ToLOGFONT32W(lpLogFontList[i],&(lpEnumLogFont->elfLogFont));
1329 lpEnumLogFont->elfFullName[0] = 0;
1330 lpEnumLogFont->elfStyle[0] = 0;
1331 lpEnumLogFont->elfScript[0] = 0;
1332 hFont = CreateFontIndirect32W((LPLOGFONT32W)lpEnumLogFont);
1333 hOldFont = SelectObject32(hDC, hFont);
1334 GetTextMetrics32W(hDC, (LPTEXTMETRIC32W)lptm);
1335 SelectObject32(hDC, hOldFont);
1336 DeleteObject32(hFont);
1337 dprintf_font(stddeb, "EnumFontFamilies32W // i=%d lpLogFont=%p lptm=%p\n", i, lpEnumLogFont, lptm);
1339 nRet = lpEnumFunc(lpEnumLogFont,lptm,0,lpData);
1340 if (nRet == 0) {
1341 dprintf_font(stddeb,"EnumFontFamilies32W // EnumEnd requested by application !\n");
1342 break;
1345 GDI_HEAP_FREE(hMet);
1346 GDI_HEAP_FREE(hLog);
1347 HeapFree( GetProcessHeap(), 0, lpszFamily );
1348 return nRet;
1352 /*************************************************************************
1353 * GetRasterizerCaps [GDI.313]
1356 BOOL GetRasterizerCaps(LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
1358 /* This is not much more than a dummy */
1359 RASTERIZER_STATUS rs;
1361 rs.nSize = sizeof(rs);
1362 rs.wFlags = 0;
1363 rs.nLanguageID = 0;
1364 return True;
1367 /*************************************************************************
1368 * GetKerningPairs [GDI.332]
1370 int GetKerningPairs(HDC16 hDC,int cPairs,LPKERNINGPAIR16 lpKerningPairs)
1372 /* This has to be dealt with when proper font handling is in place
1374 * At this time kerning is ignored (set to 0)
1377 int i;
1378 fprintf(stdnimp,"GetKerningPairs: almost empty stub!\n");
1379 for (i = 0; i < cPairs; i++) lpKerningPairs[i].iKernAmount = 0;
1380 return 0;