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 @
