16
Fonts
In X, a large number of fonts are provided on the server. Deciding which font to use and then
trying to specify fonts by name can be difficult since there are many different styles and sizes
of fonts. Most fonts are used to render text strings. The images, or glyphs, represent a char-
acter set defined mostly by the language used. However, a font may be built to support
glyphs that have nothing to do with a language. Fonts are stored on the server and are associ-
ated with the display of your workstation. The font ID is stored in the graphics context (GC),
which is used by Xlib functions like XDrawString(). Using fonts to render text is per-
haps the most common application. For example, the Courier font family displays the
classic typewriter or constant-width character set. This text is set in Times-Roman, a propor-
tionally spaced font. Often within a font family, there are different styles, such as bold or
italic, and different point sizes.* For example, lucidasans-bold-14 refers to the luci-
dasans font family, the style is bold, and the point size is 14.
Not all server fonts have a variety of styles and sizes. These special-purpose fonts are gener-
ally specified by name only—there are no corresponding styles or families for these fonts.
When accessing fonts, you typically want to specify a font either by name or by the family,
style, and size or scale of the font. In addition, XView provides an interface for determining
the dimensions (in pixels) of characters and strings rendered in a specified font.
OPEN LOOK uses predefined fonts for certain items such as panel buttons and other user
interface elements. These items cannot be changed, but you can assign text fonts to panel
choices, text subwindows and other types of windows. We will address these issues later in
this chapter.
*Note that point sizes on workstations are based on pixels, whereas point sizes for typesetters and printers are based
on inches.
Fonts
Fonts 367
16.1 Creating Fonts
Applications that use the FONT package must include the header file, <xview/font.h>. In
XView, when a font object is created, it loads the font from the X server. When we say, “cre-
ate a font,” we really mean, “load a font from the server and create an XView font object
associated with that font.” Figure 16-1 shows the class hierarchy for the font package.
Generic
Object
Fonts
Figure 16-1. Font package class hierarchy
While fonts can be created using xv_create(), it may not be necessary to create a new
instance of a font. Fonts are typically cached on the server, and XView may already have a
handle to a particular font. Therefore, you should obtain a handle to the font if it already
exists, rather than create another instance of the same font. xv_find() can be used to
return the handle of an existing font. If the handle does not exist, xv_find() can create a
new instance of the font.
Both xv_find() and xv_create() will return an object of the type Xv_Font when
using the
FONT package. The form of the call is:
Xv_Font font;
font = (Xv_Font) xv_create(owner, FONT,
attrs
, NULL);
or:
Xv_Font font;
font = (Xv_Font) xv_find(owner, FONT,
attrs
, NULL);
The owner of the font is usually the window in which the font is going to be used. The actual
X font is loaded from the server associated with the owner object. If the owner is NULL, the
default server is used. Fonts may be used on any window, memory pixmaps, or
Server_image, but these objects must have the same display associated with them as
the font, or you will get an X Protocol error. What this means is that a font can only be used
on the server on which it was created. This is only any issue if your XView application is
running on multiple servers at the same time. If the parent is NULL, the default server is used.
Otherwise, the server as determined from the parent object is used. This is only an issue if
your XView application is running on several servers at the same time.
Once a font object is created, it can be used to render text by assigning the font’s XV_XID to
the font field of a graphics context (GC) and then using any of the Xlib routines that use
fonts such as XDrawString(). Example 16-1 lists simple_font.c, a program that builds a
simple frame and canvas. The repaint routine for the canvas displays the string “Hello
World” at the upper-left corner of the window.
368 XView Programming Manual
Example 16-1. The simple_font.c program
/*
* simple_font.c -- very simple program showing how to render text
* using a font gotten from xv_find(). Hello World is printed in
* the upper-left corner of a canvas window.
*/
#include <stdio.h>
#include <X11/X.h>
#include <X11/Xlib.h> /* X.h and Xlib.h used for Xlib graphics */
#include <xview/xview.h>
#include <xview/canvas.h>
#include <xview/font.h>
#include <xview/xv_xrect.h>
#define GC_KEY 10 /* any arbitrary number -- used for XV_KEY_DATA */
main(argc, argv)
int argc;
char *argv[ ];
{
Frame frame;
Canvas canvas;
XGCValues gcvalues;
Xv_Font font;
void my_repaint_proc();
Display *dpy;
GC gc;
xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL);
frame = (Frame)xv_create(XV_NULL, FRAME, NULL);
canvas = (Canvas)xv_create(frame, CANVAS,
XV_WIDTH, 400,
XV_HEIGHT, 200,
CANVAS_X_PAINT_WINDOW, TRUE,
CANVAS_REPAINT_PROC, my_repaint_proc,
NULL);
window_fit(frame);
dpy = (Display *)xv_get(frame, XV_DISPLAY);
font = (Xv_Font)xv_find(frame, FONT,
FONT_NAME, "lucidasans-12", NULL);
if (!font) {
fprintf(stderr, "%s: \
cannot use font: lucidasans-12\n", argv[0]);
font = (Xv_Font)xv_get(frame, XV_FONT);
}
/* Create a GC to use with Xlib graphics -- set the fg/bg colors
* and set the Font, which is the XV_XID of the XView font object.
*/
gcvalues.font = (Font)xv_get(font, XV_XID);
gcvalues.foreground = BlackPixel(dpy, DefaultScreen(dpy));
gcvalues.background = WhitePixel(dpy, DefaultScreen(dpy));
gcvalues.graphics_exposures = False;
gc = XCreateGC(dpy, RootWindow(dpy, DefaultScreen(dpy)),
Fonts
Fonts 369
Example 16-1. The simple_font.c program (continued)
GCForeground | GCBackground | GCFont | GCGraphicsExposures,
&gcvalues);
/* Assign the gc to the canvas object so we can use the same
* gc each time we draw into the canvas. Also avoids a global
* variable to store the GC.
*/
xv_set(canvas, XV_KEY_DATA, GC_KEY, gc, NULL);
xv_main_loop(frame);
}
/*
* Called every time the window needs repainting.
*/
void
my_repaint_proc(canvas, pw, dpy, xwin, xrects)
Canvas canvas;
Xv_Window pw;
Display *dpy;
Window xwin;
Xv_xrectlist *xrects;
{
GC gc = (GC)xv_get(canvas, XV_KEY_DATA, GC_KEY);
XDrawString(dpy, xwin, gc, 10, 20,
"Hello World", 11); /* 11 = strlen("Hello World") */
}
The program attempts to create the font named “lucidasans-12.” If the font is not found, the
frame’s font is used as a backup. This font must exist, so there is no need to check for a
failed return value.
Since the text is rendered using Xlib graphics, we need to use a GC that has the right attri-
butes set: the foreground and background colors and a font. Because this GC is specifically
used for the canvas window, we are going to attach the GC to the canvas by using the generic
attribute XV_KEY_DATA. Using a unique key, GC_KEY (which can be any integer since no
other keys have been assigned to the object yet), the GC is attached with the call:
xv_set(canvas, XV_KEY_DATA, GC_KEY, gc, NULL);
Later, in my_repaint_proc(), the GC is retrieved:
GC gc = (GC)xv_get(canvas, XV_KEY_DATA, GC_KEY);
This method of storing the GC by using XV_KEY_DATA avoids the need for a global variable.
When creating some fonts, it may take quite some time for the font to be found and com-
pletely loaded—especially large fonts, since they may be created at runtime. Loading the
font may result in the user having to wait longer than expected. It is recommended that the
application provide visual feedback if the user must wait for some time. Do this by setting
the
FRAME_BUSY attribute to TRUE for the parent frame:
xv_set(frame, FRAME_BUSY, TRUE, NULL);
font = (Xv_Font) xv_find(frame, FONT,
FONT_NAME, "lucidasans-24",
370 XView Programming Manual
NULL);
xv_set(frame, FRAME_BUSY, FALSE, NULL);
This code fragment attempts to create a 24-point size font. Note that not all servers can do
so, either because of memory limitations or because the server cannot scale fonts at will. In
this case, the font returned may be NULL.
16.1.1 Font Families and Styles
One way to create fonts is to specify a font family, style, and size. The family of a font
describes its basic characteristics. Figure 16-2 shows the Courier family in different styles
and a range of point sizes.
Courier plain
10 12 14 16 18
Courier Bold
10 12 14 16 18
Courier italic
10
12 14 16 18
Figure 16-2. The Courier font in different styles and sizes
Some font families and styles known to XView are predefined in <xview/font.h>. To use a
font other than the ones listed, you may specify any font family and style known by your X
server. You may also specify fonts by name (see Section 16.1.4, “Fonts by Name”). The list
of XView font families include:
• FONT_FAMILY_DEFAULT
• FONT_FAMILY_DEFAULT_FIXEDWIDTH
• FONT_FAMILY_LUCIDA
• FONT_FAMILY_LUCIDA_FIXEDWIDTH
• FONT_FAMILY_ROMAN
• FONT_FAMILY_SERIF
•
FONT_FAMILY_CMR
• FONT_FAMILY_GALLENT
• FONT_FAMILY_HELVETICA
• FONT_FAMILY_OLGLYPH*
• FONT_FAMILY_OLCURSOR*
*The families FONT_FAMILY_OLGLYPH and FONT_FAMILY_OLCURSOR are used internally by XView pack-
ages. They are not for general/public use.
Fonts
Fonts 371
Get Volume 7A: XView Programming Manual now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.