MacDraw Files
Volume Number: | | 3
|
Issue Number: | | 10
|
Column Tag: | | Programmer's Forum
|
MacDraw PICT Files from Basic
By Bob Andris, Lockheed Corp.
Why Draw a PICT File?
This article should really have been titled PICTing in ZBasic , but that didnt sound quite as clear. The PICT file format is rapidly becoming the standard for transferring High Quality graphics between programs, and not just graphics programs. To name just a few, MacDraw, MacDraft, Cricket Draw, and SuperPaint all will both read and write PICT files. However, layout programs like PageMaker will also read PICT files in directly with its Place command. In addition to all of the above a word processor like Word 3.0 will pass PICT information back and forth through the clipboard and retain the individuality of each PICT element. Why all of this compatibility? The answer to that one is simply called the LaserWriter!
The LaserWriter with its PostScript language treats all PICT elements as separate objects, not bit maps, and prints (or better yet, draws) them vectorially. Thats why a diagonal line has nice sharp edges, and not the jaggies that go with the individual pixels of a bit map. This even holds true for text! As the quest for higher and higher quality proliferates, the PICT format will become even more prevalent. The PICT format is also inherently faster than most because it is the format that QuickDraw in the ROM is using to begin with!
All of the graphics programs mentioned previously also have their own proprietary file format, including MacDraw. Getting into those formats is not the purpose of this article. It is PICTing that well be covering in detail. And, as you will see, drawing a PICT file in ZBasic is even easier than painting a PNTG file in ZBasic as I covered in a previous article.
Whats in the PICTure?
First of all, there are several good references on the PICT file format and QuickDrawing a picture, so Ill give them to you now.
MacDraws PICT File Format and Comments, Macintosh Technical Note #27, by Ginger Jernigan, Aug. 20, 1986.
QuickDraws Internal Picture Definition, Macintosh Technical Note #21, by Ginger Jernigan, June 20, 1986.
Optimizing for the LaserWriter--Picture Comments, Macintosh Technical Notes #91, by Ginger Jernigan, Mar. 2, 1987.
Inside Macintosh Volume I, chapter 6, QuickDraw, in particular Pictures and Polygons starting on p 158.
As Inside Mac says on page 158, A picture in QuickDraw is a transcript of calls to routines that draw something--anything--in a bit image.. Whoa ! ! ! What happened to all this elements, objects, and vector stuff this idiot was just talking about? Well, the bit image theyre talking about on page 158 is the screen. The things that get stored in the files and also sent to the LaserWriter are those calls friends, not a bit image!
Since pictures are all of varying size, i.e., length, as we could have guessed a Picture is really just a variable length record. The record always starts with the following two fixed-length fields:
picSize:INTEGER; {size of record in bytes}
picFrame: Rect; {picture frame}
Immediately following the two fixed-length fields are the QuickDraw calls to generate the picture. It is important to point out that the size (picSize) includes the first two fixed-length fields themselves. If we were to write out this picture record to a file wed have what we need, right? Wrong! All of the programs mentioned previously would spit-up something terrible. So, whats missing? Well, its a header of some kind . . . thats what makes a picture record into a PICT file. So lets get into that now.
The MacDraw PICT file format
Referring you to tech note #21, MacDraw gives you the option to use two file formats. They are DRWG and PICT. The DRWG format is the internal one that only MacDraw understands. The PICT format is the one well look at in MacDraw. Rather than just drone on and on, its time for an example. I went into MacDraw, itself, drew a simple five-sided closed polygon, saved it as a PICT file and then went into Fedit+ to take a look at it with tech note #27 in hand. Figure 1 shows the polygon as you normally see it in MacDraw.
Fig. 1 A draw figure created from Basic!
As we can see, theres not much to it. Just an ordinary polygon. The total file size, as stored by MacDraw, is just 570 bytes. Thats good, since the actual PICTure part of it is only 58 bytes long. A quick mental calculation tells us the header is our old friend, 512-bytes, long! Same length as the Paint file headers were. Now lets view what you find in Fedit+ and take a close look at the header.
Fig. 2 Fedit+ View of the MacDrawed Polygon File
Figure 2 is the Fedit+ ed look at both sectors of the MacDraw PICT file called Polygon. The breaks in the sector views are where they become all zero from then on. The numbers in the left halves are the hex representation of the code and to the right is the ASCII representation. Heres what we find in the header (refer to tech note #27):
MacDraw PICT File Header
4452 5747fType DRWG in ASCII for
MacDraw 1.7 & 1.9
4D44 hdrID MD in ASCII
0006 version file format version
0003 to prRec 120 byte print record
0000 (ends with position 000079)
0000 0000xOrigindrawing origin
0000 0000yOrigindrawing origin
0048 0000xScale screen res (=72 dots/inch)
0048 0000yScale screen res (=72 dots/inch)
0000 to atrState state of drwg attributes
0000 (ends with position 0000CD)
0001 lCntno. of top-level objects
0001 lTottotal no. of all objects
0000 0066lSiz total size of list
000A 0000top box of all objects (= 10)
0055 0000left box of all objects (= 85)
0046 0000bottom box of all objects (= 70)
00E1 0000right box of all objects (=225)
0007 to filler 282 unused bytes
0000 (ends with position 0001FF)
Creating this header for each different file would be quite time consuming and also subject to error. Fortunately were in luck! Tech note #27 says If MacDraw opens a PICT file and finds that it has a different hdrID than MacDraw expects, or that the first block is zeroed, it ignores the header and uses its own default document settings.. So all we will have to do to create a MacDraw PICT file in ZBasic is to start it out with 512 bytes of zero (0)! The second part of Figure 2 is the data for the actual QuickDraw PICTure of the polygon. Lets get into that now.
Pic comments are Helpful
MacDraw makes extensive use of picture comments [CALL PICCOMMENT( . . . ) in ZBasic] to gain more functions than are available with the standard QuickDraw calls. They are also used to guide the LaserWriter in drawing a complex set of figures and text. A good example is using piccomments to tie arrowheads and lines together in order to make the combination a single entity, the arrowhead-line. There are two types of piccomments available, the so-called shortComment and its companion the longComment. The long one allows you to specify a variable-length data record to be executed, while the shortComment has simply one operation, like picPlyClo, which means were drawing a closed polygon. The only ones well be needing here are the short comments. They are characterized by a one (1) byte opcode, which is A0, followed by a two (2) byte kind which describes the action desired.
The first item in the QuickDraw picture is always 2 bytes of record size, which includes the 2 bytes themselves. Then comes the picture frame, of type Rectangle, which means 8 bytes (4 words or integers) of rectangle description. This is followed with the picture definition. What we do now is look at the first byte, the opcode (operation code), which tells us what is going to be described and then the descriptions will follow. Then we look for the next opcode and the process keeps repeating until the picture is finished. Now we can take a look at that PICTure data in the second half of Figure 2:
Quickdraw Picture Format
003A picSize size of entire picture, in bytes
( 58 decimal, in this case)
0000 picToploc of top of entire picture
( 0 decimal, in this case)
0000 picLeft loc of left of entire picture
( 0 decimal, in this case)
02D0 picBottom loc of bottom of entire picture
(720 decimal, in this case)
0240 picRight loc of right of entire picture
(576 decimal, in this case)
11opcode for picVersion(1 byte )
01version number for this picture
A0opcode for shortComment(2 bytes)
0082 kind for picDwgBegin
(begin a MacDraw pict)
A0opcode for shortComment(2 bytes)
00A0 kind for PolyBegin
(begin a special polygon)
A0opcode for shortComment(2 bytes)
00A5 kind for picPlyClo
(the polyn is to be closed)
01opcode for clipRgn(10 bytes, or more)
000A rgnSize size of entire region(10 bytes)
0000 top top of clipping rgn ( 0 dec)
0000 leftleft of clipping rgn ( 0 dec)
02D0 bottombottom of clipping rgn (720 dec)
0240 right right of clipping rgn (576 dec)
22opcode for short line (st.v,st.h,dh,dv)
000A start.v vert start pt for line (10 dec)
0055 start.h horiz start pt for line(85 dec)
00dh horz line length ( 0 dec)
23dv vert line length (35 dec)
23opcode for short line from(dh,dv)
63dh horiz line length(99 dec)
19dv vert line length (25 dec)
23opcode for short line from(dh,dv)
29dh horiz line length(41 dec)
C4dv vert line length (196-256=-60 *)
23opcode for short line from(dh,dv)
A6dh horiz line length(166-256=-90 *)
19dv vert line length (25 dec)
23opcode for short line from(dh,dv)
CEdh horiz line length(206-256=-50 *)
E7dv vert line length (231-256=-25 *)
A0opcode for shortComment(2 bytes)
00A1 kind for PolyEnd
(end a special polygon)
A0opcode for shortComment
(2 bytes to follow)
0083 kind for picDwgEnd
(end a MacDraw pict)
FFopcode for EndofPicture
(nothing to follow)
* dh & dv are both (-128 . . . +127), so if
number is greater than +127 decimal,
subtract 256 from it to get true neg. nos.
Now lets take a break from all of this and get into some programming.
The MacDraw/ZBasic Polygon Program
The first ZBasic program at the end of this article is called MacDrawPoly.BAS. It is the shortest and simplest of the three, and was written to try a couple of different approaches to creating the same figure. We begin by defining the opcodes for the short piccomments well be needing, and then we define the picture rectangle and CALL SETRECT( . . . ) to initialize it. After this, we open the picture and get a handle to it (PicHand&); and then begin the picture with a piccomment. I should point out here that the picDwgBeg and its converse picDwgEnd are really not necessary, but they do make the QuickDraw description of the picture much more efficient.
The first file created uses piccomments to tell it a polygon is coming, that the polygon is of the closed type, and that the polygon description is completed. The second file use the more standard QuickDraw calls to open, close, frame, and kill the polygon. Now we open a file and give it a type of PICT and creator of MDRW (for MacDraw). As discussed previously, the first thing we do is write-out a 512 byte header of zeroes. Then we get the pointer to the picture data from the handle we got at the beginning of the program.
As you can see from the coding, PicLength%=PEEK WORD(PicPtr&+0), the length of the entire picture record is contained in the first 2 bytes (one word or integer) of the record itself. We need this to know how much data to write-out to the files. The monkeying around you see to get the number of words (integers) from this length-of-record is merely to insure well include the FF (EndofPicture) at the end of the record. Ill point out that with this method, sometimes youll get an extra byte after the FF, before the file is actually closed (50-50 chance). This wont hurt anything, because MacDraw, and all the rest, know that FF means its all done drawing your picture! Figure 3 compares the polygons as done by MacDraw itself, and as done by the ZBasic program.
Fig. 3 Comparison of the Polygons
Compare the Actual Polygon File Data
As we can see, all three polygons in Figure 3 sure look the same. But the proof of the pudding is to use Fedit+ again and take a look at the actual data. Figure 4 does this for MacDraw.poly1, the first of our ZBasic files.
Well, the first thing we notice is the 512 byte header of zeroes. And since MacDraw read it in, we know that part of the approach works. In comparing Figure 2 to Figure 4, we find that our ZBasic polygons PICT data is also 58 bytes long - so far so good. As a matter of fact, the match is perfect except for the bottom and right of the clip rectangle. These numbers are $0117(279 dec) and $01E7(487 dec) which happens to be the vis and also the clip regions of ZBasics default window! We could change the clipping region in our program to get them to match perfectly - but as we will see later, the only thing affected is what is visible on the screen when the picture is being generated. MacDraw and all the rest ignore this when they read in a default-header file and reset the clip region as necessary. As a matter of fact, it changes constantly with how much reduction or expansion you are using at the time. The PICT data for MacDraw.poly2 was 65 bytes long and was constructed slightly differently. Figure 5 shows us those differences.
Fig. 4 ZBasics PICT Polygon File
The first thing we notice is that the PolyBegin, PolyEnd, and picPlyClo piccomments are missing, just as we coded the program. However there is a new opcode at position 00021A; it is $70 which is the opcode for framePoly. Our ZBasic CALL FRAMEPOLY( . . . ) produced this for us. This opcode is followed by polySize, polyBBox, and polyPoints which are the size of the polygon record, the bounding box, or rectangle, and the array of points, respectively. The method used in poly1 is more efficient than that used in poly2, but for just a few points per polygon the payoff is not that great. Now lets get on to something with a little more visual appeal.
Fig. 5 ZBasic Version of a Conventional Polygon
Fill and Pen Patterns
The second program at the end of this article, MacDrawPat.BAS, will look like Figure 6 when you run it interactively in ZBasic. Referring to the listing youll see a CALL SHOWPEN, which allows us to see what is going on while running. As mentioned in Inside Mac and the ZBasic manual, when we open a PICTure QuickDraw makes the pen invisible. Conversely, when we close it, the pen gets turned back on. So if you want to watch, do a showpen after opening the picture. Just be sure to hidepen before you hit the closepicture.
This program gets us into patterns in QuickDraw. A pattern is simply an 8 by 8 array of pixels, or data, which can be used for filling, painting, and for drawing by the pen. If you remember back when we did Painting in ZBasic, we simply did PEN ,,,,32 and got the thirty-secondth pen pattern to use. Well we can do the same thing with our MacDraw PICT files. But, BE CAREFUL! MacDraw does NOT use the same patterns as the Paint programs. It has its own patterns, while the Paint programs use a set that resides in the System File. If you use a pattern that MacDraw does not have it will do one of three things:
(1) default to black
(2) default to white
(3) spit-up all over itself
So, we will have to get the exactly correct patterns to use. There are three ways to do this that I know of. First, there is a [Not in ROM] procedure on p 473 of Inside Mac, Vol. I, called GetIndPattern which would do it. But that procedure is not yet implemented in ZBasic. Second, by using ZBasics FN GETRESOURCE( . . . ) and a little manipulation you could probably get the patterns. The third way is to look at the patterns, convert them to hex-strings, and use CALL STUFFHEX( . . . ) to put them into a real pattern record. The third way is shown pictorially in Figure 7. First fire-up ResEdit, open up MacDraw, and find the resource PAT#. Thats where the 36 fill patterns reside. The first one is None, the second is white, the third is black, etc. Watch that first one (None)! I havent found a pattern for None yet, so I just dont do a fill if the desired pattern is None.
Fig. 6 ZBasic Run of MacDrawPat.BAS
In order to save you the work of converting 36 patterns, they are all listed as DATA statements at the end of the program. There are a couple of other points of interest in MacDrawPat.BAS. First is the sequence of the graphics calls. Referring to the listing you will notice that they appear in the following order:
(1) draw the single-weight line
(2) draw the brick filled rectangle
(3) draw the diamond filled oval
(4) draw the double-weight line
(5) draw the inverted-V filled round-rectangle
Now looking back at Figure 6, you see thats how they are stacked on the screen. This is the same effect that the Bring to Front and Send to Back commands under the Arrange menu in MacDraw will produce. You can use this to your advantage.
Fig. 7 FillPattern Conversion
Fill and Paint are NOT the Same
The second item of interest, is that filling and painting are not the same action in QuickDraw. If you CALL FILLRECT( . . . ) and then follow it with CALL FRAMERECT( . . . ) you get a filled rectangle that has the pattern and the frame GROUPED as MacDraw does with its Fill menu. The top half of the file MacDraw.demo is generated this way. However, if you CALL PAINTRECT( . . . ) and then follow it with CALL FRAMERECT( . . . ) you get a painted rectangle that is NOT GROUPED. In other words, the paint can spill out of the frame. I took the file MacDraw.demo into MacDraw to demonstrate this, as shown in Figure 8.
As you can see, the bottom three figures have their paint selected and then dragged out of the frames. You can get this same effect in MacDraw, itself, by drawing your shape, filling it with your selected pattern, and then changing its frame line to 0-weight (the dashed line under the Lines menu). The only reason to do it this way in our program is that painting avoids the stuffhex call to set up the pattern and get a pointer to it.
The MacDrawFiles.BAS Program
The last program of the three is the largest and incorporates all of the features of MacDraw itself. It wont let you work interactively, like selecting lines and moving them around. Ill let that to MacDraw and the others. But it will give you the tools to create a MacDraw compatible file inside of your ZBasic program and get the full benefit of:
(1) any selected font family
(2) all 8 MacDraw font sizes
(3) all 6 MacDraw font styles & combinations
(4) all 36 MacDraw fill/pen patterns
(5) all 5 MacDraw line weights
(6) all 3 MacDraw arrowhead lines
(7) all 9 MacDraw tools along the left pallete, i.e.,:
a. text
b. orthogonal lines
c. diagonal lines
d. rectangles
e. rounded-corner rectangles
f. ovals
g. arcs
h. freehand
i. polygons
Fig. 8 Effects of Painting
Figure 9 shows two different parts of the MacDraw.text file. The upper half has several different fonts, all in 12 pt Bold. It also contains the 6 basic font styles and a combination of Bold-through-Shadow.
The lower half uses Helvetica, in Bold, to illustrate all 8 MacDraw font sizes. Although you can invoke any font size in your ZBasic program, MacDraw only allows these eight sizes. If you give it a size it doesnt have, say 16 pt, it will default to 12 pt. The moral of the story is . . . if you are going to bring your drawing into MacDraw, itself, use these sizes only - even if you fudged it (Tiny 9 is an example).
The upper left portion of Figure 10 shows most of the 36 fill patterns and the upper right shows a portion of the 36 pen patterns. Scrolling around in MacDraw will give you a better look at all of them. The center portion of the upper half of Figure 10 contains the different line weights and the start of the arrowhead lines. Some more of these arrowhead lines are shown down the center of the lower half of the figure. The geometric shapes are along the left and right sides of the lower half.
Having mentioned scrolling you should also be aware that if you extend your work of art past the boundaries you set up for your picRect the info is still there. Just go down to the bottom of the Layout menu in MacDraw to the Drawing Size item and select a few more pages to look at. Youll then be able to scroll around and see the missing portions.
Fig. 9 text Output of MacDrawFiles.BAS
Items of Special Interest
If you look at the listing of MacDrawFiles.BAS there are several things of special interest you should note. First of all, as mentioned earlier, dont even bother to call fillrect, filloval, etc., if you want None for the fill. Even though it is in the fill data, its just there for completeness of the data set. Second, the 0 pen size does produce invisible lines, but youll never find them. QuickDraw does not bother to save invisible lines. You can verify this by going directly into MacDraw, drawing a line, making it invisible, and saving the drawing in the PICT format. Quit out of it, load the drawing, and Select All under the Edit menu. Nothing. Note, the MacDraw proprietary format, however, will save those invisible lines!
Fig. 10 graphics Output of MacDrawFiles.BAS
The third thing to take a look at is the ovalWidth and ovalHeight for the rounded-corner rectangles. They are both shown as 20 pixels in size. Ive tried several different size and aspect-ratio rounded-corner rectangles in MacDraw, itself, and they always come back 20-by-20 if you leave its default settings alone. You can go under the Edit menu and change the corners to any one of 6 different settings. Our fourth item of interest is the so-called freehand tool. MacDraw uses the polygon to describe freehand drawing . . . but not exactly. It really is a polygon, but I dont know what algorithm MacDraw uses to decide when to add a new point to the polygon. When you draw freehand in your programs, youll probably use a lot more points than MacDraw ever would.
The last item is arrowheads! These were the toughest of all to nail down. Finally, I created a special subroutine called, naturally, ArrowHeads. Just feed it the x & y coordinates of both end points of the line (xahl1%, yahl1%, xahl2%, & yahl2%) and the type of arrowhead desired (ArrwPt%=1 for end-pt 1, 2 for 2, & 3 for both) and it will figure out the angles and adjust the line length for the proper match with the arrowhead(s). Study the subroutine coding (its heavily commented) and it will become clear what it has to do.
ZBasic configuration
Since ZBasic can be configured to just about any range of variables imagined, Ive elected to include the configuration that was used for running the programs in Figure 11. All three will run with version 3.03 or higher.
Fig. 11 ZBasic 3.03 Configuration
The MacDrawPoly Program
REM
REM (MacDrawPoly.BAS)
REM
REM CREATES A MACDRAW(PICT) CLOSED-POLYGON
REM
WINDOW OFF
COORDINATE WINDOW
REM
REM DEFINE SHORT PICCOMMENTS
REM
NIL&=0
noData%=0
picDwgBeg%=130
picDwgEnd%=131
PolyBegin%=160
PolyEnd%=161
picPlyClo%=165
REM
REM DEFINE PICTURE RECTANGLE (A FULL-SIZE DRAW PAGE)
REM
picRect=0.
picTop%=0
picLeft%=0
picBottom%=720
picRight%=576
REM
REM INITIALIZE PICTURE
REM
CALL SETRECT(picRect,picLeft%,picTop%,picRight%,picBottom%)
REM
REM CREATE THE MACDRAW POLYGONS
REM
FOR File%=1 TO 2
PicHand&=FN OPENPICTURE(picRect)
REM
REM BEGIN A MACDRAW PICTURE
REM
CALL PICCOMMENT(picDwgBeg%,noData%,NIL&)
IF File%=2 THEN poly2
REM
REM * CREATE MACDRAW-TYPE CLOSED-POLYGON *
REM
poly1
CALL PICCOMMENT(PolyBegin%,noData%,NIL&)
CALL PICCOMMENT(picPlyClo%,noData%,NIL&)
CALL MOVETO(85,10)
CALL LINETO(85,45)
CALL LINETO(184,70)
CALL LINETO(225,10)
CALL LINETO(135,35)
CALL LINETO(85,10)
CALL PICCOMMENT(PolyEnd%,noData%,NIL&)
GOTO EndPicture
REM
REM * * * CREATE CONVENTIONAL CLOSED-POLYGON * * *
REM
poly2
PolyHandle&=FN OPENPOLY
CALL MOVETO(85,10)
CALL LINETO(85,45)
CALL LINETO(184,70)
CALL LINETO(225,10)
CALL LINETO(135,35)
CALL LINETO(85,10)
CALL CLOSEPOLY
CALL FRAMEPOLY(PolyHandle&)
CALL KILLPOLY(PolyHandle&)
REM
REM END A MACDRAW PICTURE
REM
EndPicture
CALL PICCOMMENT(picDwgEnd%,noData%,NIL&)
REM
REM CREATE THE MACDRAW PICT FILE
REM
DEF OPEN PICTMDRW
IF File%=1 THEN OPEN O,#1,MacDraw.poly1"
IF File%=2 THEN OPEN O,#1,MacDraw.poly2"
REM
REM WRITE-OUT A 512 BYTE (256 WORDS OR INTEGERS) HEADER OF ZEROES
REM
A%=0
FOR I%=1 TO 256
WRITE #1,A%
NEXT I%
REM
REM CLOSE THE PICTURE & WRITE-OUT THE PICT DATA
REM
CALL CLOSEPICTURE
PicPtr&=PEEK LONG(PicHand&)
PicLength%=PEEK WORD(PicPtr&+0)
NumWords%=PicLength%/2
doubleNumWords%=2*NumWords%
IF doubleNumWords%<PicLength% THEN NumWords%=NumWords%+1
FOR I%=1 TO NumWords%
J%=2*(I%-1)
A%=PEEK WORD(PicPtr&+J%)
WRITE #1,A%
NEXT I%
CALL KILLPICTURE(PicHand&)
CLOSE #1
NEXT File%
END
The MacDrawPat Program
REM
REM (MacDrawPat.BAS)
REM
REM CREATES A MACDRAW(PICT) GRAPHICS-DEMO FILE
REM
WINDOW OFF
COORDINATE WINDOW
REM
REM DEFINE SHORT PICCOMMENTS
REM
NIL&=0
noData%=0
picDwgBeg%=130
picDwgEnd%=131
REM
REM READ-IN ALL 36 MACDRAW FILL/PEN PATTERNS AS HEX STRINGS
REM
DIM MacDrawPat$(36)
FOR I%=1 TO 36
READ patID%,MacDrawPat$(I%)
NEXT I%
REM
REM DEFINE PICTURE RECTANGLE (A FULL-SIZE MACDRAW PAGE)
REM
picRect=0.
picTop%=0
picLeft%=0
picBottom%=720
picRight%=576
REM
REM INITIALIZE QUICKDRAW RECTANGLE
REM
DIM qdRect,qdTop%,qdLeft%,qdBottom%,qdRight%
REM
REM INITIALIZE QUICKDRAW FILL PATTERN
REM
DIM fillPat,row12%,row34%,row56%,row78%
fillPatPtr&=VARPTR(fillPat)
REM
REM INITIALIZE PICTURE
REM
CALL SETRECT(picRect,picLeft%,picTop%,picRight%,picBottom%)
REM
REM * * * CREATE A GRAPHICS-DEMO FILE * * *
REM
PicHand&=FN OPENPICTURE(picRect)
REM
REM BEGIN A MACDRAW PICTURE
REM
CALL PICCOMMENT(picDwgBeg%,noData%,NIL&)
REM
REM TURN ON THE PEN SO WE CAN SEE WHATS HAPPENING
REM
CALL SHOWPEN
REM
REM DRAW A SINGLE-WEIGHT LINE
REM
CALL MOVETO(25,25)
CALL LINETO(325,125)
REM
REM CREATE A FILLRECT - NOTE: FILL & FRAME ARE GROUPED
REM
qdTop%=25
qdLeft%=50
qdBottom%=125
qdRight%=100
CALL SETRECT(qdRect,qdLeft%,qdTop%,qdRight%,qdBottom%)
CALL STUFFHEX(fillPatPtr&,MacDrawPat$(11))
CALL FILLRECT(qdRect,fillPat)
CALL FRAMERECT(qdRect)
REM
REM CREATE A FILLOVAL - NOTE: FILL & FRAME ARE GROUPED
REM
qdTop%=25
qdLeft%=250
qdBottom%=125
qdRight%=300
CALL SETRECT(qdRect,qdLeft%,qdTop%,qdRight%,qdBottom%)
CALL STUFFHEX(fillPatPtr&,MacDrawPat$(34))
CALL FILLOVAL(qdRect,fillPat)
CALL FRAMEOVAL(qdRect)
REM
REM DRAW A DOUBLE-WEIGHT LINE
REM
PEN 2,2,,,
CALL MOVETO(25,125)
CALL LINETO(325,25)
CALL PENNORMAL
REM
REM CREATE A FILLROUNDRECT - NOTE: FILL & FRAME ARE GROUPED
REM
qdTop%=25
qdLeft%=150
qdBottom%=125
qdRight%=200
CALL SETRECT(qdRect,qdLeft%,qdTop%,qdRight%,qdBottom%)
ovalWidth%=10
ovalHeight%=10
CALL STUFFHEX(fillPatPtr&,MacDrawPat$(30))
CALL FILLROUNDRECT(qdRect,ovalWidth%,ovalHeight%,fillPat)
CALL FRAMEROUNDRECT(qdRect,ovalWidth%,ovalHeight%)
REM
REM DRAW A SINGLE-WEIGHT LINE
REM
CALL MOVETO(25,150)
CALL LINETO(325,250)
REM
REM CREATE A PAINTRECT - NOTE: PAINT & FRAME ARE NOT! GROUPED
REM
qdTop%=150
qdLeft%=50
qdBottom%=250
qdRight%=100
CALL SETRECT(qdRect,qdLeft%,qdTop%,qdRight%,qdBottom%)
PEN ,,,,11
CALL PAINTRECT(qdRect)
CALL PENNORMAL
CALL FRAMERECT(qdRect)
REM
REM CREATE A PAINTOVAL - NOTE: PAINT & FRAME ARE NOT! GROUPED
REM
qdTop%=150
qdLeft%=250
qdBottom%=250
qdRight%=300
CALL SETRECT(qdRect,qdLeft%,qdTop%,qdRight%,qdBottom%)
PEN 2,2,,,37
CALL PAINTOVAL(qdRect)
CALL PENNORMAL
CALL FRAMEOVAL(qdRect)
REM
REM DRAW A DOUBLE-WEIGHT LINE
REM
PEN 2,2,,,
CALL MOVETO(25,250)
CALL LINETO(325,150)
CALL PENNORMAL
REM
REM CREATE A PAINTROUNDRECT - NOTE: PAINT & FRAME ARE NOT! GROUPED
REM
qdTop%=150
qdLeft%=150
qdBottom%=250
qdRight%=200
CALL SETRECT(qdRect,qdLeft%,qdTop%,qdRight%,qdBottom%)
ovalWidth%=10
ovalHeight%=10
PEN ,,,,32
CALL PAINTROUNDRECT(qdRect,ovalWidth%,ovalHeight%)
CALL PENNORMAL
CALL FRAMEROUNDRECT(qdRect,ovalWidth%,ovalHeight%)
REM
REM RESET THE PEN, DUE TO THE SHOWPEN CALL
REM
CALL HIDEPEN
REM
REM END A MACDRAW PICTURE
REM
EndPicture
CALL PICCOMMENT(picDwgEnd%,noData%,NIL&)
REM
REM CREATE THE MACDRAW PICT FILE
REM
DEF OPEN PICTMDRW
OPEN O,#1,MacDraw.demo
REM
REM WRITE-OUT A 512 BYTE (256 WORDS OR INTEGERS) HEADER OF ZEROES
REM
A%=0
FOR I%=1 TO 256
WRITE #1,A%
NEXT I%
REM
REM CLOSE THE PICTURE & WRITE-OUT THE PICT DATA
REM
CALL CLOSEPICTURE
PicPtr&=PEEK LONG(PicHand&)
PicLength%=PEEK WORD(PicPtr&+0)
NumWords%=PicLength%/2
doubleNumWords%=2*NumWords%
IF doubleNumWords%<PicLength% THEN NumWords%=NumWords%+1
FOR I%=1 TO NumWords%
J%=2*(I%-1)
A%=PEEK WORD(PicPtr&+J%)
WRITE #1,A%
NEXT I%
CALL KILLPICTURE(PicHand&)
REM
REM * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
REM
REM DATA FOR ALL 36 MACDRAW FILL/PEN PATTERNS AS HEX STRINGS
REM
DATA 1,0000000000000000"
DATA 2,0000000000000000"
DATA 3,FFFFFFFFFFFFFFFF
DATA 4,77DD77DD77DD77DD
DATA 5,AA55AA55AA55AA55"
DATA 6,8822882288228822"
DATA 7,8800220088002200"
DATA 8,8000080080000800"
DATA 9,8000000008000000"
DATA 10,8080413E080814E3"
DATA 11,FF808080FF080808"
DATA 12,8142241881422418"
DATA 13,8040201008040201"
DATA 14,E070381C0E0783C1"
DATA 15,77BBDDEE77BBDDEE
DATA 16,8844221188442211"
DATA 17,99CC663399CC6633"
DATA 18,2040800008040200"
DATA 19,FF00FF00FF00FF00"
DATA 20,FF000000FF000000"
DATA 21,CC00000033000000"
DATA 22,F0F0F0F00F0F0F0F
DATA 23,FF888888FF888888"
DATA 24,AA44AA11AA44AA11"
DATA 25,0102040810204080"
DATA 26,83070E1C3870E0C1"
DATA 27,EEDDBB77EEDDBB77"
DATA 28,1122448811224488"
DATA 29,3366CC993366CC99"
DATA 30,40A00000040A0000"
DATA 31,AAAAAAAAAAAAAAAA
DATA 32,8888888888888888"
DATA 33,0101101001011010"
DATA 34,0008142A552A1408"
DATA 35,FF80808080808080"
DATA 36,8244281028448201"
END
The MacDrawFiles Program
REM
REM (MacDrawFiles.BAS)
REM
REM CREATES A MACDRAW(PICT) TEXT-FILE & GRAPHICS-FILE
REM
REM REFER TO Macintosh Technical Note #27: MacDraws PICT File
REM Format and Comments, August 20, 1986 BY Ginger Jernigan;
REM #21: QuickDraws Internal Picture Definition, June 20, 1986
REM BY Ginger Jernigan; AND #91: Optimizing for the LaserWriter
REM --Picture Comments, March 2, 1987 BY Ginger Jernigan
REM
REM DISABLE ZBASICS DEFAULT WINDOW
REM
WINDOW OFF
REM
REM SET THE COORDINATE SYSTEM TO WINDOW PIXEL COORDINATES
REM
COORDINATE WINDOW
REM
REM ESTABLISH A STATUS WINDOW
REM
WINDOW #1,MacDrawFiles.BAS,(4,41)-(506,337),261
CALL MOVETO(144,50)
PRINT Now creating the MacDraw files . . .
REM
REM DEFINE SHORT PICCOMMENTS
REM
NIL&=0
noData%=0
picDwgBeg%=130
picDwgEnd%=131
PolyBegin%=160
PolyEnd%=161
picPlyClo%=165
REM
REM READ-IN SELECTED FONT FAMILIES
REM
DIM fontNo%(13),fontName$(13)
FOR I%=1 TO 13
READ fontNo%(I%),fontName$(I%)
NEXT I%
REM
REM READ-IN ALL 8 MACDRAW FONT SIZES
REM
DIM fontSize%(8)
FOR I%=1 TO 8
READ fontSize%(I%)
NEXT I%
REM
REM READ-IN ALL 6 MACDRAW FONT STYLES
REM
DIM fontStyle%(6),fontStyle$(6)
FOR I%=1 TO 6
READ fontStyle%(I%),fontStyle$(I%)
NEXT I%
REM
REM READ-IN ALL 36 MACDRAW FILL/PEN PATTERNS AS HEX STRINGS
REM
DIM MacDrawPat$(36)
FOR I%=1 TO 36
READ patID%,MacDrawPat$(I%)
NEXT I%
REM
REM READ-IN ALL 5 MACDRAW LINE WEIGHTS
REM
DIM penWidth%(5),penHeight%(5)
FOR I%=1 TO 5
READ penWidth%(I%),penHeight%(I%)
NEXT I%
REM
REM DEFINE PICTURE RECTANGLE (A FULL-SIZE MACDRAW PAGE)
REM
picRect=0.
picTop%=0
picLeft%=0
picBottom%=720
picRight%=576
REM
REM INITIALIZE QUICKDRAW RECTANGLE
REM
DIM qdRect,qdTop%,qdLeft%,qdBottom%,qdRight%
REM
REM INITIALIZE QUICKDRAW FILL PATTERN
REM
DIM fillPat,row12%,row34%,row56%,row78%
fillPatPtr&=VARPTR(fillPat)
REM
REM INITIALIZE PICTURE
REM
CALL SETRECT(picRect,picLeft%,picTop%,picRight%,picBottom%)
REM
REM CREATE A MACDRAW TEXT-DEMO FILE & A GRAPHICS-DEMO FILE
REM
FOR File%=1 TO 2
PicHand&=FN OPENPICTURE(picRect)
REM
REM BEGIN A MACDRAW PICTURE
REM
CALL PICCOMMENT(picDwgBeg%,noData%,NIL&)
REM
REM CHECK FOR TEXT(File%=1) OR GRAPHICS(File%=2)
REM
IF File%=2 THEN graphics
REM
REM . . . CREATE TEXT FILE . . .
REM
text
REM
REM * * SAMPLE FONT FAMILIES (USE 12 PT BOLD) * *
REM
x%=10
FOR I%=1 TO 13
y%=25*(I%+1)
CALL MOVETO(x%,y%)
TEXT fontNo%(I%),fontSize%(3),fontStyle%(2),1
CALL DRAWSTRING(fontName$(I%))
CALL DRAWSTRING( 12 pt Bold)
NEXT I%
REM
REM * * SAMPLE FONT STYLES (USE HELVETICA 12 PT) * *
REM
x%=180
FOR I%=1 TO 6
y%=25*(I%+1)
CALL MOVETO(x%,y%)
TEXT fontNo%(4),fontSize%(3),fontStyle%(I%),1
CALL DRAWSTRING(fontName$(4))
CALL DRAWSTRING( 12 pt )
CALL DRAWSTRING(fontStyle$(I%))
NEXT I%
y%=y%+25
CALL MOVETO(x%,y%)
Style%=0
Style$=
FOR I%=2 TO 6
Style%=Style%+fontStyle%(I%)
Style$=Style$+fontStyle$(I%)+
NEXT I%
TEXT fontNo%(4),fontSize%(3),Style%,1
CALL DRAWSTRING(fontName$(4))
CALL DRAWSTRING( 12 pt )
CALL DRAWSTRING(Style$)
REM
REM * * SAMPLE FONT SIZES (USE HELVETICA BOLD) * *
REM
x%=10
yold%=391
FOR I%=1 TO 8
y%=yold%+fontSize%(I%)
yold%=y%
CALL MOVETO(x%,y%)
TEXT fontNo%(4),fontSize%(I%),fontStyle%(2),1
CALL DRAWSTRING(fontName$(4))
CALL DRAWSTRING()
Size$=STR$(fontSize%(I%))
CALL DRAWSTRING(Size$)
CALL DRAWSTRING( pt Bold)
NEXT I%
GOTO EndPicture
REM
REM . . . CREATE GRAPHICS FILE . . .
REM
graphics
REM
REM * * SAMPLE ALL 36 MACDRAW FILL PATTERNS * *
REM NOTE: FILL & FRAME ARE GROUPED AUTOMATICALLY
REM
FOR I%=1 TO 3
qdBottom%=20
FOR J%=1 TO 12
K%=(I%-1)*12+J%
qdTop%=qdBottom%+5
qdLeft%=10+(I%-1)*30
qdBottom%=qdTop%+25
qdRight%=qdLeft%+25
CALL SETRECT(qdRect,qdLeft%,qdTop%,qdRight%,qdBottom%)
CALL STUFFHEX(fillPatPtr&,MacDrawPat$(K%))
IF K%>1 CALL FILLRECT(qdRect,fillPat)
CALL FRAMERECT(qdRect)
NEXT J%
NEXT I%
REM
REM * * SAMPLE ALL 5 MACDRAW LINE WEIGHTS * *
REM
TEXT fontNo%(4),fontSize%(1),fontStyle%(2),1
x%=150
FOR I%=1 TO 5
y%=10+30*I%
CALL MOVETO(x%,y%)
Width$=STR$(penWidth%(I%))
Height$=STR$(penHeight%(I%))
Note$= Line Width,Height = +Width$+,+Height$
CALL DRAWSTRING(Note$)
CALL MOVE(10,-penHeight%(I%))
CALL PENSIZE(penWidth%(I%),penHeight%(I%))
CALL LINE(41-penWidth%(I%),0)
CALL PENNORMAL
NEXT I%
REM
REM * * SAMPLE ALL 3 MACDRAW ARROWHEADS * *
REM
REM USE HORIZ LINES
REM
dx%=50
dy%=0
x%=90
REM
REM USE RIGHT(I%=1), LEFT(I%=2), & BOTH(I%=3) ARROWHEADS
REM
FOR I%=1 TO 3
x%=x%+65
REM
REM USE ALL 5 LINE WEIGHTS
REM
FOR J%=1 TO 5
y%=150+30*J%
CALL PENSIZE(penWidth%(J%),penHeight%(J%))
xahl1%=x%
yahl1%=y%
xahl2%=x%+dx%
yahl2%=y%+dy%
REM
REM ADJUST LENGTHS FOR PENSIZE
REM
IF I%=1 THEN xahl2%=xahl2%+1-penWidth%(J%)
IF I%=2 THEN xahl1%=xahl1%+1
ArrwPt%=I%
GOSUB ArrowHeads
NEXT J%
NEXT I%
REM
REM USE VERT LINES
REM
dx%=0
dy%=50
y%=270
REM
REM USE RIGHT(I%=1), LEFT(I%=2), & BOTH(I%=3) ARROWHEADS
REM
FOR I%=1 TO 3
y%=y%+65
REM
REM USE ALL 5 LINE WEIGHTS
REM
FOR J%=1 TO 5
x%=140+30*J%
CALL PENSIZE(penWidth%(J%),penHeight%(J%))
xahl1%=x%
yahl1%=y%
xahl2%=x%+dx%
yahl2%=y%+dy%
REM
REM ADJUST LENGTHS FOR PENSIZE
REM
IF I%<>2 THEN yahl1%=yahl1%-1
IF I%=1 THEN yahl2%=yahl2%-penHeight%(J%)
ArrwPt%=I%
GOSUB ArrowHeads
NEXT J%
NEXT I%
REM
REM USE 45 DEG. LINES
REM
dx%=INT(50./SQR(2.))
dy%=INT(50./SQR(2.))
y%=490
REM
REM USE RIGHT(I%=1), LEFT(I%=2), & BOTH(I%=3) ARROWHEADS
REM
FOR I%=1 TO 3
y%=y%+50
REM
REM USE ALL 5 LINE WEIGHTS
REM
FOR J%=1 TO 5
x%=125+30*J%
CALL PENSIZE(penWidth%(J%),penHeight%(J%))
xahl1%=x%
yahl1%=y%
xahl2%=x%+dx%
yahl2%=y%+dy%
REM
REM ADJUST LENGTHS FOR PENSIZE
REM
IF I%=1 THEN df1
IF I%=2 THEN df2
GOTO df3
df1 xahl2%=xahl2%-1-INT(penWidth%(J%)/SQR(2.))
yahl2%=yahl2%-1-INT(penHeight%(J%)/SQR(2.))
IF J%<5 THEN df3
xahl2%=xahl2%+1
yahl2%=yahl2%+1
GOTO df3
df2 xahl1%=xahl1%+1+INT(penWidth%(J%)/SQR(2.))
yahl1%=yahl1%+1+INT(penHeight%(J%)/SQR(2.))
IF J%<3 THEN df3
xahl1%=xahl1%-1
yahl1%=yahl1%-1
IF J%<5 THEN df3
xahl1%=xahl1%-1
yahl1%=yahl1%-1
df3 ArrwPt%=I%
GOSUB ArrowHeads
NEXT J%
NEXT I%
CALL PENNORMAL
REM
REM * * SAMPLE ALL 36 MACDRAW PEN PATTERNS * *
REM
CALL PENSIZE(penWidth%(5),penHeight%(5))
FOR I%=1 TO 3
y%=5
FOR J%=1 TO 12
K%=(I%-1)*12+J%
x%=385+(I%-1)*50
y%=y%+30
CALL MOVETO(x%,y%)
CALL STUFFHEX(fillPatPtr&,MacDrawPat$(K%))
CALL PENPAT(fillPat)
CALL LINE(40,0)
NEXT J%
NEXT I%
CALL PENNORMAL
REM
REM * * SAMPLE ALL 8 GRAPHICS TOOLS * *
REM
CALL PENSIZE(penWidth%(3),penHeight%(3))
REM
REM USE ORTHOGONAL LINES
REM
CALL MOVETO(10,420)
CALL LINETO(50,420)
CALL MOVETO(80,400)
CALL LINETO(80,440)
CALL MOVETO(110,400)
CALL LINETO(150,440)
REM
REM USE UNCONSTRAINED LINES
REM
CALL MOVETO(10,450)
CALL LINETO(75,490)
CALL MOVETO(85,490)
CALL LINETO(150,450)
REM
REM USE RECTANGLES
REM
qdTop%=510
qdLeft%=10
qdBottom%=qdTop%+40
qdRight%=qdLeft%+40
CALL SETRECT(qdRect,qdLeft%,qdTop%,qdRight%,qdBottom%)
CALL FRAMERECT(qdRect)
qdTop%=520
qdLeft%=60
qdBottom%=qdTop%+20
qdRight%=qdLeft%+60
CALL SETRECT(qdRect,qdLeft%,qdTop%,qdRight%,qdBottom%)
CALL FRAMERECT(qdRect)
qdTop%=500
qdLeft%=130
qdBottom%=qdTop%+60
qdRight%=qdLeft%+20
CALL SETRECT(qdRect,qdLeft%,qdTop%,qdRight%,qdBottom%)
CALL FRAMERECT(qdRect)
REM
REM USE ROUNDED-CORNER RECTANGLES
REM
ovalWidth%=20
ovalHeight%=20
qdTop%=580
qdLeft%=10
qdBottom%=qdTop%+40
qdRight%=qdLeft%+40
CALL SETRECT(qdRect,qdLeft%,qdTop%,qdRight%,qdBottom%)
CALL FRAMEROUNDRECT(qdRect,ovalWidth%,ovalHeight%)
qdTop%=590
qdLeft%=60
qdBottom%=qdTop%+20
qdRight%=qdLeft%+60
CALL SETRECT(qdRect,qdLeft%,qdTop%,qdRight%,qdBottom%)
CALL FRAMEROUNDRECT(qdRect,ovalWidth%,ovalHeight%)
qdTop%=570
qdLeft%=130
qdBottom%=qdTop%+60
qdRight%=qdLeft%+20
CALL SETRECT(qdRect,qdLeft%,qdTop%,qdRight%,qdBottom%)
CALL FRAMEROUNDRECT(qdRect,ovalWidth%,ovalHeight%)
REM
REM USE OVALS
REM
qdTop%=650
qdLeft%=10
qdBottom%=qdTop%+40
qdRight%=qdLeft%+40
CALL SETRECT(qdRect,qdLeft%,qdTop%,qdRight%,qdBottom%)
CALL FRAMEOVAL(qdRect)
qdTop%=660
qdLeft%=60
qdBottom%=qdTop%+20
qdRight%=qdLeft%+60
CALL SETRECT(qdRect,qdLeft%,qdTop%,qdRight%,qdBottom%)
CALL FRAMEOVAL(qdRect)
qdTop%=640
qdLeft%=130
qdBottom%=qdTop%+60
qdRight%=qdLeft%+20
CALL SETRECT(qdRect,qdLeft%,qdTop%,qdRight%,qdBottom%)
CALL FRAMEOVAL(qdRect)
REM
REM USE ARCS
REM
startAngle%=225
arcAngle%=150
qdTop%=410
qdLeft%=385
qdBottom%=qdTop%+40
qdRight%=qdLeft%+40
CALL SETRECT(qdRect,qdLeft%,qdTop%,qdRight%,qdBottom%)
CALL FRAMEARC(qdRect,startAngle%,arcAngle%)
qdTop%=420
qdLeft%=435
qdBottom%=qdTop%+20
qdRight%=qdLeft%+60
CALL SETRECT(qdRect,qdLeft%,qdTop%,qdRight%,qdBottom%)
CALL FRAMEARC(qdRect,startAngle%,arcAngle%)
qdTop%=400
qdLeft%=505
qdBottom%=qdTop%+60
qdRight%=qdLeft%+20
CALL SETRECT(qdRect,qdLeft%,qdTop%,qdRight%,qdBottom%)
CALL FRAMEARC(qdRect,startAngle%,arcAngle%)
REM
REM USE THE FREEHAND TOOL (MACDRAW USES A POLYGON)
REM
PolyHandle&=FN OPENPOLY
PI=4.*ATN(1.)
PIO20=PI/20.
THETA=0.
R=50.*COS(2.*THETA)
X%=455+INT(R*COS(THETA))
Y%=510+INT(R*SIN(THETA))
CALL MOVETO(X%,Y%)
FOR I%=1 TO 20
THETA=I%*PIO20
R=50.*COS(2.*THETA)
X%=455+INT(R*COS(THETA))
Y%=510+INT(R*SIN(THETA))
CALL LINETO(X%,Y%)
NEXT I%
CALL CLOSEPOLY
CALL FRAMEPOLY(PolyHandle&)
CALL KILLPOLY(PolyHandle&)
REM
REM USE A POLYGON
REM
PolyHandle&=FN OPENPOLY
CALL MOVETO(385,540)
CALL LINETO(385,575)
CALL LINETO(485,600)
CALL LINETO(525,540)
CALL LINETO(435,565)
CALL CLOSEPOLY
CALL FRAMEPOLY(PolyHandle&)
CALL KILLPOLY(PolyHandle&)
REM
REM USE A FORCED-CLOSE POLYGON
REM NOTE: THE PICCOMMENTS WILL FORCE CLOSURE
REM
CALL PICCOMMENT(PolyBegin%,noData%,NIL&)
CALL PICCOMMENT(picPlyClo%,noData%,NIL&)
CALL MOVETO(385,610)
CALL LINETO(385,645)
CALL LINETO(485,670)
CALL LINETO(525,610)
CALL LINETO(435,635)
CALL LINETO(385,610)
CALL PICCOMMENT(PolyEnd%,noData%,NIL&)
CALL PENNORMAL
REM
REM END A MACDRAW PICTURE
REM
EndPicture
CALL PICCOMMENT(picDwgEnd%,noData%,NIL&)
REM
REM CREATE THE MACDRAW PICT FILE
REM
CURSOR=4
DEF OPEN PICTMDRW
IF File%=1 THEN OPEN O,#1,MacDraw.text
IF File%=2 THEN OPEN O,#1,MacDraw.graphics
REM
REM WRITE-OUT A 512 BYTE (256 WORDS OR INTEGERS) HEADER OF ZEROES
REM
A%=0
FOR I%=1 TO 256
WRITE #1,A%
NEXT I%
REM
REM CLOSE THE PICTURE & WRITE-OUT THE PICT DATA
REM
CALL CLOSEPICTURE
PicPtr&=PEEK LONG(PicHand&)
PicLength%=PEEK WORD(PicPtr&+0)
NumWords%=PicLength%/2
doubleNumWords%=2*NumWords%
IF doubleNumWords%<PicLength% THEN NumWords%=NumWords%+1
FOR I%=1 TO NumWords%
J%=2*(I%-1)
A%=PEEK WORD(PicPtr&+J%)
WRITE #1,A%
NEXT I%
CALL KILLPICTURE(PicHand&)
CLOSE #1
CURSOR=0
NEXT File%
GOTO Exit
REM
REM * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
ArrowHeads
REM
REM SUBROUTINE TO CONSTRUCT A MACDRAW ARROWHEAD(S) LINE
REM
REM DEFINE ARROWHEAD PARAMETERS
REM
DIM ArrwRect,ArrwRT%,ArrwRL%,ArrwRB%,ArrwRR%
NIL&=0
noData%=0
picArrwR%=170
picArrwL%=171
picArrwB%=172
picArrwEnd%=173
arcAngle%=48
REM
REM GET PEN SIZE & ARROWHEAD RECTANGLE SIZE
REM
DIM pnLocV%,pnLocH%,pnSizeV%,pnSizeH%,pnMode%
DIM pnPat12%,pnPat34%,pnPat56%,pnPat78%
CALL GETPENSTATE(pnLocV%)
IF pnSizeV%=0 THEN RETURN
IF pnSizeV%=1 THEN ArrwWH%=20
IF pnSizeV%=2 THEN ArrwWH%=30
IF pnSizeV%=4 THEN ArrwWH%=40
IF pnSizeV%=6 THEN ArrwWH%=50
REM
REM DETERMINE LINE PROPERTIES
REM
dxahl=xahl2%-xahl1%
dyahl=yahl2%-yahl1%
lineLength=SQR(dxahl*dxahl+dyahl*dyahl)
xcorr%=INT((dyahl/lineLength)*pnSizeV%/2)
ycorr%=INT(ABS(dxahl/lineLength)*pnSizeV%/2)
IF xahl1%=xahl2% THEN ah1
tanAnglw=dyahl/dxahl
Angle=57.2957795*ATN(tanAngle)
IF xahl1%>xahl2% THEN Angle=Angle+180.
lineAngle%=INT(Angle)+90
GOTO ah3
ah1 IF yahl1%>yahl2% THEN ah2
lineAngle%=90+90
GOTO ah3
ah2 lineAngle%=-90+90
REM
REM DETERMINE WHICH ARROWHEAD(S) TO DRAW
REM (ArrwPt%=1 FOR PT 1, 2 FOR 2, 3 FOR BOTH)
REM
ah3 short=(ArrwWH%/2)/lineLength
IF ArrwPt%=2 THEN ah4
REM
REM ARROWHEAD AT PT 1
REM
bothFlag%=1
xahlc%=xahl1%
yahlc%=yahl1%
xahl1%=xahlc%+INT(short*dxahl)
yahl1%=yahlc%+INT(short*dyahl)
startAngle%=lineAngle%-arcAngle%/2
IF xahl1%>xahl2% THEN ah6
IF xahl1%<xahl2% THEN ah5
IF yahl1%>yahl2% THEN ah6
GOTO ah5
REM
REM ARROWHEAD AT PT 2
REM
ah4 bothFlag%=2
xahlc%=xahl2%
yahlc%=yahl2%
xahl2%=xahlc%-INT(short*dxahl)
yahl2%=yahlc%-INT(short*dyahl)
startAngle%=lineAngle%+180-arcAngle%/2
IF startAngle%>360 THEN startAngle%=startAngle%-360
IF xahl1%<xahl2% THEN ah6
IF xahl1%>xahl2% THEN ah5
IF yahl1%<yahl2% THEN ah6
ah5 picArrw%=picArrwL%
IF ArrwPt%=3 THEN picArrw%=picArrwB%
GOTO ah7
ah6 picArrw%=picArrwR%
IF ArrwPt%=3 THEN picArrw%=picArrwB%
REM
REM QUICKDRAW THE ARROWHEAD(S) WITH PAINTARC &
REM USE PICCOMMENTS TO TIE IT(THEM) TO THE LINE
REM
ah7 ArrwRT%=yahlc%-ArrwWH%/2
ArrwRB%=ArrwRT%+ArrwWH%
ArrwRL%=xahlc%-ArrwWH%/2
ArrwRR%=ArrwRL%+ArrwWH%
CALL SETRECT(ArrwRect,ArrwRL%,ArrwRT%,ArrwRR%,ArrwRB%)
IF ArrwPt%<3 THEN ah8
IF bothFlag%<2 THEN ah8
GOTO ah9
ah8 CALL PICCOMMENT(picArrw%,noData%,NIL&)
ah9 CALL PAINTARC(ArrwRect,startAngle%,arcAngle%)
IF ArrwPt%<3 THEN ah10
IF bothFlag%<2 THEN ah4
ah10 xahl1%=xahl1%-xcorr%
yahl1%=yahl1%-ycorr%
xahl2%=xahl2%-xcorr%
yahl2%=yahl2%-ycorr%
CALL MOVETO(xahl1%,yahl1%)
CALL LINETO(xahl2%,yahl2%)
CALL PICCOMMENT(picArrwEnd%,noData%,NIL&)
RETURN
REM
REM * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
REM
REM DATA FOR SELECTED FONT FAMILIES
REM
DATA 0,Chicago
DATA 22,Courier
DATA 3,Geneva
DATA 21,Helvetica
DATA 6,London
DATA 4,Monaco
DATA 15,N Helvetica Narrow
DATA 2,New York
DATA 16,Palatino
DATA 23,Symbol
DATA 20,Times
DATA 5,Venice
DATA 18,Zapf Chancery
REM
REM DATA FOR ALL 8 MACDRAW FONT SIZES
REM
DATA 9
DATA 10
DATA 12
DATA 14
DATA 18
DATA 24
DATA 36
DATA 48
REM
REM DATA FOR ALL 6 MACDRAW FONT STYLES
REM
DATA 0,Plain Text
DATA 1,Bold
DATA 2,Italic
DATA 4,Underline
DATA 8,Outline
DATA 16,Shadow
REM
REM DATA FOR ALL 36 MACDRAW FILL/PEN PATTERNS AS HEX STRINGS
REM
DATA 1,0000000000000000"
DATA 2,0000000000000000"
DATA 3,FFFFFFFFFFFFFFFF
DATA 4,77DD77DD77DD77DD
DATA 5,AA55AA55AA55AA55"
DATA 6,8822882288228822"
DATA 7,8800220088002200"
DATA 8,8000080080000800"
DATA 9,8000000008000000"
DATA 10,8080413E080814E3"
DATA 11,FF808080FF080808"
DATA 12,8142241881422418"
DATA 13,8040201008040201"
DATA 14,E070381C0E0783C1"
DATA 15,77BBDDEE77BBDDEE
DATA 16,8844221188442211"
DATA 17,99CC663399CC6633"
DATA 18,2040800008040200"
DATA 19,FF00FF00FF00FF00"
DATA 20,FF000000FF000000"
DATA 21,CC00000033000000"
DATA 22,F0F0F0F00F0F0F0F
DATA 23,FF888888FF888888"
DATA 24,AA44AA11AA44AA11"
DATA 25,0102040810204080"
DATA 26,83070E1C3870E0C1"
DATA 27,EEDDBB77EEDDBB77"
DATA 28,1122448811224488"
DATA 29,3366CC993366CC99"
DATA 30,40A00000040A0000"
DATA 31,AAAAAAAAAAAAAAAA
DATA 32,8888888888888888"
DATA 33,0101101001011010"
DATA 34,0008142A552A1408"
DATA 35,FF80808080808080"
DATA 36,8244281028448201"
REM
REM DATA FOR ALL 5 MACDRAW LINE WEIGHTS
REM
DATA 0,0
DATA 1,1
DATA 2,2
DATA 4,4
DATA 6,6
Exit
WINDOW CLOSE #1
WINDOW #1,MacDrawFiles.BAS,(4,41)-(506,337),261
TEXT 4,9,0,1
CALL MOVETO(162,50)
PRINT Both MacDraw files created ! !
CALL MOVETO(174,65)
PRINT Hit [Return] to exit . . .
BEEP
INPUT ANS$
WINDOW CLOSE #1
END