4 * Copyright 1993 Alexandre Julliard
7 static char Copyright
[] = "Copyright Alexandre Julliard, 1993";
11 #include <X11/Xatom.h>
14 extern Display
* XT_display
;
15 extern Screen
* XT_screen
;
18 /***********************************************************************
21 * Find a X font matching the logical font.
23 XFontStruct
* FONT_MatchFont( DC
* dc
, LOGFONT
* font
)
26 char *family
, *weight
, *charset
;
29 int width
, height
, count
;
30 XFontStruct
* fontStruct
;
32 weight
= (font
->lfWeight
> 550) ? "bold" : "medium";
33 slant
= font
->lfItalic
? 'i' : 'r';
34 height
= font
->lfHeight
* 10;
35 width
= font
->lfWidth
* 10;
36 spacing
= (font
->lfPitchAndFamily
& FIXED_PITCH
) ? 'm' :
37 (font
->lfPitchAndFamily
& VARIABLE_PITCH
) ? 'p' : '*';
38 charset
= (font
->lfCharSet
== ANSI_CHARSET
) ? "iso8859-1" : "*";
39 family
= font
->lfFaceName
;
40 if (!*family
) switch(font
->lfPitchAndFamily
& 0xf0)
42 case FF_ROMAN
: family
= "times"; break;
43 case FF_SWISS
: family
= "helvetica"; break;
44 case FF_MODERN
: family
= "courier"; break;
45 case FF_SCRIPT
: family
= "*"; break;
46 case FF_DECORATIVE
: family
= "*"; break;
47 default: family
= "*"; break;
50 sprintf( pattern
, "-*-%s-%s-%c-normal--*-%d-*-*-%c-%d-%s",
51 family
, weight
, slant
, height
, spacing
, width
, charset
);
53 printf( "FONT_MatchFont: '%s'\n", pattern
);
55 names
= XListFonts( XT_display
, pattern
, 1, &count
);
59 printf( " No matching font found\n" );
64 printf( " Found '%s'\n", *names
);
66 fontStruct
= XLoadQueryFont( XT_display
, *names
);
67 XFreeFontNames( names
);
72 /***********************************************************************
75 void FONT_GetMetrics( LOGFONT
* logfont
, XFontStruct
* xfont
,
76 TEXTMETRIC
* metrics
)
81 metrics
->tmAscent
= xfont
->ascent
;
82 metrics
->tmDescent
= xfont
->descent
;
83 metrics
->tmHeight
= xfont
->ascent
+ xfont
->descent
;
85 metrics
->tmInternalLeading
= 0;
86 if (XGetFontProperty( xfont
, XA_X_HEIGHT
, &prop
))
87 metrics
->tmInternalLeading
= xfont
->ascent
- (short)prop
;
88 metrics
->tmExternalLeading
= 0;
89 metrics
->tmMaxCharWidth
= xfont
->max_bounds
.width
;
90 metrics
->tmWeight
= logfont
->lfWeight
;
91 metrics
->tmItalic
= logfont
->lfItalic
;
92 metrics
->tmUnderlined
= logfont
->lfUnderline
;
93 metrics
->tmStruckOut
= logfont
->lfStrikeOut
;
94 metrics
->tmFirstChar
= xfont
->min_char_or_byte2
;
95 metrics
->tmLastChar
= xfont
->max_char_or_byte2
;
96 metrics
->tmDefaultChar
= xfont
->default_char
;
97 metrics
->tmBreakChar
= ' ';
98 metrics
->tmPitchAndFamily
= logfont
->lfPitchAndFamily
;
99 metrics
->tmCharSet
= logfont
->lfCharSet
;
100 metrics
->tmOverhang
= 0;
101 metrics
->tmDigitizedAspectX
= 1;
102 metrics
->tmDigitizedAspectY
= 1;
104 if (xfont
->per_char
) average
= metrics
->tmMaxCharWidth
;
107 XCharStruct
* charPtr
= xfont
->per_char
;
109 for (i
= metrics
->tmFirstChar
; i
<= metrics
->tmLastChar
; i
++)
111 average
+= charPtr
->width
;
114 average
/= metrics
->tmLastChar
- metrics
->tmFirstChar
+ 1;
116 metrics
->tmAveCharWidth
= average
;
120 /***********************************************************************
121 * CreateFontIndirect (GDI.57)
123 HFONT
CreateFontIndirect( LOGFONT
* font
)
126 HFONT hfont
= GDI_AllocObject( sizeof(FONTOBJ
), FONT_MAGIC
);
127 if (!hfont
) return 0;
128 fontPtr
= (FONTOBJ
*) GDI_HEAP_ADDR( hfont
);
129 memcpy( &fontPtr
->logfont
, font
, sizeof(LOGFONT
) );
134 /***********************************************************************
135 * CreateFont (GDI.56)
137 HFONT
CreateFont( int height
, int width
, int esc
, int orient
, int weight
,
138 BYTE italic
, BYTE underline
, BYTE strikeout
, BYTE charset
,
139 BYTE outpres
, BYTE clippres
, BYTE quality
, BYTE pitch
,
142 LOGFONT logfont
= { height
, width
, esc
, orient
, weight
, italic
, underline
,
143 strikeout
, charset
, outpres
, clippres
, quality
, pitch
, };
144 strncpy( logfont
.lfFaceName
, name
, LF_FACESIZE
);
145 return CreateFontIndirect( &logfont
);
149 /***********************************************************************
152 int FONT_GetObject( FONTOBJ
* font
, int count
, LPSTR buffer
)
154 if (count
> sizeof(LOGFONT
)) count
= sizeof(LOGFONT
);
155 memcpy( buffer
, &font
->logfont
, count
);
160 /***********************************************************************
163 HFONT
FONT_SelectObject( DC
* dc
, HFONT hfont
, FONTOBJ
* font
)
165 static X_PHYSFONT stockFonts
[LAST_STOCK_FONT
-FIRST_STOCK_FONT
+1];
166 X_PHYSFONT
* stockPtr
;
167 HFONT prevHandle
= dc
->w
.hFont
;
168 XFontStruct
* fontStruct
;
170 /* Load font if necessary */
172 if ((hfont
>= FIRST_STOCK_FONT
) && (hfont
<= LAST_STOCK_FONT
))
173 stockPtr
= &stockFonts
[hfont
- FIRST_STOCK_FONT
];
174 else stockPtr
= NULL
;
176 if (!stockPtr
|| !stockPtr
->fstruct
)
178 fontStruct
= FONT_MatchFont( dc
, &font
->logfont
);
182 fontStruct
= stockPtr
->fstruct
;
184 printf( "FONT_SelectObject: Loaded font from cache %x %p\n",
188 if (!fontStruct
) return 0;
190 /* Free previous font */
192 if ((prevHandle
< FIRST_STOCK_FONT
) || (prevHandle
> LAST_STOCK_FONT
))
194 if (dc
->u
.x
.font
.fstruct
)
195 XFreeFont( XT_display
, dc
->u
.x
.font
.fstruct
);
203 if (!stockPtr
->fstruct
)
205 stockPtr
->fstruct
= fontStruct
;
206 FONT_GetMetrics( &font
->logfont
, fontStruct
, &stockPtr
->metrics
);
208 memcpy( &dc
->u
.x
.font
, stockPtr
, sizeof(*stockPtr
) );
212 dc
->u
.x
.font
.fstruct
= fontStruct
;
213 FONT_GetMetrics( &font
->logfont
, fontStruct
, &dc
->u
.x
.font
.metrics
);
219 /***********************************************************************
220 * GetTextCharacterExtra (GDI.89)
222 short GetTextCharacterExtra( HDC hdc
)
224 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
226 return abs( (dc
->w
.charExtra
* dc
->w
.WndExtX
+ dc
->w
.VportExtX
/ 2)
231 /***********************************************************************
232 * SetTextCharacterExtra (GDI.8)
234 short SetTextCharacterExtra( HDC hdc
, short extra
)
237 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
239 extra
= (extra
* dc
->w
.VportExtX
+ dc
->w
.WndExtX
/ 2) / dc
->w
.WndExtX
;
240 prev
= dc
->w
.charExtra
;
241 dc
->w
.charExtra
= abs(extra
);
242 return (prev
* dc
->w
.WndExtX
+ dc
->w
.VportExtX
/ 2) / dc
->w
.VportExtX
;
246 /***********************************************************************
247 * SetTextJustification (GDI.10)
249 short SetTextJustification( HDC hdc
, short extra
, short breaks
)
251 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
254 extra
= abs((extra
* dc
->w
.VportExtX
+ dc
->w
.WndExtX
/ 2) / dc
->w
.WndExtX
);
255 if (!extra
) breaks
= 0;
256 dc
->w
.breakTotalExtra
= extra
;
257 dc
->w
.breakCount
= breaks
;
260 dc
->w
.breakExtra
= extra
/ breaks
;
261 dc
->w
.breakRem
= extra
- (dc
->w
.breakCount
* dc
->w
.breakExtra
);
265 dc
->w
.breakExtra
= 0;
272 /***********************************************************************
273 * GetTextExtent (GDI.91)
275 DWORD
GetTextExtent( HDC hdc
, LPSTR str
, short count
)
278 if (!GetTextExtentPoint( hdc
, str
, count
, &size
)) return 0;
279 return size
.cx
| (size
.cy
<< 16);
283 /***********************************************************************
284 * GetTextExtentPoint (GDI.471)
286 BOOL
GetTextExtentPoint( HDC hdc
, LPSTR str
, short count
, LPSIZE size
)
288 int dir
, ascent
, descent
;
291 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
292 if (!dc
) return FALSE
;
293 XTextExtents( dc
->u
.x
.font
.fstruct
, str
, count
, &dir
,
294 &ascent
, &descent
, &info
);
295 size
->cx
= abs((info
.width
+ dc
->w
.breakRem
+ count
* dc
->w
.charExtra
)
296 * dc
->w
.WndExtX
/ dc
->w
.VportExtX
);
297 size
->cy
= abs((dc
->u
.x
.font
.fstruct
->ascent
+dc
->u
.x
.font
.fstruct
->descent
)
298 * dc
->w
.WndExtY
/ dc
->w
.VportExtY
);
301 printf( "GetTextExtentPoint(%d '%s' %d %p): returning %d,%d\n",
302 hdc
, str
, count
, size
, size
->cx
, size
->cy
);
308 /***********************************************************************
309 * GetTextMetrics (GDI.93)
311 BOOL
GetTextMetrics( HDC hdc
, LPTEXTMETRIC metrics
)
313 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
314 if (!dc
) return FALSE
;
315 memcpy( metrics
, &dc
->u
.x
.font
.metrics
, sizeof(*metrics
) );
317 metrics
->tmAscent
= abs( metrics
->tmAscent
318 * dc
->w
.WndExtY
/ dc
->w
.VportExtY
);
319 metrics
->tmDescent
= abs( metrics
->tmDescent
320 * dc
->w
.WndExtY
/ dc
->w
.VportExtY
);
321 metrics
->tmHeight
= metrics
->tmAscent
+ metrics
->tmDescent
;
322 metrics
->tmInternalLeading
= abs( metrics
->tmInternalLeading
323 * dc
->w
.WndExtY
/ dc
->w
.VportExtY
);
324 metrics
->tmExternalLeading
= abs( metrics
->tmExternalLeading
325 * dc
->w
.WndExtY
/ dc
->w
.VportExtY
);
326 metrics
->tmMaxCharWidth
= abs( metrics
->tmMaxCharWidth
327 * dc
->w
.WndExtX
/ dc
->w
.VportExtX
);
328 metrics
->tmAveCharWidth
= abs( metrics
->tmAveCharWidth
329 * dc
->w
.WndExtX
/ dc
->w
.VportExtX
);
334 /***********************************************************************
335 * GetCharWidth (GDI.350)
337 BOOL
GetCharWidth(HDC hdc
, WORD wFirstChar
, WORD wLastChar
, LPINT lpBuffer
)
341 XCharStruct
*charPtr
;
344 DC
*dc
= (DC
*)GDI_GetObjPtr(hdc
, DC_MAGIC
);
345 if (!dc
) return FALSE
;
346 xfont
= dc
->u
.x
.font
.fstruct
;
349 if (xfont
->per_char
== NULL
)
351 for (i
= wFirstChar
, j
= 0; i
<= wLastChar
; i
++, j
++)
352 *(lpBuffer
+ j
) = xfont
->max_bounds
.width
;
356 charPtr
= xfont
->per_char
;
357 default_width
= (charPtr
+ xfont
->default_char
)->width
;
359 for (i
= wFirstChar
, j
= 0; i
<= wLastChar
; i
++, j
++)
361 if (i
< xfont
->min_char_or_byte2
|| i
> xfont
->max_char_or_byte2
)
362 *(lpBuffer
+ j
) = default_width
;
364 *(lpBuffer
+ j
) = charPtr
->width
;