1 /* $XConsortium: font.c /main/4 1995/11/09 12:59:38 rswiston $ */
3 * (c) Copyright 1993, 1994 Hewlett-Packard Company
4 * (c) Copyright 1993, 1994 International Business Machines Corp.
5 * (c) Copyright 1993, 1994 Novell, Inc.
6 * (c) Copyright 1993, 1994 Sun Microsystems, Inc.
11 #include <Xm/AtomMgr.h>
17 #define ABS(x) (((x) > 0) ? (x) : (-(x)))
21 * Walk a font_list looking for a FontSet with the
22 * XmFONTLIST_DEFAULT_TAG set. If we fail to find a FontSet with this tag,
23 * return the first FontSet found. If we fail to find a FontSet return
24 * the first font found.
26 * This function returns either a XFontStruct or a XFontSet. The type can
27 * be determined by the value of type_return which will equal either
28 * XmFONT_IS_FONTSET or XmFONT_IS_FONT.
30 * The XFontStruct or XFontSet that is returned is not a copy and should
36 XmFontType *type_return)
38 XmFontContext fl_context;
39 XmFontListEntry fl_entry;
40 XtPointer fl_entry_font,
42 char *fl_entry_font_tag;
43 Boolean found_font_set = False,
44 found_font_struct = False;
46 *type_return = XmFONT_IS_FONT;
48 if (!XmFontListInitFontContext(&fl_context, font_list))
49 return (XtPointer)NULL;
52 fl_entry = XmFontListNextEntry(fl_context);
55 XmFontListEntryGetFont(fl_entry, type_return);
56 if (*type_return == XmFONT_IS_FONTSET) {
58 XmFontListEntryGetTag(fl_entry);
60 * Save the first font set found in-
61 * case the default tag is not set.
63 if (!found_font_set) {
64 font_to_use = fl_entry_font;
65 found_font_set = True;
66 found_font_struct = True;
68 if (!strcmp(XmFONTLIST_DEFAULT_TAG,
71 } else if (!strcmp(XmFONTLIST_DEFAULT_TAG,
73 /* Found right font set */
74 font_to_use = fl_entry_font;
77 } else if (!found_font_struct) {
78 font_to_use = fl_entry_font;
79 found_font_struct = True;
82 } while (fl_entry != NULL);
84 XmFontListFreeFontContext(fl_context);
86 if (!found_font_set && !found_font_struct)
87 return (XtPointer)NULL;
89 return (XtPointer)font_to_use;
97 XmFontType type_return;
100 if (!font_list) return False;
102 font_data = get_font(font_list, &type_return);
107 cal_font->cf_type = type_return;
109 if (type_return == XmFONT_IS_FONTSET)
110 cal_font->f.cf_fontset = (XFontSet)font_data;
112 cal_font->f.cf_font = (XFontStruct *)font_data;
118 * Look for a font that is closest to the requested point size and resolution
119 * using the weight and family name specified.
125 unsigned long target_pixel_size,
134 closest_size_diff = 100000,
138 if (!strcmp(cal->app_data->app_font_family, "application")) {
139 sprintf (font_name, "-%s-%s-%s-r-normal-sans-*-*-*-*-p-*",
140 (with_foundry)?"dt":"*",
141 cal->app_data->app_font_family,
142 (weight == BOLD)?"bold":"medium");
144 sprintf (font_name, "-%s-%s-%s-r-normal--*-*-*-*-*-*",
145 (with_foundry)?"dt":"*",
146 cal->app_data->app_font_family,
147 (weight == BOLD)?"bold":"medium");
150 /* See if the font exists */
151 font_names = XListFonts(XtDisplay(cal->frame), font_name, 80, &nnames);
154 return ProbeForFont(cal, weight, target_pixel_size,
160 /* For the fonts that match, get their pixel size and
161 * look for the one with the pixel size closest to the size we are
164 for (i = 0; i < nnames; i++) {
165 sscanf(font_names[i],
166 "-%[^-]-%[^-]-%[^-]-%[^-]-%[^-]-%[^-]-%d-%s",
167 notused, notused, notused, notused, notused, notused,
171 sscanf(font_names[i],
172 "-%[^-]-%[^-]-%[^-]-%[^-]-%[^-]--%d-%s",
173 notused, notused, notused, notused, notused,
177 if ((ABS((int)(target_pixel_size - size)) <=
178 closest_size_diff)) {
180 ABS((int)(target_pixel_size - size));
183 if (closest_size_diff == 0)
190 if (closest_index == -1)
193 /* This one is the closest in size */
194 sprintf (font_name, "-%s-%s-%s-r-normal-%s-%d-*-*-*-*-*",
195 (with_foundry)?"dt":"*",
196 cal->app_data->app_font_family,
197 (weight == BOLD)?"bold":"medium",
198 (!strcmp(cal->app_data->app_font_family, "application")) ?
202 XFreeFontNames(font_names);
212 Cal_Font *return_font)
214 unsigned long pixel_size;
215 Display *dpy = XtDisplay(cal->frame);
217 *font_name_ptr = font_name,
221 XrmValue out_fontlist;
222 XmFontList font_list;
223 Atom pixel_atom = XmInternAtom(dpy, "PIXEL_SIZE", FALSE);
225 /* First get the pixel size from the User Font */
226 if (userfont->cf_type == XmFONT_IS_FONT) {
227 /* If we can't get the pixel size from the user font we
228 * defaults to a 12 pixel font.
230 if (!XGetFontProperty(userfont->f.cf_font, pixel_atom,
234 XFontStruct **font_struct_list;
235 char **font_name_list;
238 if (!(list_size = XFontsOfFontSet(userfont->f.cf_fontset,
244 if (!XGetFontProperty(font_struct_list[0],
251 /* If the font family is not ``application'' then it is probably
252 * multibyte so we can't assume there is an add-style or a proportional
255 if (!strcmp(cal->app_data->app_font_family, "application")) {
256 sprintf (font_name, "-dt-%s-%s-r-normal-sans-%d-*-*-*-p-*",
257 cal->app_data->app_font_family,
258 (weight == BOLD)?"bold":"medium",
261 sprintf (font_name, "-dt-%s-%s-r-normal--%d-*-*-*-*-*",
262 cal->app_data->app_font_family,
263 (weight == BOLD)?"bold":"medium",
267 /* See if the font exists */
268 font_names = XListFonts(dpy, font_name, 1, &nnames);
270 if (!ProbeForFont(cal, weight, pixel_size, TRUE,
272 /* We didn't find anything */
273 *return_font = *userfont;
277 XFreeFontNames(font_names);
279 strcat(font_name, ":");
280 in_font.size = strlen(font_name);
281 in_font.addr = font_name;
282 out_fontlist.size = sizeof(XmFontList);
283 out_fontlist.addr = (XPointer)&font_list;
285 /* Convert font string to a font list. */
286 if (!XtConvertAndStore(cal->frame, XtRString, &in_font, XmRFontList,
288 *return_font = *userfont;
291 if (!fontlist_to_font(font_list, return_font)) {
292 *return_font = *userfont;
297 * Given a font or fontset, return the extents of the text.
312 if (font->cf_type == XmFONT_IS_FONT) {
318 XTextExtents(font->f.cf_font, string, nbytes,
319 &direction, &ascent, &descent, &overall);
321 *x_return = overall.lbearing;
322 *y_return = overall.ascent;
323 *width_return = overall.width;
324 *height_return = overall.ascent + overall.descent;
329 XmbTextExtents(font->f.cf_fontset, string, nbytes,
332 *x_return = logical.x;
333 *y_return = logical.y;
334 *width_return = logical.width;
335 *height_return = logical.height;
340 * Given a font or fontset, render the text.
354 if (font->cf_type == XmFONT_IS_FONT) {
355 XSetFont(dpy, gc, font->f.cf_font->fid);
356 XDrawString(dpy, draw, gc, x, y, string, length);
358 XmbDrawString(dpy, draw, font->f.cf_fontset, gc, x, y,
366 XFontSetExtents *fse)
368 if (font->cf_type == XmFONT_IS_FONT) {
370 * These computations are stolen from _XsimlCreateFontSet()
373 fse->max_ink_extent.x = font->f.cf_font->min_bounds.lbearing;
374 fse->max_ink_extent.y = - font->f.cf_font->max_bounds.ascent;
375 fse->max_ink_extent.width = font->f.cf_font->min_bounds.width;
376 fse->max_ink_extent.height =
377 font->f.cf_font->max_bounds.ascent +
378 font->f.cf_font->max_bounds.descent;
380 fse->max_logical_extent.x = 0;
381 fse->max_logical_extent.y = - font->f.cf_font->ascent;
382 fse->max_logical_extent.width =
383 font->f.cf_font->max_bounds.width;
384 fse->max_logical_extent.height =
385 font->f.cf_font->ascent +
386 font->f.cf_font->descent;
388 *fse = *XExtentsOfFontSet(font->f.cf_fontset);