head 1.18; access; symbols; locks; strict; comment @% @; 1.18 date 2003.05.17.01.41.53; author cworth; state Exp; branches; next 1.17; 1.17 date 2003.05.16.19.55.44; author cworth; state Exp; branches; next 1.16; 1.16 date 2003.05.16.19.39.14; author keithp; state Exp; branches; next 1.15; 1.15 date 2003.05.16.19.32.51; author keithp; state Exp; branches; next 1.14; 1.14 date 2003.05.16.19.27.34; author cworth; state Exp; branches; next 1.13; 1.13 date 2003.05.16.19.21.12; author cworth; state Exp; branches; next 1.12; 1.12 date 2003.05.16.18.51.41; author cworth; state Exp; branches; next 1.11; 1.11 date 2003.05.16.16.58.13; author cworth; state Exp; branches; next 1.10; 1.10 date 2003.05.16.15.39.14; author cworth; state Exp; branches; next 1.9; 1.9 date 2003.05.16.13.29.16; author cworth; state Exp; branches; next 1.8; 1.8 date 2003.05.16.06.38.37; author cworth; state Exp; branches; next 1.7; 1.7 date 2003.05.16.05.37.30; author cworth; state Exp; branches; next 1.6; 1.6 date 2003.05.16.04.56.02; author cworth; state Exp; branches; next 1.5; 1.5 date 2003.05.16.00.32.34; author cworth; state Exp; branches; next 1.4; 1.4 date 2003.05.15.20.04.48; author cworth; state Exp; branches; next 1.3; 1.3 date 2003.05.15.17.34.17; author cworth; state Exp; branches; next 1.2; 1.2 date 2003.05.15.02.00.27; author cworth; state Exp; branches; next 1.1; 1.1 date 2003.05.14.21.04.22; author cworth; state Exp; branches; next ; desc @@ 1.18 log @Final batch of minor corrections. Should be ready to ship now. @ text @\section{API and Examples} \label{sec:api} % Not to discuss for various reasons of brokenness: XrSetDash, % XrClip, XrScaleFont, XrSelectFont, XrSetTolerance This section provides a tour of the application programming interface (API) provided by Xr. Major features of the API are demonstrated in illustrations, and the source code for each illustration is provided in Appendix~\ref{sec:source_code}. \subsection{Xr Initialization} \begin{figure}[htbp] \begin{scriptsize} \begin{verbatim} #include #define WIDTH 600 #define HEIGHT 600 #define STRIDE (WIDTH * 4) char image[STRIDE*HEIGHT]; int main (void) { XrState *xrs; xrs = XrCreate (); XrSetTargetImage (xrs, image, XrFormatARGB32, WIDTH, HEIGHT, STRIDE); /* draw things using xrs ... */ XrDestroy (xrs); /* do something useful with image (eg. write to a file) */ return 0; } \end{verbatim} \end{scriptsize} \caption{Minimal program using Xr} \label{fig:source_minimal} \end{figure} Figure~\ref{fig:source_minimal} shows a minimal program using Xr. This program does not actually do useful work---it never draws anything, but it demonstrates the initialization and cleanup procedures required for using Xr. After including the Xr header file, the first Xr function a program must call is XrCreate. This function returns a pointer to an XrState object, which is used by Xr to store its data. The XrState pointer is passed as the first argument to almost all other Xr functions. Before any drawing functions may be called, Xr must be provided with a target surface to receive the resulting graphics. The backend of Xr has support for multiple types of graphics targets. Currently, Xr has support for rendering to in-memory images as well as to any X Window System ``drawable'', (eg. a window or a pixmap). The program calls XrSetTargetImage to direct graphics to an array of bytes arranged as 4-byte ARGB pixels. A similar call, XrSetTargetDrawable, is available to direct graphics to an X drawable. When the program is done using Xr, it signifies this by calling XrDestroy. During XrDestroy, all data is released from the XrState object. It is then invalid for the program to use the value of the XrState pointer until a new object is created by calling XrCreate. The results of any graphics operations are still available on the target surface, and the program can access that surface as appropriate, (eg. write the image to a file, display the graphics on the screen, etc.). \subsection{Transformations} \label{sec:transformations} All coordinates passed from user code to Xr are in a coordinate system known as ``user space''. These coordinates are then transformed to ``device space'' which corresponds to the device grid of the target surface. This transformation is controlled by the current transformation matrix (CTM) within Xr. The initial CTM is established such that one user unit maps to an integer number of device pixels as close as possible to 3780 user units per meter (\~{}96 DPI) of physical device. This approach attempts to balance the competing desires of having a predictable real-world interpretation for user units and having the ability to draw elements on exact device pixel boundaries. Ideally, device pixels would be so small that the user could ignore pixel boundaries, but with current display pixel sizes of about 100 DPI, the pixel boundaries are still significant. The CTM can be modified by the user to position, scale, or rotate subsequent objects to be drawn. These operations are performed by the functions XrTranslate, XrScale, and XrRotate. Additionally, XrConcatMatrix will compose a given matrix into the current CTM and XrSetMatrix will directly set the CTM to a given matrix. The XrDefaultMatrix function can be used to restore the CTM to its original state. \begin{figure}[htbp] \begin{center} \epsfxsize=1in \epsfbox{examples/hering} \caption{Hering illusion (originally discovered by Ewald Hering in 1861)\cite{seckel}. The radial lines were positioned with XrTranslate and XrRotate} \label{fig:hering} \end{center} \end{figure} In Figure~\ref{fig:hering}, each of the radial lines was drawn using identical path coordinates. The different angles were achieved by calling XrRotate before drawing each line. The source code for this image is in Figure~\ref{fig:hering_source}. \subsection{Save/Restore of Graphics State} Programs using a structured approach to drawing will modify graphics state parameters in a hierarchical fashion. For example, while traversing a tree of objects to be drawn a program may modify the CTM, current color, line width, etc. at each level of the hierarchy. Xr supports this hierarchical approach to graphics by maintaining a stack of graphics state objects within the XrState object. The XrSave function pushes a copy of the current graphics state onto the top of the stack. Modifications to the graphics state are made only to the object on the top of the stack. The XrRestore function pops a graphics state object off of the stack, restoring all graphics parameters to their state before the last XrSave operation. This model has proven effective within structured C programs. Most drawing functions can be written with the following style, wrapping the body of the function with calls to XrSave and XrRestore: \begin{small} \begin{verbatim} void draw_something (XrState *xrs) { XrSave (xrs); /* draw something here */ XrRestore (xrs); } \end{verbatim} \end{small} This approach has the benefit that modifications to the graphics state within the function will not be visible outside the function, leading to more readily reusable code. Sometimes a single function will contain multiple sections of code framed by XrSave/XrRestore calls. Some find it more readable to include a new indented block between the XrSave/XrRestore calls in this case. Figure~\ref{fig:caps_joins_source} contains an example of this style. \subsection{Path Construction} \label{sec:path_example} One of the primary elements of the Xr graphics state is the current path. A path consists of one or more independent subpaths, each of which is an ordered set of straight or curved segments. Any non-empty path has a ``current point'', the final coordinate in the final segment of the current subpath. Path construction functions may read and update the current point. Xr provides several functions for constructing paths. XrNewPath installs an empty path, discarding any previously defined path. The first path construction called after XrNewPath should be XrMoveTo which simply moves the current point to the point specified. It is also valid to call XrMoveTo when the current path is non-empty in order to begin a new subpath. XrLineTo adds a straight line segment to the current path, from the current point to the point specified. XrCurveTo adds a cubic B\'ezier spline with a control polygon defined by the current point as well as the three points specified. XrClosePath closes the current subpath. This operation involves adding a straight line segment from the current point to the initial point of the current subpath, (ie. the point specified by the most recent call to XrMoveTo). Calling XrClosePath is not equivalent to adding the corresponding line segment with XrLineTo. The distinction is that a closed subpath will have a join at the junction of the final coincident point while an unclosed path will have caps on either end of the path, (even if the two ends happen to be coincident). See Section~\ref{sec:path_stroking} for more discussion of caps and joins. It is often convenient to specify path coordinates as relative offsets from the current point rather than as absolute coordinates. To allow this, Xr provides XrRelMoveTo, XrRelLineTo, and XrRelCurveTo. Figure~\ref{fig:spiral} shows a rendering of a path constructed with one call to XrMoveTo and four calls to XrRelLineTo in a loop. The source code for this figure can be seen in Figure~\ref{fig:spiral_source}. \begin{figure}[htbp] \begin{center} \epsfxsize=2in \epsfbox{examples/spiral} \caption{Nested box illusion (after a figure by Al Seckel\cite{seckel}). Constructed with XrMoveTo and XrRelLineTo} \label{fig:spiral} \end{center} \end{figure} As rectangular paths are commonly used, Xr provides a convenience function for adding a rectangular subpath to the current path. A call to \texttt{\small XrRectangle(xrs, x, y, width, height)} is equivalent to the following sequence of calls: \begin{small} \begin{verbatim} XrMoveTo (xrs, x, y); XrRelLineTo (xrs, width, 0); XrRelLineTo (xrs, 0, height); XrRelLineTo (xrs, -width, 0); XrClosePath (xrs); \end{verbatim} \end{small} After a path is constructed, it can be drawn in one of two ways: stroking its outline (XrStroke) or filling its interior (XrFill). \subsection{Path Stroking} \label{sec:path_stroking} XrStroke draws the outline formed by stroking the path with a pen that in user space is circular with a radius of the current line width, (as set by XrSetLineWidth). The specification of the XrStroke operator is based on the convolution of polygonal tracings as set forth by Guibas, Ramshaw and Stolfi~\cite{ramshaw83}. Convolution lends itself to efficient implementation as the outline of the stroke can be computed within an arbitrarily small error bound by simply using piece-wise linear approximations of the path and the pen. As subsequent segments within a subpath are drawn, they are connected according to one of three different join styles, (bevel, miter, or round), as set by XrSetLineJoin. Closed subpaths are also joined at the closure point. Unclosed subpaths have one of three different cap styles, (butt, square, or round), applied at either end of the path. The cap style is set with the XrSetLineCap function. Figure~\ref{fig:caps_joins} demonstrates the three possible cap and join styles. The source code for this figure (Figure~\ref{fig:caps_joins_source}) demonstrates the use of XrSetLineJoin and XrSetLineCap as well as XrTranslate, XrSave, and XrRestore. \begin{figure}[htbp] \begin{center} \epsfxsize=2in \epsfbox{examples/caps_joins} \caption{Demonstration of cap and join styles} \label{fig:caps_joins} \end{center} \end{figure} \subsection{Path Filling} \label{sec:path_filling} XrFill fills the area on the ``inside'' of the current path. Xr can apply either the winding rule or the even-odd rule to determine the meaning of ``inside''. This behavior is controlled by calling XrSetFillRule with a value of either XrFillRuleWinding or XrFillRuleEvenOdd. Figure~\ref{fig:stars} demonstrates the effect of the fill rule given a star-shaped path. With the winding rule the entire star is filled in, while with the even-odd rule the center of the star is considered outside the path and is not filled. Figure~\ref{fig:stars_source} contains the source code for this example. \begin{figure}[htbp] \begin{center} \epsfxsize=2in \epsfbox{examples/stars} \caption{Demonstration of the effect of the fill rule} \label{fig:stars} \end{center} \end{figure} \subsection{Controlling Accuracy} The graphics rendering of Xr is carefully implemented to allow all rendering approximations to be performed within a user-specified error tolerance, (within the limits of machine arithmetic of course). The XrSetTolerance function allows the user to specify a maximum error in units of device pixels. The tolerance value has a strong impact on the quality of rendered splines. Empirical testing with modern displays reveals that errors larger than 0.1 device pixels are observable. The default tolerance value in Xr is therefore 0.1 device pixels. The user can increase the tolerance value to tradeoff rendering accuracy for performance. Figure~\ref{fig:splines_tolerance} displays the same curved path rendered several times with increasing tolerance values. Figure~\ref{fig:splines_tolerance_source} contains the source code for this figure. \begin{figure}[htbp] \begin{center} \epsfxsize=2in \epsfbox{examples/splines_tolerance} \caption{Splines drawn with tolerance values of .1, .5, 1, 5, and 10} \label{fig:splines_tolerance} \end{center} \end{figure} \subsection{Paint} \label{sec:paint} The example renderings shown so far have all used opaque ``paint'' as the source color for all drawing operations. The color of this paint can be controlled with the XrSetRGBColor function. Xr supports more interesting possibilities for the paint used in graphics operations. First, the source color need not be opaque; the XrSetAlpha function establishes an opacity level for the source paint. The alpha value ranges from 0 (transparent) to 1 (opaque). When Xr graphics operations combine translucent surfaces, there are a number of different ways in which the source and destination colors can be combined. Xr provides support for all of the Porter/Duff compositing operators as well as the extended operators defined in the X Render Extension. The desired operator is selected by calling XrSetOperator before compositing. The default operator value is XrOperatorOver corresponding to the Porter/Duff OVER operator. Finally, the XrSetPattern function allows any XrSurface to be installed as a static or repeating pattern to be used as the ``paint'' for subsequent graphics operations. The pattern surface may have been initialized from an external image source or may have been the result of previous Xr graphics operations. Figure~\ref{fig:outline} was created by first drawing small, vertical black and white rectangles onto a 3X2 surface. This surface was then scaled, filtered, and used as the pattern for 3 XrFill operations. This demonstrates an efficient means of generating linear gradients within Xr. \begin{figure}[htbp] \begin{center} \epsfxsize=2.5in \epsfbox{examples/outline} \caption{Outline affects perception of depth from shading, (after an illustration by Isao Watanabe\cite{watanabe}). This example uses XrFill with XrSetPattern} \label{fig:outline} \end{center} \end{figure} \subsection{Images} \label{sec:images} In addition to the vector path support, Xr also supports bitmapped images as primitive objects. Images are transformed, (and optionally filtered), by the CTM in the same manner as all other primitives. In order to display an image, an XrSurface object must first be created for the image, then the surface can be displayed with the XrShowSurface function. XrShowSurface places an image of the given width and height at the origin in user space, so XrTranslate can be used to position the surface. In addition to the CTM, each surface also has its own matrix providing a transformation from user space to image space. This matrix can be used to transform a surface independently from the CTM. The XrShowSurface function has another important use besides allowing the display of external images. When using the Porter/Duff compositing operators, it is often desirable to combine several graphics primitives on an intermediate surface before compositing the result onto the target surface. This functionality is similar to the notion of transparency groups in PDF 1.4 and can be achieved with the following idiom: \begin{scriptsize} \begin{verbatim} XrSave (xrs); XrSetTargetSurface (xrs, surface); /* draw to intermediate surface with any Xr functions */ XrRestore (xrs); XrShowSurface (xrs, surface); \end{verbatim} \end{scriptsize} In this example an intermediate surface is installed as the target surface, and then graphics are drawn on the intermediate surface. When XrRestore is called, the original target surface is restored and the resulting graphics from the intermediate surface are composited onto the original target. This technique can be applied recursively with any number of levels of intermediate surfaces each receiving the results of its ``child'' surfaces before being composited onto its ``parent'' surface. Alternatively, images can be constructed from data external to the Xr environment, acquired from image files, external devices or even the window system. Because the image formats used within Xr are exposed to applications, this kind of manipulation is easy and efficient. @ 1.17 log @Fixed introduction to appendix @ text @d9 2 a10 2 illustrations along with source code sufficient to produce each illustration. d83 1 a83 1 known as ``user space''. These coordinates must be transformed to d88 1 a88 1 The initial matrix is established such that one user unit maps to an d90 1 a90 1 units per meter (~96 DPI) of physical device. This approach attempts to a142 1 a143 1 d163 1 a163 1 segment of the current subpath. All path construction functions both d181 3 a183 3 recent call to XrMoveTo or XrRelMoveTo). Calling XrClosePath is not equivalent to adding the corresponding line segment with XrLineTo or XrRelLineTo. The distinction is that a closed subpath will have a join d229 1 a229 1 Ramshaw and Stolfi~\cite{ramshaw83}. Convolution lends itself to an d231 1 a231 1 within an arbitrarily small error bound by simply using a piece-wise d284 6 a289 7 The tolerance value has a strong impact on the quality of antialiased splines. Empirical testing with modern displays revealed that users could detect errors as larger than 0.1 device pixels The default tolerance in Xr is 0.1 device pixels, as errors larger than 0.1 pixels were determined empirically to be noticeable on a 100 DPI display. The user can increase the tolerance value to tradeoff d291 1 a291 1 display the same curved path rendered several times with increasing d307 2 a308 2 The examples shown so far have all used opaque ``paint'' as the source for all drawing operations. The color of this paint is selected d320 1 a320 1 X Render extension. The desired operator is selected by calling d348 1 a348 1 images as a primitive object. Images are transformed, (and optionally d351 1 a351 1 for the image, then the image can be displayed with the XrShowSurface d371 1 a371 1 XrSetTargetSurface (xrs, intermediate); d373 1 a373 1 any Xr operations */ d387 1 a387 1 surfaces before being composited into its ``parent'' surface. @ 1.16 log @Add lame prose to fix formatting @ text @d2 1 @ 1.15 log @Stick verbatim in its own paragraph to avoid spacing troubles @ text @d391 4 a394 1 @ 1.14 log @Reordered paragraphs to moved nested block figure @ text @d369 1 d380 1 @ 1.13 log @Fixed placement of Hering figure @ text @d179 11 a204 11 Finally, XrClosePath closes the current subpath. This operation involves adding a straight line segment from the current point to the initial point of the current subpath, (ie. the point specified by the most recent call to XrMoveTo or XrRelMoveTo). Calling XrClosePath is not equivalent to adding the corresponding line segment with XrLineTo or XrRelLineTo. The distinction is that a closed subpath will have a join at the junction of the final coincident point while an unclosed path will have caps on either end of the path, (even if the two ends happen to be coincident). See Section~\ref{sec:path_stroking} for more discussion of caps and joins. @ 1.12 log @Added implementation @ text @a69 3 With the XrState object created and initialized with a rendering target, Xr is ready to accept drawing commands. a77 6 Sections~\ref{sec:transformations}-\ref{sec:images} provide examples that build on this initial program. Each example consists of a single function that accepts an XrState pointer and performs drawing operations. Each example can be made into a complete program by simply adding the new function call to the program of Figure~\ref{fig:source_minimal}. a96 5 Initially, the CTM in Xr is an identity matrix, so user space will initially align with device space, (with the origin at the upper-left corner of the surface, the X axis increasing to the right, and the Y axis increasing down). a104 4 In Figure~\ref{fig:hering}, each of the radial lines was drawn using identical path coordinates. The different angles were achieved by calling XrRotate before drawing each line. The source code for this image is in Figure~\ref{fig:hering_source}. d113 4 @ 1.11 log @Added citations for the three illusions @ text @d61 4 a64 5 target surface to receive the resulting graphics. Xr has the potential to support any of several different types of graphics targets as supported by the Xc backend. Currently, Xr/Xc have support for rendering to in-memory images as well as to any X Window System ``drawable'', (eg. a window or a pixmap). @ 1.10 log @Added reference to convolution. Added prose around the penguin figures. Added references for artwork by Larry Ewing and Simon Budig and the GIMP. Removed long (and incomplete) source code for gradient example. @ text @d128 1 a128 1 \caption{Hering illusion: Radial lines positioned with XrTranslate and XrRotate} d205 1 a205 1 \caption{Nested box illusion---constructed with XrMoveTo and XrRelLineTo} a291 7 % XXX: How do we want to attribute the illusions? % I found the spiral in Al Seckel's ``The Great Book of Optical Illusions'' (Firefly Books Ltd., 2002, Buffalo, New York) page 29. % The Hering illusion is due to Ewald Hering (1861) also in Seckel page 134. % The shape-from-shading illusion is Isao Watanabe, (he calls it ``3-D Shape and Outline''). % It's in Seckel page 286 and on Watanabe's web site: % http://www.let.kumamoto-u.ac.jp/watanabe/Watanabe-E/Illus-E/3D-E/index.html d356 1 a356 1 \caption{An example showing XrFill with XrSetPattern used to create a gradient} @ 1.9 log @Added reference to Hering figure with source code. (Had to implement this twice as I screwed up and let cvsup blow away my change the first time) @ text @d97 1 a97 1 The initial matix is established such that one user unit maps to an d99 1 a99 1 units per meter (~96DPI) of physical device. This approach attempts to d241 15 a255 8 XrStroke draws the outline formed by stroking the path with a pen of the current line width. The line width is set with the XrSetLineWidth function. As subsequent segments within a subpath are drawn, they are connected according to one of three different join styles, (bevel, miter, or round), as set by XrSetLineJoin. Closed subpaths are also joined at the closure point. Unclosed subpaths have one of three different cap styles, (butt, square, or round), applied at either end of the path. The cap style is set with the XrSetLineCap function. d323 1 a323 1 \caption{Spline drawn with tolerance of .1, .5, 1, 5, and 10} d331 1 a331 1 The exampless shown so far have all used opaque ``paint'' as the d358 1 a358 2 within Xr. The source for this image can be seen in Figure~\ref{fig:outline_source}. d373 1 a373 1 filtered), by the CTM in the same manner as all othere primitives. In @ 1.8 log @Added paint and images sections. Added source for gradient example. @ text @d120 13 d218 1 a218 1 to be coincident). See Section~\ref{sec:path_drawing} for more a234 3 \subsection{Path Drawing} \label{sec:path_drawing} d238 3 d263 3 d385 1 a385 1 \begin{small} d394 1 a394 1 \end{small} a403 9 \begin{figure}[htbp] \begin{center} \epsfxsize=1in \epsfbox{examples/hering} \caption{Example showing XrTranslate, XrRotate and XrSetLineWidth} \label{fig:line_width_example} \end{center} \end{figure} @ 1.7 log @Added source code for splines figure. Removed \texttt from function names. @ text @d82 1 a82 1 Sections~\ref{sec:transformations}-\ref{sec:paint} provide examples d305 2 a306 1 \subsection{Images} d308 37 a344 1 XXX: Discuss XrShowSurface d346 2 a347 2 \subsection{Paint} \label{sec:paint} d349 39 a387 1 XXX: Discuss XrSetRGBColor, XrSetAlpha, XrSetOperator, XrSetPattern a397 8 \begin{figure}[htbp] \begin{center} \epsfxsize=2.5in \epsfbox{examples/outline} \caption{Example showing XrSetPattern and XrFill} \label{fig:fill_example} \end{center} \end{figure} @ 1.6 log @Fixed description of default matrix. Added description of XrSetTolerance. Fixed some minor things in the introduction. @ text @d82 1 a82 1 Sections~\ref{sec:transformations}-\ref{sec:patterns} provide examples d293 2 a294 1 tolerance values. @ 1.5 log @Several minor edits to API section @ text @d3 3 d97 10 d177 1 a177 1 current point to the point specified. XrCurveTo adds a cubic Bezier d276 37 a320 3 \subsection{Using Patterns} \label{sec:patterns} @ 1.4 log @Added some figure references. Added stars example @ text @d64 3 a66 4 Figure~\ref{fig:source_minimal} includes a call to XrSetTargetImage to direct graphics to an array of bytes arranged as 4-byte ARGB pixels (alpha, red, green, and blue). Xr provides a similar call, XrSetTargetDrawable, to direct graphics to an X drawable. d72 6 a77 7 XrDestroy. At this point Xr frees any data remaining within the XrState object, and it becomes invalid for the program to use the value of the XrState pointer, (unless a new object is created by calling XrCreate). The results of any graphics operations are still available on the target surface, and the program can access that surface as appropriate, (eg. write the image to a file, display the graphics on the screen, etc.). d101 5 a105 4 functions XrTranslate, XrScale, and XrRotate. XrConcatMatrix will compose a given matrix into the current CTM and XrSetMatrix will directly set the CTM to a given matrix. The XrDefaultMatrix function can be used to restore the CTM to its original state. d110 3 a112 3 state parameters in a hierarchical fashion. For example, a program may traverse a tree of objects to be drawn modifying the CTM, current color, line width, etc. at each level of the hierarchy. d114 1 a114 1 Xr supports this hierarchical approach to graphics by maintaing a d119 2 a120 2 state object off of the stack restoring the graphics state to its state before the last XrSave operation. d123 3 a125 1 drawing functions can be written with the following style: d137 1 d156 6 a161 6 Xr provides several functions for constructing paths. XrNewPath clears the current path, discarding any previously defined path. The first path construction called after XrNewPath should be XrMoveTo which simply moves the current point to the point specified. It is also valid to call XrMoveTo when the current path is non-empty in order to begin a new subpath. d164 1 a164 1 current point to the point specified. XrCurveTo adds a cubic bezier d169 1 a169 1 from the current point rather than as aboslute coordinates. To allow d184 1 a184 1 Finally, XrClosePath closes the current subpath. This operations d186 1 a186 1 initial point of the current subpath, (ie. point specified by the most d197 1 a197 1 to \texttt{XrRectangle(xrs, x, y, width, height)} is equivalent to the d199 1 d207 1 d219 1 a219 1 miter, or round), as set by the XrSetLineJoin. Closed subpaths are d225 2 a226 2 join styles. The source code for this figure (see Figure~\ref{fig:caps_joins_source}) demonstrates the use of d237 5 a241 4 XrFill fills the area on the ``inside'' of the current path. Xr allows either the winding rule or the even-odd rule to be used to determine the area inside the path. This behavior is controlled by calling XrSetFillRule with a value of XrFillRuleWinding or XrFillRuleEvenOdd. @ 1.3 log @Spewed some text on how to use the API @ text @d81 1 a81 1 Sections~\ref{sec:path_example}-\ref{sec:pattern_example} provide examples d88 1 d112 1 a112 1 traverse a tree of objects to be drawn, modifying the CTM, current d126 2 a127 1 void draw_something (XrState *xrs) d141 1 a141 1 XrSave/XrRestore calls in this case. Figure~\ref{fig:caps_joins_code} d169 12 d190 1 a190 1 to be coincident). See Section~\ref{sec:caps_joins_example} for more d206 1 d220 13 d238 5 a242 8 Figure~\ref{fig:spiral_code} shows an example of code using XrMoveTo and XrRelLineTo to construct a spiral-shaped path. XrStroke is used to draw the outline of this path. Figure~\ref{fig:spiral_result} shows the result of this code, (a figure that appears to be several nested squares but is in fact a single continuous path). % And yes, I'm having too much fun drawing optical illusions. d245 3 a247 4 \epsfxsize=2in \epsfbox{examples/spiral} \caption{Example showing XrStroke} \label{fig:spiral_result} a259 8 \epsfxsize=2in \epsfbox{examples/caps_joins} \caption{Example showing cap and join styles} \label{fig:caps_joins_result} \end{center} \end{figure} \begin{figure}[htbp] \begin{center} d268 1 a268 1 \label{sec:pattern_example} @ 1.2 log @Added Hering illusion which has XrSetLineWidth @ text @d1 1 a1 1 \section{API} d3 214 a216 1 % Yes, I'm having too much fun drawing optical illusions d223 16 a238 1 \label{fig:stroke_example} d246 1 a246 1 \caption{Example showing XrSetLineWidth and XrStroke} d250 3 @ 1.1 log @Added a couple of figures along with their example code @ text @d3 2 d8 1 a8 1 \epsfbox{figures/spiral} d16 12 a27 3 \epsfxsize=2in \epsfbox{figures/outline} \caption{Example showing XrFill and XrSetPattern} @