4 * Copyright 1993 Alexandre Julliard
7 static char Copyright[] = "Copyright Alexandre Julliard, 1993";
12 #include <X11/Xatom.h>
16 /* #define DEBUG_FONT /* */
17 /* #undef 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 {
57 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
61 void 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";
92 /***********************************************************************
95 * Translate a Windows face name to its X11 equivalent.
96 * This will probably have to be customizable.
98 static const char *FONT_TranslateName( char *winFaceName )
102 for (i = 1; i < FontSize; i ++)
103 if( !strcmp( winFaceName, FontNames[i].window ) ) {
104 dprintf_font(stddeb, "---- Mapped %s to %s\n", winFaceName, FontNames[i].x11 );
105 return FontNames[i].x11;
107 return FontNames[0].x11;
111 /***********************************************************************
114 * Find a X font matching the logical font.
116 static XFontStruct * FONT_MatchFont( LOGFONT * font, DC * dc )
119 const char *family, *weight, *charset;
122 int width, height, count;
123 XFontStruct * fontStruct;
125 weight = (font->lfWeight > 550) ? "bold" : "medium";
126 slant = font->lfItalic ? 'i' : 'r';
127 height = font->lfHeight * dc->w.VportExtX / dc->w.WndExtX;
128 if (height == 0) height = 120; /* Default height = 12 */
131 /* If height is negative, it means the height of the characters */
132 /* *without* the internal leading. So we adjust it a bit to */
133 /* compensate. 5/4 seems to give good results for small fonts. */
134 height = 10 * (-height * 5 / 4);
137 width = 10 * (font->lfWidth * dc->w.VportExtY / dc->w.WndExtY);
138 spacing = (font->lfPitchAndFamily & FIXED_PITCH) ? 'm' :
139 (font->lfPitchAndFamily & VARIABLE_PITCH) ? 'p' : '*';
140 charset = (font->lfCharSet == ANSI_CHARSET) ? "iso8859-1" : "*-*";
141 if (*font->lfFaceName) family = FONT_TranslateName( font->lfFaceName );
142 else switch(font->lfPitchAndFamily & 0xf0)
145 family = FONT_TranslateName( "roman" );
148 family = FONT_TranslateName( "swiss" );
151 family = FONT_TranslateName( "modern" );
154 family = FONT_TranslateName( "script" );
157 family = FONT_TranslateName( "decorative" );
160 family = FontNames[0].x11;
165 /* Width==0 seems not to be a valid wildcard on SGI's, using * instead */
167 sprintf( pattern, "-%s-%s-%c-normal-*-*-%d-*-*-%c-*-%s",
168 family, weight, slant, height, spacing, charset);
170 sprintf( pattern, "-%s-%s-%c-normal-*-*-%d-*-*-%c-%d-%s",
171 family, weight, slant, height, spacing, width, charset);
172 dprintf_font(stddeb, "FONT_MatchFont: '%s'\n", pattern );
173 names = XListFonts( display, pattern, 1, &count );
174 if (count > 0) break;
177 dprintf_font(stddeb,"*** No match for %s\n", pattern );
181 dprintf_font(stddeb," Found '%s'\n", *names );
182 fontStruct = XLoadQueryFont( display, *names );
183 XFreeFontNames( names );
188 /***********************************************************************
191 void FONT_GetMetrics( LOGFONT * logfont, XFontStruct * xfont,
192 TEXTMETRIC * metrics )
194 int average, i, count;
197 metrics->tmAscent = xfont->ascent;
198 metrics->tmDescent = xfont->descent;
199 metrics->tmHeight = xfont->ascent + xfont->descent;
201 metrics->tmInternalLeading = 0;
202 if (XGetFontProperty( xfont, XA_X_HEIGHT, &prop ))
203 metrics->tmInternalLeading = xfont->ascent - (short)prop;
204 metrics->tmExternalLeading = 0;
205 metrics->tmMaxCharWidth = xfont->max_bounds.width;
206 metrics->tmWeight = logfont->lfWeight;
207 metrics->tmItalic = logfont->lfItalic;
208 metrics->tmUnderlined = logfont->lfUnderline;
209 metrics->tmStruckOut = logfont->lfStrikeOut;
210 metrics->tmFirstChar = xfont->min_char_or_byte2;
211 metrics->tmLastChar = xfont->max_char_or_byte2;
212 metrics->tmDefaultChar = xfont->default_char;
213 metrics->tmBreakChar = ' ';
214 metrics->tmPitchAndFamily = logfont->lfPitchAndFamily;
215 metrics->tmCharSet = logfont->lfCharSet;
216 metrics->tmOverhang = 0;
217 metrics->tmDigitizedAspectX = 1;
218 metrics->tmDigitizedAspectY = 1;
220 if (!xfont->per_char) average = metrics->tmMaxCharWidth;
223 XCharStruct * charPtr = xfont->per_char;
225 for (i = metrics->tmFirstChar; i <= metrics->tmLastChar; i++)
227 if (!CI_NONEXISTCHAR( charPtr ))
229 average += charPtr->width;
234 if (count) average = (average + count/2) / count;
236 metrics->tmAveCharWidth = average;
240 /***********************************************************************
241 * CreateFontIndirect (GDI.57)
243 HFONT CreateFontIndirect( LOGFONT * font )
246 HFONT hfont = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC );
247 if (!hfont) return 0;
248 fontPtr = (FONTOBJ *) GDI_HEAP_ADDR( hfont );
249 memcpy( &fontPtr->logfont, font, sizeof(LOGFONT) );
250 AnsiLower( fontPtr->logfont.lfFaceName );
251 dprintf_font(stddeb,"CreateFontIndirect(%08X); return %04X\n",font,hfont);
256 /***********************************************************************
257 * CreateFont (GDI.56)
259 HFONT CreateFont( int height, int width, int esc, int orient, int weight,
260 BYTE italic, BYTE underline, BYTE strikeout, BYTE charset,
261 BYTE outpres, BYTE clippres, BYTE quality, BYTE pitch,
264 LOGFONT logfont = { height, width, esc, orient, weight, italic, underline,
265 strikeout, charset, outpres, clippres, quality, pitch, };
266 strncpy( logfont.lfFaceName, name, LF_FACESIZE );
267 return CreateFontIndirect( &logfont );
271 /***********************************************************************
274 int FONT_GetObject( FONTOBJ * font, int count, LPSTR buffer )
276 if (count > sizeof(LOGFONT)) count = sizeof(LOGFONT);
277 memcpy( buffer, &font->logfont, count );
282 /***********************************************************************
285 HFONT FONT_SelectObject( DC * dc, HFONT hfont, FONTOBJ * font )
287 static X_PHYSFONT stockFonts[LAST_STOCK_FONT-FIRST_STOCK_FONT+1];
288 X_PHYSFONT * stockPtr;
289 HFONT prevHandle = dc->w.hFont;
290 XFontStruct * fontStruct;
291 dprintf_font(stddeb,"FONT_SelectObject(%04X, %04X, %08X); !\n",
293 /* Load font if necessary */
299 hnewfont = CreateFont(10, 7, 0, 0, FW_DONTCARE,
300 FALSE, FALSE, FALSE, DEFAULT_CHARSET, 0, 0,
301 DEFAULT_QUALITY, FF_DONTCARE, "*" );
302 font = (FONTOBJ *) GDI_HEAP_ADDR( hnewfont );
305 if (dc->header.wMagic == METAFILE_DC_MAGIC)
306 return MF_CreateFontIndirect(dc, hfont, &(font->logfont));
308 if ((hfont >= FIRST_STOCK_FONT) && (hfont <= LAST_STOCK_FONT))
309 stockPtr = &stockFonts[hfont - FIRST_STOCK_FONT];
313 if (!stockPtr || !stockPtr->fstruct)
315 fontStruct = FONT_MatchFont( &font->logfont, dc );
319 fontStruct = stockPtr->fstruct;
321 "FONT_SelectObject: Loaded font from cache %x %p\n",
324 if (!fontStruct) return 0;
326 /* Free previous font */
328 if ((prevHandle < FIRST_STOCK_FONT) || (prevHandle > LAST_STOCK_FONT))
330 if (dc->u.x.font.fstruct)
331 XFreeFont( display, dc->u.x.font.fstruct );
339 if (!stockPtr->fstruct)
341 stockPtr->fstruct = fontStruct;
342 FONT_GetMetrics( &font->logfont, fontStruct, &stockPtr->metrics );
344 memcpy( &dc->u.x.font, stockPtr, sizeof(*stockPtr) );
348 dc->u.x.font.fstruct = fontStruct;
349 FONT_GetMetrics( &font->logfont, fontStruct, &dc->u.x.font.metrics );
355 /***********************************************************************
356 * GetTextCharacterExtra (GDI.89)
358 short GetTextCharacterExtra( HDC hdc )
360 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
362 return abs( (dc->w.charExtra * dc->w.WndExtX + dc->w.VportExtX / 2)
367 /***********************************************************************
368 * SetTextCharacterExtra (GDI.8)
370 short SetTextCharacterExtra( HDC hdc, short extra )
373 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
375 extra = (extra * dc->w.VportExtX + dc->w.WndExtX / 2) / dc->w.WndExtX;
376 prev = dc->w.charExtra;
377 dc->w.charExtra = abs(extra);
378 return (prev * dc->w.WndExtX + dc->w.VportExtX / 2) / dc->w.VportExtX;
382 /***********************************************************************
383 * SetTextJustification (GDI.10)
385 short SetTextJustification( HDC hdc, short extra, short breaks )
387 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
390 extra = abs((extra * dc->w.VportExtX + dc->w.WndExtX / 2) / dc->w.WndExtX);
391 if (!extra) breaks = 0;
392 dc->w.breakTotalExtra = extra;
393 dc->w.breakCount = breaks;
396 dc->w.breakExtra = extra / breaks;
397 dc->w.breakRem = extra - (dc->w.breakCount * dc->w.breakExtra);
401 dc->w.breakExtra = 0;
408 /***********************************************************************
409 * GetTextFace (GDI.92)
411 INT GetTextFace( HDC hdc, INT count, LPSTR name )
415 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
417 if (!(font = (FONTOBJ *) GDI_GetObjPtr( dc->w.hFont, FONT_MAGIC )))
419 strncpy( name, font->logfont.lfFaceName, count );
420 name[count-1] = '\0';
425 /***********************************************************************
426 * GetTextExtent (GDI.91)
428 DWORD GetTextExtent( HDC hdc, LPSTR str, short count )
431 if (!GetTextExtentPoint( hdc, str, count, &size )) return 0;
432 return size.cx | (size.cy << 16);
436 /***********************************************************************
437 * GetTextExtentPoint (GDI.471)
439 BOOL GetTextExtentPoint( HDC hdc, LPSTR str, short count, LPSIZE size )
441 int dir, ascent, descent;
444 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
445 if (!dc) return FALSE;
446 XTextExtents( dc->u.x.font.fstruct, str, count, &dir,
447 &ascent, &descent, &info );
448 size->cx = abs((info.width + dc->w.breakRem + count * dc->w.charExtra)
449 * dc->w.WndExtX / dc->w.VportExtX);
450 size->cy = abs((dc->u.x.font.fstruct->ascent+dc->u.x.font.fstruct->descent)
451 * dc->w.WndExtY / dc->w.VportExtY);
453 dprintf_font(stddeb,"GetTextExtentPoint(%d '%s' %d %p): returning %d,%d\n",
454 hdc, str, count, size, size->cx, size->cy );
459 /***********************************************************************
460 * GetTextMetrics (GDI.93)
462 BOOL GetTextMetrics( HDC hdc, LPTEXTMETRIC metrics )
464 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
465 if (!dc) return FALSE;
466 memcpy( metrics, &dc->u.x.font.metrics, sizeof(*metrics) );
468 metrics->tmAscent = abs( metrics->tmAscent
469 * dc->w.WndExtY / dc->w.VportExtY );
470 metrics->tmDescent = abs( metrics->tmDescent
471 * dc->w.WndExtY / dc->w.VportExtY );
472 metrics->tmHeight = metrics->tmAscent + metrics->tmDescent;
473 metrics->tmInternalLeading = abs( metrics->tmInternalLeading
474 * dc->w.WndExtY / dc->w.VportExtY );
475 metrics->tmExternalLeading = abs( metrics->tmExternalLeading
476 * dc->w.WndExtY / dc->w.VportExtY );
477 metrics->tmMaxCharWidth = abs( metrics->tmMaxCharWidth
478 * dc->w.WndExtX / dc->w.VportExtX );
479 metrics->tmAveCharWidth = abs( metrics->tmAveCharWidth
480 * dc->w.WndExtX / dc->w.VportExtX );
485 /***********************************************************************
486 * SetMapperFlags (GDI.349)
488 DWORD SetMapperFlags(HDC hDC, DWORD dwFlag)
490 dprintf_font(stdnimp,"SetmapperFlags(%04X, %08X) // Empty Stub !\n",
496 /***********************************************************************/
499 /***********************************************************************
500 * GetCharWidth (GDI.350)
502 BOOL GetCharWidth(HDC hdc, WORD wFirstChar, WORD wLastChar, LPINT lpBuffer)
506 XCharStruct *cs, *def;
508 DC *dc = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC);
509 if (!dc) return FALSE;
510 xfont = dc->u.x.font.fstruct;
513 if (xfont->per_char == NULL)
515 for (i = wFirstChar, j = 0; i <= wLastChar; i++, j++)
516 *(lpBuffer + j) = xfont->max_bounds.width;
520 CI_GET_DEFAULT_INFO(xfont, def);
522 for (i = wFirstChar, j = 0; i <= wLastChar; i++, j++)
524 CI_GET_CHAR_INFO(xfont, i, def, cs);
525 *(lpBuffer + j) = cs ? cs->width : xfont->max_bounds.width;
526 if (*(lpBuffer + j) < 0)
533 /***********************************************************************
534 * AddFontResource (GDI.119)
536 int AddFontResource( LPSTR str )
538 fprintf( stdnimp, "STUB: AddFontResource('%s')\n", str );
543 /***********************************************************************
544 * RemoveFontResource (GDI.136)
546 BOOL RemoveFontResource( LPSTR str )
548 fprintf( stdnimp, "STUB: RemoveFontResource('%s')\n", str );
553 /*************************************************************************
554 * ParseFontParms [internal]
556 int ParseFontParms(LPSTR lpFont, WORD wParmsNo, LPSTR lpRetStr, WORD wMaxSiz)
559 dprintf_font(stddeb,"ParseFontParms('%s', %d, %08X, %d);\n",
560 lpFont, wParmsNo, lpRetStr, wMaxSiz);
561 if (lpFont == NULL) return 0;
562 if (lpRetStr == NULL) return 0;
563 for (i = 0; (*lpFont != '\0' && i != wParmsNo); ) {
564 if (*lpFont == '-') i++;
568 if (*lpFont == '-') lpFont++;
570 for (i = 0; (*lpFont != '\0' && *lpFont != '-' && i < wMaxSiz); i++)
571 *(lpRetStr + i) = *lpFont++;
572 *(lpRetStr + i) = '\0';
573 dprintf_font(stddeb,"ParseFontParms // '%s'\n", lpRetStr);
582 /*************************************************************************
583 * InitFontsList [internal]
589 char *family, *weight, *charset;
599 dprintf_font(stddeb,"InitFontsList !\n");
600 sprintf( pattern, "-%s-%s-%c-normal-*-*-*-*-*-%c-*-%s",
601 family, weight, slant, spacing, charset);
602 names = XListFonts( display, pattern, MAX_FONTS, &count );
603 dprintf_font(stddeb,"InitFontsList // count=%d \n", count);
604 for (i = 0; i < count; i++) {
605 lpNewFont = malloc(sizeof(LOGFONT) + LF_FACESIZE);
606 if (lpNewFont == NULL) {
607 dprintf_font(stddeb, "InitFontsList // Error alloc new font structure !\n");
610 dprintf_font(stddeb,"InitFontsList // names[%d]='%s' \n", i, names[i]);
611 ParseFontParms(names[i], 2, str, sizeof(str));
612 if (strcmp(str, "fixed") == 0) strcat(str, "sys");
614 strcpy(lpNewFont->lfFaceName, str);
615 ParseFontParms(names[i], 7, str, sizeof(str));
616 lpNewFont->lfHeight = atoi(str) / 10;
617 ParseFontParms(names[i], 12, str, sizeof(str));
618 lpNewFont->lfWidth = atoi(str) / 10;
619 lpNewFont->lfEscapement = 0;
620 lpNewFont->lfOrientation = 0;
621 lpNewFont->lfWeight = FW_REGULAR;
622 lpNewFont->lfItalic = 0;
623 lpNewFont->lfUnderline = 0;
624 lpNewFont->lfStrikeOut = 0;
625 ParseFontParms(names[i], 13, str, sizeof(str));
626 if (strcmp(str, "iso8859") == 0)
627 lpNewFont->lfCharSet = ANSI_CHARSET;
629 lpNewFont->lfCharSet = OEM_CHARSET;
630 lpNewFont->lfOutPrecision = OUT_DEFAULT_PRECIS;
631 lpNewFont->lfClipPrecision = CLIP_DEFAULT_PRECIS;
632 lpNewFont->lfQuality = DEFAULT_QUALITY;
633 ParseFontParms(names[i], 11, str, sizeof(str));
636 lpNewFont->lfPitchAndFamily = VARIABLE_PITCH | FF_SWISS;
639 lpNewFont->lfPitchAndFamily = FIXED_PITCH | FF_MODERN;
642 lpNewFont->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
645 dprintf_font(stddeb,"InitFontsList // lpNewFont->lfHeight=%d \n", lpNewFont->lfHeight);
646 dprintf_font(stddeb,"InitFontsList // lpNewFont->lfWidth=%d \n", lpNewFont->lfWidth);
647 dprintf_font(stddeb,"InitFontsList // lfFaceName='%s' \n", lpNewFont->lfFaceName);
648 lpLogFontList[i] = lpNewFont;
649 lpLogFontList[i+1] = NULL;
651 XFreeFontNames(names);
655 /*************************************************************************
658 int EnumFonts(HDC hDC, LPSTR lpFaceName, FARPROC lpEnumFunc, LPSTR lpData)
666 LPSTR lpFaceList[MAX_FONTS];
667 char FaceName[LF_FACESIZE];
671 dprintf_font(stddeb,"EnumFonts(%04X, %08X='%s', %08X, %08X)\n",
672 hDC, lpFaceName, lpFaceName, lpEnumFunc, lpData);
673 if (lpEnumFunc == NULL) return 0;
674 hLog = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(LOGFONT) + LF_FACESIZE);
675 lpLogFont = (LPLOGFONT) USER_HEAP_ADDR(hLog);
676 if (lpLogFont == NULL) {
677 dprintf_font(stddeb,"EnumFonts // can't alloc LOGFONT struct !\n");
680 hMet = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(TEXTMETRIC));
681 lptm = (LPTEXTMETRIC) USER_HEAP_ADDR(hMet);
683 USER_HEAP_FREE(hLog);
684 dprintf_font(stddeb, "EnumFonts // can't alloc TEXTMETRIC struct !\n");
687 if (lpFaceName != NULL) {
688 strcpy(FaceName, lpFaceName);
691 if (lpLogFontList[0] == NULL) InitFontsList();
692 memset(lpFaceList, 0, MAX_FONTS * sizeof(LPSTR));
694 if (lpLogFontList[i] == NULL) break;
695 if (lpFaceName == NULL) {
696 for (j = 0; j < MAX_FONTS; j++) {
697 if (lpFaceList[j] == NULL) break;
698 if (strcmp(lpFaceList[j], lpLogFontList[i]->lfFaceName) == 0) {
700 if (lpLogFontList[i] == NULL) break;
703 if (lpLogFontList[i] == NULL) break;
704 lpFaceList[j] = lpLogFontList[i]->lfFaceName;
705 dprintf_font(stddeb,"EnumFonts // enum all 'lpFaceName' '%s' !\n", lpFaceList[j]);
708 while(lpLogFontList[i] != NULL) {
709 if (strcmp(FaceName, lpLogFontList[i]->lfFaceName) == 0) break;
712 if (lpLogFontList[i] == NULL) break;
714 memcpy(lpLogFont, lpLogFontList[i++], sizeof(LOGFONT) + LF_FACESIZE);
715 hFont = CreateFontIndirect(lpLogFont);
716 hOldFont = SelectObject(hDC, hFont);
717 GetTextMetrics(hDC, lptm);
718 SelectObject(hDC, hOldFont);
720 dprintf_font(stddeb,"EnumFonts // i=%d lpLogFont=%08X lptm=%08X\n", i, lpLogFont, lptm);
723 nRet = (*lpEnumFunc)(lpLogFont, lptm, 0, lpData);
725 nRet = CallBack16(lpEnumFunc, 4, 2, (int)lpLogFont,
726 2, (int)lptm, 0, (int)0, 2, (int)lpData);
729 dprintf_font(stddeb,"EnumFonts // EnumEnd requested by application !\n");
733 USER_HEAP_FREE(hMet);
734 USER_HEAP_FREE(hLog);
739 /*************************************************************************
740 * EnumFontFamilies [GDI.330]
742 int EnumFontFamilies(HDC hDC, LPSTR lpszFamily, FARPROC lpEnumFunc, LPSTR lpData)
750 LPSTR lpFaceList[MAX_FONTS];
751 char FaceName[LF_FACESIZE];
755 dprintf_font(stddeb,"EnumFontFamilies(%04X, %08X, %08X, %08X)\n",
756 hDC, lpszFamily, lpEnumFunc, lpData);
757 if (lpEnumFunc == NULL) return 0;
758 hLog = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(LOGFONT) + LF_FACESIZE);
759 lpLogFont = (LPLOGFONT) USER_HEAP_ADDR(hLog);
760 if (lpLogFont == NULL) {
761 dprintf_font(stddeb,"EnumFontFamilies // can't alloc LOGFONT struct !\n");
764 hMet = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(TEXTMETRIC));
765 lptm = (LPTEXTMETRIC) USER_HEAP_ADDR(hMet);
767 USER_HEAP_FREE(hLog);
768 dprintf_font(stddeb,"EnumFontFamilies // can't alloc TEXTMETRIC struct !\n");
771 if (lpszFamily != NULL) {
772 strcpy(FaceName, lpszFamily);
775 if (lpLogFontList[0] == NULL) InitFontsList();
776 memset(lpFaceList, 0, MAX_FONTS * sizeof(LPSTR));
778 if (lpLogFontList[i] == NULL) break;
779 if (lpszFamily == NULL) {
780 if (lpLogFontList[i] == NULL) break;
781 for (j = 0; j < MAX_FONTS; j++) {
782 if (lpFaceList[j] == NULL) break;
783 if (lpLogFontList[i] == NULL) break;
784 if (strcmp(lpFaceList[j], lpLogFontList[i]->lfFaceName) == 0) {
788 if (lpLogFontList[i] == NULL) break;
789 lpFaceList[j] = lpLogFontList[i]->lfFaceName;
790 dprintf_font(stddeb,"EnumFontFamilies // enum all 'lpszFamily' '%s' !\n", lpFaceList[j]);
793 while(lpLogFontList[i] != NULL) {
794 if (strcmp(FaceName, lpLogFontList[i]->lfFaceName) == 0) break;
797 if (lpLogFontList[i] == NULL) break;
799 memcpy(lpLogFont, lpLogFontList[i++], sizeof(LOGFONT) + LF_FACESIZE);
800 hFont = CreateFontIndirect(lpLogFont);
801 hOldFont = SelectObject(hDC, hFont);
802 GetTextMetrics(hDC, lptm);
803 SelectObject(hDC, hOldFont);
805 dprintf_font(stddeb, "EnumFontFamilies // i=%d lpLogFont=%08X lptm=%08X\n", i, lpLogFont, lptm);
808 nRet = (*lpEnumFunc)(lpLogFont, lptm, 0, lpData);
810 nRet = CallBack16(lpEnumFunc, 4, 2, (int)lpLogFont,
811 2, (int)lptm, 0, (int)0, 2, (int)lpData);
814 dprintf_font(stddeb,"EnumFontFamilies // EnumEnd requested by application !\n");
818 USER_HEAP_FREE(hMet);
819 USER_HEAP_FREE(hLog);