4 * Copyright 1993 Alexandre Julliard
6 static char Copyright[] = "Copyright Alexandre Julliard, 1993";
12 #include <X11/Xatom.h>
17 /* #define DEBUG_FONT */
21 static LPLOGFONT lpLogFontList
[MAX_FONTS
] = { NULL
};
24 #define CI_NONEXISTCHAR(cs) (((cs)->width == 0) && \
25 (((cs)->rbearing|(cs)->lbearing| \
26 (cs)->ascent|(cs)->descent) == 0))
29 * CI_GET_CHAR_INFO - return the charinfo struct for the indicated 8bit
30 * character. If the character is in the column and exists, then return the
31 * appropriate metrics (note that fonts with common per-character metrics will
32 * return min_bounds). If none of these hold true, try again with the default
35 #define CI_GET_CHAR_INFO(fs,col,def,cs) \
38 if (col >= fs->min_char_or_byte2 && col <= fs->max_char_or_byte2) { \
39 if (fs->per_char == NULL) { \
40 cs = &fs->min_bounds; \
42 cs = &fs->per_char[(col - fs->min_char_or_byte2)]; \
43 if (CI_NONEXISTCHAR(cs)) cs = def; \
48 #define CI_GET_DEFAULT_INFO(fs,cs) \
49 CI_GET_CHAR_INFO(fs, fs->default_char, NULL, cs)
51 struct FontStructure
{
58 /***********************************************************************
61 BOOL
FONT_Init( void )
67 if( GetPrivateProfileString("fonts", NULL
, "*", temp
, sizeof(temp
), WINE_INI
) > 2 ) {
68 for( ptr
= temp
, i
= 1; strlen(ptr
) != 0; ptr
+= strlen(ptr
) + 1 )
69 if( strcmp( ptr
, "default" ) )
70 FontNames
[i
++].window
= strdup( ptr
);
73 for( i
= 1; i
< FontSize
; i
++ ) {
74 GetPrivateProfileString("fonts", FontNames
[i
].window
, "*", temp
, sizeof(temp
), WINE_INI
);
75 FontNames
[i
].x11
= strdup( temp
);
77 GetPrivateProfileString("fonts", "default", "*", temp
, sizeof(temp
), WINE_INI
);
78 FontNames
[0].x11
= strdup( temp
);
81 FontNames
[0].window
= NULL
; FontNames
[0].x11
= "bitstream-courier";
82 FontNames
[1].window
= "ms sans serif"; FontNames
[1].x11
= "*-helvetica";
83 FontNames
[2].window
= "ms serif"; FontNames
[2].x11
= "*-times";
84 FontNames
[3].window
= "fixedsys"; FontNames
[3].x11
= "*-fixed";
85 FontNames
[4].window
= "arial"; FontNames
[4].x11
= "*-helvetica";
86 FontNames
[5].window
= "helv"; FontNames
[5].x11
= "*-helvetica";
87 FontNames
[6].window
= "roman"; FontNames
[6].x11
= "*-times";
94 /***********************************************************************
97 * Translate a Windows face name to its X11 equivalent.
98 * This will probably have to be customizable.
100 static const char *FONT_TranslateName( char *winFaceName
)
104 for (i
= 1; i
< FontSize
; i
++)
105 if( !strcmp( winFaceName
, FontNames
[i
].window
) ) {
106 dprintf_font(stddeb
, "---- Mapped %s to %s\n", winFaceName
, FontNames
[i
].x11
);
107 return FontNames
[i
].x11
;
109 return FontNames
[0].x11
;
113 /***********************************************************************
116 * Find a X font matching the logical font.
118 static XFontStruct
* FONT_MatchFont( LOGFONT
* font
, DC
* dc
)
121 const char *family
, *weight
, *charset
;
124 int width
, height
, count
;
125 XFontStruct
* fontStruct
;
127 weight
= (font
->lfWeight
> 550) ? "bold" : "medium";
128 slant
= font
->lfItalic
? 'i' : 'r';
129 height
= font
->lfHeight
* dc
->w
.VportExtX
/ dc
->w
.WndExtX
;
130 if (height
== 0) height
= 120; /* Default height = 12 */
133 /* If height is negative, it means the height of the characters */
134 /* *without* the internal leading. So we adjust it a bit to */
135 /* compensate. 5/4 seems to give good results for small fonts. */
136 height
= 10 * (-height
* 5 / 4);
139 width
= 10 * (font
->lfWidth
* dc
->w
.VportExtY
/ dc
->w
.WndExtY
);
140 spacing
= (font
->lfPitchAndFamily
& FIXED_PITCH
) ? 'm' :
141 (font
->lfPitchAndFamily
& VARIABLE_PITCH
) ? 'p' : '*';
142 charset
= (font
->lfCharSet
== ANSI_CHARSET
) ? "iso8859-1" : "*-*";
143 if (*font
->lfFaceName
) family
= FONT_TranslateName( font
->lfFaceName
);
144 else switch(font
->lfPitchAndFamily
& 0xf0)
147 family
= FONT_TranslateName( "roman" );
150 family
= FONT_TranslateName( "swiss" );
153 family
= FONT_TranslateName( "modern" );
156 family
= FONT_TranslateName( "script" );
159 family
= FONT_TranslateName( "decorative" );
167 /* Width==0 seems not to be a valid wildcard on SGI's, using * instead */
169 sprintf( pattern
, "-%s-%s-%c-normal-*-*-%d-*-*-%c-*-%s",
170 family
, weight
, slant
, height
, spacing
, charset
);
172 sprintf( pattern
, "-%s-%s-%c-normal-*-*-%d-*-*-%c-%d-%s",
173 family
, weight
, slant
, height
, spacing
, width
, charset
);
174 dprintf_font(stddeb
, "FONT_MatchFont: '%s'\n", pattern
);
175 names
= XListFonts( display
, pattern
, 1, &count
);
176 if (count
> 0) break;
179 dprintf_font(stddeb
,"*** No match for %s\n", pattern
);
183 dprintf_font(stddeb
," Found '%s'\n", *names
);
184 fontStruct
= XLoadQueryFont( display
, *names
);
185 XFreeFontNames( names
);
190 /***********************************************************************
193 void FONT_GetMetrics( LOGFONT
* logfont
, XFontStruct
* xfont
,
194 TEXTMETRIC
* metrics
)
196 int average
, i
, count
;
199 metrics
->tmAscent
= xfont
->ascent
;
200 metrics
->tmDescent
= xfont
->descent
;
201 metrics
->tmHeight
= xfont
->ascent
+ xfont
->descent
;
203 metrics
->tmInternalLeading
= 0;
204 if (XGetFontProperty( xfont
, XA_X_HEIGHT
, &prop
))
205 metrics
->tmInternalLeading
= xfont
->ascent
- (short)prop
;
206 metrics
->tmExternalLeading
= 0;
207 metrics
->tmMaxCharWidth
= xfont
->max_bounds
.width
;
208 metrics
->tmWeight
= logfont
->lfWeight
;
209 metrics
->tmItalic
= logfont
->lfItalic
;
210 metrics
->tmUnderlined
= logfont
->lfUnderline
;
211 metrics
->tmStruckOut
= logfont
->lfStrikeOut
;
212 metrics
->tmFirstChar
= xfont
->min_char_or_byte2
;
213 metrics
->tmLastChar
= xfont
->max_char_or_byte2
;
214 metrics
->tmDefaultChar
= xfont
->default_char
;
215 metrics
->tmBreakChar
= ' ';
216 metrics
->tmCharSet
= logfont
->lfCharSet
;
217 metrics
->tmOverhang
= 0;
218 metrics
->tmDigitizedAspectX
= 1;
219 metrics
->tmDigitizedAspectY
= 1;
220 metrics
->tmPitchAndFamily
= (logfont
->lfPitchAndFamily
&0xf0)|TMPF_DEVICE
;
221 if (logfont
->lfPitchAndFamily
& FIXED_PITCH
)
222 metrics
->tmPitchAndFamily
|= TMPF_FIXED_PITCH
;
224 if (!xfont
->per_char
) average
= metrics
->tmMaxCharWidth
;
227 XCharStruct
* charPtr
= xfont
->per_char
;
229 for (i
= metrics
->tmFirstChar
; i
<= metrics
->tmLastChar
; i
++)
231 if (!CI_NONEXISTCHAR( charPtr
))
233 average
+= charPtr
->width
;
238 if (count
) average
= (average
+ count
/2) / count
;
240 metrics
->tmAveCharWidth
= average
;
244 /***********************************************************************
245 * CreateFontIndirect (GDI.57)
247 HFONT
CreateFontIndirect( LOGFONT
* font
)
250 HFONT hfont
= GDI_AllocObject( sizeof(FONTOBJ
), FONT_MAGIC
);
251 if (!hfont
) return 0;
252 fontPtr
= (FONTOBJ
*) GDI_HEAP_ADDR( hfont
);
253 memcpy( &fontPtr
->logfont
, font
, sizeof(LOGFONT
) );
254 AnsiLower( fontPtr
->logfont
.lfFaceName
);
255 dprintf_font(stddeb
,"CreateFontIndirect(%p); return %04x\n",font
,hfont
);
260 /***********************************************************************
261 * CreateFont (GDI.56)
263 HFONT
CreateFont( int height
, int width
, int esc
, int orient
, int weight
,
264 BYTE italic
, BYTE underline
, BYTE strikeout
, BYTE charset
,
265 BYTE outpres
, BYTE clippres
, BYTE quality
, BYTE pitch
,
268 LOGFONT logfont
= { height
, width
, esc
, orient
, weight
, italic
, underline
,
269 strikeout
, charset
, outpres
, clippres
, quality
, pitch
, };
270 strncpy( logfont
.lfFaceName
, name
, LF_FACESIZE
);
271 return CreateFontIndirect( &logfont
);
275 /***********************************************************************
278 int FONT_GetObject( FONTOBJ
* font
, int count
, LPSTR buffer
)
280 if (count
> sizeof(LOGFONT
)) count
= sizeof(LOGFONT
);
281 memcpy( buffer
, &font
->logfont
, count
);
286 /***********************************************************************
289 HFONT
FONT_SelectObject( DC
* dc
, HFONT hfont
, FONTOBJ
* font
)
291 static X_PHYSFONT stockFonts
[LAST_STOCK_FONT
-FIRST_STOCK_FONT
+1];
292 X_PHYSFONT
* stockPtr
;
293 HFONT prevHandle
= dc
->w
.hFont
;
294 XFontStruct
* fontStruct
;
295 dprintf_font(stddeb
,"FONT_SelectObject(%p, %04x, %p)\n",
297 /* Load font if necessary */
303 hnewfont
= CreateFont(10, 7, 0, 0, FW_DONTCARE
,
304 FALSE
, FALSE
, FALSE
, DEFAULT_CHARSET
, 0, 0,
305 DEFAULT_QUALITY
, FF_DONTCARE
, "*" );
306 font
= (FONTOBJ
*) GDI_HEAP_ADDR( hnewfont
);
309 if (dc
->header
.wMagic
== METAFILE_DC_MAGIC
)
310 return MF_CreateFontIndirect(dc
, hfont
, &(font
->logfont
));
312 if ((hfont
>= FIRST_STOCK_FONT
) && (hfont
<= LAST_STOCK_FONT
))
313 stockPtr
= &stockFonts
[hfont
- FIRST_STOCK_FONT
];
317 if (!stockPtr
|| !stockPtr
->fstruct
)
319 if (!(fontStruct
= FONT_MatchFont( &font
->logfont
, dc
)))
321 /* If it is not a stock font, we can simply return 0 */
322 if (!stockPtr
) return 0;
323 /* Otherwise we must try to find a substitute */
324 dprintf_font(stddeb
,"Loading font 'fixed' for %x\n", hfont
);
325 font
->logfont
.lfPitchAndFamily
&= ~VARIABLE_PITCH
;
326 font
->logfont
.lfPitchAndFamily
|= FIXED_PITCH
;
327 fontStruct
= XLoadQueryFont( display
, "fixed" );
330 fprintf( stderr
, "No system font could be found. Please check your font path.\n" );
337 fontStruct
= stockPtr
->fstruct
;
339 "FONT_SelectObject: Loaded font from cache %x %p\n",
343 /* Free previous font */
345 if ((prevHandle
< FIRST_STOCK_FONT
) || (prevHandle
> LAST_STOCK_FONT
))
347 if (dc
->u
.x
.font
.fstruct
)
348 XFreeFont( display
, dc
->u
.x
.font
.fstruct
);
356 if (!stockPtr
->fstruct
)
358 stockPtr
->fstruct
= fontStruct
;
359 FONT_GetMetrics( &font
->logfont
, fontStruct
, &stockPtr
->metrics
);
361 memcpy( &dc
->u
.x
.font
, stockPtr
, sizeof(*stockPtr
) );
365 dc
->u
.x
.font
.fstruct
= fontStruct
;
366 FONT_GetMetrics( &font
->logfont
, fontStruct
, &dc
->u
.x
.font
.metrics
);
372 /***********************************************************************
373 * GetTextCharacterExtra (GDI.89)
375 short GetTextCharacterExtra( HDC hdc
)
377 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
379 return abs( (dc
->w
.charExtra
* dc
->w
.WndExtX
+ dc
->w
.VportExtX
/ 2)
384 /***********************************************************************
385 * SetTextCharacterExtra (GDI.8)
387 short SetTextCharacterExtra( HDC hdc
, short extra
)
390 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
392 extra
= (extra
* dc
->w
.VportExtX
+ dc
->w
.WndExtX
/ 2) / dc
->w
.WndExtX
;
393 prev
= dc
->w
.charExtra
;
394 dc
->w
.charExtra
= abs(extra
);
395 return (prev
* dc
->w
.WndExtX
+ dc
->w
.VportExtX
/ 2) / dc
->w
.VportExtX
;
399 /***********************************************************************
400 * SetTextJustification (GDI.10)
402 short SetTextJustification( HDC hdc
, short extra
, short breaks
)
404 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
407 extra
= abs((extra
* dc
->w
.VportExtX
+ dc
->w
.WndExtX
/ 2) / dc
->w
.WndExtX
);
408 if (!extra
) breaks
= 0;
409 dc
->w
.breakTotalExtra
= extra
;
410 dc
->w
.breakCount
= breaks
;
413 dc
->w
.breakExtra
= extra
/ breaks
;
414 dc
->w
.breakRem
= extra
- (dc
->w
.breakCount
* dc
->w
.breakExtra
);
418 dc
->w
.breakExtra
= 0;
425 /***********************************************************************
426 * GetTextFace (GDI.92)
428 INT
GetTextFace( HDC hdc
, INT count
, LPSTR name
)
432 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
434 if (!(font
= (FONTOBJ
*) GDI_GetObjPtr( dc
->w
.hFont
, FONT_MAGIC
)))
436 strncpy( name
, font
->logfont
.lfFaceName
, count
);
437 name
[count
-1] = '\0';
442 /***********************************************************************
443 * GetTextExtent (GDI.91)
445 DWORD
GetTextExtent( HDC hdc
, LPSTR str
, short count
)
448 if (!GetTextExtentPoint( hdc
, str
, count
, &size
)) return 0;
449 return MAKELONG( size
.cx
, size
.cy
);
453 /***********************************************************************
454 * GetTextExtentPoint (GDI.471)
456 BOOL
GetTextExtentPoint( HDC hdc
, LPSTR str
, short count
, LPSIZE size
)
458 int dir
, ascent
, descent
;
461 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
462 if (!dc
) return FALSE
;
463 XTextExtents( dc
->u
.x
.font
.fstruct
, str
, count
, &dir
,
464 &ascent
, &descent
, &info
);
465 size
->cx
= abs((info
.width
+ dc
->w
.breakRem
+ count
* dc
->w
.charExtra
)
466 * dc
->w
.WndExtX
/ dc
->w
.VportExtX
);
467 size
->cy
= abs((dc
->u
.x
.font
.fstruct
->ascent
+dc
->u
.x
.font
.fstruct
->descent
)
468 * dc
->w
.WndExtY
/ dc
->w
.VportExtY
);
470 dprintf_font(stddeb
,"GetTextExtentPoint(%d '%*.*s' %d %p): returning %d,%d\n",
471 hdc
, count
, count
, str
, count
, size
, size
->cx
, size
->cy
);
476 /***********************************************************************
477 * GetTextMetrics (GDI.93)
479 BOOL
GetTextMetrics( HDC hdc
, LPTEXTMETRIC metrics
)
481 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
482 if (!dc
) return FALSE
;
483 memcpy( metrics
, &dc
->u
.x
.font
.metrics
, sizeof(*metrics
) );
485 metrics
->tmAscent
= abs( metrics
->tmAscent
486 * dc
->w
.WndExtY
/ dc
->w
.VportExtY
);
487 metrics
->tmDescent
= abs( metrics
->tmDescent
488 * dc
->w
.WndExtY
/ dc
->w
.VportExtY
);
489 metrics
->tmHeight
= metrics
->tmAscent
+ metrics
->tmDescent
;
490 metrics
->tmInternalLeading
= abs( metrics
->tmInternalLeading
491 * dc
->w
.WndExtY
/ dc
->w
.VportExtY
);
492 metrics
->tmExternalLeading
= abs( metrics
->tmExternalLeading
493 * dc
->w
.WndExtY
/ dc
->w
.VportExtY
);
494 metrics
->tmMaxCharWidth
= abs( metrics
->tmMaxCharWidth
495 * dc
->w
.WndExtX
/ dc
->w
.VportExtX
);
496 metrics
->tmAveCharWidth
= abs( metrics
->tmAveCharWidth
497 * dc
->w
.WndExtX
/ dc
->w
.VportExtX
);
502 /***********************************************************************
503 * SetMapperFlags (GDI.349)
505 DWORD
SetMapperFlags(HDC hDC
, DWORD dwFlag
)
507 dprintf_font(stdnimp
,"SetmapperFlags(%04X, %08lX) // Empty Stub !\n",
513 /***********************************************************************/
516 /***********************************************************************
517 * GetCharWidth (GDI.350)
519 BOOL
GetCharWidth(HDC hdc
, WORD wFirstChar
, WORD wLastChar
, LPINT lpBuffer
)
523 XCharStruct
*cs
, *def
;
525 DC
*dc
= (DC
*)GDI_GetObjPtr(hdc
, DC_MAGIC
);
526 if (!dc
) return FALSE
;
527 xfont
= dc
->u
.x
.font
.fstruct
;
530 if (xfont
->per_char
== NULL
)
532 for (i
= wFirstChar
, j
= 0; i
<= wLastChar
; i
++, j
++)
533 *(lpBuffer
+ j
) = xfont
->max_bounds
.width
;
537 CI_GET_DEFAULT_INFO(xfont
, def
);
539 for (i
= wFirstChar
, j
= 0; i
<= wLastChar
; i
++, j
++)
541 CI_GET_CHAR_INFO(xfont
, i
, def
, cs
);
542 *(lpBuffer
+ j
) = cs
? cs
->width
: xfont
->max_bounds
.width
;
543 if (*(lpBuffer
+ j
) < 0)
550 /***********************************************************************
551 * AddFontResource (GDI.119)
553 int AddFontResource( LPSTR str
)
555 fprintf( stdnimp
, "STUB: AddFontResource('%s')\n", str
);
560 /***********************************************************************
561 * RemoveFontResource (GDI.136)
563 BOOL
RemoveFontResource( LPSTR str
)
565 fprintf( stdnimp
, "STUB: RemoveFontResource('%s')\n", str
);
570 /*************************************************************************
571 * ParseFontParms [internal]
573 int ParseFontParms(LPSTR lpFont
, WORD wParmsNo
, LPSTR lpRetStr
, WORD wMaxSiz
)
576 dprintf_font(stddeb
,"ParseFontParms('%s', %d, %p, %d);\n",
577 lpFont
, wParmsNo
, lpRetStr
, wMaxSiz
);
578 if (lpFont
== NULL
) return 0;
579 if (lpRetStr
== NULL
) return 0;
580 for (i
= 0; (*lpFont
!= '\0' && i
!= wParmsNo
); ) {
581 if (*lpFont
== '-') i
++;
585 if (*lpFont
== '-') lpFont
++;
587 for (i
= 0; (*lpFont
!= '\0' && *lpFont
!= '-' && i
< wMaxSiz
); i
++)
588 *(lpRetStr
+ i
) = *lpFont
++;
589 *(lpRetStr
+ i
) = '\0';
590 dprintf_font(stddeb
,"ParseFontParms // '%s'\n", lpRetStr
);
599 /*************************************************************************
600 * InitFontsList [internal]
602 void InitFontsList(void)
606 char *family
, *weight
, *charset
;
616 dprintf_font(stddeb
,"InitFontsList !\n");
617 sprintf( pattern
, "-%s-%s-%c-normal-*-*-*-*-*-%c-*-%s",
618 family
, weight
, slant
, spacing
, charset
);
619 names
= XListFonts( display
, pattern
, MAX_FONTS
, &count
);
620 dprintf_font(stddeb
,"InitFontsList // count=%d \n", count
);
621 for (i
= 0; i
< count
; i
++) {
622 lpNewFont
= malloc(sizeof(LOGFONT
) + LF_FACESIZE
);
623 if (lpNewFont
== NULL
) {
624 dprintf_font(stddeb
, "InitFontsList // Error alloc new font structure !\n");
627 dprintf_font(stddeb
,"InitFontsList // names[%d]='%s' \n", i
, names
[i
]);
628 ParseFontParms(names
[i
], 2, str
, sizeof(str
));
629 if (strcmp(str
, "fixed") == 0) strcat(str
, "sys");
631 strcpy(lpNewFont
->lfFaceName
, str
);
632 ParseFontParms(names
[i
], 7, str
, sizeof(str
));
633 lpNewFont
->lfHeight
= atoi(str
) / 10;
634 ParseFontParms(names
[i
], 12, str
, sizeof(str
));
635 lpNewFont
->lfWidth
= atoi(str
) / 10;
636 lpNewFont
->lfEscapement
= 0;
637 lpNewFont
->lfOrientation
= 0;
638 lpNewFont
->lfWeight
= FW_REGULAR
;
639 lpNewFont
->lfItalic
= 0;
640 lpNewFont
->lfUnderline
= 0;
641 lpNewFont
->lfStrikeOut
= 0;
642 ParseFontParms(names
[i
], 13, str
, sizeof(str
));
643 if (strcmp(str
, "iso8859") == 0)
644 lpNewFont
->lfCharSet
= ANSI_CHARSET
;
646 lpNewFont
->lfCharSet
= OEM_CHARSET
;
647 lpNewFont
->lfOutPrecision
= OUT_DEFAULT_PRECIS
;
648 lpNewFont
->lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
649 lpNewFont
->lfQuality
= DEFAULT_QUALITY
;
650 ParseFontParms(names
[i
], 11, str
, sizeof(str
));
653 lpNewFont
->lfPitchAndFamily
= VARIABLE_PITCH
| FF_SWISS
;
656 lpNewFont
->lfPitchAndFamily
= FIXED_PITCH
| FF_MODERN
;
659 lpNewFont
->lfPitchAndFamily
= DEFAULT_PITCH
| FF_DONTCARE
;
662 dprintf_font(stddeb
,"InitFontsList // lpNewFont->lfHeight=%d \n", lpNewFont
->lfHeight
);
663 dprintf_font(stddeb
,"InitFontsList // lpNewFont->lfWidth=%d \n", lpNewFont
->lfWidth
);
664 dprintf_font(stddeb
,"InitFontsList // lfFaceName='%s' \n", lpNewFont
->lfFaceName
);
665 lpLogFontList
[i
] = lpNewFont
;
666 lpLogFontList
[i
+1] = NULL
;
668 XFreeFontNames(names
);
672 /*************************************************************************
675 int EnumFonts(HDC hDC
, LPSTR lpFaceName
, FARPROC lpEnumFunc
, LPSTR lpData
)
683 LPSTR lpFaceList
[MAX_FONTS
];
684 char FaceName
[LF_FACESIZE
];
688 dprintf_font(stddeb
,"EnumFonts(%04X, %p='%s', %p, %p)\n",
689 hDC
, lpFaceName
, lpFaceName
, lpEnumFunc
, lpData
);
690 if (lpEnumFunc
== NULL
) return 0;
691 hLog
= GDI_HEAP_ALLOC(GMEM_MOVEABLE
, sizeof(LOGFONT
) + LF_FACESIZE
);
692 lpLogFont
= (LPLOGFONT
) GDI_HEAP_ADDR(hLog
);
693 if (lpLogFont
== NULL
) {
694 dprintf_font(stddeb
,"EnumFonts // can't alloc LOGFONT struct !\n");
697 hMet
= GDI_HEAP_ALLOC(GMEM_MOVEABLE
, sizeof(TEXTMETRIC
));
698 lptm
= (LPTEXTMETRIC
) GDI_HEAP_ADDR(hMet
);
701 dprintf_font(stddeb
, "EnumFonts // can't alloc TEXTMETRIC struct !\n");
704 if (lpFaceName
!= NULL
) {
705 strcpy(FaceName
, lpFaceName
);
708 if (lpLogFontList
[0] == NULL
) InitFontsList();
709 memset(lpFaceList
, 0, MAX_FONTS
* sizeof(LPSTR
));
711 if (lpLogFontList
[i
] == NULL
) break;
712 if (lpFaceName
== NULL
) {
713 for (j
= 0; j
< MAX_FONTS
; j
++) {
714 if (lpFaceList
[j
] == NULL
) break;
715 if (strcmp(lpFaceList
[j
], lpLogFontList
[i
]->lfFaceName
) == 0) {
717 if (lpLogFontList
[i
] == NULL
) break;
720 if (lpLogFontList
[i
] == NULL
) break;
721 lpFaceList
[j
] = lpLogFontList
[i
]->lfFaceName
;
722 dprintf_font(stddeb
,"EnumFonts // enum all 'lpFaceName' '%s' !\n", lpFaceList
[j
]);
725 while(lpLogFontList
[i
] != NULL
) {
726 if (strcmp(FaceName
, lpLogFontList
[i
]->lfFaceName
) == 0) break;
729 if (lpLogFontList
[i
] == NULL
) break;
731 memcpy(lpLogFont
, lpLogFontList
[i
++], sizeof(LOGFONT
) + LF_FACESIZE
);
732 hFont
= CreateFontIndirect(lpLogFont
);
733 hOldFont
= SelectObject(hDC
, hFont
);
734 GetTextMetrics(hDC
, lptm
);
735 SelectObject(hDC
, hOldFont
);
737 dprintf_font(stddeb
,"EnumFonts // i=%d lpLogFont=%p lptm=%p\n", i
, lpLogFont
, lptm
);
740 nRet
= (*lpEnumFunc
)(lpLogFont
, lptm
, 0, lpData
);
742 nRet
= CallBack16(lpEnumFunc
, 4, 2, (int)lpLogFont
,
743 2, (int)lptm
, 0, (int)0, 2, (int)lpData
);
746 dprintf_font(stddeb
,"EnumFonts // EnumEnd requested by application !\n");
756 /*************************************************************************
757 * EnumFontFamilies [GDI.330]
759 int EnumFontFamilies(HDC hDC
, LPSTR lpszFamily
, FARPROC lpEnumFunc
, LPSTR lpData
)
767 LPSTR lpFaceList
[MAX_FONTS
];
768 char FaceName
[LF_FACESIZE
];
772 dprintf_font(stddeb
,"EnumFontFamilies(%04X, %p, %p, %p)\n",
773 hDC
, lpszFamily
, lpEnumFunc
, lpData
);
774 if (lpEnumFunc
== NULL
) return 0;
775 hLog
= GDI_HEAP_ALLOC(GMEM_MOVEABLE
, sizeof(LOGFONT
) + LF_FACESIZE
);
776 lpLogFont
= (LPLOGFONT
) GDI_HEAP_ADDR(hLog
);
777 if (lpLogFont
== NULL
) {
778 dprintf_font(stddeb
,"EnumFontFamilies // can't alloc LOGFONT struct !\n");
781 hMet
= GDI_HEAP_ALLOC(GMEM_MOVEABLE
, sizeof(TEXTMETRIC
));
782 lptm
= (LPTEXTMETRIC
) GDI_HEAP_ADDR(hMet
);
785 dprintf_font(stddeb
,"EnumFontFamilies // can't alloc TEXTMETRIC struct !\n");
788 if (lpszFamily
!= NULL
) {
789 strcpy(FaceName
, lpszFamily
);
792 if (lpLogFontList
[0] == NULL
) InitFontsList();
793 memset(lpFaceList
, 0, MAX_FONTS
* sizeof(LPSTR
));
795 if (lpLogFontList
[i
] == NULL
) break;
796 if (lpszFamily
== NULL
) {
797 if (lpLogFontList
[i
] == NULL
) break;
798 for (j
= 0; j
< MAX_FONTS
; j
++) {
799 if (lpFaceList
[j
] == NULL
) break;
800 if (lpLogFontList
[i
] == NULL
) break;
801 if (strcmp(lpFaceList
[j
], lpLogFontList
[i
]->lfFaceName
) == 0) {
805 if (lpLogFontList
[i
] == NULL
) break;
806 lpFaceList
[j
] = lpLogFontList
[i
]->lfFaceName
;
807 dprintf_font(stddeb
,"EnumFontFamilies // enum all 'lpszFamily' '%s' !\n", lpFaceList
[j
]);
810 while(lpLogFontList
[i
] != NULL
) {
811 if (strcmp(FaceName
, lpLogFontList
[i
]->lfFaceName
) == 0) break;
814 if (lpLogFontList
[i
] == NULL
) break;
816 memcpy(lpLogFont
, lpLogFontList
[i
++], sizeof(LOGFONT
) + LF_FACESIZE
);
817 hFont
= CreateFontIndirect(lpLogFont
);
818 hOldFont
= SelectObject(hDC
, hFont
);
819 GetTextMetrics(hDC
, lptm
);
820 SelectObject(hDC
, hOldFont
);
822 dprintf_font(stddeb
, "EnumFontFamilies // i=%d lpLogFont=%p lptm=%p\n", i
, lpLogFont
, lptm
);
825 nRet
= (*lpEnumFunc
)(lpLogFont
, lptm
, 0, lpData
);
827 nRet
= CallBack16(lpEnumFunc
, 4, 2, (int)lpLogFont
,
828 2, (int)lptm
, 0, (int)0, 2, (int)lpData
);
831 dprintf_font(stddeb
,"EnumFontFamilies // EnumEnd requested by application !\n");