4 * Copyright 1993 Alexandre Julliard
7 static char Copyright[] = "Copyright Alexandre Julliard, 1993";
11 #include <X11/Xatom.h>
15 /***********************************************************************
18 * Find a X font matching the logical font.
20 XFontStruct * FONT_MatchFont( DC * dc, LOGFONT * font )
23 char *family, *weight, *charset;
26 int width, height, count;
27 XFontStruct * fontStruct;
29 weight = (font->lfWeight > 550) ? "bold" : "medium";
30 slant = font->lfItalic ? 'i' : 'r';
31 height = font->lfHeight * 10;
32 width = font->lfWidth * 10;
33 spacing = (font->lfPitchAndFamily & FIXED_PITCH) ? 'm' :
34 (font->lfPitchAndFamily & VARIABLE_PITCH) ? 'p' : '*';
35 charset = (font->lfCharSet == ANSI_CHARSET) ? "iso8859-1" : "*";
36 family = font->lfFaceName;
37 if (!*family) switch(font->lfPitchAndFamily & 0xf0)
39 case FF_ROMAN: family = "times"; break;
40 case FF_SWISS: family = "helvetica"; break;
41 case FF_MODERN: family = "courier"; break;
42 case FF_SCRIPT: family = "*"; break;
43 case FF_DECORATIVE: family = "*"; break;
44 default: family = "*"; break;
47 sprintf( pattern, "-*-%s-%s-%c-normal--*-%d-*-*-%c-%d-%s",
48 family, weight, slant, height, spacing, width, charset );
50 printf( "FONT_MatchFont: '%s'\n", pattern );
52 names = XListFonts( XT_display, pattern, 1, &count );
56 printf( " No matching font found\n" );
61 printf( " Found '%s'\n", *names );
63 fontStruct = XLoadQueryFont( XT_display, *names );
64 XFreeFontNames( names );
69 /***********************************************************************
72 void FONT_GetMetrics( LOGFONT * logfont, XFontStruct * xfont,
73 TEXTMETRIC * metrics )
78 metrics->tmAscent = xfont->ascent;
79 metrics->tmDescent = xfont->descent;
80 metrics->tmHeight = xfont->ascent + xfont->descent;
82 metrics->tmInternalLeading = 0;
83 if (XGetFontProperty( xfont, XA_X_HEIGHT, &prop ))
84 metrics->tmInternalLeading = xfont->ascent - (short)prop;
85 metrics->tmExternalLeading = 0;
86 metrics->tmMaxCharWidth = xfont->max_bounds.width;
87 metrics->tmWeight = logfont->lfWeight;
88 metrics->tmItalic = logfont->lfItalic;
89 metrics->tmUnderlined = logfont->lfUnderline;
90 metrics->tmStruckOut = logfont->lfStrikeOut;
91 metrics->tmFirstChar = xfont->min_char_or_byte2;
92 metrics->tmLastChar = xfont->max_char_or_byte2;
93 metrics->tmDefaultChar = xfont->default_char;
94 metrics->tmBreakChar = ' ';
95 metrics->tmPitchAndFamily = logfont->lfPitchAndFamily;
96 metrics->tmCharSet = logfont->lfCharSet;
97 metrics->tmOverhang = 0;
98 metrics->tmDigitizedAspectX = 1;
99 metrics->tmDigitizedAspectY = 1;
101 if (xfont->per_char) average = metrics->tmMaxCharWidth;
104 XCharStruct * charPtr = xfont->per_char;
106 for (i = metrics->tmFirstChar; i <= metrics->tmLastChar; i++)
108 average += charPtr->width;
111 average /= metrics->tmLastChar - metrics->tmFirstChar + 1;
113 metrics->tmAveCharWidth = average;
117 /***********************************************************************
118 * CreateFontIndirect (GDI.57)
120 HFONT CreateFontIndirect( LOGFONT * font )
123 HFONT hfont = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC );
124 if (!hfont) return 0;
125 fontPtr = (FONTOBJ *) GDI_HEAP_ADDR( hfont );
126 memcpy( &fontPtr->logfont, font, sizeof(LOGFONT) );
131 /***********************************************************************
132 * CreateFont (GDI.56)
134 HFONT CreateFont( int height, int width, int esc, int orient, int weight,
135 BYTE italic, BYTE underline, BYTE strikeout, BYTE charset,
136 BYTE outpres, BYTE clippres, BYTE quality, BYTE pitch,
139 LOGFONT logfont = { height, width, esc, orient, weight, italic, underline,
140 strikeout, charset, outpres, clippres, quality, pitch, };
141 strncpy( logfont.lfFaceName, name, LF_FACESIZE );
142 return CreateFontIndirect( &logfont );
146 /***********************************************************************
149 int FONT_GetObject( FONTOBJ * font, int count, LPSTR buffer )
151 if (count > sizeof(LOGFONT)) count = sizeof(LOGFONT);
152 memcpy( buffer, &font->logfont, count );
157 /***********************************************************************
160 HFONT FONT_SelectObject( DC * dc, HFONT hfont, FONTOBJ * font )
162 static X_PHYSFONT stockFonts[LAST_STOCK_FONT-FIRST_STOCK_FONT+1];
163 X_PHYSFONT * stockPtr;
164 HFONT prevHandle = dc->w.hFont;
165 XFontStruct * fontStruct;
167 /* Load font if necessary */
169 if ((hfont >= FIRST_STOCK_FONT) && (hfont <= LAST_STOCK_FONT))
170 stockPtr = &stockFonts[hfont - FIRST_STOCK_FONT];
171 else stockPtr = NULL;
173 if (!stockPtr || !stockPtr->fstruct)
175 fontStruct = FONT_MatchFont( dc, &font->logfont );
179 fontStruct = stockPtr->fstruct;
181 printf( "FONT_SelectObject: Loaded font from cache %x %p\n",
185 if (!fontStruct) return 0;
187 /* Free previous font */
189 if ((prevHandle < FIRST_STOCK_FONT) || (prevHandle > LAST_STOCK_FONT))
191 if (dc->u.x.font.fstruct)
192 XFreeFont( XT_display, dc->u.x.font.fstruct );
200 if (!stockPtr->fstruct)
202 stockPtr->fstruct = fontStruct;
203 FONT_GetMetrics( &font->logfont, fontStruct, &stockPtr->metrics );
205 memcpy( &dc->u.x.font, stockPtr, sizeof(*stockPtr) );
209 dc->u.x.font.fstruct = fontStruct;
210 FONT_GetMetrics( &font->logfont, fontStruct, &dc->u.x.font.metrics );
216 /***********************************************************************
217 * GetTextCharacterExtra (GDI.89)
219 short GetTextCharacterExtra( HDC hdc )
221 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
223 return abs( (dc->w.charExtra * dc->w.WndExtX + dc->w.VportExtX / 2)
228 /***********************************************************************
229 * SetTextCharacterExtra (GDI.8)
231 short SetTextCharacterExtra( HDC hdc, short extra )
234 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
236 extra = (extra * dc->w.VportExtX + dc->w.WndExtX / 2) / dc->w.WndExtX;
237 prev = dc->w.charExtra;
238 dc->w.charExtra = abs(extra);
239 return (prev * dc->w.WndExtX + dc->w.VportExtX / 2) / dc->w.VportExtX;
243 /***********************************************************************
244 * SetTextJustification (GDI.10)
246 short SetTextJustification( HDC hdc, short extra, short breaks )
248 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
251 extra = abs((extra * dc->w.VportExtX + dc->w.WndExtX / 2) / dc->w.WndExtX);
252 if (!extra) breaks = 0;
253 dc->w.breakTotalExtra = extra;
254 dc->w.breakCount = breaks;
257 dc->w.breakExtra = extra / breaks;
258 dc->w.breakRem = extra - (dc->w.breakCount * dc->w.breakExtra);
262 dc->w.breakExtra = 0;
269 /***********************************************************************
270 * GetTextExtent (GDI.91)
272 DWORD GetTextExtent( HDC hdc, LPSTR str, short count )
275 if (!GetTextExtentPoint( hdc, str, count, &size )) return 0;
276 return size.cx | (size.cy << 16);
280 /***********************************************************************
281 * GetTextExtentPoint (GDI.471)
283 BOOL GetTextExtentPoint( HDC hdc, LPSTR str, short count, LPSIZE size )
285 int dir, ascent, descent;
288 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
289 if (!dc) return FALSE;
290 XTextExtents( dc->u.x.font.fstruct, str, count, &dir,
291 &ascent, &descent, &info );
292 size->cx = abs((info.width + dc->w.breakRem + count * dc->w.charExtra)
293 * dc->w.WndExtX / dc->w.VportExtX);
294 size->cy = abs((dc->u.x.font.fstruct->ascent+dc->u.x.font.fstruct->descent)
295 * dc->w.WndExtY / dc->w.VportExtY);
298 printf( "GetTextExtentPoint(%d '%s' %d %p): returning %d,%d\n",
299 hdc, str, count, size, size->cx, size->cy );
305 /***********************************************************************
306 * GetTextMetrics (GDI.93)
308 BOOL GetTextMetrics( HDC hdc, LPTEXTMETRIC metrics )
310 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
311 if (!dc) return FALSE;
312 memcpy( metrics, &dc->u.x.font.metrics, sizeof(*metrics) );
314 metrics->tmAscent = abs( metrics->tmAscent
315 * dc->w.WndExtY / dc->w.VportExtY );
316 metrics->tmDescent = abs( metrics->tmDescent
317 * dc->w.WndExtY / dc->w.VportExtY );
318 metrics->tmHeight = metrics->tmAscent + metrics->tmDescent;
319 metrics->tmInternalLeading = abs( metrics->tmInternalLeading
320 * dc->w.WndExtY / dc->w.VportExtY );
321 metrics->tmExternalLeading = abs( metrics->tmExternalLeading
322 * dc->w.WndExtY / dc->w.VportExtY );
323 metrics->tmMaxCharWidth = abs( metrics->tmMaxCharWidth
324 * dc->w.WndExtX / dc->w.VportExtX );
325 metrics->tmAveCharWidth = abs( metrics->tmAveCharWidth
326 * dc->w.WndExtX / dc->w.VportExtX );
331 /***********************************************************************/
333 #define CI_NONEXISTCHAR(cs) (((cs)->width == 0) && \
334 (((cs)->rbearing|(cs)->lbearing| \
335 (cs)->ascent|(cs)->descent) == 0))
338 * CI_GET_CHAR_INFO - return the charinfo struct for the indicated 8bit
339 * character. If the character is in the column and exists, then return the
340 * appropriate metrics (note that fonts with common per-character metrics will
341 * return min_bounds). If none of these hold true, try again with the default
344 #define CI_GET_CHAR_INFO(fs,col,def,cs) \
347 if (col >= fs->min_char_or_byte2 && col <= fs->max_char_or_byte2) { \
348 if (fs->per_char == NULL) { \
349 cs = &fs->min_bounds; \
351 cs = &fs->per_char[(col - fs->min_char_or_byte2)]; \
352 if (CI_NONEXISTCHAR(cs)) cs = def; \
357 #define CI_GET_DEFAULT_INFO(fs,cs) \
358 CI_GET_CHAR_INFO(fs, fs->default_char, NULL, cs)
361 /***********************************************************************
362 * SetMapperFlags (GDI.349)
364 DWORD SetMapperFlags(HDC hDC, DWORD dwFlag)
366 printf("SetmapperFlags(%04X, %08X) // Empty Stub !\n", hDC, dwFlag);
371 /***********************************************************************
372 * GetCharWidth (GDI.350)
374 BOOL GetCharWidth(HDC hdc, WORD wFirstChar, WORD wLastChar, LPINT lpBuffer)
378 XCharStruct *cs, *def;
380 DC *dc = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC);
381 if (!dc) return FALSE;
382 xfont = dc->u.x.font.fstruct;
385 if (xfont->per_char == NULL)
387 for (i = wFirstChar, j = 0; i <= wLastChar; i++, j++)
388 *(lpBuffer + j) = xfont->max_bounds.width;
392 CI_GET_DEFAULT_INFO(xfont, def);
394 for (i = wFirstChar, j = 0; i <= wLastChar; i++, j++)
396 CI_GET_CHAR_INFO(xfont, i, def, cs);
397 *(lpBuffer + j) = cs->width;