2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these libraries and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $XConsortium: font.c /main/4 1995/11/09 12:59:38 rswiston $ */
25 * (c) Copyright 1993, 1994 Hewlett-Packard Company
26 * (c) Copyright 1993, 1994 International Business Machines Corp.
27 * (c) Copyright 1993, 1994 Novell, Inc.
28 * (c) Copyright 1993, 1994 Sun Microsystems, Inc.
33 #include <Xm/AtomMgr.h>
39 #define ABS(x) (((x) > 0) ? (x) : (-(x)))
43 * Walk a font_list looking for a FontSet with the
44 * XmFONTLIST_DEFAULT_TAG set. If we fail to find a FontSet with this tag,
45 * return the first FontSet found. If we fail to find a FontSet return
46 * the first font found.
48 * This function returns either a XFontStruct or a XFontSet. The type can
49 * be determined by the value of type_return which will equal either
50 * XmFONT_IS_FONTSET or XmFONT_IS_FONT.
52 * The XFontStruct or XFontSet that is returned is not a copy and should
58 XmFontType *type_return)
60 XmFontContext fl_context;
61 XmFontListEntry fl_entry;
62 XtPointer fl_entry_font,
64 char *fl_entry_font_tag;
65 Boolean found_font_set = False,
66 found_font_struct = False;
68 *type_return = XmFONT_IS_FONT;
70 if (!XmFontListInitFontContext(&fl_context, font_list))
71 return (XtPointer)NULL;
74 fl_entry = XmFontListNextEntry(fl_context);
77 XmFontListEntryGetFont(fl_entry, type_return);
78 if (*type_return == XmFONT_IS_FONTSET) {
80 XmFontListEntryGetTag(fl_entry);
82 * Save the first font set found in-
83 * case the default tag is not set.
85 if (!found_font_set) {
86 font_to_use = fl_entry_font;
87 found_font_set = True;
88 found_font_struct = True;
90 if (!strcmp(XmFONTLIST_DEFAULT_TAG,
93 } else if (!strcmp(XmFONTLIST_DEFAULT_TAG,
95 /* Found right font set */
96 font_to_use = fl_entry_font;
99 } else if (!found_font_struct) {
100 font_to_use = fl_entry_font;
101 found_font_struct = True;
104 } while (fl_entry != NULL);
106 XmFontListFreeFontContext(fl_context);
108 if (!found_font_set && !found_font_struct)
109 return (XtPointer)NULL;
111 return (XtPointer)font_to_use;
116 XmFontList font_list,
119 XmFontType type_return;
122 if (!font_list) return False;
124 font_data = get_font(font_list, &type_return);
129 cal_font->cf_type = type_return;
131 if (type_return == XmFONT_IS_FONTSET)
132 cal_font->f.cf_fontset = (XFontSet)font_data;
134 cal_font->f.cf_font = (XFontStruct *)font_data;
140 * Look for a font that is closest to the requested point size and resolution
141 * using the weight and family name specified.
147 unsigned long target_pixel_size,
156 closest_size_diff = 100000,
160 if (!strcmp(cal->app_data->app_font_family, "application")) {
161 sprintf (font_name, "-%s-%s-%s-r-normal-sans-*-*-*-*-p-*",
162 (with_foundry)?"dt":"*",
163 cal->app_data->app_font_family,
164 (weight == BOLD)?"bold":"medium");
166 sprintf (font_name, "-%s-%s-%s-r-normal--*-*-*-*-*-*",
167 (with_foundry)?"dt":"*",
168 cal->app_data->app_font_family,
169 (weight == BOLD)?"bold":"medium");
172 /* See if the font exists */
173 font_names = XListFonts(XtDisplay(cal->frame), font_name, 80, &nnames);
176 return ProbeForFont(cal, weight, target_pixel_size,
182 /* For the fonts that match, get their pixel size and
183 * look for the one with the pixel size closest to the size we are
186 for (i = 0; i < nnames; i++) {
187 sscanf(font_names[i],
188 "-%[^-]-%[^-]-%[^-]-%[^-]-%[^-]-%[^-]-%d-%s",
189 notused, notused, notused, notused, notused, notused,
193 sscanf(font_names[i],
194 "-%[^-]-%[^-]-%[^-]-%[^-]-%[^-]--%d-%s",
195 notused, notused, notused, notused, notused,
199 if ((ABS((int)(target_pixel_size - size)) <=
200 closest_size_diff)) {
202 ABS((int)(target_pixel_size - size));
205 if (closest_size_diff == 0)
212 if (closest_index == -1)
215 /* This one is the closest in size */
216 sprintf (font_name, "-%s-%s-%s-r-normal-%s-%d-*-*-*-*-*",
217 (with_foundry)?"dt":"*",
218 cal->app_data->app_font_family,
219 (weight == BOLD)?"bold":"medium",
220 (!strcmp(cal->app_data->app_font_family, "application")) ?
224 XFreeFontNames(font_names);
234 Cal_Font *return_font)
236 unsigned long pixel_size;
237 Display *dpy = XtDisplay(cal->frame);
239 *font_name_ptr = font_name,
243 XrmValue out_fontlist;
244 XmFontList font_list;
245 Atom pixel_atom = XmInternAtom(dpy, "PIXEL_SIZE", FALSE);
247 /* First get the pixel size from the User Font */
248 if (userfont->cf_type == XmFONT_IS_FONT) {
249 /* If we can't get the pixel size from the user font we
250 * defaults to a 12 pixel font.
252 if (!XGetFontProperty(userfont->f.cf_font, pixel_atom,
256 XFontStruct **font_struct_list;
257 char **font_name_list;
260 if (!(list_size = XFontsOfFontSet(userfont->f.cf_fontset,
266 if (!XGetFontProperty(font_struct_list[0],
273 /* If the font family is not ``application'' then it is probably
274 * multibyte so we can't assume there is an add-style or a proportional
277 if (!strcmp(cal->app_data->app_font_family, "application")) {
278 sprintf (font_name, "-dt-%s-%s-r-normal-sans-%lu-*-*-*-p-*",
279 cal->app_data->app_font_family,
280 (weight == BOLD)?"bold":"medium",
283 sprintf (font_name, "-dt-%s-%s-r-normal--%lu-*-*-*-*-*",
284 cal->app_data->app_font_family,
285 (weight == BOLD)?"bold":"medium",
289 /* See if the font exists */
290 font_names = XListFonts(dpy, font_name, 1, &nnames);
292 if (!ProbeForFont(cal, weight, pixel_size, TRUE,
294 /* We didn't find anything */
295 *return_font = *userfont;
299 XFreeFontNames(font_names);
301 strcat(font_name, ":");
302 in_font.size = strlen(font_name);
303 in_font.addr = font_name;
304 out_fontlist.size = sizeof(XmFontList);
305 out_fontlist.addr = (XPointer)&font_list;
307 /* Convert font string to a font list. */
308 if (!XtConvertAndStore(cal->frame, XtRString, &in_font, XmRFontList,
310 *return_font = *userfont;
313 if (!fontlist_to_font(font_list, return_font)) {
314 *return_font = *userfont;
319 * Given a font or fontset, return the extents of the text.
334 if (font->cf_type == XmFONT_IS_FONT) {
340 XTextExtents(font->f.cf_font, string, nbytes,
341 &direction, &ascent, &descent, &overall);
343 *x_return = overall.lbearing;
344 *y_return = overall.ascent;
345 *width_return = overall.width;
346 *height_return = overall.ascent + overall.descent;
351 XmbTextExtents(font->f.cf_fontset, string, nbytes,
354 *x_return = logical.x;
355 *y_return = logical.y;
356 *width_return = logical.width;
357 *height_return = logical.height;
362 * Given a font or fontset, render the text.
376 if (font->cf_type == XmFONT_IS_FONT) {
377 XSetFont(dpy, gc, font->f.cf_font->fid);
378 XDrawString(dpy, draw, gc, x, y, string, length);
380 XmbDrawString(dpy, draw, font->f.cf_fontset, gc, x, y,
388 XFontSetExtents *fse)
390 if (font->cf_type == XmFONT_IS_FONT) {
392 * These computations are stolen from _XsimlCreateFontSet()
395 fse->max_ink_extent.x = font->f.cf_font->min_bounds.lbearing;
396 fse->max_ink_extent.y = - font->f.cf_font->max_bounds.ascent;
397 fse->max_ink_extent.width = font->f.cf_font->min_bounds.width;
398 fse->max_ink_extent.height =
399 font->f.cf_font->max_bounds.ascent +
400 font->f.cf_font->max_bounds.descent;
402 fse->max_logical_extent.x = 0;
403 fse->max_logical_extent.y = - font->f.cf_font->ascent;
404 fse->max_logical_extent.width =
405 font->f.cf_font->max_bounds.width;
406 fse->max_logical_extent.height =
407 font->f.cf_font->ascent +
408 font->f.cf_font->descent;
410 *fse = *XExtentsOfFontSet(font->f.cf_fontset);