4 * Copyright 1993 Alexandre Julliard
6 * Enhacements by Juergen Marquardt 1996
8 * Implementation of a second font cache which
9 * will be updated dynamically
15 #include <X11/Xatom.h>
24 #define FONTCACHE 32 /* dynamic font cache size */
26 static LPLOGFONT16 lpLogFontList[MAX_FONTS+1];
28 static int ParseFontParms(LPSTR lpFont, WORD wParmsNo, LPSTR lpRetStr, WORD wMaxSiz);
30 #define CI_NONEXISTCHAR(cs) (((cs)->width == 0) && \
31 (((cs)->rbearing|(cs)->lbearing| \
32 (cs)->ascent|(cs)->descent) == 0))
35 * CI_GET_CHAR_INFO - return the charinfo struct for the indicated 8bit
36 * character. If the character is in the column and exists, then return the
37 * appropriate metrics (note that fonts with common per-character metrics will
38 * return min_bounds). If none of these hold true, try again with the default
41 #define CI_GET_CHAR_INFO(fs,col,def,cs) \
44 if (col >= fs->min_char_or_byte2 && col <= fs->max_char_or_byte2) { \
45 if (fs->per_char == NULL) { \
46 cs = &fs->min_bounds; \
48 cs = &fs->per_char[(col - fs->min_char_or_byte2)]; \
49 if (CI_NONEXISTCHAR(cs)) cs = def; \
54 #define CI_GET_DEFAULT_INFO(fs,cs) \
55 CI_GET_CHAR_INFO(fs, fs->default_char, NULL, cs)
57 struct FontStructure {
64 /***********************************************************************
67 BOOL32 FONT_Init( void )
73 if (PROFILE_GetWineIniString( "fonts", NULL, "*", temp, sizeof(temp) ) > 2 )
75 for( ptr = temp, i = 1; strlen(ptr) != 0; ptr += strlen(ptr) + 1 )
76 if( strcmp( ptr, "default" ) )
77 FontNames[i++].window = xstrdup( ptr );
80 for( i = 1; i < FontSize; i++ )
82 PROFILE_GetWineIniString( "fonts", FontNames[i].window, "*",
84 FontNames[i].x11 = xstrdup( temp );
86 PROFILE_GetWineIniString( "fonts", "default", "*", temp, sizeof(temp) );
87 FontNames[0].x11 = xstrdup( temp );
90 FontNames[0].window = NULL; FontNames[0].x11 = "*-helvetica";
91 FontNames[1].window = "ms sans serif"; FontNames[1].x11 = "*-helvetica";
92 FontNames[2].window = "ms serif"; FontNames[2].x11 = "*-times";
93 FontNames[3].window = "fixedsys"; FontNames[3].x11 = "*-fixed";
94 FontNames[4].window = "arial"; FontNames[4].x11 = "*-helvetica";
95 FontNames[5].window = "helv"; FontNames[5].x11 = "*-helvetica";
96 FontNames[6].window = "roman"; FontNames[6].x11 = "*-times";
97 FontNames[7].window = "system"; FontNames[7].x11 = "*-helvetica";
103 /***********************************************************************
106 * returns a valid X11 equivalent if a Windows face name
107 * is like a X11 family - or NULL if translation is needed
109 static char *FONT_ChkX11Family(char *winFaceName )
111 static char x11fam[32+2]; /* will be returned */
114 for(i = 0; lpLogFontList[i] != NULL; i++)
115 if( !lstrcmpi32A(winFaceName, lpLogFontList[i]->lfFaceName) )
118 return strcat(x11fam,winFaceName);
120 return NULL; /* a FONT_TranslateName() call is needed */
125 /***********************************************************************
128 * Translate a Windows face name to its X11 equivalent.
129 * This will probably have to be customizable.
131 static const char *FONT_TranslateName( char *winFaceName )
135 for (i = 1; i < FontSize; i ++)
136 if( !lstrcmpi32A( winFaceName, FontNames[i].window ) ) {
137 dprintf_font(stddeb, "---- Mapped %s to %s\n", winFaceName, FontNames[i].x11 );
138 return FontNames[i].x11;
140 return FontNames[0].x11;
144 /***********************************************************************
147 * Find a X font matching the logical font.
149 static XFontStruct * FONT_MatchFont( LOGFONT16 * font, DC * dc )
152 const char *family, *weight, *charset;
154 char slant, oldspacing, spacing;
155 int width, height, oldheight, count;
156 XFontStruct * fontStruct;
159 "FONT_MatchFont(H,W = %d,%d; Weight = %d; Italic = %d; FaceName = '%s'\n",
160 font->lfHeight, font->lfWidth, font->lfWeight, font->lfItalic, font->lfFaceName);
161 weight = (font->lfWeight > 550) ? "bold" : "medium";
162 slant = font->lfItalic ? 'i' : 'r';
163 if (font->lfHeight == -1)
166 height = font->lfHeight * dc->vportExtX / dc->wndExtX;
167 if (height == 0) height = 120; /* Default height = 12 */
170 /* If height is negative, it means the height of the characters */
171 /* *without* the internal leading. So we adjust it a bit to */
172 /* compensate. 5/4 seems to give good results for small fonts. */
174 * J.M.: This causes wrong font size for bigger fonts e.g. in Winword & Write
175 height = 10 * (-height * 9 / 8);
176 * may be we have to use an non linear function
178 /* assume internal leading is 2 pixels. Else small fonts will become
180 height = (height-2) * -10;
183 width = 10 * (font->lfWidth * dc->vportExtY / dc->wndExtY);
185 dprintf_font( stddeb, "FONT_MatchFont: negative width %d(%d)\n",
186 width, font->lfWidth );
190 spacing = (font->lfPitchAndFamily & FIXED_PITCH) ? 'm' :
191 (font->lfPitchAndFamily & VARIABLE_PITCH) ? 'p' : '*';
194 charset = (font->lfCharSet == ANSI_CHARSET) ? "iso8859-1" : "*-*";
195 if (*font->lfFaceName) {
196 family = FONT_ChkX11Family(font->lfFaceName);
197 /*--do _not_ translate if lfFaceName is family from X11 A.K.*/
199 family = FONT_TranslateName( font->lfFaceName );
200 /* FIX ME: I don't if that's correct but it works J.M. */
203 else switch(font->lfPitchAndFamily & 0xf0)
206 family = FONT_TranslateName( "roman" );
209 family = FONT_TranslateName( "swiss" );
212 family = FONT_TranslateName( "modern" );
215 family = FONT_TranslateName( "script" );
218 family = FONT_TranslateName( "decorative" );
224 sprintf( pattern, "-%s-%s-*-normal-*-*-*-*-*-*-*-%s",
225 family, weight, charset);
226 dprintf_font(stddeb, "FONT_MatchFont: '%s'\n", pattern );
227 names = XListFonts( display, pattern, 1, &count );
228 if (names) XFreeFontNames( names );
231 if (strcmp(family, "*-*") == 0)
233 fprintf(stderr, "FONT_MatchFont(%s) : returning NULL\n", pattern);
239 oldspacing = spacing;
241 /* Width==0 seems not to be a valid wildcard on SGI's, using * instead */
243 sprintf( pattern, "-%s-%s-%c-normal-*-*-%d-*-*-%c-*-%s",
244 family, weight, slant, height, spacing, charset);
246 sprintf( pattern, "-%s-%s-%c-normal-*-*-%d-*-*-%c-%d-%s",
247 family, weight, slant, height, spacing, width, charset);
248 dprintf_font(stddeb, "FONT_MatchFont: '%s'\n", pattern );
249 names = XListFonts( display, pattern, 1, &count );
250 if (count > 0) break;
251 if (spacing == 'm') /* try 'c' if no 'm' found */ {
255 } else if (spacing == 'p') /* try '*' if no 'p' found */ {
259 spacing = oldspacing;
263 /* try oblique if no italic font */
268 if (spacing == 'm' && strcmp(family, "*-*") != 0) {
269 /* If a fixed spacing font could not be found, ignore
275 fprintf(stderr, "FONT_MatchFont(%s) : returning NULL\n", pattern);
279 dprintf_font(stddeb," Found '%s'\n", *names );
280 if (!*font->lfFaceName)
281 ParseFontParms(*names, 2, font->lfFaceName , LF_FACESIZE-1);
282 /* we need a font name for function GetTextFace() even if there isn't one ;-) */
283 /*AnsiUpper(font->lfFaceName);*/
285 fontStruct = XLoadQueryFont( display, *names );
286 XFreeFontNames( names );
291 /***********************************************************************
292 * FONT_LOGFONT32AToLOGFONT16
294 static void FONT_LOGFONT32AToLOGFONT16( const LOGFONT32A *font,
297 font16->lfHeight = (INT16)font->lfHeight;
298 font16->lfWidth = (INT16)font->lfWidth;
299 font16->lfEscapement = (INT16)font->lfEscapement;
300 font16->lfOrientation = (INT16)font->lfOrientation;
301 font16->lfWeight = (INT16)font->lfWeight;
302 font16->lfItalic = font->lfItalic;
303 font16->lfUnderline = font->lfUnderline;
304 font16->lfStrikeOut = font->lfStrikeOut;
305 font16->lfCharSet = font->lfCharSet;
306 font16->lfOutPrecision = font->lfOutPrecision;
307 font16->lfClipPrecision = font->lfClipPrecision;
308 font16->lfQuality = font->lfQuality;
309 font16->lfPitchAndFamily = font->lfPitchAndFamily;
310 lstrcpyn32A( font16->lfFaceName, font->lfFaceName, LF_FACESIZE );
314 /***********************************************************************
315 * FONT_LOGFONT32WToLOGFONT16
317 static void FONT_LOGFONT32WToLOGFONT16( const LOGFONT32W *font,
320 font16->lfHeight = (INT16)font->lfHeight;
321 font16->lfWidth = (INT16)font->lfWidth;
322 font16->lfEscapement = (INT16)font->lfEscapement;
323 font16->lfOrientation = (INT16)font->lfOrientation;
324 font16->lfWeight = (INT16)font->lfWeight;
325 font16->lfItalic = font->lfItalic;
326 font16->lfUnderline = font->lfUnderline;
327 font16->lfStrikeOut = font->lfStrikeOut;
328 font16->lfCharSet = font->lfCharSet;
329 font16->lfOutPrecision = font->lfOutPrecision;
330 font16->lfClipPrecision = font->lfClipPrecision;
331 font16->lfQuality = font->lfQuality;
332 font16->lfPitchAndFamily = font->lfPitchAndFamily;
333 lstrcpynWtoA( font16->lfFaceName, font->lfFaceName, LF_FACESIZE );
337 /***********************************************************************
338 * FONT_LOGFONT16ToLOGFONT32A
340 static void FONT_LOGFONT16ToLOGFONT32A( LPLOGFONT16 font,
341 LPLOGFONT32A font32A )
343 font32A->lfHeight = (INT32)font->lfHeight;
344 font32A->lfWidth = (INT32)font->lfWidth;
345 font32A->lfEscapement = (INT32)font->lfEscapement;
346 font32A->lfOrientation = (INT32)font->lfOrientation;
347 font32A->lfWeight = (INT32)font->lfWeight;
348 font32A->lfItalic = font->lfItalic;
349 font32A->lfUnderline = font->lfUnderline;
350 font32A->lfStrikeOut = font->lfStrikeOut;
351 font32A->lfCharSet = font->lfCharSet;
352 font32A->lfOutPrecision = font->lfOutPrecision;
353 font32A->lfClipPrecision = font->lfClipPrecision;
354 font32A->lfQuality = font->lfQuality;
355 font32A->lfPitchAndFamily = font->lfPitchAndFamily;
356 lstrcpyn32A( font32A->lfFaceName, font->lfFaceName, LF_FACESIZE );
360 /***********************************************************************
361 * FONT_LOGFONT16ToLOGFONT32W
363 static void FONT_LOGFONT16ToLOGFONT32W( LPLOGFONT16 font,
364 LPLOGFONT32W font32W )
366 font32W->lfHeight = (INT32)font->lfHeight;
367 font32W->lfWidth = (INT32)font->lfWidth;
368 font32W->lfEscapement = (INT32)font->lfEscapement;
369 font32W->lfOrientation = (INT32)font->lfOrientation;
370 font32W->lfWeight = (INT32)font->lfWeight;
371 font32W->lfItalic = font->lfItalic;
372 font32W->lfUnderline = font->lfUnderline;
373 font32W->lfStrikeOut = font->lfStrikeOut;
374 font32W->lfCharSet = font->lfCharSet;
375 font32W->lfOutPrecision = font->lfOutPrecision;
376 font32W->lfClipPrecision = font->lfClipPrecision;
377 font32W->lfQuality = font->lfQuality;
378 font32W->lfPitchAndFamily = font->lfPitchAndFamily;
379 lstrcpynAtoW( font32W->lfFaceName, font->lfFaceName, LF_FACESIZE );
383 /***********************************************************************
386 void FONT_GetMetrics( LOGFONT16 * logfont, XFontStruct * xfont,
387 TEXTMETRIC16 * metrics )
389 int average, i, count;
392 metrics->tmAscent = xfont->ascent;
393 metrics->tmDescent = xfont->descent;
394 metrics->tmHeight = xfont->ascent + xfont->descent;
396 metrics->tmInternalLeading = 0;
397 if (XGetFontProperty( xfont, XA_CAP_HEIGHT, &prop ))
398 metrics->tmInternalLeading = xfont->ascent+xfont->descent-(INT16)prop;
400 metrics->tmExternalLeading = 0;
401 metrics->tmMaxCharWidth = xfont->max_bounds.width;
402 metrics->tmWeight = logfont->lfWeight;
403 metrics->tmItalic = logfont->lfItalic;
404 metrics->tmUnderlined = logfont->lfUnderline;
405 metrics->tmStruckOut = logfont->lfStrikeOut;
406 metrics->tmFirstChar = xfont->min_char_or_byte2;
407 metrics->tmLastChar = xfont->max_char_or_byte2;
408 metrics->tmDefaultChar = xfont->default_char;
409 metrics->tmBreakChar = ' ';
410 metrics->tmCharSet = logfont->lfCharSet;
411 metrics->tmOverhang = 0;
412 metrics->tmDigitizedAspectX = 1;
413 metrics->tmDigitizedAspectY = 1;
414 metrics->tmPitchAndFamily = (logfont->lfPitchAndFamily&0xf0)|TMPF_DEVICE;
416 /* TMPF_FIXED_PITCH bit means variable pitch...Don't you love Microsoft? */
417 if (xfont->min_bounds.width != xfont->max_bounds.width)
418 metrics->tmPitchAndFamily |= TMPF_FIXED_PITCH;
420 if (!xfont->per_char) average = metrics->tmMaxCharWidth;
423 XCharStruct * charPtr = xfont->per_char;
425 for (i = metrics->tmFirstChar; i <= metrics->tmLastChar; i++)
427 if (!CI_NONEXISTCHAR( charPtr ))
429 average += charPtr->width;
434 if (count) average = (average + count/2) / count;
436 metrics->tmAveCharWidth = average;
439 /***********************************************************************
440 * GetGlyphOutLine (GDI.309)
442 DWORD GetGlyphOutLine( HDC16 hdc, UINT uChar, UINT fuFormat,
443 LPGLYPHMETRICS lpgm, DWORD cbBuffer, LPSTR lpBuffer,
446 fprintf( stdnimp,"GetGlyphOutLine(%04x, '%c', %04x, %p, %ld, %p, %p) // - empty stub!\n",
447 hdc, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 );
448 return (DWORD)-1; /* failure */
452 /***********************************************************************
453 * CreateScalableFontResource (GDI.310)
455 BOOL CreateScalableFontResource( UINT fHidden,LPSTR lpszResourceFile,
456 LPSTR lpszFontFile, LPSTR lpszCurrentPath )
458 /* fHidden=1 - only visible for the calling app, read-only, not
459 * enumbered with EnumFonts/EnumFontFamilies
460 * lpszCurrentPath can be NULL
462 fprintf(stdnimp,"CreateScalableFontResource(%d,%s,%s,%s) // empty stub!\n",
463 fHidden, lpszResourceFile, lpszFontFile, lpszCurrentPath );
464 return FALSE; /* create failed */
468 /***********************************************************************
469 * CreateFontIndirect16 (GDI.57)
471 HFONT16 CreateFontIndirect16( const LOGFONT16 *font )
478 fprintf(stderr,"CreateFontIndirect: font is NULL : returning NULL\n");
481 hfont = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC );
482 if (!hfont) return 0;
483 fontPtr = (FONTOBJ *) GDI_HEAP_LIN_ADDR( hfont );
484 memcpy( &fontPtr->logfont, font, sizeof(LOGFONT16) );
485 dprintf_font(stddeb,"CreateFontIndirect(%p (%d,%d)); return %04x\n",
486 font, font->lfHeight, font->lfWidth, hfont);
491 /***********************************************************************
492 * CreateFontIndirect32A (GDI32.44)
494 HFONT32 CreateFontIndirect32A( const LOGFONT32A *font )
498 FONT_LOGFONT32AToLOGFONT16(font,&font16);
500 return CreateFontIndirect16( &font16 );
504 /***********************************************************************
505 * CreateFontIndirect32W (GDI32.45)
507 HFONT32 CreateFontIndirect32W( const LOGFONT32W *font )
511 FONT_LOGFONT32WToLOGFONT16(font,&font16);
512 return CreateFontIndirect16( &font16 );
516 /***********************************************************************
517 * CreateFont16 (GDI.56)
519 HFONT16 CreateFont16( INT16 height, INT16 width, INT16 esc, INT16 orient,
520 INT16 weight, BYTE italic, BYTE underline,
521 BYTE strikeout, BYTE charset, BYTE outpres,
522 BYTE clippres, BYTE quality, BYTE pitch, LPCSTR name )
524 LOGFONT16 logfont = {height, width, esc, orient, weight, italic, underline,
525 strikeout, charset, outpres, clippres, quality, pitch, };
526 dprintf_font(stddeb,"CreateFont16(%d,%d)\n", height, width);
527 if (name) lstrcpyn32A(logfont.lfFaceName,name,sizeof(logfont.lfFaceName));
528 else logfont.lfFaceName[0] = '\0';
529 return CreateFontIndirect16( &logfont );
534 /*************************************************************************
535 * CreateFont32A (GDI32.43)
537 HFONT32 CreateFont32A( INT32 height, INT32 width, INT32 esc, INT32 orient,
538 INT32 weight, DWORD italic, DWORD underline,
539 DWORD strikeout, DWORD charset, DWORD outpres,
540 DWORD clippres, DWORD quality, DWORD pitch, LPCSTR name)
542 return (HFONT32)CreateFont16( height, width, esc, orient, weight, italic,
543 underline, strikeout, charset, outpres,
544 clippres, quality, pitch, name );
548 /*************************************************************************
549 * CreateFont32W (GDI32.46)
551 HFONT32 CreateFont32W( INT32 height, INT32 width, INT32 esc, INT32 orient,
552 INT32 weight, DWORD italic, DWORD underline,
553 DWORD strikeout, DWORD charset, DWORD outpres,
554 DWORD clippres, DWORD quality, DWORD pitch,
557 LPSTR namea = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
558 HFONT32 ret = (HFONT32)CreateFont16( height, width, esc, orient, weight,
559 italic, underline, strikeout, charset,
560 outpres, clippres, quality, pitch,
562 HeapFree( GetProcessHeap(), 0, namea );
567 /***********************************************************************
570 INT16 FONT_GetObject16( FONTOBJ * font, INT16 count, LPSTR buffer )
572 if (count > sizeof(LOGFONT16)) count = sizeof(LOGFONT16);
573 memcpy( buffer, &font->logfont, count );
578 /***********************************************************************
581 INT32 FONT_GetObject32A( FONTOBJ *font, INT32 count, LPSTR buffer )
585 memset(&fnt32, 0, sizeof(fnt32));
586 fnt32.lfHeight = font->logfont.lfHeight;
587 fnt32.lfWidth = font->logfont.lfWidth;
588 fnt32.lfEscapement = font->logfont.lfEscapement;
589 fnt32.lfOrientation = font->logfont.lfOrientation;
590 fnt32.lfWeight = font->logfont.lfWeight;
591 fnt32.lfItalic = font->logfont.lfItalic;
592 fnt32.lfUnderline = font->logfont.lfUnderline;
593 fnt32.lfStrikeOut = font->logfont.lfStrikeOut;
594 fnt32.lfCharSet = font->logfont.lfCharSet;
595 fnt32.lfOutPrecision = font->logfont.lfOutPrecision;
596 fnt32.lfClipPrecision = font->logfont.lfClipPrecision;
597 fnt32.lfQuality = font->logfont.lfQuality;
598 fnt32.lfPitchAndFamily = font->logfont.lfPitchAndFamily;
599 strncpy( fnt32.lfFaceName, font->logfont.lfFaceName,
600 sizeof(fnt32.lfFaceName) );
602 if (count > sizeof(fnt32)) count = sizeof(fnt32);
603 memcpy( buffer, &fnt32, count );
608 /***********************************************************************
611 HFONT16 FONT_SelectObject( DC * dc, HFONT16 hfont, FONTOBJ * font )
613 static X_PHYSFONT stockFonts[LAST_STOCK_FONT-FIRST_STOCK_FONT+1];
620 X_PHYSFONT cacheFont; } cacheFonts[FONTCACHE], *cacheFontsMin;
623 X_PHYSFONT * stockPtr;
624 HFONT16 prevHandle = dc->w.hFont;
625 XFontStruct * fontStruct;
626 dprintf_font(stddeb,"FONT_SelectObject(%p, %04x, %p)\n", dc, hfont, font);
628 #if 0 /* From the code in SelectObject, this can not happen */
629 /* Load font if necessary */
634 hnewfont = CreateFont16(10, 7, 0, 0, FW_DONTCARE,
635 FALSE, FALSE, FALSE, DEFAULT_CHARSET, 0, 0,
636 DEFAULT_QUALITY, FF_DONTCARE, "*" );
637 font = (FONTOBJ *) GDI_HEAP_LIN_ADDR( hnewfont );
641 if (dc->header.wMagic == METAFILE_DC_MAGIC)
642 if (MF_CreateFontIndirect(dc, hfont, &(font->logfont)))
647 if ((hfont >= FIRST_STOCK_FONT) && (hfont <= LAST_STOCK_FONT))
648 stockPtr = &stockFonts[hfont - FIRST_STOCK_FONT];
652 * Ok, It's not a stock font but
653 * may be it's cached in dynamic cache
655 for(i=0; i<FONTCACHE; i++) /* search for same handle */
656 if (cacheFonts[i].id==hfont) { /* Got the handle */
658 * Check if Handle matches the font
660 if(memcmp(&cacheFonts[i].logfont,&(font->logfont), sizeof(LOGFONT16))) {
661 /* No: remove handle id from dynamic font cache */
662 cacheFonts[i].access=0;
663 cacheFonts[i].used=0;
665 /* may be there is an unused handle which contains the font */
666 for(i=0; i<FONTCACHE; i++) {
667 if((cacheFonts[i].used == 0) &&
668 (memcmp(&cacheFonts[i].logfont,&(font->logfont), sizeof(LOGFONT16)))== 0) {
669 /* got it load from cache and set new handle id */
670 stockPtr = &cacheFonts[i].cacheFont;
671 cacheFonts[i].access=1;
672 cacheFonts[i].used=1;
673 cacheFonts[i].id=hfont;
674 dprintf_font(stddeb,"FONT_SelectObject: got font from unused handle\n");
681 /* Yes: load from dynamic font cache */
682 stockPtr = &cacheFonts[i].cacheFont;
683 cacheFonts[i].access++;
684 cacheFonts[i].used++;
689 if (!stockPtr || !stockPtr->fstruct)
691 if (!(fontStruct = FONT_MatchFont( &font->logfont, dc )))
693 /* If it is not a stock font, we can simply return 0 */
694 if (!stockPtr) return 0;
695 /* Otherwise we must try to find a substitute */
696 dprintf_font(stddeb,"Loading font 'fixed' for %04x\n", hfont );
697 font->logfont.lfPitchAndFamily &= ~VARIABLE_PITCH;
698 font->logfont.lfPitchAndFamily |= FIXED_PITCH;
699 fontStruct = XLoadQueryFont( display, "fixed" );
702 fprintf( stderr, "No system font could be found. Please check your font path.\n" );
709 fontStruct = stockPtr->fstruct;
711 "FONT_SelectObject: Loaded font from cache %04x %p\n",
715 /* Unuse previous font */
716 for (i=0; i < FONTCACHE; i++) {
717 if (cacheFonts[i].id == prevHandle) {
718 if(cacheFonts[i].used == 0)
719 fprintf(stderr, "Trying to decrement a use count of 0.\n");
721 cacheFonts[i].used--;
729 if (!stockPtr->fstruct)
731 stockPtr->fstruct = fontStruct;
732 FONT_GetMetrics( &font->logfont, fontStruct, &stockPtr->metrics );
734 memcpy( &dc->u.x.font, stockPtr, sizeof(*stockPtr) );
742 for (i=0; i < FONTCACHE; i++) {
743 if (cacheFonts[i].used==0)
744 if ((!cacheFontsMin) || ((cacheFontsMin) && (cacheFontsMin->access > cacheFonts[i].access)))
745 cacheFontsMin=&cacheFonts[i];
747 if (!cacheFontsMin) {
748 fprintf(stderr,"No unused font cache entry !!!!\n" );
751 if (cacheFontsMin->id!=0) {
753 "FONT_SelectObject: Freeing %04x \n",cacheFontsMin->id );
754 XFreeFont( display, cacheFontsMin->cacheFont.fstruct );
756 cacheFontsMin->cacheFont.fstruct = fontStruct;
757 FONT_GetMetrics( &font->logfont, fontStruct, &cacheFontsMin->cacheFont.metrics );
758 cacheFontsMin->access=1;
759 cacheFontsMin->used=1;
760 cacheFontsMin->id=hfont;
761 memcpy( &dc->u.x.font, &(cacheFontsMin->cacheFont), sizeof(cacheFontsMin->cacheFont) );
762 memcpy(&cacheFontsMin->logfont,&(font->logfont), sizeof(LOGFONT16));
769 /***********************************************************************
770 * GetTextCharacterExtra16 (GDI.89)
772 INT16 GetTextCharacterExtra16( HDC16 hdc )
774 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
776 return abs( (dc->w.charExtra * dc->wndExtX + dc->vportExtX / 2)
781 /***********************************************************************
782 * GetTextCharacterExtra32 (GDI32.225)
784 INT32 GetTextCharacterExtra32( HDC32 hdc )
786 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
788 return abs( (dc->w.charExtra * dc->wndExtX + dc->vportExtX / 2)
793 /***********************************************************************
794 * SetTextCharacterExtra16 (GDI.8)
796 INT16 SetTextCharacterExtra16( HDC16 hdc, INT16 extra )
798 return (INT16)SetTextCharacterExtra32( hdc, extra );
802 /***********************************************************************
803 * SetTextCharacterExtra32 (GDI32.337)
805 INT32 SetTextCharacterExtra32( HDC32 hdc, INT32 extra )
808 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
810 extra = (extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX;
811 prev = dc->w.charExtra;
812 dc->w.charExtra = abs(extra);
813 return (prev * dc->wndExtX + dc->vportExtX / 2) / dc->vportExtX;
817 /***********************************************************************
818 * SetTextJustification16 (GDI.10)
820 INT16 SetTextJustification16( HDC16 hdc, INT16 extra, INT16 breaks )
822 return SetTextJustification32( hdc, extra, breaks );
826 /***********************************************************************
827 * SetTextJustification32 (GDI32.339)
829 BOOL32 SetTextJustification32( HDC32 hdc, INT32 extra, INT32 breaks )
831 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
834 extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
835 if (!extra) breaks = 0;
836 dc->w.breakTotalExtra = extra;
837 dc->w.breakCount = breaks;
840 dc->w.breakExtra = extra / breaks;
841 dc->w.breakRem = extra - (dc->w.breakCount * dc->w.breakExtra);
845 dc->w.breakExtra = 0;
852 /***********************************************************************
853 * GetTextFace16 (GDI.92)
855 INT16 GetTextFace16( HDC16 hdc, INT16 count, LPSTR name )
857 return GetTextFace32A(hdc,count,name);
860 /***********************************************************************
861 * GetTextFace32A (GDI32.234)
863 INT32 GetTextFace32A( HDC32 hdc, INT32 count, LPSTR name )
867 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
869 if (!(font = (FONTOBJ *) GDI_GetObjPtr( dc->w.hFont, FONT_MAGIC )))
871 lstrcpyn32A( name, font->logfont.lfFaceName, count );
875 /***********************************************************************
876 * GetTextFace32W (GDI32.235)
878 INT32 GetTextFace32W( HDC32 hdc, INT32 count, LPWSTR name )
880 LPSTR nameA = HeapAlloc( GetProcessHeap(), 0, count );
881 INT32 res = GetTextFace32A(hdc,count,nameA);
882 lstrcpyAtoW( name, nameA );
883 HeapFree( GetProcessHeap(), 0, nameA );
888 /***********************************************************************
889 * GetTextExtent (GDI.91)
891 DWORD GetTextExtent( HDC16 hdc, LPCSTR str, INT16 count )
894 if (!GetTextExtentPoint16( hdc, str, count, &size )) return 0;
895 return MAKELONG( size.cx, size.cy );
899 /***********************************************************************
900 * GetTextExtentPoint16 (GDI.471)
902 * FIXME: Should this have a bug for compatibility?
903 * Original Windows versions of GetTextExtentPoint{A,W} have documented
906 BOOL16 GetTextExtentPoint16( HDC16 hdc, LPCSTR str, INT16 count, LPSIZE16 size)
909 BOOL32 ret = GetTextExtentPoint32A( hdc, str, count, &size32 );
910 CONV_SIZE32TO16( &size32, size );
915 /***********************************************************************
916 * GetTextExtentPoint32A (GDI32.230)
918 BOOL32 GetTextExtentPoint32A( HDC32 hdc, LPCSTR str, INT32 count,
921 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
924 if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
928 if (!dc->funcs->pGetTextExtentPoint ||
929 !dc->funcs->pGetTextExtentPoint( dc, str, count, size ))
932 dprintf_font(stddeb,"GetTextExtentPoint(%08x '%.*s' %d %p): returning %d,%d\n",
933 hdc, count, str, count, size, size->cx, size->cy );
938 /***********************************************************************
939 * GetTextExtentPoint32W (GDI32.231)
941 BOOL32 GetTextExtentPoint32W( HDC32 hdc, LPCWSTR str, INT32 count,
944 LPSTR p = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
945 BOOL32 ret = GetTextExtentPoint32A( hdc, p, count, size );
946 HeapFree( GetProcessHeap(), 0, p );
950 /***********************************************************************
951 * GetTextExtentPoint32ABuggy (GDI32.232)
953 BOOL32 GetTextExtentPoint32ABuggy( HDC32 hdc, LPCSTR str, INT32 count,
956 dprintf_font( stddeb, "GetTextExtentPoint32ABuggy: not bug compatible.\n");
957 return GetTextExtentPoint32A( hdc, str, count, size );
960 /***********************************************************************
961 * GetTextExtentPoint32WBuggy (GDI32.233)
963 BOOL32 GetTextExtentPoint32WBuggy( HDC32 hdc, LPCWSTR str, INT32 count,
966 dprintf_font( stddeb, "GetTextExtentPoint32WBuggy: not bug compatible.\n");
967 return GetTextExtentPoint32W( hdc, str, count, size );
971 /***********************************************************************
972 * GetTextExtentExPoint32A (GDI32.228)
974 BOOL32 GetTextExtentExPoint32A( HDC32 hdc, LPCSTR str, INT32 count,
975 INT32 maxExt,LPINT32 lpnFit, LPINT32 alpDx,
982 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
985 if (!(dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC )))
988 if (!dc->funcs->pGetTextExtentPoint) return FALSE;
990 size->cx=0; size->cy=0;
991 for(index=0;index<count;index++)
993 if(!dc->funcs->pGetTextExtentPoint( dc, str, 1, &tSize )) return FALSE;
994 if(extent+tSize.cx<maxExt)
999 if(alpDx) alpDx[index]=extent;
1000 if(tSize.cy > size->cy) size->cy=tSize.cy;
1006 dprintf_font(stddeb,"GetTextExtentExPoint32A(%08x '%.*s' %d) returning %d %d %d\n",
1007 hdc,count,str,maxExt,nFit, size->cx,size->cy);
1011 /***********************************************************************
1012 * GetTextExtentExPoint32W (GDI32.229)
1015 BOOL32 GetTextExtentExPoint32W( HDC32 hdc, LPCWSTR str, INT32 count,
1016 INT32 maxExt, LPINT32 lpnFit, LPINT32 alpDx,
1019 LPSTR p = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
1020 BOOL32 ret = GetTextExtentExPoint32A( hdc, p, count, maxExt,
1021 lpnFit, alpDx, size);
1022 HeapFree( GetProcessHeap(), 0, p );
1026 /***********************************************************************
1027 * GetTextMetrics16 (GDI.93)
1029 BOOL16 GetTextMetrics16( HDC16 hdc, TEXTMETRIC16 *metrics )
1031 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
1032 if (!dc) return FALSE;
1033 memcpy( metrics, &dc->u.x.font.metrics, sizeof(*metrics) );
1035 metrics->tmAscent = abs( metrics->tmAscent
1036 * dc->wndExtY / dc->vportExtY );
1037 metrics->tmDescent = abs( metrics->tmDescent
1038 * dc->wndExtY / dc->vportExtY );
1039 metrics->tmHeight = metrics->tmAscent + metrics->tmDescent;
1040 metrics->tmInternalLeading = abs( metrics->tmInternalLeading
1041 * dc->wndExtY / dc->vportExtY );
1042 metrics->tmExternalLeading = abs( metrics->tmExternalLeading
1043 * dc->wndExtY / dc->vportExtY );
1044 metrics->tmMaxCharWidth = abs( metrics->tmMaxCharWidth
1045 * dc->wndExtX / dc->vportExtX );
1046 metrics->tmAveCharWidth = abs( metrics->tmAveCharWidth
1047 * dc->wndExtX / dc->vportExtX );
1049 dprintf_font(stdnimp,"text metrics:\n
1050 InternalLeading = %i
1051 ExternalLeading = %i
1063 DigitizedAspectX = %i
1064 DigitizedAspectY = %i
1070 metrics->tmInternalLeading,
1071 metrics->tmExternalLeading,
1072 metrics->tmMaxCharWidth,
1075 metrics->tmUnderlined,
1076 metrics->tmStruckOut,
1077 metrics->tmFirstChar,
1078 metrics->tmLastChar,
1079 metrics->tmDefaultChar,
1080 metrics->tmBreakChar,
1082 metrics->tmOverhang,
1083 metrics->tmDigitizedAspectX,
1084 metrics->tmDigitizedAspectY,
1085 metrics->tmAveCharWidth,
1086 metrics->tmMaxCharWidth,
1095 /***********************************************************************
1096 * GetTextMetrics32A (GDI32.236)
1098 BOOL32 GetTextMetrics32A( HDC32 hdc, TEXTMETRIC32A *metrics )
1101 if (!GetTextMetrics16( (HDC16)hdc, &tm )) return FALSE;
1102 metrics->tmHeight = tm.tmHeight;
1103 metrics->tmAscent = tm.tmAscent;
1104 metrics->tmDescent = tm.tmDescent;
1105 metrics->tmInternalLeading = tm.tmInternalLeading;
1106 metrics->tmExternalLeading = tm.tmExternalLeading;
1107 metrics->tmAveCharWidth = tm.tmAveCharWidth;
1108 metrics->tmMaxCharWidth = tm.tmMaxCharWidth;
1109 metrics->tmWeight = tm.tmWeight;
1110 metrics->tmOverhang = tm.tmOverhang;
1111 metrics->tmDigitizedAspectX = tm.tmDigitizedAspectX;
1112 metrics->tmDigitizedAspectY = tm.tmDigitizedAspectY;
1113 metrics->tmFirstChar = tm.tmFirstChar;
1114 metrics->tmLastChar = tm.tmLastChar;
1115 metrics->tmDefaultChar = tm.tmDefaultChar;
1116 metrics->tmBreakChar = tm.tmBreakChar;
1117 metrics->tmItalic = tm.tmItalic;
1118 metrics->tmUnderlined = tm.tmUnderlined;
1119 metrics->tmStruckOut = tm.tmStruckOut;
1120 metrics->tmPitchAndFamily = tm.tmPitchAndFamily;
1121 metrics->tmCharSet = tm.tmCharSet;
1126 /***********************************************************************
1127 * GetTextMetrics32W (GDI32.237)
1129 BOOL32 GetTextMetrics32W( HDC32 hdc, TEXTMETRIC32W *metrics )
1132 if (!GetTextMetrics16( (HDC16)hdc, &tm )) return FALSE;
1133 metrics->tmHeight = tm.tmHeight;
1134 metrics->tmAscent = tm.tmAscent;
1135 metrics->tmDescent = tm.tmDescent;
1136 metrics->tmInternalLeading = tm.tmInternalLeading;
1137 metrics->tmExternalLeading = tm.tmExternalLeading;
1138 metrics->tmAveCharWidth = tm.tmAveCharWidth;
1139 metrics->tmMaxCharWidth = tm.tmMaxCharWidth;
1140 metrics->tmWeight = tm.tmWeight;
1141 metrics->tmOverhang = tm.tmOverhang;
1142 metrics->tmDigitizedAspectX = tm.tmDigitizedAspectX;
1143 metrics->tmDigitizedAspectY = tm.tmDigitizedAspectY;
1144 metrics->tmFirstChar = tm.tmFirstChar;
1145 metrics->tmLastChar = tm.tmLastChar;
1146 metrics->tmDefaultChar = tm.tmDefaultChar;
1147 metrics->tmBreakChar = tm.tmBreakChar;
1148 metrics->tmItalic = tm.tmItalic;
1149 metrics->tmUnderlined = tm.tmUnderlined;
1150 metrics->tmStruckOut = tm.tmStruckOut;
1151 metrics->tmPitchAndFamily = tm.tmPitchAndFamily;
1152 metrics->tmCharSet = tm.tmCharSet;
1157 /***********************************************************************
1158 * SetMapperFlags (GDI.349)
1160 DWORD SetMapperFlags(HDC16 hDC, DWORD dwFlag)
1162 dprintf_font(stdnimp,"SetmapperFlags(%04x, %08lX) // Empty Stub !\n",
1168 /***********************************************************************
1169 * GetCharABCWidths16 (GDI.307)
1171 BOOL16 GetCharABCWidths16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1175 if (!GetCharABCWidths32A( hdc, firstChar, lastChar, &abc32 )) return FALSE;
1176 abc->abcA = abc32.abcA;
1177 abc->abcB = abc32.abcB;
1178 abc->abcC = abc32.abcC;
1183 /***********************************************************************
1184 * GetCharABCWidths32A (GDI32.149)
1186 BOOL32 GetCharABCWidths32A( HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
1189 /* No TrueType fonts in Wine so far */
1190 fprintf( stdnimp, "STUB: GetCharABCWidths(%04x,%04x,%04x,%p)\n",
1191 hdc, firstChar, lastChar, abc );
1196 /***********************************************************************
1197 * GetCharABCWidths32W (GDI32.152)
1199 BOOL32 GetCharABCWidths32W( HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
1202 return GetCharABCWidths32A( hdc, firstChar, lastChar, abc );
1206 /***********************************************************************
1207 * GetCharWidth16 (GDI.350)
1209 BOOL16 GetCharWidth16( HDC16 hdc, UINT16 firstChar, UINT16 lastChar,
1214 XCharStruct *cs, *def;
1216 DC *dc = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC);
1217 if (!dc) return FALSE;
1218 xfont = dc->u.x.font.fstruct;
1221 if (xfont->per_char == NULL)
1223 for (i = firstChar; i <= lastChar; i++)
1224 *buffer++ = xfont->max_bounds.width;
1228 CI_GET_DEFAULT_INFO(xfont, def);
1230 for (i = firstChar; i <= lastChar; i++)
1232 CI_GET_CHAR_INFO( xfont, i, def, cs );
1233 width = cs ? cs->width : xfont->max_bounds.width;
1234 *buffer++ = MAX( width, 0 );
1240 /***********************************************************************
1241 * GetCharWidth32A (GDI32.155)
1243 BOOL32 GetCharWidth32A( HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
1248 XCharStruct *cs, *def;
1250 DC *dc = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC);
1251 if (!dc) return FALSE;
1252 xfont = dc->u.x.font.fstruct;
1255 if (xfont->per_char == NULL)
1257 for (i = firstChar; i <= lastChar; i++)
1258 *buffer++ = xfont->max_bounds.width;
1262 CI_GET_DEFAULT_INFO(xfont, def);
1264 for (i = firstChar; i <= lastChar; i++)
1266 CI_GET_CHAR_INFO( xfont, i, def, cs );
1267 width = cs ? cs->width : xfont->max_bounds.width;
1268 *buffer++ = MAX( width, 0 );
1274 /***********************************************************************
1275 * GetCharWidth32W (GDI32.158)
1277 BOOL32 GetCharWidth32W( HDC32 hdc, UINT32 firstChar, UINT32 lastChar,
1280 return GetCharWidth32A( hdc, firstChar, lastChar, buffer );
1284 /***********************************************************************
1285 * AddFontResource (GDI.119)
1287 INT AddFontResource( LPCSTR str )
1289 fprintf( stdnimp, "STUB: AddFontResource('%s')\n", str );
1294 /***********************************************************************
1295 * RemoveFontResource (GDI.136)
1297 BOOL RemoveFontResource( LPSTR str )
1299 fprintf( stdnimp, "STUB: RemoveFontResource('%s')\n", str );
1304 /*************************************************************************
1305 * ParseFontParms [internal]
1307 int ParseFontParms(LPSTR lpFont, WORD wParmsNo, LPSTR lpRetStr, WORD wMaxSiz)
1310 if (lpFont == NULL) return 0;
1311 if (lpRetStr == NULL) return 0;
1312 for (i = 0; (*lpFont != '\0' && i != wParmsNo); ) {
1313 if (*lpFont == '-') i++;
1316 if (i == wParmsNo) {
1317 if (*lpFont == '-') lpFont++;
1319 for (i = 0; (*lpFont != '\0' && *lpFont != '-' && i < wMaxSiz); i++)
1320 *(lpRetStr + i) = *lpFont++;
1321 *(lpRetStr + i) = '\0';
1330 /*************************************************************************
1331 * InitFontsList [internal]
1334 static int logfcmp(const void *a,const void *b)
1336 return lstrcmpi32A( (*(LPLOGFONT16 *)a)->lfFaceName,
1337 (*(LPLOGFONT16 *)b)->lfFaceName );
1340 void InitFontsList(void)
1344 char *family, *weight, *charset;
1346 char slant, spacing;
1348 LPLOGFONT16 lpNewFont;
1350 dprintf_font(stddeb,"InitFontsList !\n");
1358 sprintf( pattern, "-%s-%s-%c-normal-*-*-*-*-*-%c-*-%s",
1359 family, weight, slant, spacing, charset);
1360 names = XListFonts( display, pattern, MAX_FONTS, &count );
1361 dprintf_font(stddeb,"InitFontsList // count=%d \n", count);
1363 lpNewFont = malloc((sizeof(LOGFONT16)+LF_FACESIZE)*count);
1364 if (lpNewFont == NULL) {
1365 dprintf_font(stddeb,
1366 "InitFontsList // Error alloc new font structure !\n");
1367 XFreeFontNames(names);
1371 for (i = 0; i < count; i++) {
1372 dprintf_font(stddeb,"InitFontsList // names[%d]='%s' \n", i, names[i]);
1374 ParseFontParms(names[i], 2, str, sizeof(str));
1375 /* AnsiUpper(str);*/
1376 strcpy(lpNewFont->lfFaceName, str);
1377 ParseFontParms(names[i], 8, str, sizeof(str));
1378 lpNewFont->lfHeight = atoi(str) / 10;
1379 ParseFontParms(names[i], 12, str, sizeof(str));
1380 lpNewFont->lfWidth = atoi(str) / 10;
1381 lpNewFont->lfEscapement = 0;
1382 lpNewFont->lfOrientation = 0;
1383 lpNewFont->lfWeight = FW_REGULAR;
1384 lpNewFont->lfItalic = 0;
1385 lpNewFont->lfUnderline = 0;
1386 lpNewFont->lfStrikeOut = 0;
1387 ParseFontParms(names[i], 13, str, sizeof(str));
1388 if (strcmp(str, "iso8859") == 0) {
1389 lpNewFont->lfCharSet = ANSI_CHARSET;
1391 lpNewFont->lfCharSet = OEM_CHARSET;
1393 lpNewFont->lfOutPrecision = OUT_DEFAULT_PRECIS;
1394 lpNewFont->lfClipPrecision = CLIP_DEFAULT_PRECIS;
1395 lpNewFont->lfQuality = DEFAULT_QUALITY;
1396 ParseFontParms(names[i], 11, str, sizeof(str));
1399 lpNewFont->lfPitchAndFamily = VARIABLE_PITCH | FF_SWISS;
1403 lpNewFont->lfPitchAndFamily = FIXED_PITCH | FF_MODERN;
1406 lpNewFont->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
1409 dprintf_font( stddeb,
1410 "InitFontsList // lpNewFont->lfHeight=%d\n",
1411 lpNewFont->lfHeight );
1412 dprintf_font( stddeb,
1413 "InitFontsList // lpNewFont->lfWidth=%d\n",
1414 lpNewFont->lfWidth );
1415 dprintf_font( stddeb,
1416 "InitFontsList // lfFaceName='%s'\n",
1417 lpNewFont->lfFaceName );
1418 lpLogFontList[i] = lpNewFont;
1419 lpNewFont = (LPLOGFONT16)
1420 ((char *)lpNewFont + sizeof(LOGFONT16)+LF_FACESIZE);
1422 lpLogFontList[i] = NULL;
1424 qsort(lpLogFontList,count,sizeof(*lpLogFontList),logfcmp);
1425 XFreeFontNames(names);
1428 /*************************************************************************
1429 * EnumFonts [GDI.70]
1430 * We reuse EnumFontFamilies* for the callback function get the same
1431 * structs (+ extra stuff at the end which will be ignored by the enum funcs)
1433 INT16 EnumFonts16(HDC16 hDC, LPCSTR lpFaceName, FONTENUMPROC16 lpEnumFunc, LPARAM lpData)
1435 return EnumFontFamilies16(hDC,lpFaceName,lpEnumFunc,lpData);
1438 /*************************************************************************
1439 * EnumFontsA [GDI32.84]
1441 INT32 EnumFonts32A(HDC32 hDC, LPCSTR lpFaceName, FONTENUMPROC32A lpEnumFunc, LPARAM lpData)
1443 return EnumFontFamilies32A(hDC,lpFaceName,lpEnumFunc,lpData);
1446 /*************************************************************************
1447 * EnumFontsA [GDI32.84]
1449 INT32 EnumFonts32W(HDC32 hDC, LPCWSTR lpFaceName, FONTENUMPROC32W lpEnumFunc, LPARAM lpData)
1451 return EnumFontFamilies32W(hDC,lpFaceName,lpEnumFunc,lpData);
1454 /*************************************************************************
1455 * EnumFontFamilies [GDI.330]
1457 INT16 EnumFontFamilies16(HDC16 hDC, LPCSTR lpszFamily, FONTENUMPROC16 lpEnumFunc, LPARAM lpData)
1462 strcpy(LF.lfFaceName,lpszFamily);
1464 LF.lfFaceName[0]='\0';
1465 LF.lfCharSet = DEFAULT_CHARSET;
1467 return EnumFontFamiliesEx16(hDC,&LF,(FONTENUMPROCEX16)lpEnumFunc,lpData,0);
1470 /*************************************************************************
1471 * EnumFontFamiliesA [GDI32.80]
1473 INT32 EnumFontFamilies32A(HDC32 hDC, LPCSTR lpszFamily, FONTENUMPROC32A lpEnumFunc, LPARAM lpData)
1478 strcpy(LF.lfFaceName,lpszFamily);
1480 LF.lfFaceName[0]='\0';
1481 LF.lfCharSet = DEFAULT_CHARSET;
1483 return EnumFontFamiliesEx32A(hDC,&LF,(FONTENUMPROCEX32A)lpEnumFunc,lpData,0);
1486 /*************************************************************************
1487 * EnumFontFamiliesW [GDI32.83]
1489 INT32 EnumFontFamilies32W(HDC32 hDC, LPCWSTR lpszFamilyW, FONTENUMPROC32W lpEnumFunc, LPARAM lpData)
1494 lstrcpy32W(LF.lfFaceName,lpszFamilyW);
1497 LF.lfCharSet = DEFAULT_CHARSET;
1498 return EnumFontFamiliesEx32W(hDC,&LF,(FONTENUMPROCEX32W)lpEnumFunc,lpData,0);
1501 /*************************************************************************
1502 * EnumFontFamiliesEx [GDI.618]
1503 * FIXME: fill the rest of the NEWTEXTMETRICEX and ENUMLOGFONTEX structures.
1504 * (applies to all EnumFontFamiliesEx*)
1505 * winelib/16 support.
1507 INT16 EnumFontFamiliesEx16(HDC16 hDC, LPLOGFONT16 lpLF, FONTENUMPROCEX16 lpEnumFunc, LPARAM lpData,DWORD reserved)
1513 LPENUMLOGFONTEX16 lpEnumLogFont;
1514 LPNEWTEXTMETRICEX16 lptm;
1516 char FaceName[LF_FACESIZE];
1520 dprintf_font(stddeb,"EnumFontFamiliesEx(%04x, '%s', %08lx, %08lx, %08lx)\n",
1521 hDC, lpLF->lfFaceName, (DWORD)lpEnumFunc, lpData, reserved);
1522 if (lpEnumFunc == 0) return 0;
1523 hLog = GDI_HEAP_ALLOC( sizeof(ENUMLOGFONTEX16) );
1524 lpEnumLogFont = (LPENUMLOGFONTEX16) GDI_HEAP_LIN_ADDR(hLog);
1525 if (lpEnumLogFont == NULL) {
1526 fprintf(stderr,"EnumFontFamiliesEx // can't alloc LOGFONT struct !\n");
1529 hMet = GDI_HEAP_ALLOC( sizeof(NEWTEXTMETRICEX16) );
1530 lptm = (LPNEWTEXTMETRICEX16) GDI_HEAP_LIN_ADDR(hMet);
1532 GDI_HEAP_FREE(hLog);
1533 fprintf(stderr,"EnumFontFamiliesEx // can't alloc TEXTMETRIC struct !\n");
1537 strcpy(FaceName,lpLF->lfFaceName);
1538 /* AnsiUpper(lpLF->lfFaceName);*/
1540 if (lpLogFontList[0] == NULL) InitFontsList();
1541 for(i = 0; lpLogFontList[i] != NULL; i++) {
1543 if (lpLF->lfCharSet!=DEFAULT_CHARSET)
1544 if (lpLogFontList[i]->lfCharSet != lpLF->lfCharSet)
1547 /* lfPitchAndFamily only of importance in Hebrew and Arabic versions. */
1551 if (lstrcmpi32A(FaceName,lpLogFontList[i]->lfFaceName))
1556 if ((lpOldName!=NULL) &&
1557 !lstrcmpi32A(lpOldName,lpLogFontList[i]->lfFaceName))
1559 lpOldName=lpLogFontList[i]->lfFaceName;
1562 memcpy(lpEnumLogFont, lpLogFontList[i], sizeof(LOGFONT16));
1563 strcpy(lpEnumLogFont->elfFullName,"");
1564 strcpy(lpEnumLogFont->elfStyle,"");
1565 hFont = CreateFontIndirect16((LPLOGFONT16)lpEnumLogFont);
1566 hOldFont = SelectObject32(hDC, hFont);
1567 GetTextMetrics16(hDC, (LPTEXTMETRIC16)lptm);
1568 SelectObject32(hDC, hOldFont);
1569 DeleteObject32(hFont);
1570 dprintf_font(stddeb, "EnumFontFamiliesEx // i=%d lpLogFont=%p lptm=%p\n", i, lpEnumLogFont, lptm);
1572 nRet = lpEnumFunc( GDI_HEAP_SEG_ADDR(hLog), GDI_HEAP_SEG_ADDR(hMet),
1575 dprintf_font(stddeb,"EnumFontFamilies // EnumEnd requested by application !\n");
1579 GDI_HEAP_FREE(hMet);
1580 GDI_HEAP_FREE(hLog);
1584 /*************************************************************************
1585 * EnumFontFamiliesExA [GDI32.81]
1586 * FIXME: Don't use 16 bit GDI heap functions (applies to EnumFontFamiliesEx32*)
1588 INT32 EnumFontFamiliesEx32A(HDC32 hDC, LPLOGFONT32A lpLF,FONTENUMPROCEX32A lpEnumFunc, LPARAM lpData,DWORD reserved)
1594 LPENUMLOGFONTEX32A lpEnumLogFont;
1595 LPNEWTEXTMETRICEX32A lptm;
1597 char FaceName[LF_FACESIZE];
1601 dprintf_font(stddeb,"EnumFontFamilies32A(%04x, %p, %08lx, %08lx, %08lx)\n",
1602 hDC, lpLF->lfFaceName, (DWORD)lpEnumFunc, lpData,reserved);
1603 if (lpEnumFunc == 0) return 0;
1604 hLog = GDI_HEAP_ALLOC( sizeof(ENUMLOGFONTEX32A) );
1605 lpEnumLogFont = (LPENUMLOGFONTEX32A) GDI_HEAP_LIN_ADDR(hLog);
1606 if (lpEnumLogFont == NULL) {
1607 fprintf(stderr,"EnumFontFamilies // can't alloc LOGFONT struct !\n");
1610 hMet = GDI_HEAP_ALLOC( sizeof(NEWTEXTMETRICEX32A) );
1611 lptm = (LPNEWTEXTMETRICEX32A) GDI_HEAP_LIN_ADDR(hMet);
1613 GDI_HEAP_FREE(hLog);
1614 fprintf(stderr,"EnumFontFamilies32A // can't alloc TEXTMETRIC struct !\n");
1618 strcpy(FaceName,lpLF->lfFaceName);
1619 /* AnsiUpper(lpLF->lfFaceName);*/
1621 if (lpLogFontList[0] == NULL) InitFontsList();
1622 for(i = 0; lpLogFontList[i] != NULL; i++) {
1624 if (lpLF->lfCharSet!=DEFAULT_CHARSET)
1625 if (lpLogFontList[i]->lfCharSet != lpLF->lfCharSet)
1628 /* lfPitchAndFamily only of importance in Hebrew and Arabic versions. */
1631 if (lstrcmpi32A(FaceName,lpLogFontList[i]->lfFaceName))
1634 if ((lpOldName!=NULL) &&
1635 !lstrcmpi32A(lpOldName,lpLogFontList[i]->lfFaceName))
1637 lpOldName=lpLogFontList[i]->lfFaceName;
1640 FONT_LOGFONT16ToLOGFONT32A(lpLogFontList[i],&(lpEnumLogFont->elfLogFont));
1641 strcpy(lpEnumLogFont->elfFullName,"");
1642 strcpy(lpEnumLogFont->elfStyle,"");
1643 strcpy(lpEnumLogFont->elfScript,"");
1644 hFont = CreateFontIndirect32A((LPLOGFONT32A)lpEnumLogFont);
1645 hOldFont = SelectObject32(hDC, hFont);
1646 GetTextMetrics32A(hDC, (LPTEXTMETRIC32A)lptm);
1647 SelectObject32(hDC, hOldFont);
1648 DeleteObject32(hFont);
1649 dprintf_font(stddeb, "EnumFontFamiliesEx32A // i=%d lpLogFont=%p lptm=%p\n", i, lpEnumLogFont, lptm);
1651 nRet = lpEnumFunc(lpEnumLogFont,lptm,0,lpData);
1653 dprintf_font(stddeb,"EnumFontFamiliesEx32A // EnumEnd requested by application !\n");
1657 GDI_HEAP_FREE(hMet);
1658 GDI_HEAP_FREE(hLog);
1663 /*************************************************************************
1664 * EnumFontFamiliesW [GDI32.82]
1666 INT32 EnumFontFamiliesEx32W(HDC32 hDC, LPLOGFONT32W lpLF, FONTENUMPROCEX32W lpEnumFunc, LPARAM lpData, DWORD reserved)
1672 LPENUMLOGFONTEX32W lpEnumLogFont;
1673 LPNEWTEXTMETRICEX32W lptm;
1679 dprintf_font(stddeb,"EnumFontFamiliesEx32W(%04x, %p, %08lx, %08lx, %08lx)\n",
1680 hDC, lpLF, (DWORD)lpEnumFunc, lpData,reserved);
1681 if (lpEnumFunc == 0) return 0;
1682 hLog = GDI_HEAP_ALLOC( sizeof(ENUMLOGFONTEX32W) );
1683 lpEnumLogFont = (LPENUMLOGFONTEX32W) GDI_HEAP_LIN_ADDR(hLog);
1684 if (lpEnumLogFont == NULL) {
1685 fprintf(stderr,"EnumFontFamilies32W // can't alloc LOGFONT struct !\n");
1688 hMet = GDI_HEAP_ALLOC( sizeof(NEWTEXTMETRICEX32W) );
1689 lptm = (LPNEWTEXTMETRICEX32W) GDI_HEAP_LIN_ADDR(hMet);
1691 GDI_HEAP_FREE(hLog);
1692 fprintf(stderr,"EnumFontFamilies32W // can't alloc TEXTMETRIC struct !\n");
1696 lpszFamily = HEAP_strdupWtoA( GetProcessHeap(), 0, lpLF->lfFaceName );
1697 AnsiUpper(lpszFamily);
1698 if (lpLogFontList[0] == NULL) InitFontsList();
1699 for(i = 0; lpLogFontList[i] != NULL; i++) {
1701 if (lpLF->lfCharSet!=DEFAULT_CHARSET)
1702 if (lpLogFontList[i]->lfCharSet != lpLF->lfCharSet)
1705 /* lfPitchAndFamily only of importance in Hebrew and Arabic versions. */
1707 if (lpszFamily[0]) {
1708 if (lstrcmpi32A(lpszFamily,lpLogFontList[i]->lfFaceName))
1711 if ((lpOldName!=NULL) &&
1712 !lstrcmpi32A(lpOldName,lpLogFontList[i]->lfFaceName))
1714 lpOldName=lpLogFontList[i]->lfFaceName;
1717 FONT_LOGFONT16ToLOGFONT32W(lpLogFontList[i],&(lpEnumLogFont->elfLogFont));
1718 lpEnumLogFont->elfFullName[0] = 0;
1719 lpEnumLogFont->elfStyle[0] = 0;
1720 lpEnumLogFont->elfScript[0] = 0;
1721 hFont = CreateFontIndirect32W((LPLOGFONT32W)lpEnumLogFont);
1722 hOldFont = SelectObject32(hDC, hFont);
1723 GetTextMetrics32W(hDC, (LPTEXTMETRIC32W)lptm);
1724 SelectObject32(hDC, hOldFont);
1725 DeleteObject32(hFont);
1726 dprintf_font(stddeb, "EnumFontFamilies32W // i=%d lpLogFont=%p lptm=%p\n", i, lpEnumLogFont, lptm);
1728 nRet = lpEnumFunc(lpEnumLogFont,lptm,0,lpData);
1730 dprintf_font(stddeb,"EnumFontFamilies32W // EnumEnd requested by application !\n");
1734 GDI_HEAP_FREE(hMet);
1735 GDI_HEAP_FREE(hLog);
1736 HeapFree( GetProcessHeap(), 0, lpszFamily );
1741 /*************************************************************************
1742 * GetRasterizerCaps [GDI.313]
1745 BOOL GetRasterizerCaps(LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
1747 /* This is not much more than a dummy */
1748 RASTERIZER_STATUS rs;
1750 rs.nSize = sizeof(rs);
1756 /*************************************************************************
1757 * GetKerningPairs [GDI.332]
1759 int GetKerningPairs(HDC16 hDC,int cPairs,LPKERNINGPAIR16 lpKerningPairs)
1761 /* This has to be dealt with when proper font handling is in place
1763 * At this time kerning is ignored (set to 0)
1767 fprintf(stdnimp,"GetKerningPairs: almost empty stub!\n");
1768 for (i = 0; i < cPairs; i++) lpKerningPairs[i].iKernAmount = 0;