rsalz@bbn.com (Rich Salz) (06/14/88)
Submitted-by: Craig Dunwoody <dunwoody@lurch.stanford.edu> Posting-number: Volume 15, Issue 69 Archive-name: gbench/part02 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 2 (of 2)." # Contents: gbench.man ops.c # Wrapped by rsalz@fig.bbn.com on Mon Jun 13 15:32:52 1988 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'gbench.man' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'gbench.man'\" else echo shar: Extracting \"'gbench.man'\" \(17835 characters\) sed "s/^X//" >'gbench.man' <<'END_OF_FILE' X.TH GBENCH 1 "1 March 1988" "InterViews" "InterViews Reference Manual" X.SH NAME Xgbench \- graphics benchmark X.SH SYNOPSIS X\fBgbench\fP [-\fIcommandname\fP [\fIparameters\fP]]* X.SH DESCRIPTION X\fIgbench\fP is a graphics benchmark tool. It currently supports 2D Ximmediate-mode graphics and runs on top of the X Window System, both Version 10 Xand Version 11. It is written in C and it directly calls the low-level window Xsystem client library; no toolkit is used. X.PP XWhen \fIgbench\fP starts, it creates a window and begins processing Xcommands. You may supply any number of commands as arguments to the Xprogram. Once these commands have been processed, commands are read from Xstandard input, one per line. Each command directs \fIgbench\fP to Xrepeatedly perform a particular drawing operation. \fIgbench\fP copies the Xcommand to the outfile (default: standard output), executes the command, Xand prints on the outfile the host load average, the time for each Xiteration, and the number of iterations per second. X.PP XAll times are measured in real (wall-clock) time. You should establish that Xthe host(s) and network (if used) are unloaded so that valid numbers may be Xobtained. X.PP XWhen \fIgbench\fP performs a sequence of drawing operations, each operation Xis shifted by one pixel in x and y from the previous one. This shifting Xgoes back and forth over a user-definable range (default: 32 pixels), the Xintent being to average out the effects of pixel alignment in the frame Xbuffer. Pixel alignment can affect the performance of many graphics Xsystems, both low-end memory-mapped frame buffers and high-end systems with Xinterleaved pixel processors. X.PP XYou can use \fIgbench\fP either interactively, by typing Xcommands and viewing the results immediately, or in batch mode, Xwith standard input redirected to a script file and output Xredirected to a log file. To avoid cluttering up the log when Xoutput is redirected to a file, certain outputs that are only useful in Xinteractive use are directed to standard error rather than the outfile. X.PP X\fBCommands\fP X.PP XEach command consists of a command name followed by zero or more optional Xparameters separated by white space. You may abbreviate command names to Xtheir smallest unique prefix. Ambiguous command names are resolved to the Xfirst matching name. Any command name may be prefixed with the @ character, Xwhich forces all output from the command to standard error rather than Xthe outfile. This is useful for preventing selected commands from Xgoing into a log file. X.PP XThe optional parameters consist of zero or more positional parameters of the Xform \fIvalue\fP, followed by zero or more keyword parameters of the form X\fIname\fP=\fIvalue\fP. Each positional parameter has a name and may be Xspecified in keyword form as well. The positional form is more convenient Xfor interactive input, while the keyword form is more suited for creating Xself-documenting script files. X.PP XTo provide values for parameters that are not specified in a command, X\fIgbench\fP maintains a set of global defaults that may be displayed and Xchanged using the 'default' command. Each default value has a name and may Xbe overridden in a command using a \fIname\fP=\fIvalue\fP parameter. XThe names of all global default values are given below. The X'init' command restores all global defaults to their initial values. X.PP XThe first positional parameter for each command is \fIopts\fP. It is a Xcomma-separated list of option flags, the meanings of which are described Xbelow. Option flags may be supplied in any order. If the \fIopts\fP Xparameter is given in positional form, the global default option list is Xprepended to the given list; if it is given in keyword form, the given Xlist is used as is, overriding the global default option list. X.PP XThe commands are: X.TP Xarc [\fIopts\fP] [\fIsize\fP] [\fIaspect\fP] [\fIangle\fP] [\fIlwidth\fP] [\fIname\fP=\fIvalue\fP]* XDraws an arc of an ellipse. The ellipse is drawn in a bounding box with an Xarea of \fIsize\fP squared pixels and a height/width ratio of \fIaspect\fP. XThe default value of \fIaspect\fP is 1.0, yielding a circular arc. XThe arc begins at the 3 o'clock position and continues counterclockwise for X\fIangle\fP degrees. This command works only in the X11 version. X.TP Xblit [\fIopts\fP] [\fIsize\fP] [\fIoffset\fP] [\fIname\fP=\fIvalue\fP]* XCopies a square area of the window, \fIsize\fP pixels on a side, to Xan area offset by \fIoffset\fP*\fIsize\fP pixels. The default value for X\fIoffset\fP is 0.5. X.TP Xmap [\fIopts\fP] [\fIsize\fP] [\fInwin\fP] [\fIname\fP=\fIvalue\fP]* XMaps and then unmaps \fInwin\fP square subwindows, each \fIsize\fP Xpixels on a side. X.TP Xnop [\fIopts\fP] [\fIname\fP=\fIvalue\fP]* XPerforms a window server no-op. This command works only in the X11 version. X.TP Xpoint [\fIopts\fP] XDraws a point. This command works only in the X11 version. X.TP Xpoly [\fIopts\fP] [\fIsize\fP] [\fInvert\fP] [\fIlwidth\fP] [\fIname\fP=\fIvalue\fP]* XDraws a polygon with the specified number of vertices and linewidth, Xinscribed in a circle of radius \fIsize\fP pixels. X.TP Xrect [\fIopts\fP] [\fIsize\fP] [\fIlwidth\fP] [\fIname\fP=\fIvalue\fP]* XDraws an axis-aligned square, \fIsize\fP pixels on a side, with the specified Xlinewidth. X.TP Xtext [\fIopts\fP] [\fInchar\fP] [\fIptsize\fP] [\fIname\fP=\fIvalue\fP]* XDraws a text string with the specified number of characters, at the Xspecified point size. The closest available point size is chosen. X.TP Xvec [\fIopts\fP] [\fIsize\fP] [\fIangle\fP] [\fIlwidth\fP] [\fIname\fP=\fIvalue\fP]* XDraws a vector \fIsize\fP pixels long, with the specified linewidth and Xangle (given in degrees counterclockwise from the 3 o'clock position). X.TP Xconfig XPrints the host name, display name, window system version, current time, Xand tag (see below) on the outfile. X.TP Xdefaults [\fIname\fP=\fIvalue\fP]* XPrints the defaults on standard error and optionally changes them. The Xnames of the default values are given below. X.TP Xhelp XPrints a help message on the outfile listing the available commands and Xoption flags. X.TP Xinit XRestores all defaults to their initial value, and prints the updated Xset of values on standard error. X.TP Xscript [\fIfilename\fP] XRun the given script file, which may itself use the 'script' command. If Xno file is given, the built-in script is run. X.TP Xquit XExits \fIgbench\fP. X.TP X! XRepeat: Re-issue the previous drawing command, with parameters defaulting Xto the values used when that command was executed, rather than to the global Xdefault values. Positional and keyword parameters for the command may be Xgiven in the normal manner to override the defaults. As usual, if the X\fIopts\fP parameter is given in positional form, the default option Xlist is prepended to the given list, whereas if it is given in keyword Xform, the given list overrides the default option list. X.TP X# XComment: causes \fIgbench\fP to write the rest of the command to Xthe outfile. This is useful for putting comments in script files. After Xechoing and executing each command, \fIgbench\fP writes a result line Xto the outfile. Since each result line begins with the comment Xcharacter, \fIgbench\fP output logs are also valid \fIgbench\fP input Xscripts. You can run a log through \fIgbench\fP several times using Xdifferent hardware configurations. In the resulting log, each command Xwill be followed by a series of result lines, one for each configuration. X.PP X\fBOptions\fP X.PP XThe option flags are as follows: X.TP 8 Xac XAlternate the drawing color between black and white on each drawing Xoperation. This measures the effect of changing one element of the Xgraphics state for each drawing operation. X.TP Xaf XUse a separate text item, with its own font identifier, for each character Xin the 'text' command. The same font is used for all characters. This Xoption works only in the X11 version. X.TP Xag XAlternate the graphics context on each drawing operation. The two graphics Xcontexts used are identical except that one draws with white and the other Xdraws with black. The ac and ag flags can be used to compare the cost of Xchanging one element of the graphics state with the cost of swapping the Xentire graphics state. X.TP Xaw XAlternate windows on each drawing operation. This flag makes it possible Xto measure the performance impact of context-switching between windows. XIt is important to keep this overhead low in order to support applications Xthat do real-time drawing in multiple windows simultaneously. X.TP Xd XDragging. You are prompted to move the mouse around in the window while Xholding down a mouse button. Every time a mouse motion event is received, X\fIgbench\fP draws a background-color rectangle to erase the results of the Xprevious drawing operations, then performs one drawing iteration. This Xoption allows you to measure the frame rate that the system can achieve Xduring interactive animation. X.TP Xf XFill the arc, polygon, or rectangle with a solid color. X.TP Xi XDraw by inverting pixel values rather than painting. This measures Xthe additional cost of reading pixels from the frame buffer before writing. X.TP Xm XMonitor for profiling. Profiling information is accumulated while this Xcommand is executing. If \fIgbench\fP has been compiled and linked for X\fIgprof\fP profiling, this information is written to the file "gmon.out" Xin the current directory when \fIgbench\fP exits. X.TP Xn XNo options. If you choose no options and you supply \fIopt\fP as Xa positional parameter, you must use the n flag as a placeholder. X.TP Xo XOverlap the object being drawn with a very small window. The overlapping Xwindow is made small to avoid a significant change in the number of pixels Xdrawn. This measures the cost of clipping. X.TP Xos XUse an offscreen pixel map identical in size and depth to the graphics window Xas the source for blits. This option works only in the X11 version. X.TP Xod XUse an offscreen pixel map identical in size and depth to the graphics window Xas the destination for drawing operations. After the command has been Xcompleted and timed, the contents of the offscreen pixel map are blitted Xinto the graphics window so correct drawing can be verified. This option Xworks only in the X11 version. Together, the os and od options allow you Xto measure the performance impact of offscreen rendering and the cost Xof moving pixels to and from offscreen memory. X.TP Xp XPolling. Used in conjunction with the d flag, this flag specifies that X\fIgbench\fP should loop continuously, reading the mouse position and Xperforming a drawing iteration, rather than responding to mouse motion Xevents. This measures the performance difference between polling and Xevent-driven input. X.TP Xps XPolygon self-intersecting. Draw a polygon with the same vertices and number Xof edges as usual, but self-intersecting. \fInvert\fP will be rounded up Xto an odd number if necessary. X.TP Xpw XFill polygons using the non-zero winding number rule rather than the Xdefault even-odd rule. This option works only in the X11 version. X.TP Xr XReset defaults. Copy the set of parameters used in this command to the Xset of global defaults. X.TP Xs XUse a stipple pattern when drawing. The stipple pattern is a bitmap that is Xtessellated over the drawing area. When a drawing operation is performed, Xthe only pixels that are actually drawn are those inside the shape being Xdrawn that correspond to a '1' in the stipple pattern. These pixels are Xdrawn in the foreground color. Stippling is fully supported only in the X11 Xversion. X.TP Xt XUse a tile when drawing. The tile is a pixel map that is tessellated over Xthe drawing area. When a drawing operation is performed, the pixel value Xfor each pixel inside the shape being drawn is obtained from the tile. XWhen the s and t flags are used simultaneously, the stipple pattern is used Xas a tile, with '0' pixels in the stipple pattern selecting the background Xcolor and '1' pixels selecting the foreground color. This combination works Xonly in the X11 version. X.TP Xu XUnbatched. Normally the window system client library will batch many Xrequests into a single message to the window server in order to minimize Xcommunication overhead. This option causes the client's request buffer Xto be flushed after each operation, thereby preventing batching. This Xmakes it possible to directly measure the performance benefit of batching. X.PP X\fBGlobal defaults\fP X.PP XThe following global defaults may be displayed and set using the 'defaults' Xcommand: X.TP 8 Xtimegoal XWhen a command is executed, \fIgbench\fP should repeat the drawing Xoperation under test enough times to get an accurate measurement of its Xcost, but not so many times that the command takes an inordinate amount of Xtime to execute. \fIgbench\fP allows you to specify a time goal, which Xis the number of seconds that each command should take to execute (default: X1). \fIgbench\fP performs as many iterations as are necessary to reach Xthis goal. Setting timegoal to 0 forces \fIgbench\fP to execute a Xsingle iteration. X.TP Xcount XSpecifies the number of times to perform the primitive drawing operation Xon \fIeach\fP iteration. This defines the unit of work being measured. XFor example, to measure the time it takes to draw a 1000-polygon object, Xgive the command 'p count=1000' and \fIgbench\fP will repeatedly draw X1000 polygons. To get the feel of dragging around a 1000-polygon object, Xgive the command 'p d count=1000' and \fIgbench\fP will draw 1000 polygons Xevery time the mouse moves. If you want exact control over the number Xof drawing operations executed for each command, set \fItimegoal\fP to 0 Xand set \fIcount\fP as desired. X.TP Xangle XThe angle in degrees used for the 'arc' and 'vec' commands. X.TP Xaspect XA floating point value representing the height to width ratio of the Xbounding box for the 'arc' command. The default value is 1.0, which Xyields circular arcs. X.TP Xfont XA comma-separated list of font names for \fIgbench\fP to load. XIn the X11 version, each name may contain the wild-card characters * and ?. XA maximum of 16 fonts may be loaded. X.TP Xptsize XThe font size, given in points, used in the 'text' command. X.TP Xlwidth XThe line width used in the drawing operations. X.TP Xmaxshift XEach drawing operation is shifted by one pixel in x and y from the previous Xoperation. The shifting goes back and forth over a range of \fImaxshift\fP Xpixels. X.TP Xoffset XThe 'blit' command multiplies the size of the square being blitted by this Xfloating point value to determine how far to move it. The default value Xis 0.5, which causes the destination square to overlap the source square. X.TP Xnchar XThe length in characters of the string drawn by the 'text' command. X.TP Xnwin XThe number of windows mapped by the 'map' command. X.TP Xnvert XThe number of vertices drawn by the 'poly' command. X.TP Xopts XThe option list that is prepended to the option list that is given as Xthe first positional parameter of a command. It can be used to run scripts X(including the built-in script) with different lists of options. X.TP Xoutfile XThe name of the file that output is appended to (default: standard output). X.TP Xsize XThe size in pixels of the objects drawn by the various drawing commands. X.TP Xtag XAn uninterpreted string that is included in the output of the 'config' Xcommand and at the beginning of each result line. It is useful for Xassociating each result line with a named configuration when a log file is Xrun through \fIgbench\fP several times to accumulate result lines for Xdifferent configurations. For example: X Xgbench -@d tag=configname <oldlog >newlog X XNote the use of the '@' on the 'defaults' command to prevent the tag-setting Xcommand from going into the log. A suggested tag format is a quadruple of Xthe form X X<\fIrcpu\fP>.<\fIlcpu\fP>.<\fIwsys\fP>.<\fIgxsys\fP> X Xwhere \fIrcpu\fP is the type of the remote CPU running \fIgbench\fP (if any), X\fIlcpu\fP is the type of the local CPU running the window server, \fIwsys\fP Xis the name of the window system, and \fIgxsys\fP is the type of graphics Xhardware being used. Each of these components can be encoded in two or three Xcharacters. X.TP Xwinsize XThe edge length (in pixels) of the square drawing window. X.SH VERSION XThis documentation applies to Version 1.0 of \fIgbench\fP. X.SH BUGS XThere is apparently a bug in the beta release of the awm window manager Xfor X11R2 that causes the "map" command to hang \fIgbench\fP. For this Xreason, we have removed "map" from the default script. We have not Xfound this problem under any of the other X11R2 window managers, including Xthe standard uwm. X.SH EXTENSIONS XDifferent drawable depths should be supported. 3D graphics and image Xprocessing operations should be supported when they become available. XFilters should be written to combine and format raw log files. X.SH AUTHOR X\fIgbench\fP is being developed by Craig Dunwoody and Mark Linton at Stanford XUniversity's Computer Systems Lab under the Quantum project, through a gift Xfrom Digital Equipment Corporation. X.SH ADDRESS XPlease send any comments, bugfixes, scripts, or results to: X XInternet: gbench@lurch.stanford.edu X XUSEnet: {ucbvax,decvax}!decwrl!lurch.stanford.edu!gbench X X.SH COPYRIGHT X Copyright (c) 1988 by The Board of Trustees X of the Leland Stanford Junior University. X X Permission to use, copy, modify, and distribute this X software and its documentation for any purpose and without X fee is hereby granted, provided that the above copyright X notice appear in all copies and that both that copyright X notice and this permission notice appear in supporting X documentation, and that the name of Stanford not be used in X advertising or publicity pertaining to distribution of the X software without specific, written prior permission. X X Stanford makes no representations about the suitability of X this software for any purpose. The Software is provided "as is" X without express or implied warranty. END_OF_FILE if test 17835 -ne `wc -c <'gbench.man'`; then echo shar: \"'gbench.man'\" unpacked with wrong size! fi # end of 'gbench.man' fi if test -f 'ops.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'ops.c'\" else echo shar: Extracting \"'ops.c'\" \(10777 characters\) sed "s/^X//" >'ops.c' <<'END_OF_FILE' X#include <gbench.h> X Xvoid StartArc(sp,cp) X State* sp; X Cmd* cp; X{ X double adjust; X int area = cp->p.size*cp->p.size; X int origin; X double theta; X X cp->size[0] = sqrt(area/cp->p.aspect); X cp->size[1] = sqrt(area*cp->p.aspect); X if (cp->p.aspect!=1.) { X theta = cp->p.angle*Pi/180; X if (theta<(Pi/2)) adjust = 0.; X else if (theta<(3*Pi/2)) adjust = Pi; X else adjust = 2*Pi; X theta = atan(tan(theta)/cp->p.aspect)+adjust; X cp->size[2] = theta*180/Pi*64; X } X else cp->size[2] = cp->p.angle*64; X origin = Border+cp->p.lwidth; X cp->x = cp->y = Border; X cp->bbx = cp->size[0]+2*cp->p.lwidth; X cp->bby = cp->size[1]+2*cp->p.lwidth; X if (cp->o.fill) { X MoveClip( X sp,cp,cp->x+cp->bbx/2-OverlapSize,cp->y+cp->bby/2-OverlapSize X ); X } X else MoveClip(sp,cp,cp->x,cp->y+cp->bby/2); X Start(sp,cp); X} X Xvoid DoArc(sp,cp) X State* sp; X Cmd* cp; X{ X int i; X int x = cp->x+cp->p.lwidth; X int y = cp->y+cp->p.lwidth; X X for (i=0;i<cp->p.count;i++) { X StartIteration(sp,cp); X# ifdef X11 X if (cp->o.fill) { X XFillArc( X sp->d,cp->dest,cp->gc,x,y,cp->size[0],cp->size[1],0, X cp->size[2] X ); X } X else { X XDrawArc( X sp->d,cp->dest,cp->gc,x,y,cp->size[0],cp->size[1],0, X cp->size[2] X ); X } X# endif X11 X } X} X Xvoid StartBlit(sp,cp) X State* sp; X Cmd* cp; X{ X Pixel colorfg; X int i; X X Start(sp,cp); X cp->bbx = cp->bby = 0; X colorfg = cp->colorfg; X MoveClip(sp,cp,Border+cp->p.size/2,Border+cp->p.size/2); X for (i=0;i<2;i++) { X StartIteration(sp,cp); X# ifdef X10 X XPixFill( X cp->w,Border,Border,cp->p.size,cp->p.size,colorfg,0,cp->func, X AllPlanes X ); X# else X XFillRectangle( X sp->d,cp->src,sp->gc1,Border,Border,cp->p.size,cp->p.size X ); X# endif X } X cp->x = cp->y = Border; X cp->size[0] = cp->p.offset*cp->p.size; X} X Xvoid DoBlit(sp,cp) X State* sp; X Cmd* cp; X{ X XEvent e; X int i; X XGraphicsExposeEvent* xep; X X# ifdef X10 X xep = (XGraphicsExposeEvent*)&e; X# else X xep = &e.xgraphicsexpose; X# endif X for (i=0;i<cp->p.count;i++) { X StartIteration(sp,cp); X# ifdef X10 X XCopyArea( X cp->w,Border,Border,cp->x+cp->size[0],cp->y+cp->size[0], X cp->p.size,cp->p.size,cp->func,AllPlanes X ); X if (cp->o.overlap) do { X XMaskEvent(ExposeRegion|ExposureMask,&e); X if (e.type==ExposeRegion) { X XPixFill( X cp->w,xep->x,xep->y,xep->width,xep->height,cp->colorfg, X 0,cp->func,AllPlanes X ); X } X } while (e.type!=ExposureMask); X# else X XCopyArea( X sp->d,cp->src,cp->dest,cp->gc,Border,Border,cp->p.size, X cp->p.size,cp->x+cp->size[0],cp->y+cp->size[0] X ); X if (cp->o.overlap) do { X XMaskEvent(sp->d,ExposureMask,&e); X if (e.type==GraphicsExpose) { X XFillRectangle( X sp->d,cp->dest,cp->gc,xep->x,xep->y,xep->width, X xep->height X ); X } X } while ((e.type==GraphicsExpose)&&xep->count); X# endif X } X} X Xvoid StartMap(sp,cp) X State* sp; X Cmd* cp; X{ X int wheight; X int i; X int ncols = _DisplayWidth/cp->p.size; X# ifdef X11 X XSetWindowAttributes swa; X# endif X11 X X cp->x = cp->y = cp->bbx = cp->bby = 0; X cp->p.nwin = Limit(cp->p.nwin,1,ncols*_DisplayHeight/cp->p.size); X cp->o.altwin = false; X wheight = cp->p.size*(1+cp->p.nwin/ncols); X Start(sp,cp); X UnmapWin(sp,cp->w); X cp->w = XCreateSimpleWindow( X DARGC _RootWindow,0,0,_DisplayWidth,wheight,1,WhitePixmap,BlackPixmap X ); X for (i=0;i<cp->p.nwin;i++) { X XCreateSimpleWindow( X DARGC cp->w,cp->p.size*(i%ncols),cp->p.size*(i/ncols),cp->p.size, X cp->p.size,1,WhitePixmap,BlackPixmap X ); X } X# ifdef X11 X swa.override_redirect = 1; X XChangeWindowAttributes(sp->d,cp->w,CWOverrideRedirect,&swa); X# endif X11 X XRaiseWindow(DARGC cp->w); X XMapWindow(DARGC cp->w); X XSelectInput(DARGC cp->w,InputMask(cp)); X} X Xvoid DoMap(sp,cp) X State* sp; X Cmd* cp; X{ X int i; X X for (i=0;i<cp->p.count;i++) { X XMapSubwindows(DARGC cp->w); X XUnmapSubwindows(DARGC cp->w); X } X} X Xvoid FinishMap(sp,cp) X State* sp; X Cmd* cp; X{ X Finish(sp,cp); X XUnmapWindow(DARGC cp->w); X XDestroyWindow(DARGC cp->w); X cp->w = sp->w1; X MapWin(sp,cp->w); X XFlush(DARG); X} X Xvoid DoNop(sp,cp) X State* sp; X Cmd* cp; X{ X int i; X X# ifdef X11 X for (i=0;i<cp->p.count;i++) XNoOp(sp->d); X# endif X11 X} X Xvoid StartPoint(sp,cp) X State* sp; X Cmd* cp; X{ X cp->x = cp->y = Border; X cp->bbx = cp->bby = 1; X MoveClip(sp,cp,cp->x,cp->y); X Start(sp,cp); X} X Xvoid DoPoint(sp,cp) X State* sp; X Cmd* cp; X{ X int i; X X# ifdef X11 X for (i=0;i<cp->p.count;i++) { X StartIteration(sp,cp); X XDrawPoint(sp->d,cp->dest,cp->gc,cp->x,cp->y); X } X# endif X} X Xvoid StartPoly(sp,cp) X State* sp; X Cmd* cp; X{ X int fillrule; X int i; X int index; X int origin = Border+cp->p.lwidth; X int r = cp->p.size/2; X double theta; X X if (cp->o.polyself) cp->p.nvert = cp->p.nvert/2*2+1; X theta = 2*Pi/cp->p.nvert; X cp->x = cp->y = Border; X cp->bbx = cp->bby = cp->p.size+2*cp->p.lwidth; X for (i=0;i<=cp->p.nvert;i++) { X index = cp->o.polyself?(i*(cp->p.nvert/2))%cp->p.nvert:i; X sp->v[i].x = origin+r*(1+cos(PolyAngle+index*theta)); X sp->v[i].y = origin+r*(1-sin(PolyAngle+index*theta)); X } X# ifdef X10 X sp->v[0].flags = VertexStartClosed; X for (i=1;i<cp->p.nvert;i++) sp->v[i].flags = 0; X sp->v[cp->p.nvert].flags = VertexEndClosed; X# else X fillrule = cp->o.polywind?WindingRule:EvenOddRule; X XSetFillRule(sp->d,sp->gc1,fillrule); X XSetFillRule(sp->d,sp->gc2,fillrule); X# endif X if (cp->o.fill) MoveClip(sp,cp,cp->x+r,cp->x+r); X else MoveClip(sp,cp,sp->v[0].x,sp->v[0].y); X Start(sp,cp); X} X Xvoid DoPoly(sp,cp) X State* sp; X Cmd* cp; X{ X int i; X# ifdef X11 X int shape = cp->o.polyself?Complex:Convex; X# endif X11 X X MoveVert(sp,cp,cp->p.nvert); X for (i=0;i<cp->p.count;i++) { X StartIteration(sp,cp); X# ifdef X10 X X10Draw(sp,cp,cp->p.nvert+1); X# else X if (cp->o.fill) { X XFillPolygon( X sp->d,cp->dest,cp->gc,sp->v,cp->p.nvert,shape, X CoordModeOrigin X ); X } X else { X XDrawLines( X sp->d,cp->dest,cp->gc,sp->v,cp->p.nvert+1,CoordModeOrigin X ); X } X# endif X } X} X Xvoid StartRect(sp,cp) X State* sp; X Cmd* cp; X{ X int i; X int origin = Border+cp->p.lwidth; X X cp->x = cp->y = Border; X cp->bbx = cp->bby = cp->p.size+2*cp->p.lwidth; X# ifdef X10 X for (i=0;i<5;i++) { X sp->v[i].x = origin; X sp->v[i].y = origin; X } X sp->v[1].x += cp->p.size; X sp->v[2].x += cp->p.size; X sp->v[2].y += cp->p.size; X sp->v[3].y += cp->p.size; X sp->v[0].flags = VertexStartClosed; X for (i=1;i<4;i++) sp->v[i].flags = 0; X sp->v[4].flags = VertexEndClosed; X# endif X10 X if (cp->o.fill) MoveClip(sp,cp,cp->x+cp->bbx/2,cp->y+cp->bby/2); X else MoveClip(sp,cp,cp->x,cp->y); X Start(sp,cp); X} X Xvoid DoRect(sp,cp) X State* sp; X Cmd* cp; X{ X int i; X int x = cp->x+cp->p.lwidth; X int y = cp->y+cp->p.lwidth; X X# ifdef X10 X if (!cp->o.fill) MoveVert(sp,cp,5); X# endif X10 X for (i=0;i<cp->p.count;i++) { X StartIteration(sp,cp); X# ifdef X10 X if (cp->o.fill) { X if (cp->o.tile) { X XTileFill( X cp->w,x,y,cp->p.size,cp->p.size,sp->tile,0,cp->func, X AllPlanes X ); X } X else { X XPixFill( X cp->w,x,y,cp->p.size,cp->p.size,cp->colorfg,0,cp->func, X AllPlanes X ); X } X } X else X10Draw(sp,cp,5); X# else X if (cp->o.fill) { X XFillRectangle( X sp->d,cp->dest,cp->gc,x,y,cp->p.size,cp->p.size X ); X } X else { X XDrawRectangle( X sp->d,cp->dest,cp->gc,x,y,cp->p.size,cp->p.size X ); X } X# endif X } X} X Xvoid StartText(sp,cp) X State* sp; X Cmd* cp; X{ X int findex = FontIndex(sp,&cp->p.ptsize); X int i; X X cp->x = cp->y = Border; X Start(sp,cp); X if (findex<0) { X cp->p.ptsize = 0; X cp->fontid = nil; X cp->bbx = cp->bby = 0; X cp->result = NoFonts; X } X else { X# ifdef X10 X cp->p.ptsize = sp->fontinfo[findex]->height; X cp->fontid = sp->fontinfo[findex]->id; X cp->bbx = cp->p.nchar*sp->fontinfo[findex]->width; X cp->bby = sp->fontinfo[findex]->height; X# else X cp->p.ptsize = sp->fontinfo[findex]->ascent; X XSetFont(sp->d,sp->gc1,sp->fontinfo[findex]->fid); X XSetFont(sp->d,sp->gc2,sp->fontinfo[findex]->fid); X cp->fontid = sp->fontinfo[findex]->fid; X cp->size[0] = sp->fontinfo[findex]->max_bounds.ascent; X cp->bbx = cp->p.nchar*sp->fontinfo[findex]->max_bounds.width; X cp->bby = cp->size[0]+sp->fontinfo[findex]->max_bounds.descent; X if (cp->o.altfont) for (i=0;i<cp->p.nchar;i++) { X sp->texts[i].font = cp->fontid; X } X# endif X } X MoveClip(sp,cp,cp->x+cp->bbx/2,cp->y+cp->bby/2); X} X Xvoid DoText(sp,cp) X State* sp; X Cmd* cp; X{ X int i; X X if (cp->result==NoFonts) return; X for (i=0;i<cp->p.count;i++) { X StartIteration(sp,cp); X# ifdef X10 X if (cp->o.tile) { X XTextPad( X cp->w,cp->x,cp->y,sp->outstr,cp->p.nchar,cp->fontid,0,0, X cp->colorfg,cp->colorbg,cp->func,AllPlanes X ); X } X else { X XTextMaskPad( X cp->w,cp->x,cp->y,sp->outstr,cp->p.nchar,cp->fontid,0,0, X cp->colorfg,cp->func,AllPlanes X ); X } X# else X if (cp->o.altfont) { X XDrawText( X sp->d,cp->dest,cp->gc,cp->x,cp->y+cp->size[0],sp->texts, X cp->p.nchar X ); X } X else if (cp->o.tile) { X XDrawImageString( X sp->d,cp->dest,cp->gc,cp->x,cp->y+cp->size[0],sp->outstr, X cp->p.nchar X ); X } X else { X XDrawString( X sp->d,cp->dest,cp->gc,cp->x,cp->y+cp->size[0],sp->outstr, X cp->p.nchar X ); X } X# endif X } X} X Xvoid StartVec(sp,cp) X State* sp; X Cmd* cp; X{ X double theta = cp->p.angle*Pi/180; X int xoffset = cp->p.lwidth*Sign(cos(theta)); X int yoffset = cp->p.lwidth*Sign(-sin(theta)); X int xorigin = sp->winsize/2; X int yorigin = sp->winsize/2; X X# ifdef X10 X sp->v[0].flags = 0; X sp->v[1].flags = 0; X# endif X10 X cp->x = xorigin; X cp->y = yorigin; X xorigin += xoffset; X yorigin += yoffset; X cp->bbx = cp->p.size*cos(theta); X cp->bby = cp->p.size*-sin(theta); X sp->v[0].x = xorigin; X sp->v[0].y = yorigin; X sp->v[1].x = xorigin+cp->bbx; X sp->v[1].y = yorigin+cp->bby; X cp->bbx += 2*xoffset; X cp->bby += 2*yoffset; X cp->o.fill = false; X MoveClip(sp,cp,cp->x+cp->bbx/2,cp->y+cp->bby/2); X Start(sp,cp); X} X Xvoid DoVec(sp,cp) X State* sp; X Cmd* cp; X{ X int i; X X MoveVert(sp,cp,2); X for (i=0;i<cp->p.count;i++) { X StartIteration(sp,cp); X# ifdef X10 X X10Draw(sp,cp,2); X# else X XDrawLine( X sp->d,cp->dest,cp->gc,sp->v[0].x,sp->v[0].y,sp->v[1].x, X sp->v[1].y X ); X# endif X } X} END_OF_FILE if test 10777 -ne `wc -c <'ops.c'`; then echo shar: \"'ops.c'\" unpacked with wrong size! fi # end of 'ops.c' fi echo shar: End of archive 2 \(of 2\). cp /dev/null ark2isdone MISSING="" for I in 1 2 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked both archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.