4 * Copyright 1993 Alexandre Julliard
6 static char Copyright[] = "Copyright Alexandre Julliard, 1993";
12 #include <X11/Xatom.h>
18 /* #define DEBUG_FONT */
22 static LPLOGFONT lpLogFontList[MAX_FONTS] = { NULL };
25 #define CI_NONEXISTCHAR(cs) (((cs)->width == 0) && \
26 (((cs)->rbearing|(cs)->lbearing| \
27 (cs)->ascent|(cs)->descent) == 0))
30 * CI_GET_CHAR_INFO - return the charinfo struct for the indicated 8bit
31 * character. If the character is in the column and exists, then return the
32 * appropriate metrics (note that fonts with common per-character metrics will
33 * return min_bounds). If none of these hold true, try again with the default
36 #define CI_GET_CHAR_INFO(fs,col,def,cs) \
39 if (col >= fs->min_char_or_byte2 && col <= fs->max_char_or_byte2) { \
40 if (fs->per_char == NULL) { \
41 cs = &fs->min_bounds; \
43 cs = &fs->per_char[(col - fs->min_char_or_byte2)]; \
44 if (CI_NONEXISTCHAR(cs)) cs = def; \
49 #define CI_GET_DEFAULT_INFO(fs,cs) \
50 CI_GET_CHAR_INFO(fs, fs->default_char, NULL, cs)
52 struct FontStructure {
58 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
62 void Font_Init( void )
68 if( GetPrivateProfileString("fonts", NULL, "*", temp, sizeof(temp), WINE_INI) > 2 ) {
69 for( ptr = temp, i = 1; strlen(ptr) != 0; ptr += strlen(ptr) + 1 )
70 if( strcmp( ptr, "default" ) )
71 FontNames[i++].window = strdup( ptr );
74 for( i = 1; i < FontSize; i++ ) {
75 GetPrivateProfileString("fonts", FontNames[i].window, "*", temp, sizeof(temp), WINE_INI);
76 FontNames[i].x11 = strdup( temp );
78 GetPrivateProfileString("fonts", "default", "*", temp, sizeof(temp), WINE_INI);
79 FontNames[0].x11 = strdup( temp );
82 FontNames[0].window = NULL; FontNames[0].x11 = "bitstream-courier";
83 FontNames[1].window = "ms sans serif"; FontNames[1].x11 = "*-helvetica";
84 FontNames[2].window = "ms serif"; FontNames[2].x11 = "*-times";
85 FontNames[3].window = "fixedsys"; FontNames[3].x11 = "*-fixed";
86 FontNames[4].window = "arial"; FontNames[4].x11 = "*-helvetica";
87 FontNames[5].window = "helv"; FontNames[5].x11 = "*-helvetica";
88 FontNames[6].window = "roman"; FontNames[6].x11 = "*-times";
93 /***********************************************************************
96 * Translate a Windows face name to its X11 equivalent.
97 * This will probably have to be customizable.
99 static const char *FONT_TranslateName( char *winFaceName )
103 for (i = 1; i < FontSize; i ++)
104 if( !strcmp( winFaceName, FontNames[i].window ) ) {
105 dprintf_font(stddeb, "---- Mapped %s to %s\n", winFaceName, FontNames[i].x11 );
106 return FontNames[i].x11;
108 return FontNames[0].x11;
112 /***********************************************************************
115 * Find a X font matching the logical font.
117 static XFontStruct * FONT_MatchFont( LOGFONT * font, DC * dc )
120 const char *family, *weight, *charset;
123 int width, height, count;
124 XFontStruct * fontStruct;
126 weight = (font->lfWeight > 550) ? "bold" : "medium";
127 slant = font->lfItalic ? 'i' : 'r';
128 height = font->lfHeight * dc->w.VportExtX / dc->w.WndExtX;
129 if (height == 0) height = 120; /* Default height = 12 */
132 /* If height is negative, it means the height of the characters */
133 /* *without* the internal leading. So we adjust it a bit to */
134 /* compensate. 5/4 seems to give good results for small fonts. */
135 height = 10 * (-height * 5 / 4);
138 width = 10 * (font->lfWidth * dc->w.VportExtY / dc->w.WndExtY);
139 spacing = (font->lfPitchAndFamily & FIXED_PITCH) ? 'm' :
140 (font->lfPitchAndFamily & VARIABLE_PITCH) ? 'p' : '*';
141 charset = (font->lfCharSet == ANSI_CHARSET) ? "iso8859-1" : "*-*";
142 if (*font->lfFaceName) family = FONT_TranslateName( font->lfFaceName );
143 else switch(font->lfPitchAndFamily & 0xf0)
146 family = FONT_TranslateName( "roman" );
149 family = FONT_TranslateName( "swiss" );
152 family = FONT_TranslateName( "modern" );
155 family = FONT_TranslateName( "script" );
158 family = FONT_TranslateName( "decorative" );
166 /* Width==0 seems not to be a valid wildcard on SGI's, using * instead */
168 sprintf( pattern, "-%s-%s-%c-normal-*-*-%d-*-*-%c-*-%s",
169 family, weight, slant, height, spacing, charset);
171 sprintf( pattern, "-%s-%s-%c-normal-*-*-%d-*-*-%c-%d-%s",
172 family, weight, slant, height, spacing, width, charset);
173 dprintf_font(stddeb, "FONT_MatchFont: '%s'\n", pattern );
174 names = XListFonts( display, pattern, 1, &count );
175 if (count > 0) break;
178 dprintf_font(stddeb,"*** No match for %s\n", pattern );
182 dprintf_font(stddeb," Found '%s'\n", *names );
183 fontStruct = XLoadQueryFont( display, *names );
184 XFreeFontNames( names );
189 /***********************************************************************
192 void FONT_GetMetrics( LOGFONT * logfont, XFontStruct * xfont,
193 TEXTMETRIC * metrics )
195 int average, i, count;
198 metrics->tmAscent = xfont->ascent;
199 metrics->tmDescent = xfont->descent;
200 metrics->tmHeight = xfont->ascent + xfont->descent;
202 metrics->tmInternalLeading = 0;
203 if (XGetFontProperty( xfont, XA_X_HEIGHT, &prop ))
204 metrics->tmInternalLeading = xfont->ascent - (short)prop;
205 metrics->tmExternalLeading = 0;
206 metrics->tmMaxCharWidth = xfont->max_bounds.width;
207 metrics->tmWeight = logfont->lfWeight;
208 metrics->tmItalic = logfont->lfItalic;
209 metrics->tmUnderlined = logfont->lfUnderline;
210 metrics->tmStruckOut = logfont->lfStrikeOut;
211 metrics->tmFirstChar = xfont->min_char_or_byte2;
212 metrics->tmLastChar = xfont->max_char_or_byte2;
213 metrics->tmDefaultChar = xfont->default_char;
214 metrics->tmBreakChar = ' ';
215 metrics->tmPitchAndFamily = logfont->lfPitchAndFamily;
216 metrics->tmCharSet = logfont->lfCharSet;
217 metrics->tmOverhang = 0;
218 metrics->tmDigitizedAspectX = 1;
219 metrics->tmDigitizedAspectY = 1;
221 if (!xfont->per_char) average = metrics->tmMaxCharWidth;
224 XCharStruct * charPtr = xfont->per_char;
226 for (i = metrics->tmFirstChar; i <= metrics->tmLastChar; i++)
228 if (!CI_NONEXISTCHAR( charPtr ))
230 average += charPtr->width;
235 if (count) average = (average + count/2) / count;
237 metrics->tmAveCharWidth = average;
241 /***********************************************************************
242 * CreateFontIndirect (GDI.57)
244 HFONT CreateFontIndirect( LOGFONT * font )
247 HFONT hfont = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC );
248 if (!hfont) return 0;
249 fontPtr = (FONTOBJ *) GDI_HEAP_ADDR( hfont );
250 memcpy( &fontPtr->logfont, font, sizeof(LOGFONT) );
251 AnsiLower( fontPtr->logfont.lfFaceName );
252 dprintf_font(stddeb,"CreateFontIndirect(%p); return %04x\n",font,hfont);
257 /***********************************************************************
258 * CreateFont (GDI.56)
260 HFONT CreateFont( int height, int width, int esc, int orient, int weight,
261 BYTE italic, BYTE underline, BYTE strikeout, BYTE charset,
262 BYTE outpres, BYTE clippres, BYTE quality, BYTE pitch,
265 LOGFONT logfont = { height, width, esc, orient, weight, italic, underline,
266 strikeout, charset, outpres, clippres, quality, pitch, };
267 strncpy( logfont.lfFaceName, name, LF_FACESIZE );
268 return CreateFontIndirect( &logfont );
272 /***********************************************************************
275 int FONT_GetObject( FONTOBJ * font, int count, LPSTR buffer )
277 if (count > sizeof(LOGFONT)) count = sizeof(LOGFONT);
278 memcpy( buffer, &font->logfont, count );
283 /***********************************************************************
286 HFONT FONT_SelectObject( DC * dc, HFONT hfont, FONTOBJ * font )
288 static X_PHYSFONT stockFonts[LAST_STOCK_FONT-FIRST_STOCK_FONT+1];
289 X_PHYSFONT * stockPtr;
290 HFONT prevHandle = dc->w.hFont;
291 XFontStruct * fontStruct;
292 dprintf_font(stddeb,"FONT_SelectObject(%p, %04x, %p)\n",
294 /* Load font if necessary */
300 hnewfont = CreateFont(10, 7, 0, 0, FW_DONTCARE,
301 FALSE, FALSE, FALSE, DEFAULT_CHARSET, 0, 0,
302 DEFAULT_QUALITY, FF_DONTCARE, "*" );
303 font = (FONTOBJ *) GDI_HEAP_ADDR( hnewfont );
306 if (dc->header.wMagic == METAFILE_DC_MAGIC)
307 return MF_CreateFontIndirect(dc, hfont, &(font->logfont));
309 if ((hfont >= FIRST_STOCK_FONT) && (hfont <= LAST_STOCK_FONT))
310 stockPtr = &stockFonts[hfont - FIRST_STOCK_FONT];
314 if (!stockPtr || !stockPtr->fstruct)
316 fontStruct = FONT_MatchFont( &font->logfont, dc );
320 fontStruct = stockPtr->fstruct;
322 "FONT_SelectObject: Loaded font from cache %x %p\n",
325 if (!fontStruct) return 0;
327 /* Free previous font */
329 if ((prevHandle < FIRST_STOCK_FONT) || (prevHandle > LAST_STOCK_FONT))
331 if (dc->u.x.font.fstruct)
332 XFreeFont( display, dc->u.x.font.fstruct );
340 if (!stockPtr->fstruct)
342 stockPtr->fstruct = fontStruct;
343 FONT_GetMetrics( &font->logfont, fontStruct, &stockPtr->metrics );
345 memcpy( &dc->u.x.font, stockPtr, sizeof(*stockPtr) );
349 dc->u.x.font.fstruct = fontStruct;
350 FONT_GetMetrics( &font->logfont, fontStruct, &dc->u.x.font.metrics );
356 /***********************************************************************
357 * GetTextCharacterExtra (GDI.89)
359 short GetTextCharacterExtra( HDC hdc )
361 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
363 return abs( (dc->w.charExtra * dc->w.WndExtX + dc->w.VportExtX / 2)
368 /***********************************************************************
369 * SetTextCharacterExtra (GDI.8)
371 short SetTextCharacterExtra( HDC hdc, short extra )
374 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
376 extra = (extra * dc->w.VportExtX + dc->w.WndExtX / 2) / dc->w.WndExtX;
377 prev = dc->w.charExtra;
378 dc->w.charExtra = abs(extra);
379 return (prev * dc->w.WndExtX + dc->w.VportExtX / 2) / dc->w.VportExtX;
383 /***********************************************************************
384 * SetTextJustification (GDI.10)
386 short SetTextJustification( HDC hdc, short extra, short breaks )
388 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
391 extra = abs((extra * dc->w.VportExtX + dc->w.WndExtX / 2) / dc->w.WndExtX);
392 if (!extra) breaks = 0;
393 dc->w.breakTotalExtra = extra;
394 dc->w.breakCount = breaks;
397 dc->w.breakExtra = extra / breaks;
398 dc->w.breakRem = extra - (dc->w.breakCount * dc->w.breakExtra);
402 dc->w.breakExtra = 0;
409 /***********************************************************************
410 * GetTextFace (GDI.92)
412 INT GetTextFace( HDC hdc, INT count, LPSTR name )
416 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
418 if (!(font = (FONTOBJ *) GDI_GetObjPtr( dc->w.hFont, FONT_MAGIC )))
420 strncpy( name, font->logfont.lfFaceName, count );
421 name[count-1] = '\0';
426 /***********************************************************************
427 * GetTextExtent (GDI.91)
429 DWORD GetTextExtent( HDC hdc, LPSTR str, short count )
432 if (!GetTextExtentPoint( hdc, str, count, &size )) return 0;
433 return MAKELONG( size.cx, size.cy );
437 /***********************************************************************
438 * GetTextExtentPoint (GDI.471)
440 BOOL GetTextExtentPoint( HDC hdc, LPSTR str, short count, LPSIZE size )
442 int dir, ascent, descent;
445 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
446 if (!dc) return FALSE;
447 XTextExtents( dc->u.x.font.fstruct, str, count, &dir,
448 &ascent, &descent, &info );
449 size->cx = abs((info.width + dc->w.breakRem + count * dc->w.charExtra)
450 * dc->w.WndExtX / dc->w.VportExtX);
451 size->cy = abs((dc->u.x.font.fstruct->ascent+dc->u.x.font.fstruct->descent)
452 * dc->w.WndExtY / dc->w.VportExtY);
454 dprintf_font(stddeb,"GetTextExtentPoint(%d '%s' %d %p): returning %d,%d\n",
455 hdc, str, count, size, size->cx, size->cy );
460 /***********************************************************************
461 * GetTextMetrics (GDI.93)
463 BOOL GetTextMetrics( HDC hdc, LPTEXTMETRIC metrics )
465 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
466 if (!dc) return FALSE;
467 memcpy( metrics, &dc->u.x.font.metrics, sizeof(*metrics) );
469 metrics->tmAscent = abs( metrics->tmAscent
470 * dc->w.WndExtY / dc->w.VportExtY );
471 metrics->tmDescent = abs( metrics->tmDescent
472 * dc->w.WndExtY / dc->w.VportExtY );
473 metrics->tmHeight = metrics->tmAscent + metrics->tmDescent;
474 metrics->tmInternalLeading = abs( metrics->tmInternalLeading
475 * dc->w.WndExtY / dc->w.VportExtY );
476 metrics->tmExternalLeading = abs( metrics->tmExternalLeading
477 * dc->w.WndExtY / dc->w.VportExtY );
478 metrics->tmMaxCharWidth = abs( metrics->tmMaxCharWidth
479 * dc->w.WndExtX / dc->w.VportExtX );
480 metrics->tmAveCharWidth = abs( metrics->tmAveCharWidth
481 * dc->w.WndExtX / dc->w.VportExtX );
486 /***********************************************************************
487 * SetMapperFlags (GDI.349)
489 DWORD SetMapperFlags(HDC hDC, DWORD dwFlag)
491 dprintf_font(stdnimp,"SetmapperFlags(%04X, %08lX) // Empty Stub !\n",
497 /***********************************************************************/
500 /***********************************************************************
501 * GetCharWidth (GDI.350)
503 BOOL GetCharWidth(HDC hdc, WORD wFirstChar, WORD wLastChar, LPINT lpBuffer)
507 XCharStruct *cs, *def;
509 DC *dc = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC);
510 if (!dc) return FALSE;
511 xfont = dc->u.x.font.fstruct;
514 if (xfont->per_char == NULL)
516 for (i = wFirstChar, j = 0; i <= wLastChar; i++, j++)
517 *(lpBuffer + j) = xfont->max_bounds.width;
521 CI_GET_DEFAULT_INFO(xfont, def);
523 for (i = wFirstChar, j = 0; i <= wLastChar; i++, j++)
525 CI_GET_CHAR_INFO(xfont, i, def, cs);
526 *(lpBuffer + j) = cs ? cs->width : xfont->max_bounds.width;
527 if (*(lpBuffer + j) < 0)
534 /***********************************************************************
535 * AddFontResource (GDI.119)
537 int AddFontResource( LPSTR str )
539 fprintf( stdnimp, "STUB: AddFontResource('%s')\n", str );
544 /***********************************************************************
545 * RemoveFontResource (GDI.136)
547 BOOL RemoveFontResource( LPSTR str )
549 fprintf( stdnimp, "STUB: RemoveFontResource('%s')\n", str );
554 /*************************************************************************
555 * ParseFontParms [internal]
557 int ParseFontParms(LPSTR lpFont, WORD wParmsNo, LPSTR lpRetStr, WORD wMaxSiz)
560 dprintf_font(stddeb,"ParseFontParms('%s', %d, %p, %d);\n",
561 lpFont, wParmsNo, lpRetStr, wMaxSiz);
562 if (lpFont == NULL) return 0;
563 if (lpRetStr == NULL) return 0;
564 for (i = 0; (*lpFont != '\0' && i != wParmsNo); ) {
565 if (*lpFont == '-') i++;
569 if (*lpFont == '-') lpFont++;
571 for (i = 0; (*lpFont != '\0' && *lpFont != '-' && i < wMaxSiz); i++)
572 *(lpRetStr + i) = *lpFont++;
573 *(lpRetStr + i) = '\0';
574 dprintf_font(stddeb,"ParseFontParms // '%s'\n", lpRetStr);
583 /*************************************************************************
584 * InitFontsList [internal]
586 void InitFontsList(void)
590 char *family, *weight, *charset;
600 dprintf_font(stddeb,"InitFontsList !\n");
601 sprintf( pattern, "-%s-%s-%c-normal-*-*-*-*-*-%c-*-%s",
602 family, weight, slant, spacing, charset);
603 names = XListFonts( display, pattern, MAX_FONTS, &count );
604 dprintf_font(stddeb,"InitFontsList // count=%d \n", count);
605 for (i = 0; i < count; i++) {
606 lpNewFont = malloc(sizeof(LOGFONT) + LF_FACESIZE);
607 if (lpNewFont == NULL) {
608 dprintf_font(stddeb, "InitFontsList // Error alloc new font structure !\n");
611 dprintf_font(stddeb,"InitFontsList // names[%d]='%s' \n", i, names[i]);
612 ParseFontParms(names[i], 2, str, sizeof(str));
613 if (strcmp(str, "fixed") == 0) strcat(str, "sys");
615 strcpy(lpNewFont->lfFaceName, str);
616 ParseFontParms(names[i], 7, str, sizeof(str));
617 lpNewFont->lfHeight = atoi(str) / 10;
618 ParseFontParms(names[i], 12, str, sizeof(str));
619 lpNewFont->lfWidth = atoi(str) / 10;
620 lpNewFont->lfEscapement = 0;
621 lpNewFont->lfOrientation = 0;
622 lpNewFont->lfWeight = FW_REGULAR;
623 lpNewFont->lfItalic = 0;
624 lpNewFont->lfUnderline = 0;
625 lpNewFont->lfStrikeOut = 0;
626 ParseFontParms(names[i], 13, str, sizeof(str));
627 if (strcmp(str, "iso8859") == 0)
628 lpNewFont->lfCharSet = ANSI_CHARSET;
630 lpNewFont->lfCharSet = OEM_CHARSET;
631 lpNewFont->lfOutPrecision = OUT_DEFAULT_PRECIS;
632 lpNewFont->lfClipPrecision = CLIP_DEFAULT_PRECIS;
633 lpNewFont->lfQuality = DEFAULT_QUALITY;
634 ParseFontParms(names[i], 11, str, sizeof(str));
637 lpNewFont->lfPitchAndFamily = VARIABLE_PITCH | FF_SWISS;
640 lpNewFont->lfPitchAndFamily = FIXED_PITCH | FF_MODERN;
643 lpNewFont->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
646 dprintf_font(stddeb,"InitFontsList // lpNewFont->lfHeight=%d \n", lpNewFont->lfHeight);
647 dprintf_font(stddeb,"InitFontsList // lpNewFont->lfWidth=%d \n", lpNewFont->lfWidth);
648 dprintf_font(stddeb,"InitFontsList // lfFaceName='%s' \n", lpNewFont->lfFaceName);
649 lpLogFontList[i] = lpNewFont;
650 lpLogFontList[i+1] = NULL;
652 XFreeFontNames(names);
656 /*************************************************************************
659 int EnumFonts(HDC hDC, LPSTR lpFaceName, FARPROC lpEnumFunc, LPSTR lpData)
667 LPSTR lpFaceList[MAX_FONTS];
668 char FaceName[LF_FACESIZE];
672 dprintf_font(stddeb,"EnumFonts(%04X, %08X='%s', %08X, %08X)\n",
673 hDC, lpFaceName, lpFaceName, lpEnumFunc, lpData);
674 if (lpEnumFunc == NULL) return 0;
675 hLog = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(LOGFONT) + LF_FACESIZE);
676 lpLogFont = (LPLOGFONT) USER_HEAP_ADDR(hLog);
677 if (lpLogFont == NULL) {
678 dprintf_font(stddeb,"EnumFonts // can't alloc LOGFONT struct !\n");
681 hMet = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(TEXTMETRIC));
682 lptm = (LPTEXTMETRIC) USER_HEAP_ADDR(hMet);
684 USER_HEAP_FREE(hLog);
685 dprintf_font(stddeb, "EnumFonts // can't alloc TEXTMETRIC struct !\n");
688 if (lpFaceName != NULL) {
689 strcpy(FaceName, lpFaceName);
692 if (lpLogFontList[0] == NULL) InitFontsList();
693 memset(lpFaceList, 0, MAX_FONTS * sizeof(LPSTR));
695 if (lpLogFontList[i] == NULL) break;
696 if (lpFaceName == NULL) {
697 for (j = 0; j < MAX_FONTS; j++) {
698 if (lpFaceList[j] == NULL) break;
699 if (strcmp(lpFaceList[j], lpLogFontList[i]->lfFaceName) == 0) {
701 if (lpLogFontList[i] == NULL) break;
704 if (lpLogFontList[i] == NULL) break;
705 lpFaceList[j] = lpLogFontList[i]->lfFaceName;
706 dprintf_font(stddeb,"EnumFonts // enum all 'lpFaceName' '%s' !\n", lpFaceList[j]);
709 while(lpLogFontList[i] != NULL) {
710 if (strcmp(FaceName, lpLogFontList[i]->lfFaceName) == 0) break;
713 if (lpLogFontList[i] == NULL) break;
715 memcpy(lpLogFont, lpLogFontList[i++], sizeof(LOGFONT) + LF_FACESIZE);
716 hFont = CreateFontIndirect(lpLogFont);
717 hOldFont = SelectObject(hDC, hFont);
718 GetTextMetrics(hDC, lptm);
719 SelectObject(hDC, hOldFont);
721 dprintf_font(stddeb,"EnumFonts // i=%d lpLogFont=%08X lptm=%08X\n", i, lpLogFont, lptm);
724 nRet = (*lpEnumFunc)(lpLogFont, lptm, 0, lpData);
726 nRet = CallBack16(lpEnumFunc, 4, 2, (int)lpLogFont,
727 2, (int)lptm, 0, (int)0, 2, (int)lpData);
730 dprintf_font(stddeb,"EnumFonts // EnumEnd requested by application !\n");
734 USER_HEAP_FREE(hMet);
735 USER_HEAP_FREE(hLog);
740 /*************************************************************************
741 * EnumFontFamilies [GDI.330]
743 int EnumFontFamilies(HDC hDC, LPSTR lpszFamily, FARPROC lpEnumFunc, LPSTR lpData)
751 LPSTR lpFaceList[MAX_FONTS];
752 char FaceName[LF_FACESIZE];
756 dprintf_font(stddeb,"EnumFontFamilies(%04X, %08X, %08X, %08X)\n",
757 hDC, lpszFamily, lpEnumFunc, lpData);
758 if (lpEnumFunc == NULL) return 0;
759 hLog = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(LOGFONT) + LF_FACESIZE);
760 lpLogFont = (LPLOGFONT) USER_HEAP_ADDR(hLog);
761 if (lpLogFont == NULL) {
762 dprintf_font(stddeb,"EnumFontFamilies // can't alloc LOGFONT struct !\n");
765 hMet = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(TEXTMETRIC));
766 lptm = (LPTEXTMETRIC) USER_HEAP_ADDR(hMet);
768 USER_HEAP_FREE(hLog);
769 dprintf_font(stddeb,"EnumFontFamilies // can't alloc TEXTMETRIC struct !\n");
772 if (lpszFamily != NULL) {
773 strcpy(FaceName, lpszFamily);
776 if (lpLogFontList[0] == NULL) InitFontsList();
777 memset(lpFaceList, 0, MAX_FONTS * sizeof(LPSTR));
779 if (lpLogFontList[i] == NULL) break;
780 if (lpszFamily == NULL) {
781 if (lpLogFontList[i] == NULL) break;
782 for (j = 0; j < MAX_FONTS; j++) {
783 if (lpFaceList[j] == NULL) break;
784 if (lpLogFontList[i] == NULL) break;
785 if (strcmp(lpFaceList[j], lpLogFontList[i]->lfFaceName) == 0) {
789 if (lpLogFontList[i] == NULL) break;
790 lpFaceList[j] = lpLogFontList[i]->lfFaceName;
791 dprintf_font(stddeb,"EnumFontFamilies // enum all 'lpszFamily' '%s' !\n", lpFaceList[j]);
794 while(lpLogFontList[i] != NULL) {
795 if (strcmp(FaceName, lpLogFontList[i]->lfFaceName) == 0) break;
798 if (lpLogFontList[i] == NULL) break;
800 memcpy(lpLogFont, lpLogFontList[i++], sizeof(LOGFONT) + LF_FACESIZE);
801 hFont = CreateFontIndirect(lpLogFont);
802 hOldFont = SelectObject(hDC, hFont);
803 GetTextMetrics(hDC, lptm);
804 SelectObject(hDC, hOldFont);
806 dprintf_font(stddeb, "EnumFontFamilies // i=%d lpLogFont=%08X lptm=%08X\n", i, lpLogFont, lptm);
809 nRet = (*lpEnumFunc)(lpLogFont, lptm, 0, lpData);
811 nRet = CallBack16(lpEnumFunc, 4, 2, (int)lpLogFont,
812 2, (int)lptm, 0, (int)0, 2, (int)lpData);
815 dprintf_font(stddeb,"EnumFontFamilies // EnumEnd requested by application !\n");
819 USER_HEAP_FREE(hMet);
820 USER_HEAP_FREE(hLog);