written by Randy Ding 8/93, for sx and gx randyd@crl.com Hello all! Here is a high speed HP48 graphic editor I have been working on. These are some of it's features... 1) supports unlimited grob size (well really 65536x65536). 2) time critical routines written in sys-rpl and machine language. 3) features a machine language fill/pattern fill routine which will fill any region bordered by on pixels or edge of grob. User can define 8x8 bitmaped fill patterns as well as solid fill. 4) the main menu (which is the smallest portion of this program) is written in user-rpl which allows easy user customization. 5) supports high speed editing of graph grob with full menu control. editing features are fill, erase region, cut/paste type feature, circle, box, and line drawing. 6) User can easily take subroutines from this program (such as the fill routine) and use them in other applications. 7) Its Free! Enjoy. The rest of this document contains: Chapter 0. -- Too anxious to read the manual Chapter 1. -- General Operation Chapter 2. -- Description of programs and variables in the UDRAW directory. Chapter 3. -- Suggestions on customizing the main menu. Source for the main menu follows. ---------------------------------------------------------------------- Chapter 0. -- Too anxious to read the manual Ok, try this out. Press 'start' in the udraw directory. Press NXT three times. Press the LOAD menu key. This is a demo for the fill program. Move the cursor to an area you wish to fill. Now press NXT. Press FPAT menu key, stands for FILL w/pattern. Select the fill pattern you like. Pressing NXT shows more patterns. ---------------------------------------------------------------------- Chapter 1: General Operation Pressing START will invoke the UDRAW program. At this time PICT becomes the active display along with the EDIT menu. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! TO EXIT THE PROGRAM you must press ON in the EDIT menu. If you ! ! get a beep when pressing ON you need to abort your present action and ! ! return to the EDIT menu. As discussed below, pressing NXT from the EDIT ! ! menu will present an alternate menu, one of the keys in this menu is ! ! called EDIT and will return you to the EDIT menu. ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! The six menukeys of the EDIT menu: DOT+,DOT- sets plot mode, bullet in box shows when it's active. 'C' key performs no function. It's menu label is just a number which indicates the cursor stepsize. This can be changed by pressing keys 0..9, 0 is really 10. X-Y briefly displays the cursor's x and y coordinates. Reference is the absolute 0,0 of the grob, not the UL corner of the screen if the PICT has been scrolled by cursor movements. CROSS will change the cursor (looks like a '+' sign) between normal and invert mode. SHBOX will show the box until released. One corner of the box is the present cursor position and the other corner was defined by the cursor position when the Times key (75.1) was pressed. The region inside the box (including border) defines the region of PICT that will be operated on by other commands discussed later. Arrow keys: move cursor (naturally), right shift of the keys will jump to the edge of PICT. *!* If DOT+,DOT- is active, moving the cursor with a stepsize >1 will *!* draw lines connecting the old and new cursor positions. *!* this will not happen with the right-shift movement, however. ENTER: compliments pixil under cursor. 0..9: as said before will change the cursor stepsize. Times key: the mark key. Minus key: Draws line from mark to cursor. Use SHOWBOX to verify the position of the mark. Line will be drawn diagonally from the cursor to the opposite corner of the box (position of mark). ON: exits program (EDIT menu only!). NXT: exits Edit mode, changes menu to alternate list of commands. after pressing NXT for the first time the following commands become active in the menu row (press NXT again to see more commands). NEWP: Creates a new user defined fill pattern which is taken from the upper left 8x8 pixels of PICT. Be sure you have scrolled all-the-way to absolute 0,0 of PICT when making your fill pattern. After pressing this key the screen will flicker for a second and the Fill pattern menu will become active. The program is looking for a keypress which will show where you want to place your new pattern in the Menu. Pressing NXT will display more fill patterns. Pressing a menu key of an existing fill pattern will overwrite the old pattern. Near the end of the list of patterns there should be some blank 'BLNK' entries for you. I have provided 24 places in the Fill menu for patterns. SIZE: briefly displays PICT's dimensions. EDIT: returns to Edit menu (note that the program can only be exited by pressing ON from the Edit menu, your graphics is preserved in PICT). INV: inverts PICT FILL, FPAT: FILL will just use the previously selected fill pattern. FPAT will first give you the list of patterns to select a pattern. Pressing NXT will display more patterns. ZERO: zeros the region inside the box. See SHBOX above. NEG: inverts region inside box. SUB: takes region inside box (subgrob) and stores it. GXOR: takes stored region and XORs it with display, places UL corner of stored region at the cursor position. GOR, REPL: similar to GXOR but performs appropriate action. CIRC: draws circle, center at mark, radius is from mark to cursor. See SHBOX above to see about verifying position of mark. BOX: similar to circle but draws box. LOAD, SAVE: copies PICT to/from a variable in UDRAW directory called 'pict'. RES: clears and resets PICT to 131x64 pixels. CLR: does a ERASE of the current PICT display. Does not change size. ---------------------------------------------------------------------- Chapter 2. -- Description of programs and variables in the UDRAW directory. start: (lower case!) This is a user-rpl program. It contains the code for the main menu. See chapter 3 for more details. pict: (lower case!) a grob variable used by SAVE to store PICT, and used by LOAD to load PICT. SUBG: This is also a grob variable (stands for subgrob) and it is used by SUB to store a subgrob and used by GXOR, GOR, and REPL to recall a stored grob which is placed with the UL corner at the cursor position. PATLIST: This is a list of fill patterns. It has the following format... { { MenuGrob21x8 << #HXSfillpattern %KEYno. >> } { etc. } { etc. } } A fill pattern is described in more detail later and is a 64 bit hex string (or otherwise known as a user-binary). The %KEYno. is a real number which is used by the start program. The first entry in PATLIST must have a real number 1 for %KEYno. and 2 for the second, etc. PATLIST must have some multiple of 6 entries. See ALTMENU for more details on why this is so. If you want to increase the number of fill patterns available to the UDRAW program, you must follow the list's pattern and increase the number of entries by 6 at a time. A single blank entry has this format... { 'BLNK' << 0 %KEYno. >> } If you add six of these blank entries to the end of the PATLIST (note you must use the correct %KEYno.) you will effectively add an extra six blank slots for user defined patterns in the UDRAW program. MAKEFPAT: It is a sys-rpl program which takes nothing from the stack. It will read the PICT upper left 8x8 pixels and return a menugrob21x8 which looks like your user defined fill pattern and will also return a 64 bit hex string (user binary) which represents the user defined fill pattern. This hex string is the third parameter used by the fill routine (see below). MAKEFPAT calls the FILL program. It must be in the current path. FILL: The graphic fill routine. It will fill any concave/convex or complex shape bordered by on-pixels or edge of Grob. Fill works on the current display grob. It can draw on the stack display if you want. A fill pattern is a 8x8 bitmap pattern image which will be repeated over the area to be filled. This bitmap is stored on the stack as a 64 bit user binary number. Note that each of the sixteen 4 bit nibbles have the bit order reversed. You can use the MAKEFPAT program described above to generate both a menu key label grob and 64 bit user binary fill pattern. Fill takes 3 arguments from stack. ! Also note that since the graph grob can be larger than the display, fill may be used to fill a region which is not presently on the screen. In this case you will not see the fill taking place, this does not indicate that the program has frozen - give it time to finish if it is a large region. FILL case i. ( For Pattern Fill ) Levels 3 and 2 contain X and Y user binary numbers to indicate the filling start point. Level 1 contains a fill pattern 64 bit user binary. FILL case ii. ( For Solid Fill ) Levels 3 and 2 contain X and Y user binary numbers to indicate the filling start point. Level 1 contains a real number 0. ALTMENU: This is a sys-rpl program which takes a user defined menu list from the stack. It has exactly the same format as the Custom menu described in the HP48 user manual with the exception that the left/right shift of the menu key defs. are not supported. Altmenu works in much the same way as TMENU except the key 'action' part will be executed when you press it's menu key. Altmenu will wait for a keypress and return control back to the user program after one of the six menukeys has been pressed. ! To make altmenu work properly, you should provide multiples of 6 key definitions so that there are not any undefined menu keys. If you wish for one of the keys to have no action then define it as such by giving that key a null list {} key action part. Unlike using TMENU within a user program, altmenu will allow you to use more than 6 key definitions. NXT/PREV will select between the different pages of the menu. CURSOR: This is the program which gives you the EDIT menu for the UDRAW editor. This program is called by the 'start' program. Calling this from a user program will bring up the Graph grob display and begin editing it. Some keypresses are pre-programmed to terminate the Cursor routine and the keycode of that key will be on level 1. The entire display is frozen until another keypress (like 7 FREEZE). CURSOR reads in and updates on exit the following variables... < these 5 vars contain user binary numbers > X - cursor x Y - cursor y MX - mark x MY - mark y STEPSIZE - cursor stepsize ------------------------------------------------------------------------- Chapter 3. -- Suggestions on customizing the main menu. Note that 'start' is lower case in the UDRAW directory. Upper case 'START' would not be accepted, since it is a reserved word. You may rename 'start' as anything you wish, it is the main menu program and is not called by any other UDRAW programs. I have included the source code with comments of the program 'start' following this brief discussion; it has been provided for easy modification and consequent downloading to replace the existing start program. The main menu in the 'start' program is an ALTMENU based application. See discussion above on how to use ALTMENU. You may easily add or modify entries in the menu list to provide graphic editing functions which are more suited to your own needs. Be careful to follow the guidelines of ALTMENU, especially when adding or deleting menu key definitions so that you always have all six menu keys defined, regardless of which page of the menu is presently being viewed. Use a null list {} for a key without a definition. ----------------------- cut here ---------------------------- ------------------- source for 'start' ---------------------- %%HP: T(3)A(D)F(.); @ Randy Ding 8/93 @ @ version 1.2 @ \<< 0 \-> FPAT @ hxs for old fill pattern @ \<< RCLF 64 STWS DEG CURSOR @ returns exit keycode @ WHILE DUP 91.1 \=/ REPEAT CASE DUP 26.1 == THEN @ handle NEXT menu key from CURSOR @ @ define a menu driven application, call ALTMENU @ { {"NEWP" @ generate new fill patern and store in PATLIST @ \<< @ entry in patlist has format ...{ menugrob << hxs key# >> }...@ MAKEFPAT @ read from graphics screen 8x8 bitmap UL corner at 0,0 @ @ returns menu GROB and HXS|0 @ PATLIST DUP 4 ROLLD ALTMENU @ now select where to store it @ SWAP DROP @ get rid of old hxs stored there @ IF OVER #0h == THEN @ make a blank if #0h pattern @ ROT DROP "BLNK" 3 ROLLD END IF DUP 2 > THEN @ don't overwrite keys 1 or 2 @ DUP 4 ROLLD @ save key# for repl command @ "\>>" + " " SWAP + + @ format data for repl command @ "\<<" SWAP + OBJ\-> @ make it into a program @ 2 \->LIST 1 \->LIST @ { { menugrob << HXS KEY# >> } } REPL 'PATLIST' STO @ overwrite old pattern with new @ ELSE 4 DROPN 340 .07 BEEP END @ alert user can't use those keys @ \>> } @ end NEWP @ {"SIZE" \<< PICT SIZE B\->R "Height= " SWAP + SWAP B\->R "Width = " SWAP + 10 CHR + SWAP + #12B85h SYSEVAL \>> } @ edit inverse menukey grob @ { GROB 21 8 FFFFFF100001173D11115901175901115901173901FFFFFF \<< \>> } @ abort NEXT, go back to edit mode @ {"INV" \<< PICT NEG \>> } {"FILL" \<< X Y FPAT IF DUP #0h \=/ THEN FILL ELSE 3 DROPN END \>> } {"FPAT" \<< PATLIST ALTMENU DROP DUP 'FPAT' STO X Y ROT IF DUP #0h \=/ THEN FILL ELSE 3 DROPN END \>> } {"ZERO" \<< PICT { \<< IF DUP2 < THEN SWAP END DUP2 - #1h + ROT DROP \>> } X MX 3 PICK EVAL Y MY 5 ROLL EVAL 4 ROLL 3 ROLL 2\->LIST 3 ROLLD BLANK REPL \>> } @ end ZERO @ {"NEG" \<< PICT PICT X Y 2 \->LIST MX MY 2\->LIST SUB NEG X MX IF DUP2 > THEN SWAP END DROP Y MY IF DUP2 > THEN SWAP END DROP 2 \->LIST SWAP REPL \>> } {"SUB" \<< PICT X Y 2 \->LIST MX MY 2 \->LIST SUB 'SUBG' STO \>> } {"GXOR" \<< PICT X Y 2 \->LIST SUBG GXOR \>> } {"GOR" \<< PICT X Y 2 \->LIST SUBG GOR \>> } {"REPL" \<< PICT X Y 2 \->LIST SUBG REPL \>> } {"CIRC" \<< X B\->R MX B\->R - Y B\->R MY B\->R - \->V2 ABS R\->B MX MY 2 \->LIST SWAP 360 0 ARC \>> } {"BOX" \<< X Y 2 \->LIST MX MY 2 \->LIST BOX \>> } {"LOAD" \<< #641FCh SYSEVAL pict IF DUP TYPE 11 == THEN #128B0h SYSEVAL ELSE 3 DROPN END \>> } {"SAVE" \<< PICT RCL 'pict' STO \>> } {"RES" \<< #131d #64d BLANK PICT STO \>> } {"CLR" \<< ERASE \>> } } ALTMENU @ !!! ALTMENU LISTS MUST HAVE MULTIPLES OF 6 ENTRIES !!! @ @ waits for keypress, executes object following label name, @ @ execution object must be in {} OR << >> delimiters @ END @ end NEXT dispatch @ DUP 75.1 == THEN X 'MX' STO Y 'MY' STO END @ do mark @ DUP 85.1 == THEN MX MY 2 \->LIST X Y 2 \->LIST LINE END @ do line @ END DROP @ keycode from last CURSOR call @ CURSOR END @ WHILE not OnKey loop @ DROP STOF 2 MENU \>> \>> @ end of readme file @