You are on page 1of 6

Chapter 9

Drawing Graphics

After'ybu create the windows and set up the event handling code, to com-
plete your application, you need to arrange to display text and graphics
in the windows. Although an X display is an array' (or raster) of pixels,
you do not always have to or one pixel at a time. The X1ib library in-
dud ma.tl)'-drawingfunctions; those functions can be grouped into"three
road categories:
.•. I:unctions to draw graphical ob"ects such as lines, rectangles, and
cirdes
.•. Functions to draw text
.•. Functions to display and manipulate images

This chapter describes the graphics drawing functions. Chapters 10,


"Drawing Text," and 12, "Pixmaps, Bitmaps, and Images," cover the
topics of text output and image manipulation, respectively. These chap-
ters do not discuss color, except to point out how the current foreground
and background colors affect the output. Chapter 11, "Using Color in
X," explores the topic of how color is handled in X.
This chapter starts with a discussion of the graphics context (GC). Recall that a GC is a data structure
(a resource) maintained in the ertj;r to store graphics attributes such as backg70und and foreground Figure 9.1.
colors, line style, and font. The appearance of graphics and text is controlled by these attributes. A drawable in X
After descri ing GCs and the functions that mani ulate~s, this chapter presents the Xlib functions
you can use to dr~r.a-pgjcal ob' ects, such as oints, lines, rectanales, 01 ons, arcs~an cue s~
Aavanced drawing techniques such as drawing ru -oer-band lines and changing fill styles and clip-
ping are also covered. An example program illustrates how to use the graphics drawi~ functions in
Xlib. --

raphics Contexts
,L / From th~ moment you be~in displaying output in.a window, the graphics context (~C) bec~mes the
::::/ focal POInt of your attention. A C must be s£eClfied as an argument for each Xllb function that
draws in a window. Through the GC ou s eci attributes such as coler, font, atterns and ine
sty es. Wit ot er X resources, you have to create a GC, initialize it, and then use it. Before gett' g
into those topics, consider the process of drawing in X and see where the GC fits into the scheme.

Purpose of a GC 19 create a drawing, follow these steps (see Figure 9.2):


The X server goes through a number of steps before altering the appropriate pixels in a window or
1. Select ixels that sho be altered to" aint" the gra hical ob·ect.
a pixmap (a drawable) tl? generate a requested output, such as a line of a specified width and style
(dashed, for instance). The GC is the repository of information needed to complete the drawing 2. ;iAi:PI'PiiiilY;:sth=e~1X='
=e=tv:::a1=u=es=t;.;o_t::.h;.;e~s~e:..;le~ct.:.;e~d~p;:.;i:..;x.:.el.:.s,:...u;.;.s:....in...:g~a
p~~pecified in the GC.
process. 3. Use the clip rectangles~ sp.ecified in th GC as a stencil through which the drawing occurs.
4. Use another stencil defined by-the visible region of the window where the output will
ap ear.
5. Alter the values ofcthese ixels according to the function and plane_mask attributes in
~ drawable refers to a window or a pixmap.Both represent a raster of pixels, qne on
screen (window) and the other, off screen pixmatr). Conceptually, each drawable is a twO-
dimensional array of memory locations where each location can ho1<:1 a number of bits of
-
the GC.
The two stenciling steps determine the final set of pixels that have to b~ changed. The GC controls
information representing a pixel v~ue-(see Figure 9.1). The number of bits i~ each pixel each step of the rendering process shown in Figure 9.2.
value gives the drawable its depth. You can also think of the two-dimensional drawable as

E~I/H/HLH·H~
I
being organized into a number or bit planes, in which each bit plane has a depth of one (see
Figure 9.1). .

Pixels Pattern,color Clippedby Clippedby .Pixelsdrawnin


seleC\lld applied clip rectangles visiblepart screenor pixmap
~ in GC of window (drawable)

NOTE:
. The conce t of GC was introduced in XII. In'XI 0, dra~ing functions proVided all gniphiJ
attributes (such as line width and oreground pixel) in each call. This was inefficient
because the parameters had to be sent to the server for each drawing request, even if you
never ~ the attributes. XII takes the more efficient M'proach of setting up a GC on<;¢
and referring to it by a single resource ID in each drawing request: '
A pointer ro rhe Dis lay

An unsigned -
The 10 of a drawable (a Windowor a Pixmap variable)
long bir mask
GC Attribute Specification
Instead of accepting the default values, you can create a GCwirh some or all of its attributes set to
he address of an XGCValues structure
values of your choice. Yo specifYrhe values of a GC'sattributes rhrough.an XGCValues structure,
You specifYvarious ra2hics attribut~s in the XGCValues s~ructure and use the bit mask ro indicate - 4

which members of the structure have valid"values. The sy'~ax of calling XCreateGC is as follows: which is defined in <X!.:!/~~as follo~ V\~\J /\111 • JA
typedef struct {\ rJ~
Display *p_disp;
Drawable win_or_pix; 1* Operation on pixels *I,t\~
unsigned long mask; 1* Bit planes affected *I ~
XGCValues xgcv; 1* Foreground pixel value *1
GC new_GC; 1* Background pixel value *1
~ 1* Line width (0 or more) *1 tJc,
1* One of: LineSolid,

int cap_style;
LineOnOffDash,
LineDoubleDash
1* One of: CapNotLast,
j
CapButt, CapRound,
CapProjecting
NOTE:
int join_style; 1* One of: JoinMiter,
JoinRound, JoinBevel *1
It is common practice in Xlib to use a structure ~irh a bif mask to indicate the valid fields
int fill_style; 1* One of: FillSolid,
in rhat structure. - FillTiled, FillStippled,
FillOpaqueStippled *1
int fill _rule; 1* One of: EvenOddRule,
WindingRule
If you want ro create a GCwith the default settings (which is described soon), call XCreateGC with
int arc_mode; 1* One of: ArcChord,
a 0 value for the bit mask and the pointer to rhe XGCValues structure: ArcPieSlice *I
~
D~splay *p_disp;
Pixmap tile; 1* Pixmap for tilinQ *1
Window Pixmap stipple; 1* Bitmap for stippling *1
my_window; x and y offset for tile*1
GC int ts_x_origin; 1*
mLGC; 1* or stipple operations *1
int ts_y_origin;
ont font; 1* Default font *I
my_GC XCreateGC(p_disp, my_window, 0, NULL);
int su w~naow_mode; 1* One of: ClipByChildren,
Includelnferiors *1
Once a GCis created rhis way:,lOU can alter specific attributes of 1;.h by usi!l.gthe Xlib function
Bool graphics_exposures; 1* True=generate exposures*1

~------------
XChangeGCor by using convenience functions such as XSetForeground and XSetBackground. int
int
Pixmap
clip_x_origin;
clip_y_origin;
clip_mask;
1* Origin of clip_mask

1* Bitmap for clipping


*1

*1
One GC for Many Drawables int dash_offset; 1* Controls dashed line *1
char dashes; 1* Pattern of dashes *1
Although you specifYthe 10 of a window or a pixmap (a drawable) when creating a GC,rhere is no XGCValues;
requirement that the GCbe used with that specific drawable. What matters is the number of bit The members of rhe XGCValues structure include all graphics attributes necessary ro control rhe
planes in the drawable-its deprh. Thus,.you can use ~ single GCwirh any window or ixma as appearance of text and graphics output in X. Table 9.1 shows rhe default values of rhe members of
long as they borh have the same de rh and are on the same screen. rhe XGCValues structure. The table also lists rhe value of rhe bit mask rhat identifies each member
.t is commo~ ractice to create as many GCsas re uired by rhe distinct drawing styles (determined of rhe XGeValues structure .
by sets of graphi~·attributes) used in an ap licarion. For example, i your application requires sev-
--
Part Three: Drawing in an X Window

Table 9.1. Default Values and Selection


Here is how you can use this information. Su ose ou want a GCwith all default attributes except
Masks for Members of the XGCValues Structure
the f()reground and back round ixel values _ etou the GC,this is what you do:
Bit Mask Value Default
1. Define an XGCValues structure.
Member Name Purpose to Select Member Value
2. In that sgucture, set t e foregroun.d:apd ba.ckgr.Q&nd-Illembers Q..desiJ:~dalues.
function Operation on pixels GCFunction GXcopy
3. <Set the unsigned long bit mask variable to the bitwise-OR ofGCForeground and
plane_mask Bit planes affected GCPlaneMask All Planes GCBackground, the constants rom able 9.1 that identifY these particular mem ersof the
foreground Foreground pixel GCForeground 0 XGCValues structure.
background Background pixel GCBackground 4. ~ eate the GCby calling XCreateGC:
line_width Line width GCLineWidth 0 Display *p_disp;
line_style Line style GCLineStyle LineSolid Window window_1 ;
cap_style Line endings GCCapStyle CapButt unsigned long gc_mask;
XGCValues xgcv;
join_style Line joinings GCJoinStyle JoinMiter
GC new_GC;
fill_style Filling style GCFillStyle FillSolid
fillJule Pixels to be filled GCFillRule EvenOddRule /* Set values of selected members of xgcv, as needed.
arc_mode Arcs to be filled as pie GCArcMode ArcPieSlice * Then set gc_mask. This example sets the foreground and the
slices or closed * background pixels to the default white and black colors
with a chord * for the screen.
*/
tile Pixmap for tiling GCTile Pixmap filled
xgcv.foreground = WhitePixe~disp, DefaultScreen(p disp));
with
xgcv.background = BlackPixel(p_disp, DefaultScreen(p_disp));
foreground
gc_mask = GCForeground : GCBackground;
pixel
stipple Bitmap for stippling GCStipple Bitmap of all 1s
ts x x-offset for tiling GCTileStipXOrigin 0
or stippling
tS_Lorigin y-offset for tiling GCTileStipYOrigin 0
or stippling Because a GCis a resource, it consumes memory in the X server. eniore, you should free a GC
when ~ is no longer needed. You can do so with the XFreeGC function:
font Default font for GCFont Server-
text output dependent Display *p_disp;
GC mLGC;
subwindow_mode Whether to draw GCSubwindowMode ClipByChildren
into children
graph~cs_exposures Exposure events GCGraphicsExposures True All your application's resources (including GCs)are automatically freed when the application exits,
generated if True so you need to destroy a GCexplicitly when you have created one for a temporary purpose
Clip_x_origin x-origin of clip_mask GCClipXOrigin 0
clip_LOf'igin y-origin of clip_mask GCClipYOrigin 0 GC Manipulation
Clip_mask Bitmap for clipping GCClipMask None After you create a GC,you can modifY the attributes by calling the XChangeGCfunction:
dash_offset Starting point in GCDashOffset 0 Display *p_disp;
dash pattern GC old_GC;
unsigned long gc_mask;
dashes Pattern of dashes GCDashList {4,4} XGCValues xgcv;
Function XGCValues Member
Name Set by Function Summary Description
XChangeGC(p_di$p, old_GC, gc_mask, &xgcv);
Specifies which bit planes are
The bit mask gc_mask and the XGCValues structure xgcv are used in the same way as they are in affected by a drawing request
the XCreateGC function: you set the values of selected members of the XGCValues structure and XSetRegion clip_mask Sets clip_mask to a region
indicate these members through the mask.
XSetState background, Sets four attributes in
XChangeGCis not the only way to alter graphics attributes in a GC.Xlib includes a number of con- foreground, a single call
venience functions to help set specific attributes. Table 9.2 summarizes these functions. You will function,
see these functions used and mentioned again in the rest of the chapter. plane_mask
stipple Specifies bitmap that determines
Table 9.2. Convenience Functions for Setting Attributes in a GC the pattern of foreground and,
background pixels
Function XGCValues Member
Name Set by Function Summary Description Determines whether graphics are
clipped by the subwindows
Determines whether filled arcs are Sets pixmap used for tiling
XSetTile
drawn as pie slices or a chord
closes the arc XSetTSOrigin ts_x_origin Sets origin of a stipple
tS_Lorigin or tile relative to
XSetBackground background Sets background pixel value
drawable
XSetClipmask clip_mask Specifies bitmap against which
drawings are clipped
clip_x~origin Controls position of the In addition to changing attributes in a GC,you also can copy selected attributes from one GCto
clip_Lorigin clip mask in the GC another (both GCsmust already exist). Use the XCopyGCfunction to do this'. For example, to copy
clip_mask Sets clip_mask to be a the foreground and background colors from oldGC to newGC,you write this:
clip_x_origin collection of rectangles XCopyGC(p_disp, oldGC, GCForeground : GCBackground, newGC)j
clip_Lorigin and alters origin
As with XCreateGC and XChang'eGC,the attributes that XCopyGCcopies from oldGC to newGCare
dash_offset Specifies dashed line
identified by a mask.
dashes style
fillJule Specifies rule used to determine . Now that you have seen the functions used to manipulate GCs,it's time to take a look at the specific
pixels to be filled graphics attributes affected by these functions.
XSetFillStyle fill_style Determines how areas are filled
XSetFont font Sets font for text output Display Functions
XSetForeground foreground Sets foreground pixel value Because the pixels in a drawable's raster (window or pixmap) already have existing values, the server
XSetFunction function Specifies how old and new pixel has to be told how to change the value-should it overwrite the, old value with the new one or com-
values are combined bine the old and new values in some way? You indicate this through the function member of the
XGCValues structure. Sometimes this attribute is known as raster operation or displayfunction be-
Determines whether
cause it indicates the birwise logical operations berween old and new pixel values in a drawable's
GraphicsExpose and
raster and, consequently, determines the final appearance of the graphics output.
NoExpose events are generated
line_Width, Determines appearance of lines X supports sixteen distinct raster operations. Table 9.3 lists those operations and shows the sym-
line_style bolic name for each operation in )(Jib (defined in <X11/Xlib. h».
cap_style;
join_style
rable 9.3. Display Functions in X
Symbolic Name Final Pixel Value
After the logical operation specified by the function attribute has been performed, another step is
of Function (old = existingpixel, new = new pixel)
still required before any pixels in the raster are altered. The plane_mask attribute in the GCspecifies
GXClear 0 which bit planes in the raster are altered by a graphics operation. The plane mask has a 1 in each bit
GXand new AND old position that may be modified. If a bit in plane_mask is 0, the corresponding bit in the raster's
existing pixel values is not changed. For example, in a display with four bit planes, the least-signifi-
GXandReverse new AND (NOT old)
cant four bits in the plane_mask attribute control how the planes are altered. If you want only bits
GXcopy new 1 and 3 (0 being the least significant bit) of each pixel value affected by a graphics operation, you
GXandInverted (NOT new) AND old can set the plane_mask attribute to the binary pattern 1010 (0x0a in C's notation for hexadecimal
GXnoop old numbers). You can set this in a GCby calling XSetPlaneMask:

GXxor newXORold
GXor new OR old After this is done, if a pixel .value of 0110 ;s to be copied to the raster, only bit 1 of each affected
GXnor NOT (new OR old) pixel will be set to 1.
GXequiv (NOT new) XOR old If you want a graphics operation to affect all bit planes, you can set plane_mask to the constant
GXinvert NOT old AllPlanes, which is a macro that refers to all the bit planes. The default value of the plane mask is
GXorReverse new OR (NOT old)' AllPlanes.
GXcopyInverted NOT new
GXorInverted (NOT new) OR old Foreground and Background Pixels
GXnand NOT (new AND old) The foreground and background ra hics attributes' specifYthe foreground and background col-
GXset 1 ors use or graphics operations. You can use the functions XSetForeground and XSetBackground
to set these attributes. Each attribute is a pixel value, so the colormap associated with the 'window
determines the actual colors displayed. The default values for foreground and background de-
pend on the X server. If you want black and white drawings, you can use the macros BlackPixel
'he default value of function is GXcoPY,which means that the new pixel values overwrite the old
and WhitePixel (they take the display and screen as arguments) as pixel values that map to black
les. Another important display function is GXxor which performs an exclusive-OR (XOR)of the
and white colors on the screen. '
d pixel value with the new. This function is useful in erasing drawings because of the following
:operty of the XOR operation:

hich says that if you exclusive-OR a pixel value x with y you can get back x by repeating the exclu- The background pixel specified in a GCis used differently from the background attribute of
ve-OR with y. Thus, if you use the GXxor function, you can erase a figure by simply redrawing . a window.
rer the old one. You can use this property of GXxor to animate drawings in X by erasing at the old
cation and drawing at the new one. A common use of the GXxor display function is in rubber-
l11ding,where a figure such as a\line or a rectangle is stretched and shrunk as the user moves the
Ouse. (You will see an example of rubber-banding later in this chapter.)
There are four attributes in a GCthat determine the appearance of lines:
~~Gx:nvert function is useful for highlighting an area in a black and white drawing by changing
lIte pIXelsto black and vice versa. •. line_Width

>ucan set the function attribute of a GCby calling XSetFunction. For example, to set the dis- •. line_style
ay function in a GCto GXxor, write the following: •. cap_-style
etFunction(p_disp, this_GC, GXxor); •. join_style