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 AnsiLower( fontPtr
->logfont
.lfFaceName
);
486 dprintf_font(stddeb
,"CreateFontIndirect(%p (%d,%d)); return %04x\n",
487 font
, font
->lfHeight
, font
->lfWidth
, hfont
);
492 /***********************************************************************
493 * CreateFontIndirect32A (GDI32.44)
495 HFONT32
CreateFontIndirect32A( const LOGFONT32A
*font
)
499 FONT_LOGFONT32AToLOGFONT16(font
,&font16
);
501 return CreateFontIndirect16( &font16
);
505 /***********************************************************************
506 * CreateFontIndirect32W (GDI32.45)
508 HFONT32
CreateFontIndirect32W( const LOGFONT32W
*font
)
512 FONT_LOGFONT32WToLOGFONT16(font
,&font16
);
513 return CreateFontIndirect16( &font16
);
517 /***********************************************************************
518 * CreateFont16 (GDI.56)
520 HFONT16
CreateFont16( INT16 height
, INT16 width
, INT16 esc
, INT16 orient
,
521 INT16 weight
, BYTE italic
, BYTE underline
,
522 BYTE strikeout
, BYTE charset
, BYTE outpres
,
523 BYTE clippres
, BYTE quality
, BYTE pitch
, LPCSTR name
)
525 LOGFONT16 logfont
= {height
, width
, esc
, orient
, weight
, italic
, underline
,
526 strikeout
, charset
, outpres
, clippres
, quality
, pitch
, };
527 dprintf_font(stddeb
,"CreateFont16(%d,%d)\n", height
, width
);
528 if (name
) lstrcpyn32A(logfont
.lfFaceName
,name
,sizeof(logfont
.lfFaceName
));
529 else logfont
.lfFaceName
[0] = '\0';
530 return CreateFontIndirect16( &logfont
);
535 /*************************************************************************
536 * CreateFont32A (GDI32.43)
538 HFONT32
CreateFont32A( INT32 height
, INT32 width
, INT32 esc
, INT32 orient
,
539 INT32 weight
, DWORD italic
, DWORD underline
,
540 DWORD strikeout
, DWORD charset
, DWORD outpres
,
541 DWORD clippres
, DWORD quality
, DWORD pitch
, LPCSTR name
)
543 return (HFONT32
)CreateFont16( height
, width
, esc
, orient
, weight
, italic
,
544 underline
, strikeout
, charset
, outpres
,
545 clippres
, quality
, pitch
, name
);
549 /*************************************************************************
550 * CreateFont32W (GDI32.46)
552 HFONT32
CreateFont32W( INT32 height
, INT32 width
, INT32 esc
, INT32 orient
,
553 INT32 weight
, DWORD italic
, DWORD underline
,
554 DWORD strikeout
, DWORD charset
, DWORD outpres
,
555 DWORD clippres
, DWORD quality
, DWORD pitch
,
558 LPSTR namea
= HEAP_strdupWtoA( GetProcessHeap(), 0, name
);
559 HFONT32 ret
= (HFONT32
)CreateFont16( height
, width
, esc
, orient
, weight
,
560 italic
, underline
, strikeout
, charset
,
561 outpres
, clippres
, quality
, pitch
,
563 HeapFree( GetProcessHeap(), 0, namea
);
568 /***********************************************************************
571 INT16
FONT_GetObject16( FONTOBJ
* font
, INT16 count
, LPSTR buffer
)
573 if (count
> sizeof(LOGFONT16
)) count
= sizeof(LOGFONT16
);
574 memcpy( buffer
, &font
->logfont
, count
);
579 /***********************************************************************
582 INT32
FONT_GetObject32A( FONTOBJ
*font
, INT32 count
, LPSTR buffer
)
586 memset(&fnt32
, 0, sizeof(fnt32
));
587 fnt32
.lfHeight
= font
->logfont
.lfHeight
;
588 fnt32
.lfWidth
= font
->logfont
.lfWidth
;
589 fnt32
.lfEscapement
= font
->logfont
.lfEscapement
;
590 fnt32
.lfOrientation
= font
->logfont
.lfOrientation
;
591 fnt32
.lfWeight
= font
->logfont
.lfWeight
;
592 fnt32
.lfItalic
= font
->logfont
.lfItalic
;
593 fnt32
.lfUnderline
= font
->logfont
.lfUnderline
;
594 fnt32
.lfStrikeOut
= font
->logfont
.lfStrikeOut
;
595 fnt32
.lfCharSet
= font
->logfont
.lfCharSet
;
596 fnt32
.lfOutPrecision
= font
->logfont
.lfOutPrecision
;
597 fnt32
.lfClipPrecision
= font
->logfont
.lfClipPrecision
;
598 fnt32
.lfQuality
= font
->logfont
.lfQuality
;
599 fnt32
.lfPitchAndFamily
= font
->logfont
.lfPitchAndFamily
;
600 strncpy( fnt32
.lfFaceName
, font
->logfont
.lfFaceName
,
601 sizeof(fnt32
.lfFaceName
) );
603 if (count
> sizeof(fnt32
)) count
= sizeof(fnt32
);
604 memcpy( buffer
, &fnt32
, count
);
609 /***********************************************************************
612 HFONT16
FONT_SelectObject( DC
* dc
, HFONT16 hfont
, FONTOBJ
* font
)
614 static X_PHYSFONT stockFonts
[LAST_STOCK_FONT
-FIRST_STOCK_FONT
+1];
621 X_PHYSFONT cacheFont
; } cacheFonts
[FONTCACHE
], *cacheFontsMin
;
624 X_PHYSFONT
* stockPtr
;
625 HFONT16 prevHandle
= dc
->w
.hFont
;
626 XFontStruct
* fontStruct
;
627 dprintf_font(stddeb
,"FONT_SelectObject(%p, %04x, %p)\n", dc
, hfont
, font
);
629 #if 0 /* From the code in SelectObject, this can not happen */
630 /* Load font if necessary */
635 hnewfont
= CreateFont16(10, 7, 0, 0, FW_DONTCARE
,
636 FALSE
, FALSE
, FALSE
, DEFAULT_CHARSET
, 0, 0,
637 DEFAULT_QUALITY
, FF_DONTCARE
, "*" );
638 font
= (FONTOBJ
*) GDI_HEAP_LIN_ADDR( hnewfont
);
642 if (dc
->header
.wMagic
== METAFILE_DC_MAGIC
)
643 if (MF_CreateFontIndirect(dc
, hfont
, &(font
->logfont
)))
648 if ((hfont
>= FIRST_STOCK_FONT
) && (hfont
<= LAST_STOCK_FONT
))
649 stockPtr
= &stockFonts
[hfont
- FIRST_STOCK_FONT
];
653 * Ok, It's not a stock font but
654 * may be it's cached in dynamic cache
656 for(i
=0; i
<FONTCACHE
; i
++) /* search for same handle */
657 if (cacheFonts
[i
].id
==hfont
) { /* Got the handle */
659 * Check if Handle matches the font
661 if(memcmp(&cacheFonts
[i
].logfont
,&(font
->logfont
), sizeof(LOGFONT16
))) {
662 /* No: remove handle id from dynamic font cache */
663 cacheFonts
[i
].access
=0;
664 cacheFonts
[i
].used
=0;
666 /* may be there is an unused handle which contains the font */
667 for(i
=0; i
<FONTCACHE
; i
++) {
668 if((cacheFonts
[i
].used
== 0) &&
669 (memcmp(&cacheFonts
[i
].logfont
,&(font
->logfont
), sizeof(LOGFONT16
)))== 0) {
670 /* got it load from cache and set new handle id */
671 stockPtr
= &cacheFonts
[i
].cacheFont
;
672 cacheFonts
[i
].access
=1;
673 cacheFonts
[i
].used
=1;
674 cacheFonts
[i
].id
=hfont
;
675 dprintf_font(stddeb
,"FONT_SelectObject: got font from unused handle\n");
682 /* Yes: load from dynamic font cache */
683 stockPtr
= &cacheFonts
[i
].cacheFont
;
684 cacheFonts
[i
].access
++;
685 cacheFonts
[i
].used
++;
690 if (!stockPtr
|| !stockPtr
->fstruct
)
692 if (!(fontStruct
= FONT_MatchFont( &font
->logfont
, dc
)))
694 /* If it is not a stock font, we can simply return 0 */
695 if (!stockPtr
) return 0;
696 /* Otherwise we must try to find a substitute */
697 dprintf_font(stddeb
,"Loading font 'fixed' for %04x\n", hfont
);
698 font
->logfont
.lfPitchAndFamily
&= ~VARIABLE_PITCH
;
699 font
->logfont
.lfPitchAndFamily
|= FIXED_PITCH
;
700 fontStruct
= XLoadQueryFont( display
, "fixed" );
703 fprintf( stderr
, "No system font could be found. Please check your font path.\n" );
710 fontStruct
= stockPtr
->fstruct
;
712 "FONT_SelectObject: Loaded font from cache %04x %p\n",
716 /* Unuse previous font */
717 for (i
=0; i
< FONTCACHE
; i
++) {
718 if (cacheFonts
[i
].id
== prevHandle
) {
719 if(cacheFonts
[i
].used
== 0)
720 fprintf(stderr
, "Trying to decrement a use count of 0.\n");
722 cacheFonts
[i
].used
--;
730 if (!stockPtr
->fstruct
)
732 stockPtr
->fstruct
= fontStruct
;
733 FONT_GetMetrics( &font
->logfont
, fontStruct
, &stockPtr
->metrics
);
735 memcpy( &dc
->u
.x
.font
, stockPtr
, sizeof(*stockPtr
) );
743 for (i
=0; i
< FONTCACHE
; i
++) {
744 if (cacheFonts
[i
].used
==0)
745 if ((!cacheFontsMin
) || ((cacheFontsMin
) && (cacheFontsMin
->access
> cacheFonts
[i
].access
)))
746 cacheFontsMin
=&cacheFonts
[i
];
748 if (!cacheFontsMin
) {
749 fprintf(stderr
,"No unused font cache entry !!!!\n" );
752 if (cacheFontsMin
->id
!=0) {
754 "FONT_SelectObject: Freeing %04x \n",cacheFontsMin
->id
);
755 XFreeFont( display
, cacheFontsMin
->cacheFont
.fstruct
);
757 cacheFontsMin
->cacheFont
.fstruct
= fontStruct
;
758 FONT_GetMetrics( &font
->logfont
, fontStruct
, &cacheFontsMin
->cacheFont
.metrics
);
759 cacheFontsMin
->access
=1;
760 cacheFontsMin
->used
=1;
761 cacheFontsMin
->id
=hfont
;
762 memcpy( &dc
->u
.x
.font
, &(cacheFontsMin
->cacheFont
), sizeof(cacheFontsMin
->cacheFont
) );
763 memcpy(&cacheFontsMin
->logfont
,&(font
->logfont
), sizeof(LOGFONT16
));
770 /***********************************************************************
771 * GetTextCharacterExtra16 (GDI.89)
773 INT16
GetTextCharacterExtra16( HDC16 hdc
)
775 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
777 return abs( (dc
->w
.charExtra
* dc
->wndExtX
+ dc
->vportExtX
/ 2)
782 /***********************************************************************
783 * GetTextCharacterExtra32 (GDI32.225)
785 INT32
GetTextCharacterExtra32( HDC32 hdc
)
787 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
789 return abs( (dc
->w
.charExtra
* dc
->wndExtX
+ dc
->vportExtX
/ 2)
794 /***********************************************************************
795 * SetTextCharacterExtra16 (GDI.8)
797 INT16
SetTextCharacterExtra16( HDC16 hdc
, INT16 extra
)
799 return (INT16
)SetTextCharacterExtra32( hdc
, extra
);
803 /***********************************************************************
804 * SetTextCharacterExtra32 (GDI32.337)
806 INT32
SetTextCharacterExtra32( HDC32 hdc
, INT32 extra
)
809 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
811 extra
= (extra
* dc
->vportExtX
+ dc
->wndExtX
/ 2) / dc
->wndExtX
;
812 prev
= dc
->w
.charExtra
;
813 dc
->w
.charExtra
= abs(extra
);
814 return (prev
* dc
->wndExtX
+ dc
->vportExtX
/ 2) / dc
->vportExtX
;
818 /***********************************************************************
819 * SetTextJustification16 (GDI.10)
821 INT16
SetTextJustification16( HDC16 hdc
, INT16 extra
, INT16 breaks
)
823 return SetTextJustification32( hdc
, extra
, breaks
);
827 /***********************************************************************
828 * SetTextJustification32 (GDI32.339)
830 BOOL32
SetTextJustification32( HDC32 hdc
, INT32 extra
, INT32 breaks
)
832 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
835 extra
= abs((extra
* dc
->vportExtX
+ dc
->wndExtX
/ 2) / dc
->wndExtX
);
836 if (!extra
) breaks
= 0;
837 dc
->w
.breakTotalExtra
= extra
;
838 dc
->w
.breakCount
= breaks
;
841 dc
->w
.breakExtra
= extra
/ breaks
;
842 dc
->w
.breakRem
= extra
- (dc
->w
.breakCount
* dc
->w
.breakExtra
);
846 dc
->w
.breakExtra
= 0;
853 /***********************************************************************
854 * GetTextFace16 (GDI.92)
856 INT16
GetTextFace16( HDC16 hdc
, INT16 count
, LPSTR name
)
858 return GetTextFace32A(hdc
,count
,name
);
861 /***********************************************************************
862 * GetTextFace32A (GDI32.234)
864 INT32
GetTextFace32A( HDC32 hdc
, INT32 count
, LPSTR name
)
868 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
870 if (!(font
= (FONTOBJ
*) GDI_GetObjPtr( dc
->w
.hFont
, FONT_MAGIC
)))
872 lstrcpyn32A( name
, font
->logfont
.lfFaceName
, count
);
876 /***********************************************************************
877 * GetTextFace32W (GDI32.235)
879 INT32
GetTextFace32W( HDC32 hdc
, INT32 count
, LPWSTR name
)
881 LPSTR nameA
= HeapAlloc( GetProcessHeap(), 0, count
);
882 INT32 res
= GetTextFace32A(hdc
,count
,nameA
);
883 lstrcpyAtoW( name
, nameA
);
884 HeapFree( GetProcessHeap(), 0, nameA
);
889 /***********************************************************************
890 * GetTextExtent (GDI.91)
892 DWORD
GetTextExtent( HDC16 hdc
, LPCSTR str
, INT16 count
)
895 if (!GetTextExtentPoint16( hdc
, str
, count
, &size
)) return 0;
896 return MAKELONG( size
.cx
, size
.cy
);
900 /***********************************************************************
901 * GetTextExtentPoint16 (GDI.471)
903 * FIXME: Should this have a bug for compatibility?
904 * Original Windows versions of GetTextExtentPoint{A,W} have documented
907 BOOL16
GetTextExtentPoint16( HDC16 hdc
, LPCSTR str
, INT16 count
, LPSIZE16 size
)
910 BOOL32 ret
= GetTextExtentPoint32A( hdc
, str
, count
, &size32
);
911 CONV_SIZE32TO16( &size32
, size
);
916 /***********************************************************************
917 * GetTextExtentPoint32A (GDI32.230)
919 BOOL32
GetTextExtentPoint32A( HDC32 hdc
, LPCSTR str
, INT32 count
,
922 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
925 if (!(dc
= (DC
*)GDI_GetObjPtr( hdc
, METAFILE_DC_MAGIC
)))
929 if (!dc
->funcs
->pGetTextExtentPoint
||
930 !dc
->funcs
->pGetTextExtentPoint( dc
, str
, count
, size
))
933 dprintf_font(stddeb
,"GetTextExtentPoint(%08x '%.*s' %d %p): returning %d,%d\n",
934 hdc
, count
, str
, count
, size
, size
->cx
, size
->cy
);
939 /***********************************************************************
940 * GetTextExtentPoint32W (GDI32.231)
942 BOOL32
GetTextExtentPoint32W( HDC32 hdc
, LPCWSTR str
, INT32 count
,
945 LPSTR p
= HEAP_strdupWtoA( GetProcessHeap(), 0, str
);
946 BOOL32 ret
= GetTextExtentPoint32A( hdc
, p
, count
, size
);
947 HeapFree( GetProcessHeap(), 0, p
);
951 /***********************************************************************
952 * GetTextExtentPoint32ABuggy (GDI32.232)
954 BOOL32
GetTextExtentPoint32ABuggy( HDC32 hdc
, LPCSTR str
, INT32 count
,
957 dprintf_font( stddeb
, "GetTextExtentPoint32ABuggy: not bug compatible.\n");
958 return GetTextExtentPoint32A( hdc
, str
, count
, size
);
961 /***********************************************************************
962 * GetTextExtentPoint32WBuggy (GDI32.233)
964 BOOL32
GetTextExtentPoint32WBuggy( HDC32 hdc
, LPCWSTR str
, INT32 count
,
967 dprintf_font( stddeb
, "GetTextExtentPoint32WBuggy: not bug compatible.\n");
968 return GetTextExtentPoint32W( hdc
, str
, count
, size
);
972 /***********************************************************************
973 * GetTextExtentExPoint32A (GDI32.228)
975 BOOL32
GetTextExtentExPoint32A( HDC32 hdc
, LPCSTR str
, INT32 count
,
976 INT32 maxExt
,LPINT32 lpnFit
, LPINT32 alpDx
,
983 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
986 if (!(dc
= (DC
*)GDI_GetObjPtr( hdc
, METAFILE_DC_MAGIC
)))
989 if (!dc
->funcs
->pGetTextExtentPoint
) return FALSE
;
991 size
->cx
=0; size
->cy
=0;
992 for(index
=0;index
<count
;index
++)
994 if(!dc
->funcs
->pGetTextExtentPoint( dc
, str
, 1, &tSize
)) return FALSE
;
995 if(extent
+tSize
.cx
<maxExt
)
1000 if(alpDx
) alpDx
[index
]=extent
;
1001 if(tSize
.cy
> size
->cy
) size
->cy
=tSize
.cy
;
1007 dprintf_font(stddeb
,"GetTextExtentExPoint32A(%08x '%.*s' %d) returning %d %d %d\n",
1008 hdc
,count
,str
,maxExt
,nFit
, size
->cx
,size
->cy
);
1012 /***********************************************************************
1013 * GetTextExtentExPoint32W (GDI32.229)
1016 BOOL32
GetTextExtentExPoint32W( HDC32 hdc
, LPCWSTR str
, INT32 count
,
1017 INT32 maxExt
, LPINT32 lpnFit
, LPINT32 alpDx
,
1020 LPSTR p
= HEAP_strdupWtoA( GetProcessHeap(), 0, str
);
1021 BOOL32 ret
= GetTextExtentExPoint32A( hdc
, p
, count
, maxExt
,
1022 lpnFit
, alpDx
, size
);
1023 HeapFree( GetProcessHeap(), 0, p
);
1027 /***********************************************************************
1028 * GetTextMetrics16 (GDI.93)
1030 BOOL16
GetTextMetrics16( HDC16 hdc
, TEXTMETRIC16
*metrics
)
1032 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
1033 if (!dc
) return FALSE
;
1034 memcpy( metrics
, &dc
->u
.x
.font
.metrics
, sizeof(*metrics
) );
1036 metrics
->tmAscent
= abs( metrics
->tmAscent
1037 * dc
->wndExtY
/ dc
->vportExtY
);
1038 metrics
->tmDescent
= abs( metrics
->tmDescent
1039 * dc
->wndExtY
/ dc
->vportExtY
);
1040 metrics
->tmHeight
= metrics
->tmAscent
+ metrics
->tmDescent
;
1041 metrics
->tmInternalLeading
= abs( metrics
->tmInternalLeading
1042 * dc
->wndExtY
/ dc
->vportExtY
);
1043 metrics
->tmExternalLeading
= abs( metrics
->tmExternalLeading
1044 * dc
->wndExtY
/ dc
->vportExtY
);
1045 metrics
->tmMaxCharWidth
= abs( metrics
->tmMaxCharWidth
1046 * dc
->wndExtX
/ dc
->vportExtX
);
1047 metrics
->tmAveCharWidth
= abs( metrics
->tmAveCharWidth
1048 * dc
->wndExtX
/ dc
->vportExtX
);
1050 dprintf_font(stdnimp
,"text metrics:\n
1051 InternalLeading = %i
1052 ExternalLeading = %i
1064 DigitizedAspectX = %i
1065 DigitizedAspectY = %i
1071 metrics
->tmInternalLeading
,
1072 metrics
->tmExternalLeading
,
1073 metrics
->tmMaxCharWidth
,
1076 metrics
->tmUnderlined
,
1077 metrics
->tmStruckOut
,
1078 metrics
->tmFirstChar
,
1079 metrics
->tmLastChar
,
1080 metrics
->tmDefaultChar
,
1081 metrics
->tmBreakChar
,
1083 metrics
->tmOverhang
,
1084 metrics
->tmDigitizedAspectX
,
1085 metrics
->tmDigitizedAspectY
,
1086 metrics
->tmAveCharWidth
,
1087 metrics
->tmMaxCharWidth
,
1096 /***********************************************************************
1097 * GetTextMetrics32A (GDI32.236)
1099 BOOL32
GetTextMetrics32A( HDC32 hdc
, TEXTMETRIC32A
*metrics
)
1102 if (!GetTextMetrics16( (HDC16
)hdc
, &tm
)) return FALSE
;
1103 metrics
->tmHeight
= tm
.tmHeight
;
1104 metrics
->tmAscent
= tm
.tmAscent
;
1105 metrics
->tmDescent
= tm
.tmDescent
;
1106 metrics
->tmInternalLeading
= tm
.tmInternalLeading
;
1107 metrics
->tmExternalLeading
= tm
.tmExternalLeading
;
1108 metrics
->tmAveCharWidth
= tm
.tmAveCharWidth
;
1109 metrics
->tmMaxCharWidth
= tm
.tmMaxCharWidth
;
1110 metrics
->tmWeight
= tm
.tmWeight
;
1111 metrics
->tmOverhang
= tm
.tmOverhang
;
1112 metrics
->tmDigitizedAspectX
= tm
.tmDigitizedAspectX
;
1113 metrics
->tmDigitizedAspectY
= tm
.tmDigitizedAspectY
;
1114 metrics
->tmFirstChar
= tm
.tmFirstChar
;
1115 metrics
->tmLastChar
= tm
.tmLastChar
;
1116 metrics
->tmDefaultChar
= tm
.tmDefaultChar
;
1117 metrics
->tmBreakChar
= tm
.tmBreakChar
;
1118 metrics
->tmItalic
= tm
.tmItalic
;
1119 metrics
->tmUnderlined
= tm
.tmUnderlined
;
1120 metrics
->tmStruckOut
= tm
.tmStruckOut
;
1121 metrics
->tmPitchAndFamily
= tm
.tmPitchAndFamily
;
1122 metrics
->tmCharSet
= tm
.tmCharSet
;
1127 /***********************************************************************
1128 * GetTextMetrics32W (GDI32.237)
1130 BOOL32
GetTextMetrics32W( HDC32 hdc
, TEXTMETRIC32W
*metrics
)
1133 if (!GetTextMetrics16( (HDC16
)hdc
, &tm
)) return FALSE
;
1134 metrics
->tmHeight
= tm
.tmHeight
;
1135 metrics
->tmAscent
= tm
.tmAscent
;
1136 metrics
->tmDescent
= tm
.tmDescent
;
1137 metrics
->tmInternalLeading
= tm
.tmInternalLeading
;
1138 metrics
->tmExternalLeading
= tm
.tmExternalLeading
;
1139 metrics
->tmAveCharWidth
= tm
.tmAveCharWidth
;
1140 metrics
->tmMaxCharWidth
= tm
.tmMaxCharWidth
;
1141 metrics
->tmWeight
= tm
.tmWeight
;
1142 metrics
->tmOverhang
= tm
.tmOverhang
;
1143 metrics
->tmDigitizedAspectX
= tm
.tmDigitizedAspectX
;
1144 metrics
->tmDigitizedAspectY
= tm
.tmDigitizedAspectY
;
1145 metrics
->tmFirstChar
= tm
.tmFirstChar
;
1146 metrics
->tmLastChar
= tm
.tmLastChar
;
1147 metrics
->tmDefaultChar
= tm
.tmDefaultChar
;
1148 metrics
->tmBreakChar
= tm
.tmBreakChar
;
1149 metrics
->tmItalic
= tm
.tmItalic
;
1150 metrics
->tmUnderlined
= tm
.tmUnderlined
;
1151 metrics
->tmStruckOut
= tm
.tmStruckOut
;
1152 metrics
->tmPitchAndFamily
= tm
.tmPitchAndFamily
;
1153 metrics
->tmCharSet
= tm
.tmCharSet
;
1158 /***********************************************************************
1159 * SetMapperFlags (GDI.349)
1161 DWORD
SetMapperFlags(HDC16 hDC
, DWORD dwFlag
)
1163 dprintf_font(stdnimp
,"SetmapperFlags(%04x, %08lX) // Empty Stub !\n",
1169 /***********************************************************************
1170 * GetCharABCWidths16 (GDI.307)
1172 BOOL16
GetCharABCWidths16( HDC16 hdc
, UINT16 firstChar
, UINT16 lastChar
,
1176 if (!GetCharABCWidths32A( hdc
, firstChar
, lastChar
, &abc32
)) return FALSE
;
1177 abc
->abcA
= abc32
.abcA
;
1178 abc
->abcB
= abc32
.abcB
;
1179 abc
->abcC
= abc32
.abcC
;
1184 /***********************************************************************
1185 * GetCharABCWidths32A (GDI32.149)
1187 BOOL32
GetCharABCWidths32A( HDC32 hdc
, UINT32 firstChar
, UINT32 lastChar
,
1190 /* No TrueType fonts in Wine so far */
1191 fprintf( stdnimp
, "STUB: GetCharABCWidths(%04x,%04x,%04x,%p)\n",
1192 hdc
, firstChar
, lastChar
, abc
);
1197 /***********************************************************************
1198 * GetCharABCWidths32W (GDI32.152)
1200 BOOL32
GetCharABCWidths32W( HDC32 hdc
, UINT32 firstChar
, UINT32 lastChar
,
1203 return GetCharABCWidths32A( hdc
, firstChar
, lastChar
, abc
);
1207 /***********************************************************************
1208 * GetCharWidth16 (GDI.350)
1210 BOOL16
GetCharWidth16( HDC16 hdc
, UINT16 firstChar
, UINT16 lastChar
,
1215 XCharStruct
*cs
, *def
;
1217 DC
*dc
= (DC
*)GDI_GetObjPtr(hdc
, DC_MAGIC
);
1218 if (!dc
) return FALSE
;
1219 xfont
= dc
->u
.x
.font
.fstruct
;
1222 if (xfont
->per_char
== NULL
)
1224 for (i
= firstChar
; i
<= lastChar
; i
++)
1225 *buffer
++ = xfont
->max_bounds
.width
;
1229 CI_GET_DEFAULT_INFO(xfont
, def
);
1231 for (i
= firstChar
; i
<= lastChar
; i
++)
1233 CI_GET_CHAR_INFO( xfont
, i
, def
, cs
);
1234 width
= cs
? cs
->width
: xfont
->max_bounds
.width
;
1235 *buffer
++ = MAX( width
, 0 );
1241 /***********************************************************************
1242 * GetCharWidth32A (GDI32.155)
1244 BOOL32
GetCharWidth32A( HDC32 hdc
, UINT32 firstChar
, UINT32 lastChar
,
1249 XCharStruct
*cs
, *def
;
1251 DC
*dc
= (DC
*)GDI_GetObjPtr(hdc
, DC_MAGIC
);
1252 if (!dc
) return FALSE
;
1253 xfont
= dc
->u
.x
.font
.fstruct
;
1256 if (xfont
->per_char
== NULL
)
1258 for (i
= firstChar
; i
<= lastChar
; i
++)
1259 *buffer
++ = xfont
->max_bounds
.width
;
1263 CI_GET_DEFAULT_INFO(xfont
, def
);
1265 for (i
= firstChar
; i
<= lastChar
; i
++)
1267 CI_GET_CHAR_INFO( xfont
, i
, def
, cs
);
1268 width
= cs
? cs
->width
: xfont
->max_bounds
.width
;
1269 *buffer
++ = MAX( width
, 0 );
1275 /***********************************************************************
1276 * GetCharWidth32W (GDI32.158)
1278 BOOL32
GetCharWidth32W( HDC32 hdc
, UINT32 firstChar
, UINT32 lastChar
,
1281 return GetCharWidth32A( hdc
, firstChar
, lastChar
, buffer
);
1285 /***********************************************************************
1286 * AddFontResource (GDI.119)
1288 INT
AddFontResource( LPCSTR str
)
1290 fprintf( stdnimp
, "STUB: AddFontResource('%s')\n", str
);
1295 /***********************************************************************
1296 * RemoveFontResource (GDI.136)
1298 BOOL
RemoveFontResource( LPSTR str
)
1300 fprintf( stdnimp
, "STUB: RemoveFontResource('%s')\n", str
);
1305 /*************************************************************************
1306 * ParseFontParms [internal]
1308 int ParseFontParms(LPSTR lpFont
, WORD wParmsNo
, LPSTR lpRetStr
, WORD wMaxSiz
)
1311 if (lpFont
== NULL
) return 0;
1312 if (lpRetStr
== NULL
) return 0;
1313 for (i
= 0; (*lpFont
!= '\0' && i
!= wParmsNo
); ) {
1314 if (*lpFont
== '-') i
++;
1317 if (i
== wParmsNo
) {
1318 if (*lpFont
== '-') lpFont
++;
1320 for (i
= 0; (*lpFont
!= '\0' && *lpFont
!= '-' && i
< wMaxSiz
); i
++)
1321 *(lpRetStr
+ i
) = *lpFont
++;
1322 *(lpRetStr
+ i
) = '\0';
1331 /*************************************************************************
1332 * InitFontsList [internal]
1335 static int logfcmp(const void *a
,const void *b
)
1337 return lstrcmpi32A( (*(LPLOGFONT16
*)a
)->lfFaceName
,
1338 (*(LPLOGFONT16
*)b
)->lfFaceName
);
1341 void InitFontsList(void)
1345 char *family
, *weight
, *charset
;
1347 char slant
, spacing
;
1349 LPLOGFONT16 lpNewFont
;
1351 dprintf_font(stddeb
,"InitFontsList !\n");
1359 sprintf( pattern
, "-%s-%s-%c-normal-*-*-*-*-*-%c-*-%s",
1360 family
, weight
, slant
, spacing
, charset
);
1361 names
= XListFonts( display
, pattern
, MAX_FONTS
, &count
);
1362 dprintf_font(stddeb
,"InitFontsList // count=%d \n", count
);
1364 lpNewFont
= malloc((sizeof(LOGFONT16
)+LF_FACESIZE
)*count
);
1365 if (lpNewFont
== NULL
) {
1366 dprintf_font(stddeb
,
1367 "InitFontsList // Error alloc new font structure !\n");
1368 XFreeFontNames(names
);
1372 for (i
= 0; i
< count
; i
++) {
1373 dprintf_font(stddeb
,"InitFontsList // names[%d]='%s' \n", i
, names
[i
]);
1375 ParseFontParms(names
[i
], 2, str
, sizeof(str
));
1376 /* AnsiUpper(str);*/
1377 strcpy(lpNewFont
->lfFaceName
, str
);
1378 ParseFontParms(names
[i
], 8, str
, sizeof(str
));
1379 lpNewFont
->lfHeight
= atoi(str
) / 10;
1380 ParseFontParms(names
[i
], 12, str
, sizeof(str
));
1381 lpNewFont
->lfWidth
= atoi(str
) / 10;
1382 lpNewFont
->lfEscapement
= 0;
1383 lpNewFont
->lfOrientation
= 0;
1384 lpNewFont
->lfWeight
= FW_REGULAR
;
1385 lpNewFont
->lfItalic
= 0;
1386 lpNewFont
->lfUnderline
= 0;
1387 lpNewFont
->lfStrikeOut
= 0;
1388 ParseFontParms(names
[i
], 13, str
, sizeof(str
));
1389 if (strcmp(str
, "iso8859") == 0) {
1390 lpNewFont
->lfCharSet
= ANSI_CHARSET
;
1392 lpNewFont
->lfCharSet
= OEM_CHARSET
;
1394 lpNewFont
->lfOutPrecision
= OUT_DEFAULT_PRECIS
;
1395 lpNewFont
->lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
1396 lpNewFont
->lfQuality
= DEFAULT_QUALITY
;
1397 ParseFontParms(names
[i
], 11, str
, sizeof(str
));
1400 lpNewFont
->lfPitchAndFamily
= VARIABLE_PITCH
| FF_SWISS
;
1404 lpNewFont
->lfPitchAndFamily
= FIXED_PITCH
| FF_MODERN
;
1407 lpNewFont
->lfPitchAndFamily
= DEFAULT_PITCH
| FF_DONTCARE
;
1410 dprintf_font( stddeb
,
1411 "InitFontsList // lpNewFont->lfHeight=%d\n",
1412 lpNewFont
->lfHeight
);
1413 dprintf_font( stddeb
,
1414 "InitFontsList // lpNewFont->lfWidth=%d\n",
1415 lpNewFont
->lfWidth
);
1416 dprintf_font( stddeb
,
1417 "InitFontsList // lfFaceName='%s'\n",
1418 lpNewFont
->lfFaceName
);
1419 lpLogFontList
[i
] = lpNewFont
;
1420 lpNewFont
= (LPLOGFONT16
)
1421 ((char *)lpNewFont
+ sizeof(LOGFONT16
)+LF_FACESIZE
);
1423 lpLogFontList
[i
] = NULL
;
1425 qsort(lpLogFontList
,count
,sizeof(*lpLogFontList
),logfcmp
);
1426 XFreeFontNames(names
);
1429 /*************************************************************************
1430 * EnumFonts [GDI.70]
1431 * We reuse EnumFontFamilies* for the callback function get the same
1432 * structs (+ extra stuff at the end which will be ignored by the enum funcs)
1434 INT16
EnumFonts16(HDC16 hDC
, LPCSTR lpFaceName
, FONTENUMPROC16 lpEnumFunc
, LPARAM lpData
)
1436 return EnumFontFamilies16(hDC
,lpFaceName
,lpEnumFunc
,lpData
);
1439 /*************************************************************************
1440 * EnumFontsA [GDI32.84]
1442 INT32
EnumFonts32A(HDC32 hDC
, LPCSTR lpFaceName
, FONTENUMPROC32A lpEnumFunc
, LPARAM lpData
)
1444 return EnumFontFamilies32A(hDC
,lpFaceName
,lpEnumFunc
,lpData
);
1447 /*************************************************************************
1448 * EnumFontsA [GDI32.84]
1450 INT32
EnumFonts32W(HDC32 hDC
, LPCWSTR lpFaceName
, FONTENUMPROC32W lpEnumFunc
, LPARAM lpData
)
1452 return EnumFontFamilies32W(hDC
,lpFaceName
,lpEnumFunc
,lpData
);
1455 /*************************************************************************
1456 * EnumFontFamilies [GDI.330]
1458 INT16
EnumFontFamilies16(HDC16 hDC
, LPCSTR lpszFamily
, FONTENUMPROC16 lpEnumFunc
, LPARAM lpData
)
1463 strcpy(LF
.lfFaceName
,lpszFamily
);
1465 LF
.lfFaceName
[0]='\0';
1466 LF
.lfCharSet
= DEFAULT_CHARSET
;
1468 return EnumFontFamiliesEx16(hDC
,&LF
,(FONTENUMPROCEX16
)lpEnumFunc
,lpData
,0);
1471 /*************************************************************************
1472 * EnumFontFamiliesA [GDI32.80]
1474 INT32
EnumFontFamilies32A(HDC32 hDC
, LPCSTR lpszFamily
, FONTENUMPROC32A lpEnumFunc
, LPARAM lpData
)
1479 strcpy(LF
.lfFaceName
,lpszFamily
);
1481 LF
.lfFaceName
[0]='\0';
1482 LF
.lfCharSet
= DEFAULT_CHARSET
;
1484 return EnumFontFamiliesEx32A(hDC
,&LF
,(FONTENUMPROCEX32A
)lpEnumFunc
,lpData
,0);
1487 /*************************************************************************
1488 * EnumFontFamiliesW [GDI32.83]
1490 INT32
EnumFontFamilies32W(HDC32 hDC
, LPCWSTR lpszFamilyW
, FONTENUMPROC32W lpEnumFunc
, LPARAM lpData
)
1495 lstrcpy32W(LF
.lfFaceName
,lpszFamilyW
);
1498 LF
.lfCharSet
= DEFAULT_CHARSET
;
1499 return EnumFontFamiliesEx32W(hDC
,&LF
,(FONTENUMPROCEX32W
)lpEnumFunc
,lpData
,0);
1502 /*************************************************************************
1503 * EnumFontFamiliesEx [GDI.618]
1504 * FIXME: fill the rest of the NEWTEXTMETRICEX and ENUMLOGFONTEX structures.
1505 * (applies to all EnumFontFamiliesEx*)
1506 * winelib/16 support.
1508 INT16
EnumFontFamiliesEx16(HDC16 hDC
, LPLOGFONT16 lpLF
, FONTENUMPROCEX16 lpEnumFunc
, LPARAM lpData
,DWORD reserved
)
1514 LPENUMLOGFONTEX16 lpEnumLogFont
;
1515 LPNEWTEXTMETRICEX16 lptm
;
1517 char FaceName
[LF_FACESIZE
];
1521 dprintf_font(stddeb
,"EnumFontFamiliesEx(%04x, '%s', %08lx, %08lx, %08lx)\n",
1522 hDC
, lpLF
->lfFaceName
, (DWORD
)lpEnumFunc
, lpData
, reserved
);
1523 if (lpEnumFunc
== 0) return 0;
1524 hLog
= GDI_HEAP_ALLOC( sizeof(ENUMLOGFONTEX16
) );
1525 lpEnumLogFont
= (LPENUMLOGFONTEX16
) GDI_HEAP_LIN_ADDR(hLog
);
1526 if (lpEnumLogFont
== NULL
) {
1527 fprintf(stderr
,"EnumFontFamiliesEx // can't alloc LOGFONT struct !\n");
1530 hMet
= GDI_HEAP_ALLOC( sizeof(NEWTEXTMETRICEX16
) );
1531 lptm
= (LPNEWTEXTMETRICEX16
) GDI_HEAP_LIN_ADDR(hMet
);
1533 GDI_HEAP_FREE(hLog
);
1534 fprintf(stderr
,"EnumFontFamiliesEx // can't alloc TEXTMETRIC struct !\n");
1538 strcpy(FaceName
,lpLF
->lfFaceName
);
1539 /* AnsiUpper(lpLF->lfFaceName);*/
1541 if (lpLogFontList
[0] == NULL
) InitFontsList();
1542 for(i
= 0; lpLogFontList
[i
] != NULL
; i
++) {
1544 if (lpLF
->lfCharSet
!=DEFAULT_CHARSET
)
1545 if (lpLogFontList
[i
]->lfCharSet
!= lpLF
->lfCharSet
)
1548 /* lfPitchAndFamily only of importance in Hebrew and Arabic versions. */
1552 if (lstrcmpi32A(FaceName
,lpLogFontList
[i
]->lfFaceName
))
1557 if ((lpOldName
!=NULL
) &&
1558 !lstrcmpi32A(lpOldName
,lpLogFontList
[i
]->lfFaceName
))
1560 lpOldName
=lpLogFontList
[i
]->lfFaceName
;
1563 memcpy(lpEnumLogFont
, lpLogFontList
[i
], sizeof(LOGFONT16
));
1564 strcpy(lpEnumLogFont
->elfFullName
,"");
1565 strcpy(lpEnumLogFont
->elfStyle
,"");
1566 hFont
= CreateFontIndirect16((LPLOGFONT16
)lpEnumLogFont
);
1567 hOldFont
= SelectObject32(hDC
, hFont
);
1568 GetTextMetrics16(hDC
, (LPTEXTMETRIC16
)lptm
);
1569 SelectObject32(hDC
, hOldFont
);
1570 DeleteObject32(hFont
);
1571 dprintf_font(stddeb
, "EnumFontFamiliesEx // i=%d lpLogFont=%p lptm=%p\n", i
, lpEnumLogFont
, lptm
);
1573 nRet
= lpEnumFunc( GDI_HEAP_SEG_ADDR(hLog
), GDI_HEAP_SEG_ADDR(hMet
),
1576 dprintf_font(stddeb
,"EnumFontFamilies // EnumEnd requested by application !\n");
1580 GDI_HEAP_FREE(hMet
);
1581 GDI_HEAP_FREE(hLog
);
1585 /*************************************************************************
1586 * EnumFontFamiliesExA [GDI32.81]
1587 * FIXME: Don't use 16 bit GDI heap functions (applies to EnumFontFamiliesEx32*)
1589 INT32
EnumFontFamiliesEx32A(HDC32 hDC
, LPLOGFONT32A lpLF
,FONTENUMPROCEX32A lpEnumFunc
, LPARAM lpData
,DWORD reserved
)
1595 LPENUMLOGFONTEX32A lpEnumLogFont
;
1596 LPNEWTEXTMETRICEX32A lptm
;
1598 char FaceName
[LF_FACESIZE
];
1602 dprintf_font(stddeb
,"EnumFontFamilies32A(%04x, %p, %08lx, %08lx, %08lx)\n",
1603 hDC
, lpLF
->lfFaceName
, (DWORD
)lpEnumFunc
, lpData
,reserved
);
1604 if (lpEnumFunc
== 0) return 0;
1605 hLog
= GDI_HEAP_ALLOC( sizeof(ENUMLOGFONTEX32A
) );
1606 lpEnumLogFont
= (LPENUMLOGFONTEX32A
) GDI_HEAP_LIN_ADDR(hLog
);
1607 if (lpEnumLogFont
== NULL
) {
1608 fprintf(stderr
,"EnumFontFamilies // can't alloc LOGFONT struct !\n");
1611 hMet
= GDI_HEAP_ALLOC( sizeof(NEWTEXTMETRICEX32A
) );
1612 lptm
= (LPNEWTEXTMETRICEX32A
) GDI_HEAP_LIN_ADDR(hMet
);
1614 GDI_HEAP_FREE(hLog
);
1615 fprintf(stderr
,"EnumFontFamilies32A // can't alloc TEXTMETRIC struct !\n");
1619 strcpy(FaceName
,lpLF
->lfFaceName
);
1620 /* AnsiUpper(lpLF->lfFaceName);*/
1622 if (lpLogFontList
[0] == NULL
) InitFontsList();
1623 for(i
= 0; lpLogFontList
[i
] != NULL
; i
++) {
1625 if (lpLF
->lfCharSet
!=DEFAULT_CHARSET
)
1626 if (lpLogFontList
[i
]->lfCharSet
!= lpLF
->lfCharSet
)
1629 /* lfPitchAndFamily only of importance in Hebrew and Arabic versions. */
1632 if (lstrcmpi32A(FaceName
,lpLogFontList
[i
]->lfFaceName
))
1635 if ((lpOldName
!=NULL
) &&
1636 !lstrcmpi32A(lpOldName
,lpLogFontList
[i
]->lfFaceName
))
1638 lpOldName
=lpLogFontList
[i
]->lfFaceName
;
1641 FONT_LOGFONT16ToLOGFONT32A(lpLogFontList
[i
],&(lpEnumLogFont
->elfLogFont
));
1642 strcpy(lpEnumLogFont
->elfFullName
,"");
1643 strcpy(lpEnumLogFont
->elfStyle
,"");
1644 strcpy(lpEnumLogFont
->elfScript
,"");
1645 hFont
= CreateFontIndirect32A((LPLOGFONT32A
)lpEnumLogFont
);
1646 hOldFont
= SelectObject32(hDC
, hFont
);
1647 GetTextMetrics32A(hDC
, (LPTEXTMETRIC32A
)lptm
);
1648 SelectObject32(hDC
, hOldFont
);
1649 DeleteObject32(hFont
);
1650 dprintf_font(stddeb
, "EnumFontFamiliesEx32A // i=%d lpLogFont=%p lptm=%p\n", i
, lpEnumLogFont
, lptm
);
1652 nRet
= lpEnumFunc(lpEnumLogFont
,lptm
,0,lpData
);
1654 dprintf_font(stddeb
,"EnumFontFamiliesEx32A // EnumEnd requested by application !\n");
1658 GDI_HEAP_FREE(hMet
);
1659 GDI_HEAP_FREE(hLog
);
1664 /*************************************************************************
1665 * EnumFontFamiliesW [GDI32.82]
1667 INT32
EnumFontFamiliesEx32W(HDC32 hDC
, LPLOGFONT32W lpLF
, FONTENUMPROCEX32W lpEnumFunc
, LPARAM lpData
, DWORD reserved
)
1673 LPENUMLOGFONTEX32W lpEnumLogFont
;
1674 LPNEWTEXTMETRICEX32W lptm
;
1680 dprintf_font(stddeb
,"EnumFontFamiliesEx32W(%04x, %p, %08lx, %08lx, %08lx)\n",
1681 hDC
, lpLF
, (DWORD
)lpEnumFunc
, lpData
,reserved
);
1682 if (lpEnumFunc
== 0) return 0;
1683 hLog
= GDI_HEAP_ALLOC( sizeof(ENUMLOGFONTEX32W
) );
1684 lpEnumLogFont
= (LPENUMLOGFONTEX32W
) GDI_HEAP_LIN_ADDR(hLog
);
1685 if (lpEnumLogFont
== NULL
) {
1686 fprintf(stderr
,"EnumFontFamilies32W // can't alloc LOGFONT struct !\n");
1689 hMet
= GDI_HEAP_ALLOC( sizeof(NEWTEXTMETRICEX32W
) );
1690 lptm
= (LPNEWTEXTMETRICEX32W
) GDI_HEAP_LIN_ADDR(hMet
);
1692 GDI_HEAP_FREE(hLog
);
1693 fprintf(stderr
,"EnumFontFamilies32W // can't alloc TEXTMETRIC struct !\n");
1697 lpszFamily
= HEAP_strdupWtoA( GetProcessHeap(), 0, lpLF
->lfFaceName
);
1698 AnsiUpper(lpszFamily
);
1699 if (lpLogFontList
[0] == NULL
) InitFontsList();
1700 for(i
= 0; lpLogFontList
[i
] != NULL
; i
++) {
1702 if (lpLF
->lfCharSet
!=DEFAULT_CHARSET
)
1703 if (lpLogFontList
[i
]->lfCharSet
!= lpLF
->lfCharSet
)
1706 /* lfPitchAndFamily only of importance in Hebrew and Arabic versions. */
1708 if (lpszFamily
[0]) {
1709 if (lstrcmpi32A(lpszFamily
,lpLogFontList
[i
]->lfFaceName
))
1712 if ((lpOldName
!=NULL
) &&
1713 !lstrcmpi32A(lpOldName
,lpLogFontList
[i
]->lfFaceName
))
1715 lpOldName
=lpLogFontList
[i
]->lfFaceName
;
1718 FONT_LOGFONT16ToLOGFONT32W(lpLogFontList
[i
],&(lpEnumLogFont
->elfLogFont
));
1719 lpEnumLogFont
->elfFullName
[0] = 0;
1720 lpEnumLogFont
->elfStyle
[0] = 0;
1721 lpEnumLogFont
->elfScript
[0] = 0;
1722 hFont
= CreateFontIndirect32W((LPLOGFONT32W
)lpEnumLogFont
);
1723 hOldFont
= SelectObject32(hDC
, hFont
);
1724 GetTextMetrics32W(hDC
, (LPTEXTMETRIC32W
)lptm
);
1725 SelectObject32(hDC
, hOldFont
);
1726 DeleteObject32(hFont
);
1727 dprintf_font(stddeb
, "EnumFontFamilies32W // i=%d lpLogFont=%p lptm=%p\n", i
, lpEnumLogFont
, lptm
);
1729 nRet
= lpEnumFunc(lpEnumLogFont
,lptm
,0,lpData
);
1731 dprintf_font(stddeb
,"EnumFontFamilies32W // EnumEnd requested by application !\n");
1735 GDI_HEAP_FREE(hMet
);
1736 GDI_HEAP_FREE(hLog
);
1737 HeapFree( GetProcessHeap(), 0, lpszFamily
);
1742 /*************************************************************************
1743 * GetRasterizerCaps [GDI.313]
1746 BOOL
GetRasterizerCaps(LPRASTERIZER_STATUS lprs
, UINT cbNumBytes
)
1748 /* This is not much more than a dummy */
1749 RASTERIZER_STATUS rs
;
1751 rs
.nSize
= sizeof(rs
);
1757 /*************************************************************************
1758 * GetKerningPairs [GDI.332]
1760 int GetKerningPairs(HDC16 hDC
,int cPairs
,LPKERNINGPAIR16 lpKerningPairs
)
1762 /* This has to be dealt with when proper font handling is in place
1764 * At this time kerning is ignored (set to 0)
1768 fprintf(stdnimp
,"GetKerningPairs: almost empty stub!\n");
1769 for (i
= 0; i
< cPairs
; i
++) lpKerningPairs
[i
].iKernAmount
= 0;