Release 960114
[wine/gsoc-2012-control.git] / objects / font.c
blobb3df1a2160a7fb461f13a51e735217d90cdac42b
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 "wine.h"
16 #include "callback.h"
17 #include "xmalloc.h"
18 #include "stddebug.h"
19 #include "debug.h"
21 #define MAX_FONTS 256
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))
29 /*
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
34 * char.
36 #define CI_GET_CHAR_INFO(fs,col,def,cs) \
37 { \
38 cs = def; \
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; \
42 } else { \
43 cs = &fs->per_char[(col - fs->min_char_or_byte2)]; \
44 if (CI_NONEXISTCHAR(cs)) cs = def; \
45 } \
46 } \
49 #define CI_GET_DEFAULT_INFO(fs,cs) \
50 CI_GET_CHAR_INFO(fs, fs->default_char, NULL, cs)
52 struct FontStructure {
53 char *window;
54 char *x11;
55 } FontNames[32];
56 int FontSize;
59 /***********************************************************************
60 * FONT_Init
62 BOOL FONT_Init( void )
64 char temp[1024];
65 LPSTR ptr;
66 int i;
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 = xstrdup( ptr );
72 FontSize = i;
74 for( i = 1; i < FontSize; i++ ) {
75 GetPrivateProfileString("fonts", FontNames[i].window, "*", temp, sizeof(temp), WINE_INI);
76 FontNames[i].x11 = xstrdup( temp );
78 GetPrivateProfileString("fonts", "default", "*", temp, sizeof(temp), WINE_INI);
79 FontNames[0].x11 = xstrdup( temp );
81 } else {
82 FontNames[0].window = NULL; FontNames[0].x11 = "*-helvetica";
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";
89 FontSize = 7;
91 return TRUE;
95 /***********************************************************************
96 * FONT_TranslateName
98 * Translate a Windows face name to its X11 equivalent.
99 * This will probably have to be customizable.
101 static const char *FONT_TranslateName( char *winFaceName )
103 int i;
105 for (i = 1; i < FontSize; i ++)
106 if( !strcmp( winFaceName, FontNames[i].window ) ) {
107 dprintf_font(stddeb, "---- Mapped %s to %s\n", winFaceName, FontNames[i].x11 );
108 return FontNames[i].x11;
110 return FontNames[0].x11;
114 /***********************************************************************
115 * FONT_MatchFont
117 * Find a X font matching the logical font.
119 static XFontStruct * FONT_MatchFont( LOGFONT * font, DC * dc )
121 char pattern[100];
122 const char *family, *weight, *charset;
123 char **names;
124 char slant, spacing;
125 int width, height, oldheight, count;
126 XFontStruct * fontStruct;
128 weight = (font->lfWeight > 550) ? "bold" : "medium";
129 slant = font->lfItalic ? 'i' : 'r';
130 height = font->lfHeight * dc->w.VportExtX / dc->w.WndExtX;
131 if (height == 0) height = 120; /* Default height = 12 */
132 else if (height < 0)
134 /* If height is negative, it means the height of the characters */
135 /* *without* the internal leading. So we adjust it a bit to */
136 /* compensate. 5/4 seems to give good results for small fonts. */
137 height = 10 * (-height * 5 / 4);
139 else height *= 10;
140 width = 10 * (font->lfWidth * dc->w.VportExtY / dc->w.WndExtY);
141 if (width < 0) {
142 dprintf_font( stddeb, "FONT_MatchFont: negative width %d(%d)\n",
143 width, font->lfWidth );
144 width = -width;
146 spacing = (font->lfPitchAndFamily & FIXED_PITCH) ? 'm' :
147 (font->lfPitchAndFamily & VARIABLE_PITCH) ? 'p' : '*';
148 charset = (font->lfCharSet == ANSI_CHARSET) ? "iso8859-1" : "*-*";
149 if (*font->lfFaceName) family = FONT_TranslateName( font->lfFaceName );
150 else switch(font->lfPitchAndFamily & 0xf0)
152 case FF_ROMAN:
153 family = FONT_TranslateName( "roman" );
154 break;
155 case FF_SWISS:
156 family = FONT_TranslateName( "swiss" );
157 break;
158 case FF_MODERN:
159 family = FONT_TranslateName( "modern" );
160 break;
161 case FF_SCRIPT:
162 family = FONT_TranslateName( "script" );
163 break;
164 case FF_DECORATIVE:
165 family = FONT_TranslateName( "decorative" );
166 break;
167 default:
168 family = "*-*";
169 break;
172 oldheight = height;
173 while (TRUE) {
174 /* Width==0 seems not to be a valid wildcard on SGI's, using * instead */
175 if ( width == 0 )
176 sprintf( pattern, "-%s-%s-%c-normal-*-*-%d-*-*-%c-*-%s",
177 family, weight, slant, height, spacing, charset);
178 else
179 sprintf( pattern, "-%s-%s-%c-normal-*-*-%d-*-*-%c-%d-%s",
180 family, weight, slant, height, spacing, width, charset);
181 dprintf_font(stddeb, "FONT_MatchFont: '%s'\n", pattern );
182 names = XListFonts( display, pattern, 1, &count );
183 if (count > 0) break;
184 height -= 10;
185 if (height < 10) {
186 dprintf_font(stddeb,"*** No match for %s\n", pattern );
187 if(slant == 'i') {
188 /* try oblique if no italic font */
189 slant = 'o';
190 height = oldheight;
191 continue;
193 if (spacing == 'm') {
194 /* If a fixed spacing font could not be found, ignore
195 * the family */
196 family = "*-*";
197 height = oldheight;
198 continue;
200 return NULL;
203 dprintf_font(stddeb," Found '%s'\n", *names );
204 fontStruct = XLoadQueryFont( display, *names );
205 XFreeFontNames( names );
206 return fontStruct;
210 /***********************************************************************
211 * FONT_GetMetrics
213 void FONT_GetMetrics( LOGFONT * logfont, XFontStruct * xfont,
214 TEXTMETRIC * metrics )
216 int average, i, count;
217 unsigned long prop;
219 metrics->tmAscent = xfont->ascent;
220 metrics->tmDescent = xfont->descent;
221 metrics->tmHeight = xfont->ascent + xfont->descent;
223 metrics->tmInternalLeading = 0;
224 if (XGetFontProperty( xfont, XA_X_HEIGHT, &prop ))
225 metrics->tmInternalLeading = xfont->ascent - (short)prop;
226 metrics->tmExternalLeading = 0;
227 metrics->tmMaxCharWidth = xfont->max_bounds.width;
228 metrics->tmWeight = logfont->lfWeight;
229 metrics->tmItalic = logfont->lfItalic;
230 metrics->tmUnderlined = logfont->lfUnderline;
231 metrics->tmStruckOut = logfont->lfStrikeOut;
232 metrics->tmFirstChar = xfont->min_char_or_byte2;
233 metrics->tmLastChar = xfont->max_char_or_byte2;
234 metrics->tmDefaultChar = xfont->default_char;
235 metrics->tmBreakChar = ' ';
236 metrics->tmCharSet = logfont->lfCharSet;
237 metrics->tmOverhang = 0;
238 metrics->tmDigitizedAspectX = 1;
239 metrics->tmDigitizedAspectY = 1;
240 metrics->tmPitchAndFamily = (logfont->lfPitchAndFamily&0xf0)|TMPF_DEVICE;
241 if (logfont->lfPitchAndFamily & FIXED_PITCH)
242 metrics->tmPitchAndFamily |= TMPF_FIXED_PITCH;
244 if (!xfont->per_char) average = metrics->tmMaxCharWidth;
245 else
247 XCharStruct * charPtr = xfont->per_char;
248 average = count = 0;
249 for (i = metrics->tmFirstChar; i <= metrics->tmLastChar; i++)
251 if (!CI_NONEXISTCHAR( charPtr ))
253 average += charPtr->width;
254 count++;
256 charPtr++;
258 if (count) average = (average + count/2) / count;
260 metrics->tmAveCharWidth = average;
263 /***********************************************************************
264 * GetGlyphOutLine (GDI.309)
266 DWORD GetGlyphOutLine(HDC hdc, UINT uChar, UINT fuFormat, LPGLYPHMETRICS lpgm,
267 DWORD cbBuffer, LPSTR lpBuffer, LPMAT2 lpmat2)
269 fprintf( stdnimp,"GetGlyphOutLine("NPFMT", '%c', %04x, %p, %ld, %p, %p) // - empty stub!\n",
270 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
271 return (DWORD)-1; /* failure */
275 /***********************************************************************
276 * CreateScalableFontResource (GDI.310)
278 BOOL CreateScalableFontResource( UINT fHidden,LPSTR lpszResourceFile,
279 LPSTR lpszFontFile, LPSTR lpszCurrentPath )
281 /* fHidden=1 - only visible for the calling app, read-only, not
282 * enumbered with EnumFonts/EnumFontFamilies
283 * lpszCurrentPath can be NULL
285 fprintf(stdnimp,"CreateScalableFontResource(%d,%s,%s,%s) // empty stub!\n",
286 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
287 return FALSE; /* create failed */
291 /***********************************************************************
292 * CreateFontIndirect (GDI.57)
294 HFONT CreateFontIndirect( LOGFONT * font )
296 FONTOBJ * fontPtr;
297 HFONT hfont = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC );
298 if (!hfont) return 0;
299 fontPtr = (FONTOBJ *) GDI_HEAP_LIN_ADDR( hfont );
300 memcpy( &fontPtr->logfont, font, sizeof(LOGFONT) );
301 AnsiLower( fontPtr->logfont.lfFaceName );
302 dprintf_font(stddeb,"CreateFontIndirect(%p); return "NPFMT"\n",font,hfont);
303 return hfont;
307 /***********************************************************************
308 * CreateFont (GDI.56)
310 HFONT CreateFont( int height, int width, int esc, int orient, int weight,
311 BYTE italic, BYTE underline, BYTE strikeout, BYTE charset,
312 BYTE outpres, BYTE clippres, BYTE quality, BYTE pitch,
313 LPSTR name )
315 LOGFONT logfont = { height, width, esc, orient, weight, italic, underline,
316 strikeout, charset, outpres, clippres, quality, pitch, };
317 if (name) strncpy( logfont.lfFaceName, name, LF_FACESIZE );
318 else logfont.lfFaceName[0] = '\0';
319 return CreateFontIndirect( &logfont );
323 /***********************************************************************
324 * FONT_GetObject
326 int FONT_GetObject( FONTOBJ * font, int count, LPSTR buffer )
328 if (count > sizeof(LOGFONT)) count = sizeof(LOGFONT);
329 memcpy( buffer, &font->logfont, count );
330 return count;
334 /***********************************************************************
335 * FONT_SelectObject
337 HFONT FONT_SelectObject( DC * dc, HFONT hfont, FONTOBJ * font )
339 static X_PHYSFONT stockFonts[LAST_STOCK_FONT-FIRST_STOCK_FONT+1];
340 X_PHYSFONT * stockPtr;
341 HFONT prevHandle = dc->w.hFont;
342 XFontStruct * fontStruct;
343 dprintf_font(stddeb,"FONT_SelectObject(%p, "NPFMT", %p)\n",
344 dc, hfont, font);
345 /* Load font if necessary */
347 if (!font)
349 HFONT hnewfont;
351 hnewfont = CreateFont(10, 7, 0, 0, FW_DONTCARE,
352 FALSE, FALSE, FALSE, DEFAULT_CHARSET, 0, 0,
353 DEFAULT_QUALITY, FF_DONTCARE, "*" );
354 font = (FONTOBJ *) GDI_HEAP_LIN_ADDR( hnewfont );
357 if (dc->header.wMagic == METAFILE_DC_MAGIC)
358 if (MF_CreateFontIndirect(dc, hfont, &(font->logfont)))
359 return prevHandle;
360 else
361 return 0;
363 /* Must be DWORD for WINELIB32 support */
364 if ((hfont >= FIRST_STOCK_FONT) && (hfont <= LAST_STOCK_FONT))
365 stockPtr = &stockFonts[(DWORD)hfont - (DWORD)FIRST_STOCK_FONT];
366 else
367 stockPtr = NULL;
369 if (!stockPtr || !stockPtr->fstruct)
371 if (!(fontStruct = FONT_MatchFont( &font->logfont, dc )))
373 /* If it is not a stock font, we can simply return 0 */
374 if (!stockPtr) return 0;
375 /* Otherwise we must try to find a substitute */
376 dprintf_font(stddeb,"Loading font 'fixed' for "NPFMT"\n", hfont );
377 font->logfont.lfPitchAndFamily &= ~VARIABLE_PITCH;
378 font->logfont.lfPitchAndFamily |= FIXED_PITCH;
379 fontStruct = XLoadQueryFont( display, "fixed" );
380 if (!fontStruct)
382 fprintf( stderr, "No system font could be found. Please check your font path.\n" );
383 exit( 1 );
387 else
389 fontStruct = stockPtr->fstruct;
390 dprintf_font(stddeb,
391 "FONT_SelectObject: Loaded font from cache "NPFMT" %p\n",
392 hfont, fontStruct );
395 /* Free previous font */
397 if ((prevHandle < FIRST_STOCK_FONT) || (prevHandle > LAST_STOCK_FONT))
399 if (dc->u.x.font.fstruct)
400 XFreeFont( display, dc->u.x.font.fstruct );
403 /* Store font */
405 dc->w.hFont = hfont;
406 if (stockPtr)
408 if (!stockPtr->fstruct)
410 stockPtr->fstruct = fontStruct;
411 FONT_GetMetrics( &font->logfont, fontStruct, &stockPtr->metrics );
413 memcpy( &dc->u.x.font, stockPtr, sizeof(*stockPtr) );
415 else
417 dc->u.x.font.fstruct = fontStruct;
418 FONT_GetMetrics( &font->logfont, fontStruct, &dc->u.x.font.metrics );
420 return prevHandle;
424 /***********************************************************************
425 * GetTextCharacterExtra (GDI.89)
427 short GetTextCharacterExtra( HDC hdc )
429 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
430 if (!dc) return 0;
431 return abs( (dc->w.charExtra * dc->w.WndExtX + dc->w.VportExtX / 2)
432 / dc->w.VportExtX );
436 /***********************************************************************
437 * SetTextCharacterExtra (GDI.8)
439 short SetTextCharacterExtra( HDC hdc, short extra )
441 short prev;
442 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
443 if (!dc) return 0;
444 extra = (extra * dc->w.VportExtX + dc->w.WndExtX / 2) / dc->w.WndExtX;
445 prev = dc->w.charExtra;
446 dc->w.charExtra = abs(extra);
447 return (prev * dc->w.WndExtX + dc->w.VportExtX / 2) / dc->w.VportExtX;
451 /***********************************************************************
452 * SetTextJustification (GDI.10)
454 short SetTextJustification( HDC hdc, short extra, short breaks )
456 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
457 if (!dc) return 0;
459 extra = abs((extra * dc->w.VportExtX + dc->w.WndExtX / 2) / dc->w.WndExtX);
460 if (!extra) breaks = 0;
461 dc->w.breakTotalExtra = extra;
462 dc->w.breakCount = breaks;
463 if (breaks)
465 dc->w.breakExtra = extra / breaks;
466 dc->w.breakRem = extra - (dc->w.breakCount * dc->w.breakExtra);
468 else
470 dc->w.breakExtra = 0;
471 dc->w.breakRem = 0;
473 return 1;
477 /***********************************************************************
478 * GetTextFace (GDI.92)
480 INT GetTextFace( HDC hdc, INT count, LPSTR name )
482 FONTOBJ *font;
484 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
485 if (!dc) return 0;
486 if (!(font = (FONTOBJ *) GDI_GetObjPtr( dc->w.hFont, FONT_MAGIC )))
487 return 0;
488 lstrcpyn( name, font->logfont.lfFaceName, count );
489 return strlen(name);
493 /***********************************************************************
494 * GetTextExtent (GDI.91)
496 DWORD GetTextExtent( HDC hdc, LPSTR str, short count )
498 SIZE size;
499 if (!GetTextExtentPoint( hdc, str, count, &size )) return 0;
500 return MAKELONG( size.cx, size.cy );
504 /***********************************************************************
505 * GetTextExtentPoint (GDI.471)
507 BOOL GetTextExtentPoint( HDC hdc, LPSTR str, short count, LPSIZE size )
509 int dir, ascent, descent;
510 XCharStruct info;
512 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
513 if (!dc) return FALSE;
514 XTextExtents( dc->u.x.font.fstruct, str, count, &dir,
515 &ascent, &descent, &info );
516 size->cx = abs((info.width + dc->w.breakRem + count * dc->w.charExtra)
517 * dc->w.WndExtX / dc->w.VportExtX);
518 size->cy = abs((dc->u.x.font.fstruct->ascent+dc->u.x.font.fstruct->descent)
519 * dc->w.WndExtY / dc->w.VportExtY);
521 dprintf_font(stddeb,"GetTextExtentPoint("NPFMT" '%*.*s' %d %p): returning %ld,%ld\n",
522 hdc, count, count, str, count, size, (LONG)size->cx,
523 (LONG)size->cy );
524 return TRUE;
528 /***********************************************************************
529 * GetTextMetrics (GDI.93)
531 BOOL GetTextMetrics( HDC hdc, LPTEXTMETRIC metrics )
533 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
534 if (!dc) return FALSE;
535 memcpy( metrics, &dc->u.x.font.metrics, sizeof(*metrics) );
537 metrics->tmAscent = abs( metrics->tmAscent
538 * dc->w.WndExtY / dc->w.VportExtY );
539 metrics->tmDescent = abs( metrics->tmDescent
540 * dc->w.WndExtY / dc->w.VportExtY );
541 metrics->tmHeight = metrics->tmAscent + metrics->tmDescent;
542 metrics->tmInternalLeading = abs( metrics->tmInternalLeading
543 * dc->w.WndExtY / dc->w.VportExtY );
544 metrics->tmExternalLeading = abs( metrics->tmExternalLeading
545 * dc->w.WndExtY / dc->w.VportExtY );
546 metrics->tmMaxCharWidth = abs( metrics->tmMaxCharWidth
547 * dc->w.WndExtX / dc->w.VportExtX );
548 metrics->tmAveCharWidth = abs( metrics->tmAveCharWidth
549 * dc->w.WndExtX / dc->w.VportExtX );
550 return TRUE;
554 /***********************************************************************
555 * SetMapperFlags (GDI.349)
557 DWORD SetMapperFlags(HDC hDC, DWORD dwFlag)
559 dprintf_font(stdnimp,"SetmapperFlags("NPFMT", %08lX) // Empty Stub !\n",
560 hDC, dwFlag);
561 return 0L;
565 /***********************************************************************/
568 /***********************************************************************
569 * GetCharWidth (GDI.350)
571 BOOL GetCharWidth(HDC hdc, WORD wFirstChar, WORD wLastChar, LPINT lpBuffer)
573 int i, j;
574 XFontStruct *xfont;
575 XCharStruct *cs, *def;
577 DC *dc = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC);
578 if (!dc) return FALSE;
579 xfont = dc->u.x.font.fstruct;
581 /* fixed font? */
582 if (xfont->per_char == NULL)
584 for (i = wFirstChar, j = 0; i <= wLastChar; i++, j++)
585 *(lpBuffer + j) = xfont->max_bounds.width;
586 return TRUE;
589 CI_GET_DEFAULT_INFO(xfont, def);
591 for (i = wFirstChar, j = 0; i <= wLastChar; i++, j++)
593 CI_GET_CHAR_INFO(xfont, i, def, cs);
594 *(lpBuffer + j) = cs ? cs->width : xfont->max_bounds.width;
595 if (*(lpBuffer + j) < 0)
596 *(lpBuffer + j) = 0;
598 return TRUE;
602 /***********************************************************************
603 * AddFontResource (GDI.119)
605 INT AddFontResource( LPCSTR str )
607 fprintf( stdnimp, "STUB: AddFontResource('%s')\n", str );
608 return 1;
612 /***********************************************************************
613 * RemoveFontResource (GDI.136)
615 BOOL RemoveFontResource( LPSTR str )
617 fprintf( stdnimp, "STUB: RemoveFontResource('%s')\n", str );
618 return TRUE;
622 /*************************************************************************
623 * ParseFontParms [internal]
625 int ParseFontParms(LPSTR lpFont, WORD wParmsNo, LPSTR lpRetStr, WORD wMaxSiz)
627 int i;
628 dprintf_font(stddeb,"ParseFontParms('%s', %d, %p, %d);\n",
629 lpFont, wParmsNo, lpRetStr, wMaxSiz);
630 if (lpFont == NULL) return 0;
631 if (lpRetStr == NULL) return 0;
632 for (i = 0; (*lpFont != '\0' && i != wParmsNo); ) {
633 if (*lpFont == '-') i++;
634 lpFont++;
636 if (i == wParmsNo) {
637 if (*lpFont == '-') lpFont++;
638 wMaxSiz--;
639 for (i = 0; (*lpFont != '\0' && *lpFont != '-' && i < wMaxSiz); i++)
640 *(lpRetStr + i) = *lpFont++;
641 *(lpRetStr + i) = '\0';
642 dprintf_font(stddeb,"ParseFontParms // '%s'\n", lpRetStr);
643 return i;
645 else
646 lpRetStr[0] = '\0';
647 return 0;
651 /*************************************************************************
652 * InitFontsList [internal]
655 static int logfcmp(const void *a,const void *b)
657 return strcmp( (*(LPLOGFONT *)a)->lfFaceName, (*(LPLOGFONT *)b)->lfFaceName );
660 void InitFontsList(void)
662 char str[32];
663 char pattern[100];
664 char *family, *weight, *charset;
665 char **names;
666 char slant, spacing;
667 int i, count;
668 LPLOGFONT lpNewFont;
669 weight = "medium";
670 slant = 'r';
671 spacing = '*';
672 charset = "*";
673 family = "*-*";
674 dprintf_font(stddeb,"InitFontsList !\n");
675 sprintf( pattern, "-%s-%s-%c-normal-*-*-*-*-*-%c-*-%s",
676 family, weight, slant, spacing, charset);
677 names = XListFonts( display, pattern, MAX_FONTS, &count );
678 dprintf_font(stddeb,"InitFontsList // count=%d \n", count);
679 for (i = 0; i < count; i++) {
680 lpNewFont = malloc(sizeof(LOGFONT) + LF_FACESIZE);
681 if (lpNewFont == NULL) {
682 dprintf_font(stddeb, "InitFontsList // Error alloc new font structure !\n");
683 break;
685 dprintf_font(stddeb,"InitFontsList // names[%d]='%s' \n", i, names[i]);
686 ParseFontParms(names[i], 2, str, sizeof(str));
687 if (strcmp(str, "fixed") == 0) strcat(str, "sys");
688 AnsiUpper(str);
689 strcpy(lpNewFont->lfFaceName, str);
690 ParseFontParms(names[i], 8, str, sizeof(str));
691 lpNewFont->lfHeight = atoi(str) / 10;
692 ParseFontParms(names[i], 12, str, sizeof(str));
693 lpNewFont->lfWidth = atoi(str) / 10;
694 lpNewFont->lfEscapement = 0;
695 lpNewFont->lfOrientation = 0;
696 lpNewFont->lfWeight = FW_REGULAR;
697 lpNewFont->lfItalic = 0;
698 lpNewFont->lfUnderline = 0;
699 lpNewFont->lfStrikeOut = 0;
700 ParseFontParms(names[i], 13, str, sizeof(str));
701 if (strcmp(str, "iso8859") == 0) {
702 lpNewFont->lfCharSet = ANSI_CHARSET;
703 } else {
704 lpNewFont->lfCharSet = OEM_CHARSET;
706 lpNewFont->lfOutPrecision = OUT_DEFAULT_PRECIS;
707 lpNewFont->lfClipPrecision = CLIP_DEFAULT_PRECIS;
708 lpNewFont->lfQuality = DEFAULT_QUALITY;
709 ParseFontParms(names[i], 11, str, sizeof(str));
710 switch(str[0]) {
711 case 'p':
712 lpNewFont->lfPitchAndFamily = VARIABLE_PITCH | FF_SWISS;
713 break;
714 case 'm':
715 lpNewFont->lfPitchAndFamily = FIXED_PITCH | FF_MODERN;
716 break;
717 default:
718 lpNewFont->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
719 break;
721 dprintf_font(stddeb,"InitFontsList // lpNewFont->lfHeight=%d \n", lpNewFont->lfHeight);
722 dprintf_font(stddeb,"InitFontsList // lpNewFont->lfWidth=%d \n", lpNewFont->lfWidth);
723 dprintf_font(stddeb,"InitFontsList // lfFaceName='%s' \n", lpNewFont->lfFaceName);
724 lpLogFontList[i] = lpNewFont;
725 lpLogFontList[i+1] = NULL;
727 qsort(lpLogFontList,count,sizeof(*lpLogFontList),logfcmp);
728 XFreeFontNames(names);
732 /*************************************************************************
733 * EnumFonts [GDI.70]
735 int EnumFonts(HDC hDC, LPSTR lpFaceName, FARPROC lpEnumFunc, LPSTR lpData)
737 HANDLE hLog;
738 HANDLE hMet;
739 HFONT hFont;
740 HFONT hOldFont;
741 LPLOGFONT lpLogFont;
742 LPTEXTMETRIC lptm;
743 LPSTR lpOldName;
744 char FaceName[LF_FACESIZE];
745 int nRet = 0;
746 int i;
748 dprintf_font(stddeb,"EnumFonts("NPFMT", %p='%s', %08lx, %p)\n",
749 hDC, lpFaceName, lpFaceName, (LONG)lpEnumFunc, lpData);
750 if (lpEnumFunc == 0) return 0;
751 hLog = GDI_HEAP_ALLOC( sizeof(LOGFONT) + LF_FACESIZE );
752 lpLogFont = (LPLOGFONT) GDI_HEAP_LIN_ADDR(hLog);
753 if (lpLogFont == NULL) {
754 fprintf(stderr,"EnumFonts // can't alloc LOGFONT struct !\n");
755 return 0;
757 hMet = GDI_HEAP_ALLOC( sizeof(TEXTMETRIC) );
758 lptm = (LPTEXTMETRIC) GDI_HEAP_LIN_ADDR(hMet);
759 if (lptm == NULL) {
760 GDI_HEAP_FREE(hLog);
761 fprintf(stderr, "EnumFonts // can't alloc TEXTMETRIC struct !\n");
762 return 0;
764 if (lpFaceName != NULL) {
765 strcpy(FaceName, lpFaceName);
766 AnsiUpper(FaceName);
768 lpOldName = NULL;
770 if (lpLogFontList[0] == NULL) InitFontsList();
771 for(i = 0; lpLogFontList[i] != NULL; i++) {
772 if (lpFaceName == NULL) {
773 if (lpOldName != NULL) {
774 if (strcmp(lpOldName,lpLogFontList[i]->lfFaceName) == 0) continue;
776 lpOldName = lpLogFontList[i]->lfFaceName;
777 } else {
778 if (strcmp(FaceName, lpLogFontList[i]->lfFaceName) != 0) continue;
780 dprintf_font(stddeb,"EnumFonts // enum '%s' !\n", lpLogFontList[i]->lfFaceName);
781 dprintf_font(stddeb,"EnumFonts // %p !\n", lpLogFontList[i]);
782 memcpy(lpLogFont, lpLogFontList[i], sizeof(LOGFONT) + LF_FACESIZE);
783 hFont = CreateFontIndirect(lpLogFont);
784 hOldFont = SelectObject(hDC, hFont);
785 GetTextMetrics(hDC, lptm);
786 SelectObject(hDC, hOldFont);
787 DeleteObject(hFont);
788 dprintf_font(stddeb,"EnumFonts // i=%d lpLogFont=%p lptm=%p\n", i, lpLogFont, lptm);
789 nRet = CallEnumFontsProc(lpEnumFunc, GDI_HEAP_SEG_ADDR(hLog),
790 GDI_HEAP_SEG_ADDR(hMet), 0, (LONG)lpData );
791 if (nRet == 0) {
792 dprintf_font(stddeb,"EnumFonts // EnumEnd requested by application !\n");
793 break;
796 GDI_HEAP_FREE(hMet);
797 GDI_HEAP_FREE(hLog);
798 return nRet;
802 /*************************************************************************
803 * EnumFontFamilies [GDI.330]
805 int EnumFontFamilies(HDC hDC, LPSTR lpszFamily, FARPROC lpEnumFunc, LPSTR lpData)
807 HANDLE hLog;
808 HANDLE hMet;
809 HFONT hFont;
810 HFONT hOldFont;
811 LPENUMLOGFONT lpEnumLogFont;
812 LPTEXTMETRIC lptm;
813 LPSTR lpOldName;
814 char FaceName[LF_FACESIZE];
815 int nRet = 0;
816 int i;
818 dprintf_font(stddeb,"EnumFontFamilies("NPFMT", %p, %08lx, %p)\n",
819 hDC, lpszFamily, (DWORD)lpEnumFunc, lpData);
820 if (lpEnumFunc == 0) return 0;
821 hLog = GDI_HEAP_ALLOC( sizeof(ENUMLOGFONT) );
822 lpEnumLogFont = (LPENUMLOGFONT) GDI_HEAP_LIN_ADDR(hLog);
823 if (lpEnumLogFont == NULL) {
824 fprintf(stderr,"EnumFontFamilies // can't alloc LOGFONT struct !\n");
825 return 0;
827 hMet = GDI_HEAP_ALLOC( sizeof(TEXTMETRIC) );
828 lptm = (LPTEXTMETRIC) GDI_HEAP_LIN_ADDR(hMet);
829 if (lptm == NULL) {
830 GDI_HEAP_FREE(hLog);
831 fprintf(stderr,"EnumFontFamilies // can't alloc TEXTMETRIC struct !\n");
832 return 0;
834 lpOldName = NULL;
835 if (lpszFamily != NULL) {
836 strcpy(FaceName, lpszFamily);
837 AnsiUpper(FaceName);
839 if (lpLogFontList[0] == NULL) InitFontsList();
840 for(i = 0; lpLogFontList[i] != NULL; i++) {
841 if (lpszFamily == NULL) {
842 if (lpOldName != NULL) {
843 if (strcmp(lpOldName,lpLogFontList[i]->lfFaceName) == 0) continue;
845 lpOldName = lpLogFontList[i]->lfFaceName;
846 } else {
847 if (strcmp(FaceName, lpLogFontList[i]->lfFaceName) != 0) continue;
849 memcpy(lpEnumLogFont, lpLogFontList[i], sizeof(LOGFONT));
850 strcpy(lpEnumLogFont->elfFullName,"");
851 strcpy(lpEnumLogFont->elfStyle,"");
852 hFont = CreateFontIndirect((LPLOGFONT)lpEnumLogFont);
853 hOldFont = SelectObject(hDC, hFont);
854 GetTextMetrics(hDC, lptm);
855 SelectObject(hDC, hOldFont);
856 DeleteObject(hFont);
857 dprintf_font(stddeb, "EnumFontFamilies // i=%d lpLogFont=%p lptm=%p\n", i, lpEnumLogFont, lptm);
859 nRet = CallEnumFontFamProc( lpEnumFunc,
860 GDI_HEAP_SEG_ADDR(hLog),
861 GDI_HEAP_SEG_ADDR(hMet),
862 0, (LONG)lpData );
863 if (nRet == 0) {
864 dprintf_font(stddeb,"EnumFontFamilies // EnumEnd requested by application !\n");
865 break;
868 GDI_HEAP_FREE(hMet);
869 GDI_HEAP_FREE(hLog);
870 return nRet;
873 /*************************************************************************
874 * GetRasterizerCaps [GDI.313]
877 BOOL GetRasterizerCaps(LPRASTERIZER_STATUS lprs, WORD cbNumBytes)
879 /* This is not much more than a dummy */
880 RASTERIZER_STATUS rs;
882 rs.nSize = sizeof(rs);
883 rs.wFlags = 0;
884 rs.nLanguageID = 0;
885 return True;
888 /*************************************************************************
889 * GetKerningPairs [GDI.332]
890 * FIXME: The last parameter is actually LPKERNINGPAIR
892 int GetKerningPairs(WORD hDC,int cBufLen,LPVOID lpKerningPairs)
894 /* Wine fonts are ugly and don't support kerning :) */
895 return 0;