CDraw  -  Draw files from Basic

by Gordon Gilmore, Michael Janse, Keith Vernon, John Banks and Jack Pike


Back in RISC User 5:5 and 5:6 we published an article entitled Creating Draw Files in Basic by Gordon Gilmore, which provided routines that enabled you to create Draw files from within your own programs, and thus generate graphical output which can be exported to other applications. This proved to be very popular - so popular in fact that we were deluged with add-ons and updates to the original CDraw library. Further information on the basic routines was given in RISC User 5:8, followed by major additions to the library in 6:3 and on the 6:7 disc, which provided routines to create ellipses and to use RGB colour. In each case the magazine disc for that month carried the relevant CDraw routines, enabling users to build up a complete library.

Several new additions to the library are included on this month's disc. These provide routines to mimic Basic commands, to create arcs, segments and sectors of circles, to group objects and to position text more accurately, and to include sprites in Draw files.

Running the application from the RISC User menu system opens a directory called Files, which contains a number of objects, as follows:

The Original Libraries
CDrawEll consists of the original CDraw library plus the routines for drawing ellipses, as published on the RISC User 6:3 disc.

CDrawRGB is the CDrawRGB library as published on the RISC User 6:7 disc. Note that many of the CDraw routines have been updated from the original library. Some procedure names and their parameters have changed, so you will need to update any programs which use the old routines in order to make use of the RGB versions.

Basic Command Mimicry
CDrawMimic consists the new routines by Jack Pike which mimic Basic commands. The procedures are designed as additions to the original library (not the RGB version), and are as follows:
PROCCDraw_ORIGIN(x,y)
PROCCDraw_VDU5_PRINT(S$)
PROCCDraw_MOVE(x,y)
PROCCDraw_DRAW(x,y)
PROCCDraw_RECTANGLE(x,y,w,h)
PROCCDraw_SAVE(DrawFile$)
PROCCDraw_CLG
Each of these procedures works in exactly the same way as the corresponding Basic keyword; for example:
  PROCCDraw_RECTANGLE(x,y,w,h)
draws a rectangle starting at x,y with width w and height h, exactly the same as the Basic command:
  RECTANGLE x,y,w,h

Sprites in Draw Files
CDrawSpr consists of the new routines written by Keith Vernon allowing you to include sprites in Draw files. These can be used with either version of the CDraw library. The generalised approach to plotting sprites can best be unsdwrstood in pseudo code, as follows:

  Load the CDraw library procedures
  Initialise CDraw
  Load the Sprites to be plotted
  Select a particular sprite that is loaded
  Write the sprite to a block of memory
  Repeat for further sprites
  Add any other geometric shapes and text
  Save the Draw file
  Reset the CDraw procedure
  View the result

Procedure Definitions

As with all CDraw procedures it is necessary to
start by calling the procedure PROCCDrawRGB_initialise. Failure to call this will result in
the subsequent procedures giving an "Unknown or
missing variable" error. 

The calls to load and use the sprites are:

PROCCDraw_load_sprites(_spfile$)
where _spfile$ is a valid pathname.
Any number of sprites may be added.
All sprites are loaded at once for simplicity.

PROCCDraw_select_sprite(sp_name$)
where sp_name$ is the sprite required from _spfile$.
This procedure checks that the sprite exists and gives a report when it is not found.

PROCCDraw_write_sprite(xorigin%,yorigin%)
where xorigin% and yorigin% are the x and y co-ordinates in OS units relative to the bottom left hand corner of the window origin.

PROCerror - a general error handler

PROCmess(text$) - a general message report which displays the text string.
Clicking Cancel will stop the program.

The last two procedures use a common error block errbk% which should be DIMensioned before the initialisation stage.


Arcs and Groups
CDrawArc is an updated version of the original CDrawRGB together with the new routines written by John Banks to create arcs and segments, to group objects and to position text more accurately. Adding curves to the CDraw library will allow you to complete quite complex mixed text-and-graphics Draw Files. It is absolutely essential for these that the facility exists to group objects together, or the most harmless click of the mouse in Draw is likely to wreck your beautiful creation; hence grouping of objects is also implemented by the new routines, as described below. Also included is a simple routine to shift the text so that the specified co-ordinate pair is at the left, right or centre of the printed string as you choose, giving useful added flexibility.

It is recommended that you read the following description while referring to the actual routines within CDrawArc's !RunImage program. 

Circular Arcs
Draw renders a curved line from one point to another by allowing the path taken to be influenced by two control points - the two points in each subpath that are shown in orange in Draw's Edit mode. We shall refrain from exploring the theory involved here, but mathematically unchallenged readers will find much of interest in two articles in RISC User 4:3 and 4:4, where Derek Marriott put a tentative toe into these waters. Here we will concentrate on the practical problem: given a centre, radius and angle for our arc, where are the control points?

As was pointed out as long ago as RISC User 4:1 (Hints & Tips), Draw's "circles" are not circles at all, but close approximations to them that are easier and faster to render than true circles would be. In Draw Tools (RISC User 5:1), these mysterious control points are taken along the tangents at either end of the arc. An equally valid approach which reflects the total symmetry of the circle is to have the control points at angles which trisect the angle (((q, that is at angles (((q/3 and 2(((q/3 to the direction of the starting vector, and this method is used in the present program. For simplicity we always assume that the arc is centred at the origin and starts from a point horizontally to the right; we then use the SWI Draw_TransformPath to deliver the actual arc desired. This requires some space (24 bytes) to be dimensioned to hold the transformation matrix.

In order to use the new routines a few global variables must be defined in the initialisation routine PROCCDrawRGB_initialise. Alter the line:
DIM _buffer% size%
to:
DIM_buffer%size%,_matrix%24, _group%48, _data%1023
and insert declarations of two global constants on the next line:
_unity%=1<<16:_gptr%=0
These alterations have been made in the version of CDrawRGB included with CDrawArc.

To draw an arc, the simplest case for coding is when we are given the centre of the circle, starting point of arc, its angle and the usual colour, dash style and thickness required by the other drawing procedures in this library. We also however need to specify the sense of the arc (clockwise or anticlockwise), and also whether a plain arc, sector or segment is needed. Now there is a limit to how far parameters in a procedure can be multiplied whilst retaining comprehensibility and ease of use, and really CDrawRGB is already on the wrong side of that limit with six colour parameters where two words would do (it's very easy to enter too few or too many zeroes!); the solution is to provide a flag word as Acorn uses in many SWIs and let that do the work. To draw an arc, therefore, we have a new procedure PROCCDrawRGB_arc, whose ten parameters are: xcentre, ycentre, xstart, ystart, angle (degrees), fill colours (3), line colours (3), line thickness, dash parameter and the flag word whose meaning is as follows:
Bit 0 set: new path
Bit 0 unset: continue

Bit 1 set: sector
Bit 1 unset: arc

Bit 2 set: segment

Bit 3 set: close path

Bit 4 set: plot clockwise
Bit 4 unset: plot anti-clockwise

The flag word takes as its value the sum of the contributions of the set bits, so 3 would start a new path with a sector plotting anti-clockwise, while 20 would extend a previous path with a clockwise segment.

The related problem of joining two points with an arc of given radius is solved in the procedure PROCCDrawRGB_arcjoin, which calls the previous procedure after doing the necessary calculations.

Groups
Grouping of objects is initiated by a call to PROCCDrawRGB_startgroup, and completed with PROCCDrawRGB_closegroup. You may nest groups as you want, to a maximum depth of an unnecessarily lavish eleven. Naturally you will get an error if you try to save the Draw File with a "hanging", unclosed group.

Shifted Text
PROCCDrawRGB_textshift works exactly as PROCCDrawRGB_textobject, with an extra parameter shift%, which has values as follows:
  0 string starts at x,y
  1 string finished at x,y
  2 string centred at x,y
Higher values of shift% are valid, but not really useful - they shift the text to the left by ever smaller amounts.

Running the Test Program
Running CDrawArc installs three demonstration Draw files in the Files subdirectory of the CDrawArc application directory. For this reason you cannot run the program directly from this disc as there is insufficient room to create the files. The files show the power of the new procedures by creating phases of the moon, a pie chart, and an example of positioned text.

Moons
A procedure is provided in the library to produce moon images like the one in the test file. Parameters taken by PROCmoon are xcentre, ycentre, radius, elongation, tilt and three colours each for the lit and unlit parts. Here elongation is the angular distance from the sun (0-360) and determines the phase and tilt rotates the image as you choose.

PROCmonth uses this procedure to create an image of the moon as it is seen at 24 hour intervals for a period of 32 days, the result being the file Moons, one of those generated by the application when double clicked on and stored in Files.

Pie Charts
The procedure PROCpiechart works just as you would imagine. Its parameters are:
- Filename for the data (if not a full path-name, then the application directory is assumed)
- pointer to workspace, around 1000 bytes will almost always suffice
- xcentre, ycentre and radius of chart
- outline%: if this flag is set then sectors are outlined in black


Copyright  RISC User 1994