Release 950109
[wine/multimedia.git] / objects / font.c
blob36d0ce4f564fee86c85bfb315653f17db8f7014e
1 /*
2 * GDI font objects
4 * Copyright 1993 Alexandre Julliard
6 static char Copyright[] = "Copyright Alexandre Julliard, 1993";
7 */
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <X11/Xatom.h>
13 #include "font.h"
14 #include "metafile.h"
15 #include "callback.h"
16 #include "stddebug.h"
17 /* #define DEBUG_FONT */
18 #include "debug.h"
20 #define MAX_FONTS 256
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))
28 /*
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
33 * char.
35 #define CI_GET_CHAR_INFO(fs,col,def,cs) \
36 { \
37 cs = def; \
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; \
41 } else { \
42 cs = &fs->per_char[(col - fs->min_char_or_byte2)]; \
43 if (CI_NONEXISTCHAR(cs)) cs = def; \
44 } \
45 } \
48 #define CI_GET_DEFAULT_INFO(fs,cs) \
49 CI_GET_CHAR_INFO(fs, fs->default_char, NULL, cs)
51 struct FontStructure {
52 char *window;
53 char *x11;
54 } FontNames[32];
55 int FontSize;
58 /***********************************************************************
59 * FONT_Init
61 BOOL FONT_Init( void )
63 char temp[1024];
64 LPSTR ptr;
65 int i;
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 );
71 FontSize = i;
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 );
80 } else {
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";
88 FontSize = 7;
90 return TRUE;
94 /***********************************************************************
95 * FONT_TranslateName
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 )
102 int i;
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 /***********************************************************************
114 * FONT_MatchFont
116 * Find a X font matching the logical font.
118 static XFontStruct * FONT_MatchFont( LOGFONT * font, DC * dc )
120 char pattern[100];
121 const char *family, *weight, *charset;
122 char **names;
123 char slant, spacing;
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 */
131 else if (height < 0)
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);
138 else height *= 10;
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)
146 case FF_ROMAN:
147 family = FONT_TranslateName( "roman" );
148 break;
149 case FF_SWISS:
150 family = FONT_TranslateName( "swiss" );
151 break;
152 case FF_MODERN:
153 family = FONT_TranslateName( "modern" );
154 break;
155 case FF_SCRIPT:
156 family = FONT_TranslateName( "script" );
157 break;
158 case FF_DECORATIVE:
159 family = FONT_TranslateName( "decorative" );
160 break;
161 default:
162 family = "*-*";
163 break;
166 while (TRUE) {
167 /* Width==0 seems not to be a valid wildcard on SGI's, using * instead */
168 if ( width == 0 )
169 sprintf( pattern, "-%s-%s-%c-normal-*-*-%d-*-*-%c-*-%s",
170 family, weight, slant, height, spacing, charset);
171 else
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;
177 height -= 10;
178 if (height < 10) {
179 dprintf_font(stddeb,"*** No match for %s\n", pattern );
180 return NULL;
183 dprintf_font(stddeb," Found '%s'\n", *names );
184 fontStruct = XLoadQueryFont( display, *names );
185 XFreeFontNames( names );
186 return fontStruct;
190 /***********************************************************************
191 * FONT_GetMetrics
193 void FONT_GetMetrics( LOGFONT * logfont, XFontStruct * xfont,
194 TEXTMETRIC * metrics )
196 int average, i, count;
197 unsigned long prop;
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;
225 else
227 XCharStruct * charPtr = xfont->per_char;
228 average = count = 0;
229 for (i = metrics->tmFirstChar; i <= metrics->tmLastChar; i++)
231 if (!CI_NONEXISTCHAR( charPtr ))
233 average += charPtr->width;
234 count++;
236 charPtr++;
238 if (count) average = (average + count/2) / count;
240 metrics->tmAveCharWidth = average;
244 /***********************************************************************
245 * CreateFontIndirect (GDI.57)
247 HFONT CreateFontIndirect( LOGFONT * font )
249 FONTOBJ * fontPtr;
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);
256 return 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,
266 LPSTR name )
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 /***********************************************************************
276 * FONT_GetObject
278 int FONT_GetObject( FONTOBJ * font, int count, LPSTR buffer )
280 if (count > sizeof(LOGFONT)) count = sizeof(LOGFONT);
281 memcpy( buffer, &font->logfont, count );
282 return count;
286 /***********************************************************************
287 * FONT_SelectObject
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",
296 dc, hfont, font);
297 /* Load font if necessary */
299 if (!font)
301 HFONT hnewfont;
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];
314 else
315 stockPtr = NULL;
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" );
328 if (!fontStruct)
330 fprintf( stderr, "No system font could be found. Please check your font path.\n" );
331 exit( 1 );
335 else
337 fontStruct = stockPtr->fstruct;
338 dprintf_font(stddeb,
339 "FONT_SelectObject: Loaded font from cache %x %p\n",
340 hfont, fontStruct );
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 );
351 /* Store font */
353 dc->w.hFont = hfont;
354 if (stockPtr)
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) );
363 else
365 dc->u.x.font.fstruct = fontStruct;
366 FONT_GetMetrics( &font->logfont, fontStruct, &dc->u.x.font.metrics );
368 return prevHandle;
372 /***********************************************************************
373 * GetTextCharacterExtra (GDI.89)
375 short GetTextCharacterExtra( HDC hdc )
377 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
378 if (!dc) return 0;
379 return abs( (dc->w.charExtra * dc->w.WndExtX + dc->w.VportExtX / 2)
380 / dc->w.VportExtX );
384 /***********************************************************************
385 * SetTextCharacterExtra (GDI.8)
387 short SetTextCharacterExtra( HDC hdc, short extra )
389 short prev;
390 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
391 if (!dc) return 0;
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 );
405 if (!dc) return 0;
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;
411 if (breaks)
413 dc->w.breakExtra = extra / breaks;
414 dc->w.breakRem = extra - (dc->w.breakCount * dc->w.breakExtra);
416 else
418 dc->w.breakExtra = 0;
419 dc->w.breakRem = 0;
421 return 1;
425 /***********************************************************************
426 * GetTextFace (GDI.92)
428 INT GetTextFace( HDC hdc, INT count, LPSTR name )
430 FONTOBJ *font;
432 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
433 if (!dc) return 0;
434 if (!(font = (FONTOBJ *) GDI_GetObjPtr( dc->w.hFont, FONT_MAGIC )))
435 return 0;
436 strncpy( name, font->logfont.lfFaceName, count );
437 name[count-1] = '\0';
438 return strlen(name);
442 /***********************************************************************
443 * GetTextExtent (GDI.91)
445 DWORD GetTextExtent( HDC hdc, LPSTR str, short count )
447 SIZE size;
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;
459 XCharStruct info;
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 );
472 return TRUE;
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 );
498 return TRUE;
502 /***********************************************************************
503 * SetMapperFlags (GDI.349)
505 DWORD SetMapperFlags(HDC hDC, DWORD dwFlag)
507 dprintf_font(stdnimp,"SetmapperFlags(%04X, %08lX) // Empty Stub !\n",
508 hDC, dwFlag);
509 return 0L;
513 /***********************************************************************/
516 /***********************************************************************
517 * GetCharWidth (GDI.350)
519 BOOL GetCharWidth(HDC hdc, WORD wFirstChar, WORD wLastChar, LPINT lpBuffer)
521 int i, j;
522 XFontStruct *xfont;
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;
529 /* fixed font? */
530 if (xfont->per_char == NULL)
532 for (i = wFirstChar, j = 0; i <= wLastChar; i++, j++)
533 *(lpBuffer + j) = xfont->max_bounds.width;
534 return TRUE;
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)
544 *(lpBuffer + j) = 0;
546 return TRUE;
550 /***********************************************************************
551 * AddFontResource (GDI.119)
553 int AddFontResource( LPSTR str )
555 fprintf( stdnimp, "STUB: AddFontResource('%s')\n", str );
556 return 1;
560 /***********************************************************************
561 * RemoveFontResource (GDI.136)
563 BOOL RemoveFontResource( LPSTR str )
565 fprintf( stdnimp, "STUB: RemoveFontResource('%s')\n", str );
566 return TRUE;
570 /*************************************************************************
571 * ParseFontParms [internal]
573 int ParseFontParms(LPSTR lpFont, WORD wParmsNo, LPSTR lpRetStr, WORD wMaxSiz)
575 int i;
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++;
582 lpFont++;
584 if (i == wParmsNo) {
585 if (*lpFont == '-') lpFont++;
586 wMaxSiz--;
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);
591 return i;
593 else
594 lpRetStr[0] = '\0';
595 return 0;
599 /*************************************************************************
600 * InitFontsList [internal]
602 void InitFontsList(void)
604 char str[32];
605 char pattern[100];
606 char *family, *weight, *charset;
607 char **names;
608 char slant, spacing;
609 int i, count;
610 LPLOGFONT lpNewFont;
611 weight = "medium";
612 slant = 'r';
613 spacing = '*';
614 charset = "*";
615 family = "*-*";
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");
625 break;
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");
630 AnsiUpper(str);
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;
645 else
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));
651 switch(str[0]) {
652 case 'p':
653 lpNewFont->lfPitchAndFamily = VARIABLE_PITCH | FF_SWISS;
654 break;
655 case 'm':
656 lpNewFont->lfPitchAndFamily = FIXED_PITCH | FF_MODERN;
657 break;
658 default:
659 lpNewFont->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
660 break;
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 /*************************************************************************
673 * EnumFonts [GDI.70]
675 int EnumFonts(HDC hDC, LPSTR lpFaceName, FARPROC lpEnumFunc, LPSTR lpData)
677 HANDLE hLog;
678 HANDLE hMet;
679 HFONT hFont;
680 HFONT hOldFont;
681 LPLOGFONT lpLogFont;
682 LPTEXTMETRIC lptm;
683 LPSTR lpFaceList[MAX_FONTS];
684 char FaceName[LF_FACESIZE];
685 int nRet;
686 int j, i = 0;
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");
695 return 0;
697 hMet = GDI_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(TEXTMETRIC));
698 lptm = (LPTEXTMETRIC) GDI_HEAP_ADDR(hMet);
699 if (lptm == NULL) {
700 GDI_HEAP_FREE(hLog);
701 dprintf_font(stddeb, "EnumFonts // can't alloc TEXTMETRIC struct !\n");
702 return 0;
704 if (lpFaceName != NULL) {
705 strcpy(FaceName, lpFaceName);
706 AnsiUpper(FaceName);
708 if (lpLogFontList[0] == NULL) InitFontsList();
709 memset(lpFaceList, 0, MAX_FONTS * sizeof(LPSTR));
710 while (TRUE) {
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) {
716 i++; j = 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]);
724 else {
725 while(lpLogFontList[i] != NULL) {
726 if (strcmp(FaceName, lpLogFontList[i]->lfFaceName) == 0) break;
727 i++;
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);
736 DeleteObject(hFont);
737 dprintf_font(stddeb,"EnumFonts // i=%d lpLogFont=%p lptm=%p\n", i, lpLogFont, lptm);
739 #ifdef WINELIB
740 nRet = (*lpEnumFunc)(lpLogFont, lptm, 0, lpData);
741 #else
742 nRet = CallBack16(lpEnumFunc, 4, 2, (int)lpLogFont,
743 2, (int)lptm, 0, (int)0, 2, (int)lpData);
744 #endif
745 if (nRet == 0) {
746 dprintf_font(stddeb,"EnumFonts // EnumEnd requested by application !\n");
747 break;
750 GDI_HEAP_FREE(hMet);
751 GDI_HEAP_FREE(hLog);
752 return 0;
756 /*************************************************************************
757 * EnumFontFamilies [GDI.330]
759 int EnumFontFamilies(HDC hDC, LPSTR lpszFamily, FARPROC lpEnumFunc, LPSTR lpData)
761 HANDLE hLog;
762 HANDLE hMet;
763 HFONT hFont;
764 HFONT hOldFont;
765 LPLOGFONT lpLogFont;
766 LPTEXTMETRIC lptm;
767 LPSTR lpFaceList[MAX_FONTS];
768 char FaceName[LF_FACESIZE];
769 int nRet;
770 int j, i = 0;
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");
779 return 0;
781 hMet = GDI_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(TEXTMETRIC));
782 lptm = (LPTEXTMETRIC) GDI_HEAP_ADDR(hMet);
783 if (lptm == NULL) {
784 GDI_HEAP_FREE(hLog);
785 dprintf_font(stddeb,"EnumFontFamilies // can't alloc TEXTMETRIC struct !\n");
786 return 0;
788 if (lpszFamily != NULL) {
789 strcpy(FaceName, lpszFamily);
790 AnsiUpper(FaceName);
792 if (lpLogFontList[0] == NULL) InitFontsList();
793 memset(lpFaceList, 0, MAX_FONTS * sizeof(LPSTR));
794 while (TRUE) {
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) {
802 i++; j = 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]);
809 else {
810 while(lpLogFontList[i] != NULL) {
811 if (strcmp(FaceName, lpLogFontList[i]->lfFaceName) == 0) break;
812 i++;
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);
821 DeleteObject(hFont);
822 dprintf_font(stddeb, "EnumFontFamilies // i=%d lpLogFont=%p lptm=%p\n", i, lpLogFont, lptm);
824 #ifdef WINELIB
825 nRet = (*lpEnumFunc)(lpLogFont, lptm, 0, lpData);
826 #else
827 nRet = CallBack16(lpEnumFunc, 4, 2, (int)lpLogFont,
828 2, (int)lptm, 0, (int)0, 2, (int)lpData);
829 #endif
830 if (nRet == 0) {
831 dprintf_font(stddeb,"EnumFontFamilies // EnumEnd requested by application !\n");
832 break;
835 GDI_HEAP_FREE(hMet);
836 GDI_HEAP_FREE(hLog);
837 return 0;