4 * Copyright 1993 Alexandre Julliard
6 static char Copyright[] = "Copyright Alexandre Julliard, 1993";
12 #include <X11/Xatom.h>
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, oldheight, 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);
141 dprintf_font( stddeb, "FONT_MatchFont: negative width %d(%d)\n",
142 width, font->lfWidth );
145 spacing = (font->lfPitchAndFamily & FIXED_PITCH) ? 'm' :
146 (font->lfPitchAndFamily & VARIABLE_PITCH) ? 'p' : '*';
147 charset = (font->lfCharSet == ANSI_CHARSET) ? "iso8859-1" : "*-*";
148 if (*font->lfFaceName) family = FONT_TranslateName( font->lfFaceName );
149 else switch(font->lfPitchAndFamily & 0xf0)
152 family = FONT_TranslateName( "roman" );
155 family = FONT_TranslateName( "swiss" );
158 family = FONT_TranslateName( "modern" );
161 family = FONT_TranslateName( "script" );
164 family = FONT_TranslateName( "decorative" );
173 /* Width==0 seems not to be a valid wildcard on SGI's, using * instead */
175 sprintf( pattern, "-%s-%s-%c-normal-*-*-%d-*-*-%c-*-%s",
176 family, weight, slant, height, spacing, charset);
178 sprintf( pattern, "-%s-%s-%c-normal-*-*-%d-*-*-%c-%d-%s",
179 family, weight, slant, height, spacing, width, charset);
180 dprintf_font(stddeb, "FONT_MatchFont: '%s'\n", pattern );
181 names = XListFonts( display, pattern, 1, &count );
182 if (count > 0) break;
185 dprintf_font(stddeb,"*** No match for %s\n", pattern );
187 /* try oblique if no italic font */
192 if (spacing == 'm') {
193 /* If a fixed spacing font could not be found, ignore
202 dprintf_font(stddeb," Found '%s'\n", *names );
203 fontStruct = XLoadQueryFont( display, *names );
204 XFreeFontNames( names );
209 /***********************************************************************
212 void FONT_GetMetrics( LOGFONT * logfont, XFontStruct * xfont,
213 TEXTMETRIC * metrics )
215 int average, i, count;
218 metrics->tmAscent = xfont->ascent;
219 metrics->tmDescent = xfont->descent;
220 metrics->tmHeight = xfont->ascent + xfont->descent;
222 metrics->tmInternalLeading = 0;
223 if (XGetFontProperty( xfont, XA_X_HEIGHT, &prop ))
224 metrics->tmInternalLeading = xfont->ascent - (short)prop;
225 metrics->tmExternalLeading = 0;
226 metrics->tmMaxCharWidth = xfont->max_bounds.width;
227 metrics->tmWeight = logfont->lfWeight;
228 metrics->tmItalic = logfont->lfItalic;
229 metrics->tmUnderlined = logfont->lfUnderline;
230 metrics->tmStruckOut = logfont->lfStrikeOut;
231 metrics->tmFirstChar = xfont->min_char_or_byte2;
232 metrics->tmLastChar = xfont->max_char_or_byte2;
233 metrics->tmDefaultChar = xfont->default_char;
234 metrics->tmBreakChar = ' ';
235 metrics->tmCharSet = logfont->lfCharSet;
236 metrics->tmOverhang = 0;
237 metrics->tmDigitizedAspectX = 1;
238 metrics->tmDigitizedAspectY = 1;
239 metrics->tmPitchAndFamily = (logfont->lfPitchAndFamily&0xf0)|TMPF_DEVICE;
240 if (logfont->lfPitchAndFamily & FIXED_PITCH)
241 metrics->tmPitchAndFamily |= TMPF_FIXED_PITCH;
243 if (!xfont->per_char) average = metrics->tmMaxCharWidth;
246 XCharStruct * charPtr = xfont->per_char;
248 for (i = metrics->tmFirstChar; i <= metrics->tmLastChar; i++)
250 if (!CI_NONEXISTCHAR( charPtr ))
252 average += charPtr->width;
257 if (count) average = (average + count/2) / count;
259 metrics->tmAveCharWidth = average;
262 /***********************************************************************
263 * GetGlyphOutLine (GDI.309)
265 DWORD GetGlyphOutLine(HDC hdc, UINT uChar, UINT fuFormat, LPGLYPHMETRICS lpgm,
266 DWORD cbBuffer, LPSTR lpBuffer, LPMAT2 lpmat2)
268 fprintf( stdnimp,"GetGlyphOutLine(%04x, '%c', %04x, %p, %ld, %p, %p) // - empty stub!\n",
269 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
270 return (DWORD)-1; /* failure */
274 /***********************************************************************
275 * CreateScalableFontResource (GDI.310)
277 BOOL CreateScalableFontResource( UINT fHidden,LPSTR lpszResourceFile,
278 LPSTR lpszFontFile, LPSTR lpszCurrentPath )
280 /* fHidden=1 - only visible for the calling app, read-only, not
281 * enumbered with EnumFonts/EnumFontFamilies
282 * lpszCurrentPath can be NULL
284 fprintf(stdnimp,"CreateScalableFontResource(%d,%s,%s,%s) // empty stub!\n",
285 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
286 return FALSE; /* create failed */
290 /***********************************************************************
291 * CreateFontIndirect (GDI.57)
293 HFONT CreateFontIndirect( LOGFONT * font )
296 HFONT hfont = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC );
297 if (!hfont) return 0;
298 fontPtr = (FONTOBJ *) GDI_HEAP_LIN_ADDR( hfont );
299 memcpy( &fontPtr->logfont, font, sizeof(LOGFONT) );
300 AnsiLower( fontPtr->logfont.lfFaceName );
301 dprintf_font(stddeb,"CreateFontIndirect(%p); return %04x\n",font,hfont);
306 /***********************************************************************
307 * CreateFont (GDI.56)
309 HFONT CreateFont( int height, int width, int esc, int orient, int weight,
310 BYTE italic, BYTE underline, BYTE strikeout, BYTE charset,
311 BYTE outpres, BYTE clippres, BYTE quality, BYTE pitch,
314 LOGFONT logfont = { height, width, esc, orient, weight, italic, underline,
315 strikeout, charset, outpres, clippres, quality, pitch, };
316 strncpy( logfont.lfFaceName, name, LF_FACESIZE );
317 return CreateFontIndirect( &logfont );
321 /***********************************************************************
324 int FONT_GetObject( FONTOBJ * font, int count, LPSTR buffer )
326 if (count > sizeof(LOGFONT)) count = sizeof(LOGFONT);
327 memcpy( buffer, &font->logfont, count );
332 /***********************************************************************
335 HFONT FONT_SelectObject( DC * dc, HFONT hfont, FONTOBJ * font )
337 static X_PHYSFONT stockFonts[LAST_STOCK_FONT-FIRST_STOCK_FONT+1];
338 X_PHYSFONT * stockPtr;
339 HFONT prevHandle = dc->w.hFont;
340 XFontStruct * fontStruct;
341 dprintf_font(stddeb,"FONT_SelectObject(%p, %04x, %p)\n",
343 /* Load font if necessary */
349 hnewfont = CreateFont(10, 7, 0, 0, FW_DONTCARE,
350 FALSE, FALSE, FALSE, DEFAULT_CHARSET, 0, 0,
351 DEFAULT_QUALITY, FF_DONTCARE, "*" );
352 font = (FONTOBJ *) GDI_HEAP_LIN_ADDR( hnewfont );
355 if (dc->header.wMagic == METAFILE_DC_MAGIC)
356 return MF_CreateFontIndirect(dc, hfont, &(font->logfont));
358 if ((hfont >= FIRST_STOCK_FONT) && (hfont <= LAST_STOCK_FONT))
359 stockPtr = &stockFonts[hfont - FIRST_STOCK_FONT];
363 if (!stockPtr || !stockPtr->fstruct)
365 if (!(fontStruct = FONT_MatchFont( &font->logfont, dc )))
367 /* If it is not a stock font, we can simply return 0 */
368 if (!stockPtr) return 0;
369 /* Otherwise we must try to find a substitute */
370 dprintf_font(stddeb,"Loading font 'fixed' for %x\n", hfont );
371 font->logfont.lfPitchAndFamily &= ~VARIABLE_PITCH;
372 font->logfont.lfPitchAndFamily |= FIXED_PITCH;
373 fontStruct = XLoadQueryFont( display, "fixed" );
376 fprintf( stderr, "No system font could be found. Please check your font path.\n" );
383 fontStruct = stockPtr->fstruct;
385 "FONT_SelectObject: Loaded font from cache %x %p\n",
389 /* Free previous font */
391 if ((prevHandle < FIRST_STOCK_FONT) || (prevHandle > LAST_STOCK_FONT))
393 if (dc->u.x.font.fstruct)
394 XFreeFont( display, dc->u.x.font.fstruct );
402 if (!stockPtr->fstruct)
404 stockPtr->fstruct = fontStruct;
405 FONT_GetMetrics( &font->logfont, fontStruct, &stockPtr->metrics );
407 memcpy( &dc->u.x.font, stockPtr, sizeof(*stockPtr) );
411 dc->u.x.font.fstruct = fontStruct;
412 FONT_GetMetrics( &font->logfont, fontStruct, &dc->u.x.font.metrics );
418 /***********************************************************************
419 * GetTextCharacterExtra (GDI.89)
421 short GetTextCharacterExtra( HDC hdc )
423 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
425 return abs( (dc->w.charExtra * dc->w.WndExtX + dc->w.VportExtX / 2)
430 /***********************************************************************
431 * SetTextCharacterExtra (GDI.8)
433 short SetTextCharacterExtra( HDC hdc, short extra )
436 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
438 extra = (extra * dc->w.VportExtX + dc->w.WndExtX / 2) / dc->w.WndExtX;
439 prev = dc->w.charExtra;
440 dc->w.charExtra = abs(extra);
441 return (prev * dc->w.WndExtX + dc->w.VportExtX / 2) / dc->w.VportExtX;
445 /***********************************************************************
446 * SetTextJustification (GDI.10)
448 short SetTextJustification( HDC hdc, short extra, short breaks )
450 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
453 extra = abs((extra * dc->w.VportExtX + dc->w.WndExtX / 2) / dc->w.WndExtX);
454 if (!extra) breaks = 0;
455 dc->w.breakTotalExtra = extra;
456 dc->w.breakCount = breaks;
459 dc->w.breakExtra = extra / breaks;
460 dc->w.breakRem = extra - (dc->w.breakCount * dc->w.breakExtra);
464 dc->w.breakExtra = 0;
471 /***********************************************************************
472 * GetTextFace (GDI.92)
474 INT GetTextFace( HDC hdc, INT count, LPSTR name )
478 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
480 if (!(font = (FONTOBJ *) GDI_GetObjPtr( dc->w.hFont, FONT_MAGIC )))
482 strncpy( name, font->logfont.lfFaceName, count );
483 name[count-1] = '\0';
488 /***********************************************************************
489 * GetTextExtent (GDI.91)
491 DWORD GetTextExtent( HDC hdc, LPSTR str, short count )
494 if (!GetTextExtentPoint( hdc, str, count, &size )) return 0;
495 return MAKELONG( size.cx, size.cy );
499 /***********************************************************************
500 * GetTextExtentPoint (GDI.471)
502 BOOL GetTextExtentPoint( HDC hdc, LPSTR str, short count, LPSIZE size )
504 int dir, ascent, descent;
507 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
508 if (!dc) return FALSE;
509 XTextExtents( dc->u.x.font.fstruct, str, count, &dir,
510 &ascent, &descent, &info );
511 size->cx = abs((info.width + dc->w.breakRem + count * dc->w.charExtra)
512 * dc->w.WndExtX / dc->w.VportExtX);
513 size->cy = abs((dc->u.x.font.fstruct->ascent+dc->u.x.font.fstruct->descent)
514 * dc->w.WndExtY / dc->w.VportExtY);
516 dprintf_font(stddeb,"GetTextExtentPoint(%d '%*.*s' %d %p): returning %d,%d\n",
517 hdc, count, count, str, count, size, size->cx, size->cy );
522 /***********************************************************************
523 * GetTextMetrics (GDI.93)
525 BOOL GetTextMetrics( HDC hdc, LPTEXTMETRIC metrics )
527 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
528 if (!dc) return FALSE;
529 memcpy( metrics, &dc->u.x.font.metrics, sizeof(*metrics) );
531 metrics->tmAscent = abs( metrics->tmAscent
532 * dc->w.WndExtY / dc->w.VportExtY );
533 metrics->tmDescent = abs( metrics->tmDescent
534 * dc->w.WndExtY / dc->w.VportExtY );
535 metrics->tmHeight = metrics->tmAscent + metrics->tmDescent;
536 metrics->tmInternalLeading = abs( metrics->tmInternalLeading
537 * dc->w.WndExtY / dc->w.VportExtY );
538 metrics->tmExternalLeading = abs( metrics->tmExternalLeading
539 * dc->w.WndExtY / dc->w.VportExtY );
540 metrics->tmMaxCharWidth = abs( metrics->tmMaxCharWidth
541 * dc->w.WndExtX / dc->w.VportExtX );
542 metrics->tmAveCharWidth = abs( metrics->tmAveCharWidth
543 * dc->w.WndExtX / dc->w.VportExtX );
548 /***********************************************************************
549 * SetMapperFlags (GDI.349)
551 DWORD SetMapperFlags(HDC hDC, DWORD dwFlag)
553 dprintf_font(stdnimp,"SetmapperFlags(%04X, %08lX) // Empty Stub !\n",
559 /***********************************************************************/
562 /***********************************************************************
563 * GetCharWidth (GDI.350)
565 BOOL GetCharWidth(HDC hdc, WORD wFirstChar, WORD wLastChar, LPINT lpBuffer)
569 XCharStruct *cs, *def;
571 DC *dc = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC);
572 if (!dc) return FALSE;
573 xfont = dc->u.x.font.fstruct;
576 if (xfont->per_char == NULL)
578 for (i = wFirstChar, j = 0; i <= wLastChar; i++, j++)
579 *(lpBuffer + j) = xfont->max_bounds.width;
583 CI_GET_DEFAULT_INFO(xfont, def);
585 for (i = wFirstChar, j = 0; i <= wLastChar; i++, j++)
587 CI_GET_CHAR_INFO(xfont, i, def, cs);
588 *(lpBuffer + j) = cs ? cs->width : xfont->max_bounds.width;
589 if (*(lpBuffer + j) < 0)
596 /***********************************************************************
597 * AddFontResource (GDI.119)
599 int AddFontResource( LPSTR str )
601 fprintf( stdnimp, "STUB: AddFontResource('%s')\n", str );
606 /***********************************************************************
607 * RemoveFontResource (GDI.136)
609 BOOL RemoveFontResource( LPSTR str )
611 fprintf( stdnimp, "STUB: RemoveFontResource('%s')\n", str );
616 /*************************************************************************
617 * ParseFontParms [internal]
619 int ParseFontParms(LPSTR lpFont, WORD wParmsNo, LPSTR lpRetStr, WORD wMaxSiz)
622 dprintf_font(stddeb,"ParseFontParms('%s', %d, %p, %d);\n",
623 lpFont, wParmsNo, lpRetStr, wMaxSiz);
624 if (lpFont == NULL) return 0;
625 if (lpRetStr == NULL) return 0;
626 for (i = 0; (*lpFont != '\0' && i != wParmsNo); ) {
627 if (*lpFont == '-') i++;
631 if (*lpFont == '-') lpFont++;
633 for (i = 0; (*lpFont != '\0' && *lpFont != '-' && i < wMaxSiz); i++)
634 *(lpRetStr + i) = *lpFont++;
635 *(lpRetStr + i) = '\0';
636 dprintf_font(stddeb,"ParseFontParms // '%s'\n", lpRetStr);
645 /*************************************************************************
646 * InitFontsList [internal]
649 static int logfcmp(const void *a,const void *b)
651 return strcmp( (*(LPLOGFONT *)a)->lfFaceName, (*(LPLOGFONT *)b)->lfFaceName );
654 void InitFontsList(void)
658 char *family, *weight, *charset;
668 dprintf_font(stddeb,"InitFontsList !\n");
669 sprintf( pattern, "-%s-%s-%c-normal-*-*-*-*-*-%c-*-%s",
670 family, weight, slant, spacing, charset);
671 names = XListFonts( display, pattern, MAX_FONTS, &count );
672 dprintf_font(stddeb,"InitFontsList // count=%d \n", count);
673 for (i = 0; i < count; i++) {
674 lpNewFont = malloc(sizeof(LOGFONT) + LF_FACESIZE);
675 if (lpNewFont == NULL) {
676 dprintf_font(stddeb, "InitFontsList // Error alloc new font structure !\n");
679 dprintf_font(stddeb,"InitFontsList // names[%d]='%s' \n", i, names[i]);
680 ParseFontParms(names[i], 2, str, sizeof(str));
681 if (strcmp(str, "fixed") == 0) strcat(str, "sys");
683 strcpy(lpNewFont->lfFaceName, str);
684 ParseFontParms(names[i], 8, str, sizeof(str));
685 lpNewFont->lfHeight = atoi(str) / 10;
686 ParseFontParms(names[i], 12, str, sizeof(str));
687 lpNewFont->lfWidth = atoi(str) / 10;
688 lpNewFont->lfEscapement = 0;
689 lpNewFont->lfOrientation = 0;
690 lpNewFont->lfWeight = FW_REGULAR;
691 lpNewFont->lfItalic = 0;
692 lpNewFont->lfUnderline = 0;
693 lpNewFont->lfStrikeOut = 0;
694 ParseFontParms(names[i], 13, str, sizeof(str));
695 if (strcmp(str, "iso8859") == 0) {
696 lpNewFont->lfCharSet = ANSI_CHARSET;
698 lpNewFont->lfCharSet = OEM_CHARSET;
700 lpNewFont->lfOutPrecision = OUT_DEFAULT_PRECIS;
701 lpNewFont->lfClipPrecision = CLIP_DEFAULT_PRECIS;
702 lpNewFont->lfQuality = DEFAULT_QUALITY;
703 ParseFontParms(names[i], 11, str, sizeof(str));
706 lpNewFont->lfPitchAndFamily = VARIABLE_PITCH | FF_SWISS;
709 lpNewFont->lfPitchAndFamily = FIXED_PITCH | FF_MODERN;
712 lpNewFont->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
715 dprintf_font(stddeb,"InitFontsList // lpNewFont->lfHeight=%d \n", lpNewFont->lfHeight);
716 dprintf_font(stddeb,"InitFontsList // lpNewFont->lfWidth=%d \n", lpNewFont->lfWidth);
717 dprintf_font(stddeb,"InitFontsList // lfFaceName='%s' \n", lpNewFont->lfFaceName);
718 lpLogFontList[i] = lpNewFont;
719 lpLogFontList[i+1] = NULL;
721 qsort(lpLogFontList,count,sizeof(*lpLogFontList),logfcmp);
722 XFreeFontNames(names);
726 /*************************************************************************
729 int EnumFonts(HDC hDC, LPSTR lpFaceName, FARPROC lpEnumFunc, LPSTR lpData)
738 char FaceName[LF_FACESIZE];
742 dprintf_font(stddeb,"EnumFonts(%04X, %p='%s', %08lx, %p)\n",
743 hDC, lpFaceName, lpFaceName, (LONG)lpEnumFunc, lpData);
744 if (lpEnumFunc == 0) return 0;
745 hLog = GDI_HEAP_ALLOC( sizeof(LOGFONT) + LF_FACESIZE );
746 lpLogFont = (LPLOGFONT) GDI_HEAP_LIN_ADDR(hLog);
747 if (lpLogFont == NULL) {
748 fprintf(stderr,"EnumFonts // can't alloc LOGFONT struct !\n");
751 hMet = GDI_HEAP_ALLOC( sizeof(TEXTMETRIC) );
752 lptm = (LPTEXTMETRIC) GDI_HEAP_LIN_ADDR(hMet);
755 fprintf(stderr, "EnumFonts // can't alloc TEXTMETRIC struct !\n");
758 if (lpFaceName != NULL) {
759 strcpy(FaceName, lpFaceName);
764 if (lpLogFontList[0] == NULL) InitFontsList();
765 for(i = 0; lpLogFontList[i] != NULL; i++) {
766 if (lpFaceName == NULL) {
767 if (lpOldName != NULL) {
768 if (strcmp(lpOldName,lpLogFontList[i]->lfFaceName) == 0) continue;
770 lpOldName = lpLogFontList[i]->lfFaceName;
772 if (strcmp(FaceName, lpLogFontList[i]->lfFaceName) != 0) continue;
774 dprintf_font(stddeb,"EnumFonts // enum '%s' !\n", lpLogFontList[i]->lfFaceName);
775 dprintf_font(stddeb,"EnumFonts // %p !\n", lpLogFontList[i]);
776 memcpy(lpLogFont, lpLogFontList[i], sizeof(LOGFONT) + LF_FACESIZE);
777 hFont = CreateFontIndirect(lpLogFont);
778 hOldFont = SelectObject(hDC, hFont);
779 GetTextMetrics(hDC, lptm);
780 SelectObject(hDC, hOldFont);
782 dprintf_font(stddeb,"EnumFonts // i=%d lpLogFont=%p lptm=%p\n", i, lpLogFont, lptm);
783 nRet = CallEnumFontsProc(lpEnumFunc, GDI_HEAP_SEG_ADDR(hLog),
784 GDI_HEAP_SEG_ADDR(hMet), 0, (LONG)lpData );
786 dprintf_font(stddeb,"EnumFonts // EnumEnd requested by application !\n");
796 /*************************************************************************
797 * EnumFontFamilies [GDI.330]
799 int EnumFontFamilies(HDC hDC, LPSTR lpszFamily, FARPROC lpEnumFunc, LPSTR lpData)
805 LPENUMLOGFONT lpEnumLogFont;
808 char FaceName[LF_FACESIZE];
812 dprintf_font(stddeb,"EnumFontFamilies(%04X, %p, %08lx, %p)\n",
813 hDC, lpszFamily, lpEnumFunc, lpData);
814 if (lpEnumFunc == 0) return 0;
815 hLog = GDI_HEAP_ALLOC( sizeof(ENUMLOGFONT) );
816 lpEnumLogFont = (LPENUMLOGFONT) GDI_HEAP_LIN_ADDR(hLog);
817 if (lpEnumLogFont == NULL) {
818 fprintf(stderr,"EnumFontFamilies // can't alloc LOGFONT struct !\n");
821 hMet = GDI_HEAP_ALLOC( sizeof(TEXTMETRIC) );
822 lptm = (LPTEXTMETRIC) GDI_HEAP_LIN_ADDR(hMet);
825 fprintf(stderr,"EnumFontFamilies // can't alloc TEXTMETRIC struct !\n");
829 if (lpszFamily != NULL) {
830 strcpy(FaceName, lpszFamily);
833 if (lpLogFontList[0] == NULL) InitFontsList();
834 for(i = 0; lpLogFontList[i] != NULL; i++) {
835 if (lpszFamily == NULL) {
836 if (lpOldName != NULL) {
837 if (strcmp(lpOldName,lpLogFontList[i]->lfFaceName) == 0) continue;
839 lpOldName = lpLogFontList[i]->lfFaceName;
841 if (strcmp(FaceName, lpLogFontList[i]->lfFaceName) != 0) continue;
843 memcpy(lpEnumLogFont, lpLogFontList[i], sizeof(LOGFONT));
844 strcpy(lpEnumLogFont->elfFullName,"");
845 strcpy(lpEnumLogFont->elfStyle,"");
846 hFont = CreateFontIndirect((LPLOGFONT)lpEnumLogFont);
847 hOldFont = SelectObject(hDC, hFont);
848 GetTextMetrics(hDC, lptm);
849 SelectObject(hDC, hOldFont);
851 dprintf_font(stddeb, "EnumFontFamilies // i=%d lpLogFont=%p lptm=%p\n", i, lpEnumLogFont, lptm);
853 nRet = CallEnumFontFamProc( lpEnumFunc,
854 GDI_HEAP_SEG_ADDR(hLog),
855 GDI_HEAP_SEG_ADDR(hMet),
858 dprintf_font(stddeb,"EnumFontFamilies // EnumEnd requested by application !\n");
867 /*************************************************************************
868 * GetRasterizerCaps [GDI.313]
871 BOOL GetRasterizerCaps(LPRASTERIZER_STATUS lprs, WORD cbNumBytes)
873 /* This is not much more than a dummy */
874 RASTERIZER_STATUS rs;
876 rs.nSize = sizeof(rs);
882 /*************************************************************************
883 * GetKerningPairs [GDI.332]
884 * FIXME: The last parameter is actually LPKERNINGPAIR
886 int GetKerningPairs(WORD hDC,int cBufLen,LPVOID lpKerningPairs)
888 /* Wine fonts are ugly and don't support kerning :) */