Victor R. Volkman received a BS in computer science from Michigan Technological University in 1986. He is currently employed as software engineer at Cimage Corporation of Ann Arbor, Michigan. He can be reached at the HAL 9000 BBS, 313-663-4173, 1200/2400/9600 baud or any BBS in the W-Net Network.
GraphX is a device-independent graphics library with two and three-dimensional drawing capabilities. GraphX provides 185 functions for manipulating 2-D figures, 3-D figures, stroke text, and raster text. GraphX is apppropriate for intermediate level C programmers with some prior exposure to 3-D graphics and can be used with either Borland Turbo C 2.0 or Microsoft C 5.1.
I tested the 02/28/90 release for Turbo C 2.0, distributed on a single high-density 5-1/4" 1.2M diskette. GraphX is also available on 3-1/2" 720K or 1.44M diskettes.
Programs developed with GraphX will run on any IBM-PC compatible system with 640K RAM and the appropriate graphics hardware. However, an 80286-based computer, hard disk, and Intel 80x87 Numeric Data Processor (NDP) are recommended. Third-party NDPs such as the Weitek 4167 aren't supported. GraphX uses neither EMS nor extended memory for any purpose. A telephone call to Civilized Software revealed they are planning to release a version developed with the Eclipse's 16-bit 80286 DOS Extender at an unspecified date.
GraphX supports only the large memory model (code > 64K, data > 64K). This is an unusual requirement since other graphics packages, such as Halo '88 and GSS*CGI, offer support for at least the small, medium, and large models. Since GraphX contains a single library (.LIB) file encompassing all possible supported devices, it will add at least 175K to the size of your application.
GraphX requires MS-DOS v3.0 or later. My GraphX applications ran without complaint on MS-DOS v3.30 and IBM PC-DOS v4.01. Although not DESQview-aware, programs built with GraphX functioned correctly with DESQview v2.25 from Quarterdeck Office Systems. GraphX also worked fine in Novell Netware 2.15 and 3.00 environments. I tested GraphX with both the ATI VGA/Wonder and an IBM PS/2 VGA adapters.
GraphX competes with graphics packages such as Halo '88 by Media Cybernetics, Inc. and GSS*CGI Computer Graphics Interface by Graphics Software Systems, Inc. All three offer similar functionality in the same price range. I will compare GraphX, Halo '88 and GSS*CGI on the basis of how well each supports devices, drawing operations, and fonts. Additionally, I will compare the performance of GraphX and Halo '88.
Device Support
GraphX supports mainly graphics adapters which are closely compatible with the IBM EGA and VGA display modes. A total of six adapter and mode combinations are supported, including EGA 640x350x16, VGA 640x480x16, Genoa SuperVGA 800x600x16, and ATI Wonder 800x600x16.Most notably missing from the list are AT&T Targa, Hercules monochrome and InColor, IBM CGA, PGA, MCGA, and 8514/A support, as well as the IBM VGA 320x200x256 mode. Super VGA adapters with 512K or more video RAM such as the ATI VGA/Wonder and Video-7 VRAM are also not represented. Modern graphics cards based on the Texas Instruments Graphics Array (TIGA) 340x0 CPUs are also not supported. All of the above mentioned displays are supported by both Halo '88 and GSS*CGI.
A telephone call to Civilized Software indicated IBM 8514/A adapter (1024x768x256) support would be forthcoming at an as yet unspecified date. Additionally, the tutorial manual promises a Hercules monochrome driver in the future.
For hardcopy output, GraphX currently supports only HP LaserJet II and Postscript compatible printers. Documents larger than "A" size (8.5 in. x 11 in.) are not supported. Both Halo '88 and GSS*CGI support several devices in each of these categories. A call to Civilized Software indicated they are planning to release a version supporting the new HP LaserJet III and possibly the HP PaintJet at an unspecified date.
For locator input devices, any two or three-button mouse that uses a Microsoft mouse compatible driver will work. There is no GraphX support for X-Y location via joystick, graphics tablets, light pens, or other input devices. Both Halo '88 and GSS*CGI support several devices in each of these categories. In GraphX, the locator cursor is always displayed as an arrow pointer of the same fixed size. By contrast, GSS*CGI allows the locator cursor to be set to an arbitrary bitmap pattern or one of six pre-defined styles (crosshair, arrow, hourglass, etc.). In Halo '88, the locator cursor is a crosshair whose height, width, and color is user-defined.
In GraphX, the console keyboard is not supported as a device of its own. Consequently, any keyboard input while in graphics mode must be supplied by routines of your own construction, because keystrokes should not be echoed on the display. An example of a suitable keyboard input routine is given in the GraphX Tutorial manual. Although Halo '88 provides a separate cursor for text display in addition to the locator cursor, it does not address the console keyboard as a device either. GSS*CGI does support the console keyboard as a device. You can read from the keyboard in sample (polled) or request mode (wait for keystrokes). The output can optionally be echoed at a given screen coordinate using the current font.
GraphX does not support input from imaging devices such as video digitizers (frame grabbers), video overlays (genlocking), or page scanners without conversion to GraphX format. Halo '88 supports serveral devices in each of the above mentioned categories. GSS*CGI supports only page scanning devices.
GraphX differs from Halo '88 and GSS*CGI by linking all of the device drivers into the application program. This has two important effects. First, you cannot update drivers independently of the main application, so your customers will have to get new versions of your software to take advantage of increased device support in the future. Second, the opportunity for direct use of third-party device support programs is eliminated. For example, many CAD programs have interfaces for third-party device drivers. These device drivers are usually small resident programs that interact with the application via a software interrupt. This type of interface allows hardware vendors to develop, improve, and distribute their own device drivers independently. If device drivers cannot be provided independently, then hardware vendors will be reluctant to commit resources to their development.
GSS*CGI requires "true" device drivers that are loaded from CONFIG.SYS during system boot time. Since they use a significant amount of MS-DOS memory, you may need to perform a different boot before running a non-graphics application. In Halo '88, the device drivers are loaded during run-time with calls to setdev() for display adapters and to setprn() for printers. GraphX doesn't offer any screen-dump facility such as offered by the gprint() function of Halo'88.
Drawing Support
GraphX is strongest in its support for 2-D and 3-D graphics drawing. GraphX provides separate 2-D and 3-D functions for drawing dots, lines, polygons, splines and moving the world cursor. The 3-D functions specify coordinates in triples of (X,Y,Z)a Cartesian coordinates. The 2-D functions operate on the X-Y plane (Z=0). Each of the functions is available in a version which uses absolute or relative coordinates. Coordinate units consisting of user-world units, device-independent 0 to 1 viewplane units, pixel units, and absolute inches may all be used. All of the drawing on the window takes place within the context of the current transformation. For example, if you have specified a transformation consisting of a rotation about the Z-axis and a translation on the X-axis, then all objects will be drawn as transformed accordingly. A smaller set of dot, line, and move functions is available for drawing on the current viewplane, which is 2-D and independent of window transformations. A viewplane is a user-defined rectangular portion of the display in which the actual drawing takes place. Additionally, 2-D elliptical arcs (which includes circular arcs as a special case) may be drawn on the viewplane, but not on the window. Objects may be drawn in any one of four writing modes: replacing, XOR-ing, OR-ing, or AND-ing with the previous pixel values.GraphX also provides clipping windows and perspective support. Just as a rectangle is used to clip against a two-dimensional window, a 3-D box is used to clip against a three-dimensional window. Of course, since a CRT can only display two-dimensional objects, a three-dimensional window is simulated by projection onto a two-dimensional viewplane. GraphX supports several combinations of pyramid clipping for perspective projections, and perspective foreshortening on the Z-axis.
Although it can be argued that any graphical shape can be rendered using only lines, a graphics application library should provide more than just these primitive objects. Although neither Halo '88 nor GSS*CGI has 3-D primitives, they do support a wide set of 2-D graphics primitives. For example, both support bar, box, circle, filled circle, pie wedge, and marker symbol primitives in addition to those offered by GraphX. (A marker symbol is an icon or a character (such as an "X") that can be used, for example, to highlight the vertices of a segmented line.)
In addition to the shape-drawing primitives, a complete package provides fill functions. GraphX supports a vector-fill operation for arbitrarily complex polygons, but does not support a traditional bitmap flood-fill operation. (A flood-fill paints a display region beginning from a specified seed point. Painting continues to spread until the edge of a bordered region is reached.) Unlike flood-fills that operate blindly, a vector-fill operates on a set of vertices defining a closed polygon. Thus, the polygon boundaries define the region border instead of using the existence of previously drawn objects.
Halo '88 and GSS*CGI offer a range of hatch patterns with which to fill. The GraphX vector-fill uses only a pattern of parallel lines with user-defined spacing, slope, and other characteristics, requiring repetitive fills to achieve cross-hatch patterns. Halo '88 offers ten hatch patterns for all fill types; five of these may be user-defined. GSS*CGI offers 33 standard hatch patterns plus one user-defined bitmap hatch pattern. Halo '88 offers three styles of bitmap flood-fills as well as a vector-fill. GSS*CGI has a vector-fill but no flood-fill.
GraphX also has support for manipulating rectangular bitmap areas, referred to as "patches". Patches can exist both in memory and on the screen. Patches can be created, copied, displayed, written to files and read back from files. Copying a bitmap area is often more complex than just replacing the old pixel values with the new ones from another bitmap. For example, you might want to logically OR one bitmap against another bitmap to combine pictures. GraphX provides a total of 26 bitmap operators including AND, OR, NOT, XOR, min, max, rotate, sum, difference, and average. These are a superset of the nine bitmap operators offered by Halo '88 and the 16 writing modes available in GSS*CGI.
GraphX has another uncommon feature for bitmap manipulation: patches may be subpatches of other patches. This nesting of patches simulates a n-ary tree. GraphX also supports "pictures", sequences of move and draw commands, which can be created and then redrawn as desired. Pictures may be called as picture subroutines to form a hierarchical structure.
Font Support
GraphX provides both stroke and bitmap fonts. Stroke fonts are character sets defined by brush strokes in the form of vectors. Just as a calligrapher always writes a letter in the same way, a stroke font specifies a uniform description of each character. Since stroke fonts are composed of vectors, they can easily be enlarged, reduced, rotated and drawn in 3-D with minimal distortion. Bitmap fonts specify patterns of pixels, rather than vectors, to describe each character. When bitmap text is enlarged, its appearance becomes more block-like. Bitmap text is always faster to display than stroke text since the font data is copied rather than computed.Fonts provided with GraphX include Times-Roman, Helvetica, Courier, Old English, Gothic, Cyrillic, Greek, Block, Cursive, and Symbols. Dozens of symbols are available throughout the fonts including musical, mathematic, scientific, and astronomical symbols. Most of the fonts are available with a variety of stroke weights and also in italicised form. The initial font selection is better than most supplied by competing graphics packages. Figure 6 shows some text in each of the 34 stroke fonts as plotted by the Postscript landscape-mode driver. Note that the missing letter "G" and partial letter "t" in Font #32 of Figure 6 represent bugs in the Postscript landscape-mode driver.
Stroke fonts numbered one through 34 are provided in a single font file named GXFONTS.O. Although completely unique to GraphX, the stroke font file format is fully documented. Up to 99 stroke fonts can be distributed in a single font file. A single custom stroke font, FONTO, can be constructed with the DUCHAR() library function which writes a single stroke character to the FONTO file. An individual stroke font character may be composed of any combination of lines, arcs, cubic splines, boundary-directed splines, polygons, filled polygons, and scale multipliers.
The GraphX stroke fonts can be agonizingly slow compared to most other graphics applications I have used. Fonts with heavier stroke weights are proportionally slower to display than fonts with lighter stroke weights. Fonts composed of characters that are defined by polygon fills are by far the slowest. For example, a 12MHz AT with a VGA monitor displays fewer than 40 characters per minute from font #30 (a polygon-fill font).
GraphX provides 34 bitmap fonts identical to the stroke fonts. Again, the file format is completely unique to GraphX, although documented. These fonts are simply rasterizations of corresponding stroke fonts at a height of roughly twenty pixels. Bitmap font number zero always maps to the built-in character set ROM of the display device you are using. For example, font number zero on an EGA display would have character cells of 8x14. This is analogous to "fast text" fonts in Halo '88 and "cursor text" in GSS*CGI.
The utility of bitmap fonts is limited because they may not be scaled as they are displayed. Additionally, strings of bitmapped text may only be written in the left-to-right direction. Halo '88 and GSS*CGI graphics packages both allow bitmap fonts to be scaled by an integer value. Halo '88 even allows the width and height of bitmap fonts to be scaled independently. In Halo '88, bitmap text may be drawn in any of the four compass paths, including right-to-left and top-to-bottom.
Except for the harware font 0, both stroke and bitmap fonts are limited to the 128-character ASCII character set.
GraphX does not maintain separate position cursors for graphics and text a single "internal world position" is used for both text and graphics objects. Halo '88 and GSS*CGI both have separate cursors for text positioning and graphics positioning, allowing a crosshair cursor and an text input prompt to be displayed simultaneously, for example.
The GraphX bitmap fonts are not downloadable to the HP LaserJet II printer. Since all 34 fonts are not available on the HP LaserJet II printer, GraphX attempts to find the best fit between its internal bitmap font description and one of the twelve fonts resident in the printer. For PostScript printers, GraphX supports four hardware stroke fonts: Times-Roman, Helvetica, Courier, and Symbols. Although you can override the font mapping routine and specify a printer-specific hardware font, doing so defeats the purpose of device independence.
Documentation
The manual contains approximately 130 pages divided into tutorial and reference manuals of roughly equal size. The manuals would serve better if bound separately since each section has its own independent table of contents and index. The texts make frequent use of mathematical notation to describe how GraphX works, especially in the sections about 3-D drawing and transformations. I would recommend having at least a college-level course in linear algebra in order to understand the derivations.The tutorial manual briefly covers each of the major functional areas of GraphX: initialization, drawing 2-D images, text drawing, 3-D object viewing, polygons, and so forth. Hardcopy devices, however, are mentioned only in passing. Most sections contain several code fragments and screen dumps that show the effect of the code. The examples include practical applications, such as a simplified paint program.
The reference manual consists mainly of a catalog of GraphX functions listed alphabetically within each major functional area. The reference manual contains no figures and few code samples to illustrate the functions. The function descriptions uniformly use real when they should in fact be double. Although this idiosyncracy is mentioned in a footnote, it still may confuse some readers. Appendices in the reference manual provide font file formats, complete font listings, display list data structures, device specific information, and a listing of runtime error messages.
Civilized Software's support policy and update practices aren't mentioned anywhere in the documentation. No registration materials or license agreement were included in the package. A telephone call to Civilized Software revealed that each GraphX license includes lifetime telephone support. Civilized Software also promised to provide free updates to customers who turn in bug reports. Civilized Software reported that they will mail update disks for major enhancements, but did not have a definite release schedule.
Case Study: Porting Bargraph
Bargraph is a script-driven program for producing presentation quality bar charts (see bibliography). Bargraph was originally written to use the interface provided by the Halo '88 graphics library. As a practical test of GraphX's functionality, I ported bargraph to the GraphX environment. Figure 1 is a Postscript plot of my bargraph benchmark as printed by GraphX. The entire porting process, including learning how to use GraphX, took less than two days from start to finish. Most of the Halo '88 functions had a one-to-one correspondence with equivalent GraphX functions. The two exceptions were drawing stroke text at an angle and drawing filled rectangles.Unlike Halo '88 and GSS*CGI, GraphX does not have a function to set the baseline angle at which stroke text will be drawn. In the Halo '88 version of the bargraph program, I used angled stroke text to prevent the labels below the graph from overwriting one another (see Figure 1) . In GraphX, you must do this indirectly by defining a rotation vector, calling DROTATE() to produce a 4x4 transformation matrix, and then calling DAPPLY() to apply the transformation to all subsequent vectors. Next, you must set up a 4x4 translation matrix with DTRANSLATE(). Lastly, you combine both transformations with DRCOMPOSE(). This process has to be repeated for each string of text you want to display. The source code for angle_text() in Figure 2 demonstrates the steps.
Although GraphX has a filled rectangle primitive obscurely provided by its DLINETYPE() function, I chose to supply my own equivalent function. The best solution was to start by defining a closed rectangular polygon. Next, I fetched the vertices into a dynamically created array with DMATRIX() and drew the rectangle with DDRAWP(). Last, I called DFILLP() to do a solid vector-fill and then deallocated arrays with DKILLP(). The source code for draw_bar() in Figure 3 illustrates this process.
When vector filling a polygon, each fill-line creates a new vector, and each new vector requires an allocation from the heap to record its characteristics. The ensuing allocation overhead coupled with floating point arithmetic combines to make the fill process noticeably slower than with Halo '88. The process is slowest when filling an area with a solid hatch pattern.
Figure 4 compares the bargraph programs built with Halo '88 and GraphX. The basic object code files are of nearly equal size, but the bargraph program was roughly 76K larger when linked with the GraphX library. Programs built with GraphX will require more heap memory during run-time, due to the extra overhead of maintaining lists of polygon vertices and other objects drawn by the application program. The GraphX bargraph version required effectively twice as much MS-DOS memory as the Halo '88 version (210K). For larger applications, the difference may be less significant.
The most apparent difference was the speed at which the bargraph program executed (see Figure 4 for summary). On a standard 12MHz 80286 computer with a 640x480x 16 VGA display, the GraphX version required almost one minute to paint the screen. By contrast, the Halo '88 version of the application finished in little more than two seconds. The addition of an 80287 math coprocessor allowed the GraphX application to finish in one third of the original time or about 18 seconds still an order of magnitude slower. The Halo '88 version showed no measurable change when using the math coprocessor. The time required by GraphX is proportional to the number of vectors drawn, so cross-hatched rather than fully-filled bars goes proportionally faster.
I had mixed results using the hardcopy output drivers for GraphX. According to the tutorial, the HP LaserJet II driver is "not fully implemented". (The press release and reference manual indicated otherwise.) I was unable to produce a complete printout with either the portrait or the landscape mode drivers. The best I could achieve with either was to print about 60 percent of the page. I tested the HP LaserJet driver on an HP LaserJet II and an HP LaserJet 2000, both with more than 2Mb of RAM, and got identical results. Inspection of the print files indicated they were indeed smaller than the expected 900K (2325 dots x 3100 dots / 8 dots/byte = 900K).
Next, I tried using the Postscript drivers which were supposed to be fully implemented. When using the Postscript portrait-mode (PSP) driver, I received the following error:
GraphX ERROR: gxalloc, called from fnn in fill: >64K requested.after which the application exited. I had complete success only with the Postscript landscape-mode (PSL) driver. This driver produced nearly 400K of Postscript commands which consisted of almost exclusively of "moveto" and "lineto" commands. Figure 1 is the Postscript landscape mode printout.After the failures using Postscript portrait-mode and all of the HP LaserJet drivers, I began to suspect that perhaps the drawing was too complex for the drivers. (Civilized Software confirmed that the difficulty is that the vector fill operation requires a temporary array large enough to hold all the fill-line end points. When solid-filling, this is proportional to the vertical revolution of the output device, and for PSP this array is too large.) I changed the solid vector-fill to a crosshatch pattern requiring considerably fewer vectors. The result was that all drivers finished without any fatal gxalloc errors. Thus, the main problem with the printer drivers is that they cannot handle drawings with as many vectors as GraphX can plot. A summary of my results with the GraphX printer drivers appears in Figure 6. A telephone call to Civilized Software later confirmed that work on these bugs is in progress.
Summary
GraphX is strongest in its support for 3-D drawing and viewing operations. These operations are both powerful and easy to use. However, a succesful graphics package must offer more: fast performance, a complete and reliable set of device drivers, and a full complement of raster and vector functions. Until these issues are addressed, I can only recommend GraphX to developers who have an overriding interest in three-dimensional graphics. When the other problems are resolved, GraphX will be a formidable contender in the graphics support arena.
Bibliography
Volkman, Victor R. "The Halo Graphics Library". The C Users Journal, March 1990, Vol. 8, No. 3, pp. 115-124.This is a script based program for producing presentation quality bar charts with Halo '88.
Foley, J.D, and Van Dam, A. Fundamentals of Interactive Computer Graphics.
A thorough survey of the issues and implementations of computer graphics for an intermediate-level programmer with no prior experience. Contains a good introduction to the mathematics of planar geometric projections as well as advanced topics such as shading models, hidden-edge removal, and color chromatics.
GraphX
Civilized Software
7735 Old Georgetown Road
Office 410
Bethesda, MD 27814
(301) 652-4714
Figure 5