summaryrefslogtreecommitdiff
path: root/support/qfig
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/qfig
Initial commit
Diffstat (limited to 'support/qfig')
-rw-r--r--support/qfig/eepicsup.sty140
-rw-r--r--support/qfig/q-eepic.tex12
-rw-r--r--support/qfig/q-eepice.tex18
-rw-r--r--support/qfig/q-pictex.tex39
-rw-r--r--support/qfig/qfig11a.doc409
l---------support/qfig/qfig11a.txt1
-rw-r--r--support/qfig/qfig3ple.298
-rw-r--r--support/qfig/qfig4pic.tex86
-rw-r--r--support/qfig/qfig_set.dat59
-rw-r--r--support/qfig/src/mouse.bas187
-rw-r--r--support/qfig/src/mouse.bi13
-rw-r--r--support/qfig/src/qfig.bas1124
-rw-r--r--support/qfig/src/qfig.bi130
-rw-r--r--support/qfig/src/qfig.mak6
-rw-r--r--support/qfig/src/qfigsrc.txt66
-rw-r--r--support/qfig/src/qfigsub1.bas1242
-rw-r--r--support/qfig/src/qfigsub2.bas1206
-rw-r--r--support/qfig/src/qfigsub3.bas620
-rw-r--r--support/qfig/src/qfigsub4.bas347
-rw-r--r--support/qfig/src/qfsrc.bat1
20 files changed, 6004 insertions, 0 deletions
diff --git a/support/qfig/eepicsup.sty b/support/qfig/eepicsup.sty
new file mode 100644
index 0000000000..5909866319
--- /dev/null
+++ b/support/qfig/eepicsup.sty
@@ -0,0 +1,140 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% eepic-supplement to %%% eepic Version 1.1b < Febrary 7, 1988 > %%%
+% %%% Written by Conrad Kwok %%%
+% Version 0.1 < 26 Feb 1993 >
+% by IWAKUMA Tetsuo (bear@hashi1.civil.tohoku.ac.jp)
+%
+\typeout{%
+Supplement to Eepic and LaTeX. Version 0.1 <26 Feb 1993>}
+% to adjust shading pattern
+\def\shade{\@ifnextchar[{\shade@special}{\@killglue\special{sh}\ignorespaces}}
+\def\shade@special[#1]{\@killglue\special{sh #1}\ignorespaces}
+%
+% to add shaded area with/without lines or curves
+\def\shadingwithoutoutline{\gdef\@fp@special{ip}\gdef\@ar@special{ia}}
+\def\outlinedshading{\gdef\@fp@special{fp}\gdef\@ar@special{ar}}
+\outlinedshading % default
+%
+\def\@absspdrawline(#1,#2)(#3,#4){%
+ \special{pn \the\@gphlinewidth}%
+ \@tempdimc=#1\relax
+ \@tempcnta \@tempdimc\relax \advance\@tempcnta 2368 \divide\@tempcnta 4736
+ \@tempdimc=#2\relax
+ \@tempcntb -\@tempdimc\relax \advance\@tempcntb -2368 \divide\@tempcntb 4736
+ \@paspecial{\the\@tempcnta}{\the\@tempcntb}%
+ \@tempdimc=#3\relax
+ \@tempcnta\@tempdimc\relax \advance\@tempcnta 2368 \divide\@tempcnta 4736
+ \@tempdimc=#4\relax
+ \@tempcntb -\@tempdimc\relax \advance\@tempcntb -2368 \divide\@tempcntb 4736
+ \@paspecial{\the\@tempcnta}{\the\@tempcntb}%
+ \special{\@fp@special}%
+ \ignorespaces
+}
+%
+\def\@linespecial#1#2{%
+ \special{pn \the\@gphlinewidth}%
+ \special{pa 0 0}%
+ \special{pa #1 #2}%
+ \special{\@fp@special}%
+}
+%
+\def\@path(#1,#2){%
+ \@tempdima #1\unitlength
+ \@tempdimb #2\unitlength
+ \@tempcnta \@tempdima \advance\@tempcnta 2368 \divide\@tempcnta 4736
+ \@tempcntb -\@tempdimb \advance\@tempcntb -2368 \divide\@tempcntb 4736
+ \@paspecial{\the\@tempcnta}{\the\@tempcntb}%
+ \@ifnextchar ({\@path}{\special{\@fp@special}}%
+}
+%
+\def\@circlespecial#1#2#3#4{%
+ \special{pn \the\@gphlinewidth}%
+ \special{\@ar@special 0 0 #1 #2 #3 #4}
+}
+%
+\def\@qcircspecial#1#2#3#4#5{\special{\@ar@special #1 #2 #3 #3 #4 #5}}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\endinput
+%%
+%% an example
+%%
+\documentstyle[epic,eepic,eepicsup]{article}
+\textheight=20cm
+\newcommand{\bs}{{\tt\symbol{'134}}}
+\begin{document}
+\title{Supplement to eepic.sty}
+\author{an author}
+\date{26 Feb 1993}
+\maketitle\thispagestyle{empty}
+\unitlength=.25mm
+\begin{description}
+\item[{\tt {\bs}shade[n]} : ] to change shading pattern,
+where {\tt n} can be a number between 0 and 1.
+\begin{center}
+\begin{picture}(192,149)(205,-5)
+\thinlines
+\shade\put(320,63){\circle{40}}
+\shade[0.1]\path (300,115)(312,139)(352,127)(352,95)(328,95)(300,115)
+\shade[0.7]\path (376,95)(375.6,96.4)(375,97.6)(374.4,98.4)(373.8,98.8)
+(373,99)(372.2,98.8)(371.2,98.4)(370.2,97.6)(369.2,96.4)
+(368,95)(365.7,91.6)(363.5,88.3)(361.5,85)(359.7,81.7)
+(358,78.5)(356.5,75.3)(355.1,72.2)(353.9,69.1)(352.9,66)
+(352,63)(350.4,58.9)(349.1,55.2)(348.2,51.7)(347.7,48.4)
+(347.5,45.5)(347.7,42.8)(348.2,40.5)(349.1,38.4)(350.4,36.5)
+(352,35)(356.9,33.4)(361.4,32.1)(365.7,31.2)(369.8,30.7)
+(373.5,30.5)(377,30.7)(380.1,31.2)(383,32.1)(385.7,33.4)
+(388,35)(390.1,39.1)(391.8,43.2)(393.3,47.1)(394.6,50.8)
+(395.5,54.5)(396.2,58)(396.5,61.5)(396.6,64.8)(396.5,67.9)
+(396,71)(395.3,73.9)(394.2,76.8)(392.9,79.5)(391.4,82)
+(389.5,84.5)(387.4,86.8)(384.9,89.1)(382.2,91.2)(379.3,93.1)(376,95)
+\end{picture}
+\end{center}
+
+\item[{\tt {\bs}shadingwithoutoutline} : ] to remove outlines
+of the shaded areas.
+\shadingwithoutoutline
+\begin{center}
+\begin{picture}(192,149)(205,-5)
+\thinlines
+\shade\put(320,63){\circle{40}}
+\shade[0.8]\path (300,115)(312,139)(352,127)(352,95)(328,95)(300,115)
+\shade[0.2]\path (376,95)(375.6,96.4)(375,97.6)(374.4,98.4)(373.8,98.8)
+(373,99)(372.2,98.8)(371.2,98.4)(370.2,97.6)(369.2,96.4)
+(368,95)(365.7,91.6)(363.5,88.3)(361.5,85)(359.7,81.7)
+(358,78.5)(356.5,75.3)(355.1,72.2)(353.9,69.1)(352.9,66)
+(352,63)(350.4,58.9)(349.1,55.2)(348.2,51.7)(347.7,48.4)
+(347.5,45.5)(347.7,42.8)(348.2,40.5)(349.1,38.4)(350.4,36.5)
+(352,35)(356.9,33.4)(361.4,32.1)(365.7,31.2)(369.8,30.7)
+(373.5,30.5)(377,30.7)(380.1,31.2)(383,32.1)(385.7,33.4)
+(388,35)(390.1,39.1)(391.8,43.2)(393.3,47.1)(394.6,50.8)
+(395.5,54.5)(396.2,58)(396.5,61.5)(396.6,64.8)(396.5,67.9)
+(396,71)(395.3,73.9)(394.2,76.8)(392.9,79.5)(391.4,82)
+(389.5,84.5)(387.4,86.8)(384.9,89.1)(382.2,91.2)(379.3,93.1)(376,95)
+\outlinedshading
+\whiten\put(326,57){\circle{40}}
+\end{picture}
+\end{center}
+
+\item[{\tt {\bs}outlinedshading} : ] for outlined shadings.
+\outlinedshading
+\begin{center}
+\begin{picture}(192,149)(205,-5)
+\thinlines
+\shade\put(320,63){\circle{40}}
+\shade[0.6]\path (300,115)(312,139)(352,127)(352,95)(328,95)(300,115)
+\shade[0.5]\path (376,95)(375.6,96.4)(375,97.6)(374.4,98.4)(373.8,98.8)
+(373,99)(372.2,98.8)(371.2,98.4)(370.2,97.6)(369.2,96.4)
+(368,95)(365.7,91.6)(363.5,88.3)(361.5,85)(359.7,81.7)
+(358,78.5)(356.5,75.3)(355.1,72.2)(353.9,69.1)(352.9,66)
+(352,63)(350.4,58.9)(349.1,55.2)(348.2,51.7)(347.7,48.4)
+(347.5,45.5)(347.7,42.8)(348.2,40.5)(349.1,38.4)(350.4,36.5)
+(352,35)(356.9,33.4)(361.4,32.1)(365.7,31.2)(369.8,30.7)
+(373.5,30.5)(377,30.7)(380.1,31.2)(383,32.1)(385.7,33.4)
+(388,35)(390.1,39.1)(391.8,43.2)(393.3,47.1)(394.6,50.8)
+(395.5,54.5)(396.2,58)(396.5,61.5)(396.6,64.8)(396.5,67.9)
+(396,71)(395.3,73.9)(394.2,76.8)(392.9,79.5)(391.4,82)
+(389.5,84.5)(387.4,86.8)(384.9,89.1)(382.2,91.2)(379.3,93.1)(376,95)
+\end{picture}
+\end{center}
+\end{description}
+\end{document}
diff --git a/support/qfig/q-eepic.tex b/support/qfig/q-eepic.tex
new file mode 100644
index 0000000000..32142deb31
--- /dev/null
+++ b/support/qfig/q-eepic.tex
@@ -0,0 +1,12 @@
+\documentstyle[12pt,epic,eepic]{article}
+% \documentstyle[12pt,epic,eepicemu]{article} % if not supported
+% \documentstyle[12pt,epic,ecleepic]{article} % if you have it
+\typein[\Fname]{Enter File Name to be input}
+\begin{document}
+\begin{figure}
+\begin{center}
+\input{\Fname}
+\end{center}
+\caption{Test of eepic.sty}
+\end{figure}
+\end{document}
diff --git a/support/qfig/q-eepice.tex b/support/qfig/q-eepice.tex
new file mode 100644
index 0000000000..ef6f1d3fe2
--- /dev/null
+++ b/support/qfig/q-eepice.tex
@@ -0,0 +1,18 @@
+\documentclass[12pt]{article}
+\usepackage{epic,eepic}
+\typein[\Fname]{Enter File Name to be input}
+\begin{document}
+This is an example for latex2e (please remember that you have to modify
+qfig-set.dat so that the output will be compatible with latex2e see
+qfig.doc for more details). \\
+Here, I put the figure,
+\begin{figure}
+\begin{center}
+\input{\Fname}
+\end{center}
+\caption{Test of eepic.sty}
+\end{figure}
+before this line.
+This is an example.
+\end{document}
+ \ No newline at end of file
diff --git a/support/qfig/q-pictex.tex b/support/qfig/q-pictex.tex
new file mode 100644
index 0000000000..38567a7311
--- /dev/null
+++ b/support/qfig/q-pictex.tex
@@ -0,0 +1,39 @@
+\documentstyle[12pt]{article}
+\input{prepictex}
+\input{pictex}
+\input{postpictex}
+\typein[\Fname]{Enter File Name to be input}
+\begin{document}
+This is an example.
+This is an example.
+This is an example.
+This is an example.
+This is an example.
+This is an example.
+This is an example.
+This is an example.
+This is an example.
+This is an example.
+This is an example.
+This is an example.
+This is an example.
+This is an example.
+Here, I put the figure,
+\input{\Fname}
+before this line.
+This is an example.
+This is an example.
+This is an example.
+This is an example.
+This is an example.
+This is an example.
+This is an example.
+This is an example.
+This is an example.
+This is an example.
+This is an example.
+This is an example.
+This is an example.
+This is an example.
+This is an example.
+\end{document}
diff --git a/support/qfig/qfig11a.doc b/support/qfig/qfig11a.doc
new file mode 100644
index 0000000000..33a4ed6bd7
--- /dev/null
+++ b/support/qfig/qfig11a.doc
@@ -0,0 +1,409 @@
+
+ QFIG (Ver.1.1a : 3/24/1997)
+
+QFIG is a graphics program for LaTeX for use on IBM Compatible PCs (MS-DOS and
+DOS/V). This is a version of the NEC PC9801 qfig 0.9c for IBM/J-3100 PCs.
+The NEC version was written by MR T. Iwakuma (bear@hashi1.civil.tohoku.ac.jp) and
+modified for IBM/J-3100 PCs using Quick-Basic.
+
+ This program is free software; you can redistribute it and/or modify it at will,
+however, if you make modifications/bug fixes to this program, please contact me first for
+redistribution to prevent many different versions from appearing all over at the same
+time and also to keep other users up to date with improvements to QFIG. I would also
+appreciate it if our names are not removed from this document. This is to enable people
+with questions, comments or suggestions to be able to contact us.
+ This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. Whoever uses it does so at her/his own risk.
+We cannot take any responsibility on correct function or correct documentation.
+
+The source should be available through the same channel that you got QFIG from.
+
+
+ Questions and Comments:
+If you have any comments, please inform me (preferably in english) at the email address
+below. Since I do not use LaTeX, this is probably the last version of Qfig I will be
+releasing. I will however try to correct any major bugs found in this version and release
+bug-fix updates.
+
+ William Ofosu-Amaah
+ e-mail: XI6W-OFSA@asahi-net.or.jp
+
+Special thanks to Dr Lazhar Ben-Brahim who tested Qfig 1.0 & 1.1. l would also like to
+say thanks to Simon Maxwell for the Logo design and also to Ken Tanaka, Takene and
+Phil Swan for their significant contributions to Qfig 1.0 and Bruce Dearden
+<dearden@pc4.math.und.nodak.edu> for kindly donating a Qfig Plain TeX PiCTeX
+shim.
+
+
+The QFIG program contains the following:
+ QFIG.EXE - The .exe file for QFIG
+ QFIG.DOC - This document
+ QFIG_SET.DAT - A file for setting your own user-data
+ Q-EEPIC.TEX - Used to compile figures outputted in eepic code
+ Q-EEPICE.TEX - Used to compile figures outputted in eepic code
+ for LaTeX2e. Please refer to the file for further
+ details.
+ Q-PICTEX.TEX - Used to compile figures outputted in pictex code
+ QFIG3PLE - QFIG example file
+ EEPICSUP.STY - Supplement style file to Eepic and LaTeX for adjust
+ shading pattern
+ QFIG4PIC.TEX - Interface for QFIG-generated PiCTeX code and PiCTeX
+ to use with Plain TeX (Donated by Bruce Dearden).
+ Please refer to the file for further details.
+
+All other required .STY files are available at CTAN (e.g. ftp.tex.ac.uk)
+or other mirror sites.
+
+1. NOTES
+
+(i) This version will only run on EGA/VGA/SVGA PCs. There is no CGA version.
+
+(ii) Mouse use:
+This program supports use of a mouse although a mouse is not necessary. If a mouse is
+to be used, the mouse driver should be loaded before running qfig.
+
+(iii) Caps-Lock and Num-Lock:
+IMPORTANT NOTE: Caps-Lock and Num-Lock should be OFF for proper operation of
+QFIG
+control+keystroke commands. Caps-Lock and Num-Lock can, however, be used when
+entering text.
+
+2. Starting QFIG
+
+QFIG startup options: QFIG /? /e /f /nc /s
+
+(i) /? option
+
+To get help on the options which could be used when QFIG is started up use the "/?"
+option i.e.
+
+ C:> qfig /? <CR>
+
+(ii) /e option
+
+If an EGA monitor is being used, the "/e" option is essential for running QFIG in EGA
+mode.
+
+(iii) /f option
+
+To use your own settings from the file QFIG_SET.DAT.
+If QFIG is started without using the "/f" option, QFIG uses the default settings.
+IMPORTANT NOTE 1: QFIG_SET.DAT should be placed somewhere in the path.
+IMPORTANT NOTE 2: If you are on a network and have network drives in the path,
+make sure QFIG_SET.DAT is placed in a directory in the path BEFORE directories you don't
+have write access to. The way Qfig is written, it will not work if it encounters
+a read-only directory while searching the path for QFIG_SET.DAT. An alternative is to
+write a small bat file which sets the path and removes all the read-only directories
+from it. You could then write another bat file to restore the path after using Qfig.
+This is not a problem if you are not using the QFIG_SET.DAT file.
+
+
+(iv) /nc option
+
+This was part of the NEC version and is for those who are using dvi-drivers without
+TPIC specials. In this case, shadings are imitated by drawing many dotted lines, etc.
+This option can be ignored.
+
+(v) /s option
+
+The NEC 0.9c version of QFIG converts some special inputted text characters to other
+output in the .TEX files (e.g. if "\" was input, it becomes "\tt\symbol{'134}" in .TEX file
+output). In the IBM version this use of special characters has been made optional. To
+use these special characters, the "/s" option should be added when starting up QFIG. If
+this option is not used, the inputted characters are not converted. (i.e. if "\" is input it
+remains "\" in the .TEX file output).
+This option can be ignored.
+
+3. Printing
+
+There is no built-in printing function in QFIG. To print, QFIG files have to be converted
+to .TEX files and printed using LaTeX (see 6. below).
+
+4. Menus
+
+(a) The three rows at the bottom of the screen are the selection choices for QFIG. The
+"ESC" key is used as a toggle between the three rows with the active row indicated by
+the "@" sign to the left of the row. Function keys F1 - F10 are used for selecting specific
+choices in the rows.
+Selections can also be made with a mouse by moving the cursor to the desired selection
+and clicking one of the two mouse buttons.
+Before switching from one menu item to another the "DEL" key must be used to clear
+the current menu choice before another item menu can be selected (see table below for
+equivalent mouse action). The "DEL" key is also used to quit performing a function (e.g.
+clear a line which you decide not to draw while in the middle of drawing it.).
+The following table shows the mouse equivalent to keyboard functions used.
+
+ Keyboard | Mouse
+ ---------------------------
+ Return Key | Right Button
+ Space Key | Left Button
+ DEL key | Simultaneous use of the
+ | Left & Right Buttons
+ Arrow keys | Mouse movement
+
+For simplicity, this document will use only the Keyboard keys in the following
+explanations since the mouse can be made to perform the same functions using the table
+above.
+
+(b) Menu Items
+
+These are explained for the function keys. Note that each function key has two or three
+selections connected. The one which is chosen depends on which menu row is active (see
+4(a) above). For more information on using a specific function use the online help
+available in the program which is explained below (4(c)).
+
+f.1 Straight Lines / Move / Fill Pattern for Boxes
+
+f.2 Curved Lines / Copy/ Font Type
+
+f.3 Circle+Ellipse / Symmetric Copy / Font Size
+
+f.4 Arc /Rotate / Zoom
+
+f.5 Box / Edit/ Text Hide or Show (Text Toggle)
+
+
+f.6 Polygon / Displace or Cut / Redraw screen
+
+f.7 Closed Curve / Kill / Reset screen (this erases the current drawing)
+
+f.8 Arrow / Line Type
+
+f.9 Strings (i.e. text) / Thickness
+
+f.10 File Operations / Pitch (i.e. cursor movement step size when using the arrow keys.
+This does not affect the cursor movement when using the mouse.
+
+NOTE:
+The menu items which are green in color (Box Fill Pattern, Font type/Size, Line
+Type/Thickness, Cursor Pitch) can be changed during performing operations (e.g.
+changing line type/thickness while drawing lines)
+
+
+[Keyboard Shortcuts]
+Some of the menu items have keyboard shortcuts. These are the same as they were in
+Qfig ver 1.0
+
+They are:
+QUIT [CTRL+q] - This is used to quit the program. QUIT is also available from the File
+(f.10) menu. As a precautionary measure, the user is prompted twice. Once to confirm
+quitting and then to check if the user wants the file saved. If yes is answered to this, the
+file is saved by default under the name $_qfig_$.qfg unless the user specifies another
+filename when prompted to do so.
+
+ZOOM [CTRL+w] - The zoom function cannot be used to zoom in.
+** If a mouse is being used, zooming is possible by placing the cursor in the top left
+corner of the screen and clicking with either button.
+
+REDRAW [CTRL+r] - This is used to refresh the screen
+
+RESET [CTR+s] - This clears the present drawing.
+
+TEXT TOGGLE [CTRL+t] - This is used to toggle text on the screen between showing
+the complete text and showing only the first character of each text entry. Showing only
+the first character of each entry significantly improves the screen refreshing speed.
+
+
+(c) Other Functions
+
+There are other QFIG functions available which are not in the menus and can usually
+only be operated from the keyboard. They are usually triggered by the simultaneous use
+of the Control Key and another key. Mouse operation is also supported for some of these
+functions and will be explained where neccessary. Note that mouse operations can be
+duplicated using the keyboard, by using the arrow keys to move the cursor and the space
+bar and return key instead of the left and right mouse buttons respectively.
+
+CTRL+h (HELP) - This is used to obtain online help. The help contents vary depending
+on which menu item has been selected. This enables more help to be available for each
+function. For example to get help on using Lines, select "Lines" from the menu and then
+CTRL+h.
+
+PgUp/PgDn - This is used to scroll the drawing up or down.
+** This can also be done using a mouse by clicking in the bottom left corner
+(PgDn) or clicking at the top of the screen (PgUp).
+
+CTRL+left/right arrows - This is used to shift the screen left or right.
+** This can also be performed using the mouse by clicking at the rightmost or leftmost
+sides of the screen.
+
+5. QFIG File Output
+
+The output of QFIG (i.e. QFIG form files) is as follows:
+1st Line: % Output of qfig.bas
+2nd Line: xmin%, xmax%, ymin%, ymax% (i.e. the dimensions of the figure).
+3rd Line: The Line onward contain the data of the drawing. Each element drawn or
+written consists of a minimum of two lines.
+The first line consists of the type of object and its characteristics (this will be explained
+below) i.e. obj%(i%,j%), j%=0 to 6.
+The second line on consists of the x and y coordinates of the object i.e. xx(i%,j%),
+yy(i%,j%) j% = 0 to obj%(i%,1).
+
+[obj%] 0 1 2 3 4 5 6
+Straight Line 1 node% node% node%-1 thick% ltype% fill%
+Straight Line 1 node% node% node% thick% ltype% 0
+Polygon 2 node% node%-1 node%-1 thick% ltype% 0
+Curved Line 3 node% node% node% thick% ltype% 0
+Closed Curve 4 node% node%-1 node%-1 thick% ltype% 0
+Circle 5 2 1 -1 thick% ltype% 0
+Arc 6 4 2 -1 thick% ltype% 0
+Ellipse 7 2 1 -1 thick% ltype% 0
+Box 8 1 1 -1 thick% ltype% 0
+Filled Box 9 1 1 -1 thick% ltype% fill%
+String (Text) 10 length 0 -1 12 stype% object# + 1
+Arrows 11 2 -1 -1 thick% object# node%
+
+
+6. TeX File Output
+
+There are three included output codes for LaTeX:
+
+ a. PICTEX - This needs the following macro files - "prepictex.tex, pictex.tex,
+postpictex.tex" - which are supplied with LaTeX. This is supported by practically all DVI
+screen/print drivers. It is, however, slower.
+
+ b. EEPIC - This needs the epic.sty and eepic.sty style files. With EEPIC pictures,
+the .TEX files are smaller and LaTeX runs a lot faster while requiring less memory than
+the other two. However DVI screen/print drivers which support EEPIC are necessary.
+
+ c. EEPICEMU - Emulator for EEPIC.
+
+7. String Output
+
+The string output (font size and type) is compatible with LaTeX 2.09 and uses "xiipt" and
+"xpt" commands to specify font size. It is now possible to easily change this by changing
+the
+output codes in the qfig_set.dat file. Please refer to this file for details on how
+and where to do this.
+
+For example, for one way to generate LaTeX2e output you can replace the following
+lines in
+the qfig_set.dat file:
+
+\xpt\rm ;10pt roman
+\xpt\bf ;10pt bold
+\xpt\it ;10pt italic
+\xpt\FonttenBI ;10pt bold italic
+\xiipt\rm ;12pt roman
+\xiipt\bf ;12pt bold
+\xiipt\it ;12pt italic
+\xiipt\FonttwlBI ;12pt bold italic
+
+
+with the following:
+
+\sf ;10pt roman
+\bf ;10pt bold
+\it ;10pt italic
+\bf\it ;10pt bold italic
+\large\sf ;12pt roman
+\large\bf ;12pt bold
+\large\it ;12pt italic
+\large\bf\it ;12pt bold italic
+
+
+8. Loading/Saving
+
+Loading
+Qfig now displays only the files with a .qfg extension. You can still load in files which
+don't use this extension by typing in the full file name. Note that to load any file
+(including .qfg
+files) you have to include the extension. We recommend that you add the extension
+".qfg" to all your old qfig data files.
+
+Saving
+Qfig is now written to save .qfg files as the default. It is possible to override the .qfg
+extension when saving by typing the extension type [e.g. "filename.ext" instead of
+"filename"]. Typing just "filename" will add a ".qfg" extension automatically.
+The saving process has been simplified. You can now save both the .qfg file and the tex
+file at the same time.
+
+
+9. Box Text
+
+Limited support for centering text in a Box was added. This just calculates the center of
+the box to locate the correct position for the text.
+IMPORTANT NOTE: Changes made to the size of the box or its position will not keep
+the text at the center. It is however possible to keep the text centered if both the Box and
+centered text are moved together.
+
+
+10. Area Kill/Edit
+
+In the Kill/Edit functions, it is now possible to select a rectangular area and kill/Edit all
+objects within the selected area. In the case of Edit, the string and line types must be
+selected before editing. The lines within the selected area are automatically changed to
+the selected thickness and type. Changing the string font/size within the selected area is
+however optional.
+Note that any object with a node in the selected area is considered as being selected.
+
+--------------------------------------------------------------------------
+Change from Qfig 1.1 to Qfig 1.1a
+
+1. Fixed bug in Boxtext
+
+------------------------
+Changes from Qfig 1.0 to Qfig 1.1
+
+1. Added a third menu line for easier program use
+
+2. Allowed string output to be user-configured
+
+3. Box Text added (allows centering of text in a box)
+
+4. Kill multiple items at the same time (Area Kill)
+
+5. Edit multiple items at the same time (Area Edit)
+
+6. Changes in thickness of a line now automatically changes the
+ thickness of attached arrow.
+
+7. NGRAPH support removed (including Ctrl+p)
+
+8. Ctrl+g (GROUP/UNGROUP) removed (use functions like Area Kill/Edit instead)
+
+9. Simplication of saving and loading
+
+10. Answering to "y/n?" questions now possible with mouse
+ (expect in a few places like when Quiting or using Reset. These
+ respond only to keyboard "y" and "n" commands.)
+
+11. A Bug in "Rotate" fixed
+
+12. Bug in maximum allowed text length fixed
+
+13. Added a Quit Program option to the File menu
+
+14. Editing Improved (Ctrl+n no longer required)
+
+15. Extended maximum capacity of QFIG from 301 objects by 52 nodes to 301 objects by
+64 nodes.
+
+16. Many other small improvements and bug fixes
+
+------------------------
+Changes from NEC qfig 0.9c+1 to IBM Compatible/J3100 qfig 1.0
+
+1. Kanji not directly supported by qfig 1.0.
+
+2. "qfig /?" gives help on start-up options for qfig
+
+3. qfig without the "/s" option allows inputted text to be saved in .TEX files without any
+changes.
+
+4. CTRL+t added as a Hide(all but first letter)/Show text toggle.
+
+5. CTRL+n allows only the Line thickness and pattern to be modified in Lines, Curves,
+Polygons and Closed-curves.
+
+6. Seperation of Menu Bar from Drawing Area
+
+7. Added a QFIG Logo
+
+8. Extended maximum capacity of QFIG from 256 objects by 32 nodes to 301 objects by
+52 nodes.
+
+9. Added an option enabling selection of desired object if more than one start from the
+same point.
+
+10. Some bugs fixed
diff --git a/support/qfig/qfig11a.txt b/support/qfig/qfig11a.txt
new file mode 120000
index 0000000000..52fa25d39d
--- /dev/null
+++ b/support/qfig/qfig11a.txt
@@ -0,0 +1 @@
+qfig11a.doc \ No newline at end of file
diff --git a/support/qfig/qfig3ple. b/support/qfig/qfig3ple.
new file mode 100644
index 0000000000..bab3390dcc
--- /dev/null
+++ b/support/qfig/qfig3ple.
@@ -0,0 +1,298 @@
+% Output of qfig.bas
+ 172 516 48 340
+ 1 1 1 1 0 0 0
+ 200 160
+ 260 160
+ 1 1 1 1 0 1 0
+ 260 176
+ 200 176
+ 1 1 1 1 0 2 0
+ 200 192
+ 260 192
+ 1 1 1 1 0 3 0
+ 260 208
+ 200 208
+ 1 1 1 1 1 3 0
+ 276 208
+ 340 208
+ 1 1 1 1 1 2 0
+ 276 192
+ 340 192
+ 1 1 1 1 1 1 0
+ 340 176
+ 276 176
+ 1 1 1 1 1 0 0
+ 276 160
+ 340 160
+ 1 1 1 1 2 0 0
+ 356 160
+ 420 160
+ 1 1 1 1 2 1 0
+ 356 176
+ 420 176
+ 1 1 1 1 2 2 0
+ 420 192
+ 356 192
+ 1 1 1 1 2 3 0
+ 356 208
+ 420 208
+ 3 2 2 2 0 0 0
+ 432 228
+ 400 248
+ 400 272
+ 3 2 2 2 1 1 0
+ 416 272
+ 408 256
+ 440 236
+ 3 2 2 2 2 2 0
+ 456 236
+ 424 260
+ 432 272
+ 3 2 2 2 0 3 0
+ 452 272
+ 440 264
+ 464 244
+ 5 2 1 -1 0 0 0
+ 196 240
+ 196 216
+ 24 0
+ 5 2 1 -1 1 0 0
+ 236 272
+ 236 252
+ 20 0
+ 5 2 1 -1 2 0 0
+ 204 312
+ 204 292
+ 20 0
+ 7 2 1 -1 2 0 0
+ 274 322
+ 308 322
+ 34 .5294118
+ 7 2 1 -1 1 0 0
+ 276 270
+ 276 244
+ 26 2.166667
+ 7 2 1 -1 0 0 0
+ 256 230
+ 288 230
+ 32 .3125
+ 6 4 2 -1 0 0 0
+ 476 228
+ 448 224
+ 428 204
+ 28.28427 6.141288
+ 0 2.356194
+ 6 4 2 -1 1 0 0
+ 432 184
+ 459.4546 182
+ 476 160
+ 27.52729 3.214312
+ 0 .9259746
+ 6 4 2 -1 2 0 0
+ 456 124
+ 478.3636 154.3636
+ 476 192
+ 37.71051 2.205619
+ 0 4.649669
+ 9 1 1 -1 2 0 3
+ 176 148
+ 204 80
+ 8 1 1 -1 0 0 0
+ 212 80
+ 268 96
+ 8 1 1 -1 0 1 0
+ 268 104
+ 212 120
+ 8 1 1 -1 1 0 0
+ 212 128
+ 268 148
+ 8 1 1 -1 2 3 0
+ 276 148
+ 296 80
+ 9 1 1 -1 1 0 1
+ 308 80
+ 340 100
+ 9 1 1 -1 0 0 2
+ 340 112
+ 308 148
+ 2 5 4 4 0 0 0
+ 352 80
+ 360 140
+ 380 128
+ 364 112
+ 376 92
+ 352 80
+ 2 3 2 2 1 1 0
+ 368 76
+ 388 64
+ 412 88
+ 368 76
+ 4 6 5 5 0 3 0
+ 484 100
+ 448 120
+ 432 120
+ 420 100
+ 428 84
+ 452 84
+ 484 100
+ 4 12 11 11 2 0 0
+ 412 96
+ 396 94
+ 384 96
+ 376 112
+ 388 120
+ 384 132
+ 400 148
+ 420 148
+ 428 132
+ 412 124
+ 420 112
+ 416 100
+ 412 96
+ 11 2 -1 -2 2 24 2
+ 466.4349 186.5677
+ 476 192
+ 465.1809 193.9869
+ 11 2 -1 -2 1 23 2
+ 480.321 168.4605
+ 476 160
+ 484.7483 163.7036
+ 11 2 -1 -2 1 23 0
+ 430.3775 193.3604
+ 432 184
+ 436.7739 192.2134
+ 11 2 -1 -2 0 22 0
+ 479.0137 220.5894
+ 476 228
+ 473.5451 220.386
+ 11 2 -1 -2 2 14 0
+ 445.2008 238.0921
+ 456 236
+ 449.0721 244.5442
+ 11 2 -1 -2 1 13 0
+ 410.0168 264.6209
+ 416 272
+ 406.6734 270.1932
+ 11 2 -1 -2 0 12 2
+ 398.4785 264.146
+ 400 272
+ 393.786 266.9615
+ 11 2 -1 -2 0 12 0
+ 424.0191 228.5528
+ 432 228
+ 426.2416 233.5535
+ 11 2 -1 -2 2 10 0
+ 409.6634 188.2378
+ 420 192
+ 409.6634 195.7622
+ 11 2 -1 -2 2 9 0
+ 366.3366 179.7622
+ 356 176
+ 366.3366 172.2378
+ 11 2 -1 -2 1 7 1
+ 331.0729 156.7508
+ 340 160
+ 331.0729 163.2492
+ 11 2 -1 -2 1 7 0
+ 284.9271 163.2492
+ 276 160
+ 284.9271 156.7508
+ 11 2 -1 -2 0 1 0
+ 252.4825 173.2638
+ 260 176
+ 252.4825 178.7362
+ 11 2 -1 -2 0 2 0
+ 207.5175 194.7362
+ 200 192
+ 207.5175 189.2638
+ 11 2 -1 -2 1 4 0
+ 284.9271 211.2492
+ 276 208
+ 284.9271 204.7508
+ 10 10 0 -1 12 0 0
+ 308 228
+ 49 0
+ 50 0
+ 112 0
+ 116 0
+ 32 0
+ 82 0
+ 111 0
+ 109 0
+ 97 0
+ 110 0
+ 10 9 0 -1 10 1 0
+ 300 256
+ 49 0
+ 48 0
+ 112 0
+ 116 0
+ 32 0
+ 66 0
+ 111 0
+ 108 0
+ 100 0
+ 10 16 0 -1 10 3 0
+ 308 288
+ 49 0
+ 48 0
+ 112 0
+ 116 0
+ 32 0
+ 66 0
+ 111 0
+ 108 0
+ 100 0
+ 32 0
+ 73 0
+ 116 0
+ 97 0
+ 108 0
+ 105 0
+ 99 0
+ 10 11 0 -1 12 2 0
+ 332 320
+ 73 0
+ 116 0
+ 97 0
+ 108 0
+ 105 0
+ 99 0
+ 32 0
+ 49 0
+ 50 0
+ 112 0
+ 116 0
+ 2 3 2 2 2 2 0
+ 477.7479 260.5974
+ 484 336
+ 440 328
+ 477.7479 260.5974
+ 3 6 6 6 0 0 0
+ 376 56
+ 410.5332 53.44503
+ 451.8903 57.46955
+ 488.9896 66.99519
+ 511.8903 79.46955
+ 514.4563 91.55015
+ 496 99.99999
+ 10 18 0 -1 12 0 0
+ 174 48
+ 84 0
+ 104 0
+ 105 0
+ 115 0
+ 32 0
+ 105 0
+ 115 0
+ 32 0
+ 97 0
+ 110 0
+ 32 0
+ 101 0
+ 120 0
+ 97 0
+ 109 0
+ 112 0
+ 108 0
+ 101 0
diff --git a/support/qfig/qfig4pic.tex b/support/qfig/qfig4pic.tex
new file mode 100644
index 0000000000..9bade2a4ac
--- /dev/null
+++ b/support/qfig/qfig4pic.tex
@@ -0,0 +1,86 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% qfig4pic.tex --- Interface for QFIG-generated PiCTeX code and PiCTeX %
+% to use with Plain TeX. %
+% %
+% Donated by: Bruce Dearden <dearden@pc4.math.und.nodak.edu> %
+% %
+% To use QFIG-generated PiCTeX code, read in this file %
+% followed by pictex.tex at the top of your TeX file: %
+% %
+% \input qfig4pic %
+% \input pictex %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\def\wlog#1{} % don't write allocations to log.
+
+% Smaller fonts for labels in pictures.
+% (This replaces Qfig's 12 pt font)
+
+\font\ninerm=cmr9 \font\eightrm=cmr8 \font\sixrm=cmr6
+\font\ninei=cmmi9 \font\eighti=cmmi8 \font\sixi=cmmi6
+\font\ninesy=cmsy9 \font\eightsy=cmsy8 \font\sixsy=cmsy6
+\font\ninebf=cmbx9 \font\eightbf=cmbx8 \font\sixbf=cmbx6
+\font\ninett=cmtt9 \font\eighttt=cmtt8
+\font\nineit=cmti9 \font\eightit=cmti8
+\font\ninesl=cmsl9 \font\eightsl=cmsl8
+
+% Smaller math formulas have nonstandard \skewchar
+
+\skewchar\ninei='177 \skewchar\eighti='177 \skewchar\sixi='177
+\skewchar\ninesy='60 \skewchar\eightsy='60 \skewchar\sixsy='60
+\hyphenchar\ninett=-1 \hyphenchar\eighttt=-1 \hyphenchar\tentt=-1
+
+
+% Macros to set the font size environment.
+\catcode`@=11 % need access to private plain TeX macros.
+\newskip\ttglue
+
+\def\tenpoint{\def\rm{\fam0\tenrm}% Switch to 10-point type.
+ \textfont0=\tenrm \scriptfont0=\sevenrm \scriptscriptfont0=\fiverm
+ \textfont1=\teni \scriptfont1=\seveni \scriptscriptfont1=\fivei
+ \textfont2=\tensy \scriptfont2=\sevensy \scriptscriptfont2=\fivesy
+ \textfont3=\tenex \scriptfont3=\tenex \scriptscriptfont3=\tenex
+ \textfont\itfam=\tenit \def\it{\fam\itfam\tenit}%
+ \textfont\slfam=\tensl \def\sl{\fam\slfam\tensl}%
+ \textfont\ttfam=\tentt \def\tt{\fam\ttfam\tentt}%
+ \textfont\bffam=\tenbf \scriptfont\bffam=\sevenbf
+ \scriptscriptfont\bffam=\fivebf \def\bf{\fam\bffam\tenbf}%
+ \tt \ttglue=.5em plus.25em minus.15em
+ \normalbaselineskip=12pt
+ \setbox\strutbox=\hbox{\vrule height8.5pt depth3.5pt width0pt}%
+ \let\sc=\eightrm \let\big=\tenbig \normalbaselines\rm}
+
+
+\def\ninepoint{\def\rm{\fam0\ninerm}% Switch to 9-point type.
+ \textfont0=\ninerm \scriptfont0=\sixrm \scriptscriptfont0=\fiverm
+ \textfont1=\ninei \scriptfont1=\sixi \scriptscriptfont1=\fivei
+ \textfont2=\ninesy \scriptfont2=\sixsy \scriptscriptfont2=\fivesy
+ \textfont3=\tenex \scriptfont3=\tenex \scriptscriptfont3=\tenex
+ \textfont\itfam=\nineit \def\it{\fam\itfam\nineit}%
+ \textfont\slfam=\ninesl \def\sl{\fam\slfam\ninesl}%
+ \textfont\ttfam=\ninett \def\tt{\fam\ttfam\ninett}%
+ \textfont\bffam=\ninebf \scriptfont\bffam=\sixbf
+ \scriptscriptfont\bffam=\fivebf \def\bf{\fam\bffam\ninebf}%
+ \tt \ttglue=.5em plus.25em minus.15em
+ \normalbaselineskip=11pt
+ \setbox\strutbox=\hbox{\vrule height8pt depth3pt width0pt}%
+ \let\sc=\sevenrm \let\big=\ninebig \normalbaselines\rm}
+
+\def\tenbig#1{{\hbox{$\left#1\vbox to8.5pt{}\right.\n@space$}}}
+\def\ninebig#1{{\hbox{$\textfont0=\tenrm\textfont2=\tensy
+ \left#1\vbox to 7.25pt{}\right.\n@space$}}}
+
+
+\catcode`@=12 % @ is not a letter any more.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Interface macros
+
+\def\mbox#1{\leavevmode\hbox{#1}}
+\def\typeout#1{\message{#1}}
+\def\symbol#1{\char '#1\relax}
+\let\xpt=\tenpoint % QFIG's 10-point really is 10-point.
+\let\xiipt=\ninepoint % Force QFIG's 12-points to the smaller 9-points.
+\newdimen\unitlength
+
+%%%%%%%%%%%%%%%%%%%%%
+
diff --git a/support/qfig/qfig_set.dat b/support/qfig/qfig_set.dat
new file mode 100644
index 0000000000..0ccbe4f3d7
--- /dev/null
+++ b/support/qfig/qfig_set.dat
@@ -0,0 +1,59 @@
+; qfig_set.dat : user-definable data settings
+; a symbol ";" can NEVER be removed in this file
+; data must be given left-flushed and be punctuated by ";"
+;arrow = arrowhead + darrowhead * obj%(n%, 4) in dot (1dot=.25mm)
+8! ;arrowhead
+1.5 ;darrowhead
+;
+;arrow directions
+9! ;arrowdirect=pi/(this number): arrow is directed to \pm arrowdirect
+30! ;arcarrowd=pi/(this number): correction of inward direction on the arc
+;
+;dashpattern on PiCTeX : line gap [dot gap [dot gap]]
+6pt, 3pt ;dpattern$(1) : dashed line
+10pt, 3pt, 2pt, 3pt ;dpattern$(2) : dash-dotted line
+10pt, 3pt, 2pt, 3pt, 2pt, 3pt ;dpattern$(3) : dash-double dotted line
+;
+;filler color on N-Graph : 0:black, 1:blue, 2:green, 3:cyan
+; 4:red, 5:magenta, 6:yellow, 7:white
+0 ;filler%(0) : no filler
+2 ;filler%(1) : thin
+6 ;filler%(2) : medium
+1 ;filler%(3) : thick
+;
+;dashpattern on eepic (actual value = number \times .25mm)
+;
+\dottedline{3} ;eepicpattern$(1) : dotted line
+\dashline[50]{10} ;eepicpattern$(2) : dashed line
+\dashline[50]{10}[2] ;eepicpattern$(3) : dot dashed line
+;
+;filler pattern on eepic : \special{sh 0.4} ...etc.
+;
+[0.1] ;tpicshade$(1)
+[0.4] ;tpicshade$(2)
+[0.7] ;tpicshade$(3)
+;
+;step of horizontal/vertical scroll
+;
+200 ;hscroll% > 0, <= 200
+120 ;vscroll% > 0, <= 120
+;
+;approximate curves by piecewise lines
+;
+10 ;interpolcurve% = # of interpolation points between two data
+5. ;interpolang (in degree) : interpol. pts. at every this angle
+;
+; For definition of font type and size for LaTeX/TeX output
+;NOTE: No spaces are allowed within the definitions. A space
+;will automatically be added at the end of the string
+;e.g. "\xpt\rm" will become "\xpt\rm " in the output.
+;
+\xpt\rm ;10pt roman
+\xpt\bf ;10pt bold
+\xpt\it ;10pt italic
+\xpt\FonttenBI ;10pt bold italic
+\xiipt\rm ;12pt roman
+\xiipt\bf ;12pt bold
+\xiipt\it ;12pt italic
+\xiipt\FonttwlBI ;12pt bold italic
+;
diff --git a/support/qfig/src/mouse.bas b/support/qfig/src/mouse.bas
new file mode 100644
index 0000000000..9427c03938
--- /dev/null
+++ b/support/qfig/src/mouse.bas
@@ -0,0 +1,187 @@
+
+'$INCLUDE: 'QB.BI'
+'$INCLUDE: 'MOUSE.BI'
+TYPE MouseFlagsType
+ Active AS INTEGER
+ button AS INTEGER
+ Cursor AS INTEGER
+END TYPE
+DIM SHARED MouseFlags AS MouseFlagsType
+CONST NoArg = 0
+CONST FALSE = 0
+CONST TRUE = NOT FALSE
+
+'MouseBorder SUB PROGRAM
+'
+'
+' (Quick Library) MOUSE.QLB
+' (INCLUDE FILE) QB.BI, MOUSE.BI
+'
+SUB MouseBorder (row1%, col1%, row2%, col2%)
+ IF MouseReady% = FALSE THEN ERROR 68
+ MouseDriver 7, NoArg, col1%, col2% '
+
+ MouseDriver 8, NoArg%, row1%, row2%
+
+END SUB
+
+'MouseDriver SUB PROGRAM
+'
+'
+' (Quick Library) MOUSE.QLB
+' (INCLUDE FILE) QB.BI, MOUSE.BI
+'
+SUB MouseDriver (M0%, M1%, M2%, M3%)
+ DIM inreg AS RegType
+ DIM outreg AS RegType
+ inreg.ax = M0%
+ inreg.bx = M1%
+ inreg.cx = M2%
+ inreg.dx = M3%
+ INTERRUPT &H33, inreg, outreg
+ M0% = outreg.ax
+ M1% = outreg.bx
+ M2% = outreg.cx
+ M3% = outreg.dx
+END SUB
+
+'MouseHide SUB PROGRAM
+'
+'
+' (Quick Library) MOUSE.QLB
+' (INCLUDE FILE) QB.BI, MOUSE.BI
+'
+SUB MouseHide
+ IF MouseReady% = FALSE THEN ERROR 68
+ IF MouseFlags.Cursor THEN
+ MouseDriver 2, NoArg, NoArg, NoArg
+ MouseFlags.Cursor = FALSE
+ END IF
+END SUB
+
+'MouseInit SUB PROGRAM
+'
+'
+' (Quick Library) MOUSE.QLB
+' (INCLUDE FILE) QB.BI, MOUSE.BI
+'
+SUB MouseInit
+ IF MouseReady% = FALSE THEN ERROR 68
+ M0% = 0
+ MouseDriver M0%, M1%, NoArg, NoArg
+ MouseFlags.button = M1%
+ MouseFlags.Active = TRUE
+END SUB
+
+'MouseLocate SUB PROGRAM
+'
+'
+' (Quick Library) MOUSE.QLB
+' (INCLUDE FILE) QB.BI, MOUSE.BI
+'
+SUB MouseLocate (row%, col%)
+ IF MouseReady% = FALSE THEN ERROR 68
+ MouseDriver 4, NoArg, col%, row%
+END SUB
+
+'MouseMode SUB PROGRAM
+'
+'
+' (Quick Library) MOUSE.QLB
+' (INCLUDE FILE) QB.BI, MOUSE.BI
+'
+'
+SUB MouseMode (Func%)
+ IF MouseReady% = FALSE THEN ERROR 68
+ MouseHide
+ IF Func% = FALSE THEN
+ MouseInit
+ ELSE
+ CLS
+ M0% = 10
+ M1% = 0
+ M2% = &H70FF
+ M3% = &H500
+ MouseDriver M0%, M1%, M2%, M3%
+ END IF
+END SUB
+
+'MousePoll SUB PROGRAM
+'
+'
+' (Quick Library) MOUSE.QLB
+' (INCLUDE FILE) QB.BI, MOUSE.BI
+'
+SUB MousePoll (row%, col%, lbutton%, rbutton%)
+ IF MouseReady% = FALSE THEN ERROR 68
+ MouseDriver 3, M1%, M2%, M3%
+ row% = M3%
+ col% = M2%
+ lbutton% = (M1% AND 1) <> 0
+ rbutton% = (M1% AND 2) <> 0
+END SUB
+
+'MousePush SUB PROGRAM
+'
+'
+' (Quick Library) MOUSE.QLB
+' (INCLUDE FILE) QB.BI, MOUSE.BI
+'
+SUB MousePush (button%, row%, col%, lbutton%, rbutton%)
+ IF MouseReady% = FALSE THEN ERROR 68
+ M0% = 5
+ M1% = button%
+ MouseDriver M0%, M1%, M2%, M3%
+ lbutton% = (M0% AND 1) = 1
+ rbutton% = (M0% AND 2) = 2
+ button% = M1%
+ col% = M2%
+ row% = M3%
+END SUB
+
+'
+' (Quick Library) MOUSE.QLB
+' (INCLUDE FILE) QB.BI, MOUSE.BI
+FUNCTION MouseReady% STATIC
+ IF NotFirstCall% THEN
+ MouseReady% = NotFirstCall%
+ ELSE
+ M0% = 0
+ MouseDriver M0%, M1%, NoArg, NoArg
+ MouseFlags.button = M1%
+ MouseReady% = (M0% <> 0)
+ NotFirstCall% = (M0% <> 0)
+ END IF
+END FUNCTION
+
+'MouseRelease SUB PROGRAM
+'
+'
+' (Quick Library) MOUSE.QLB
+' (INCLUDE FILE) QB.BI, MOUSE.BI
+'
+SUB MouseRelease (button%, row%, col%, lbutton%, rbutton%)
+ IF MouseReady% = FALSE THEN ERROR 68
+ M0% = 6
+ M1% = button%
+ MouseDriver M0%, M1%, M2%, M3%
+ lbutton% = (M0% AND 1) = 1
+ rbutton% = (M0% AND 2) = 2
+ button% = M1%
+ col% = M2%
+ row% = M3%
+END SUB
+
+'MouseShow SUB PROGRAM
+'
+' (Quick Library) MOUSE.QLB
+' (INCLUDE FILE) QB.BI, MOUSE.BI
+'
+SUB MouseShow
+ IF MouseReady% = FALSE THEN ERROR 68
+ IF NOT MouseFlags.Cursor THEN
+ MouseDriver 1, NoArg, NoArg, NoArg
+ MouseFlags.Cursor = NOT FALSE
+ END IF
+END SUB
+
diff --git a/support/qfig/src/mouse.bi b/support/qfig/src/mouse.bi
new file mode 100644
index 0000000000..5356322eea
--- /dev/null
+++ b/support/qfig/src/mouse.bi
@@ -0,0 +1,13 @@
+DECLARE FUNCTION MouseReady% ()
+DECLARE SUB MouseBorder (row1%, col1%, row2%, col2%)
+DECLARE SUB MouseDriver (M0%, M1%, M3%, M4%)
+DECLARE SUB MouseLocate (row%, col%)
+DECLARE SUB MouseMode (Func%)
+DECLARE SUB MouseHide ()
+DECLARE SUB MouseInit ()
+DECLARE SUB MousePoll (row%, col%, lbutton%, rbutton%)
+DECLARE SUB MousePush (button%, row%, col%, lbutton%, rbutton%)
+DECLARE SUB MouseRelease (button%, row%, col%, lbutton%, rbutton%)
+DECLARE SUB MouseShow ()
+DECLARE SUB SetMouseEvent (Mode%)
+
diff --git a/support/qfig/src/qfig.bas b/support/qfig/src/qfig.bas
new file mode 100644
index 0000000000..281f2d5f38
--- /dev/null
+++ b/support/qfig/src/qfig.bas
@@ -0,0 +1,1124 @@
+'****************************************************************************
+' qfig.bas <-- bfig.bas <-- motivated by "xfig" on X-*indow of UN*X
+' 2/21/1993 T.Iwakuma (bear@hashi1.civil.tohoku.ac.jp)
+'****************************************************************************
+' "mouse.obj" and "graph.obj" must be "link"ed and "lib"ed to make
+' "qfig.lib" as well as "qfig.qlb".
+' interpreter must be activated as "qb /lqfig"
+'****************************************************************************
+'$INCLUDE: 'QB.BI'
+'$DYNAMIC
+'$INCLUDE: 'MOUSE.BI'
+'$INCLUDE: 'QFIG.BI'
+'****************************************************************************
+qfigtitle$ = "qfig Ver.1.1a (3/24/1997)"
+'qfigtitle1$ = "modified for J-3100/IBM compatible PCs"
+qfigtitle2$ = "by: William Ofosu-Amaah"
+'qfigtitle3$ = "from: qfig NEC Ver.0.9c+1 (3/20/1993)"
+'qfigtitle4$ = "by: Mr T.Iwakuma (bear@hashi1.tohoku.ac.jp)"
+qfigtitle5$ = "(XI6W-OFSA@asahi-net.or.jp)"
+'****************************************************************************
+'
+IF INSTR(COMMAND$, "/?") <> 0 THEN
+ whelp
+ END
+END IF
+
+Preparation
+' key call
+ON KEY(1) GOSUB f.1
+ON KEY(2) GOSUB f.2
+ON KEY(3) GOSUB f.3
+ON KEY(4) GOSUB f.4
+ON KEY(5) GOSUB f.5
+ON KEY(6) GOSUB f.6
+ON KEY(7) GOSUB f.7
+ON KEY(8) GOSUB f.8
+ON KEY(9) GOSUB f.9
+ON KEY(10) GOSUB f.10
+ON KEY(15) GOSUB fnctn: KEY 15, CHR$(&H0) + CHR$(&H1) 'ESC
+ON KEY(16) GOSUB redraw: KEY 16, CHR$(&H4) + CHR$(&H13) 'CTRL+R
+ON KEY(17) GOSUB Help: KEY 17, CHR$(&H4) + CHR$(&H23) 'CTRL+H
+ON KEY(19) GOSUB quit: KEY 19, CHR$(&H4) + CHR$(&H10) 'CTRL+Q
+ON KEY(20) GOSUB clreset: KEY 20, CHR$(&H4) + CHR$(&H1F) 'CTRL+S
+ON KEY(22) GOSUB stext: KEY 22, CHR$(&H4) + CHR$(&H14)'CTRL+T
+ON KEY(24) GOSUB widewindow: KEY 24, CHR$(&H4) + CHR$(&H11) 'CTRL+W
+KeySwitch 1
+KEY(8) ON: KEY(9) ON: KEY(10) ON: KEY(17) ON: KEY(19) ON
+KEY OFF
+ON ERROR GOTO somethingwrong
+' mouse activation
+IF MouseReady% THEN '<=== when Mouse is used
+ MouseInit '|
+ MouseMode 1 '|
+ MouseHide '|
+ MouseBorder pymin%, pxmin%, pymax%, pxmax% '|
+ MouseLocate py%, px% '|
+ mouswitch% = -1 '|
+END IF '<=== when Mouse is used
+
+SCREEN scrtype%
+GOSUB title
+VIEW SCREEN (0, 0)-(windowx%(0), windowy%(0))
+WINDOW SCREEN (0, 0)-(windowx%(0), windowy%(0))
+CL.R.edraw 0, 0
+SetInst -1
+
+' Main infinite LOOP
+DO
+ pxold% = px%: pyold% = py%
+ keyin% = KeyIsTyped%
+ IF ((keyin% > 4) AND (job% = 0)) THEN
+ ON keyin% - 4 GOSUB rollup, rolldown, leftmost, rightmost
+ END IF
+ IF keyin% = 2 OR keyin% = 3 THEN
+ qx% = INT(CSNG(px% - pxo%) / wndwxy(wndwfctr%) + .9)
+ qy% = INT(CSNG(py% - pyo%) / wndwxy(wndwfctr%) + .9)
+ IF qy% > windowy%(0) - 48 THEN
+ IF qx% < 15 THEN
+ IF py% >= pymax% - 4 THEN GOSUB rolldown
+ ELSEIF qx% < 295 THEN
+ i% = INT((CSNG(qx%) + 41!) / 56!)
+ IF qx% < 56 * i% + 8 THEN
+ GOSUB setbymouse
+ ON i% GOSUB f.1, f.2, f.3, f.4, f.5
+ END IF
+ ELSEIF qx% > 366 THEN
+ i% = INT((CSNG(qx%) - 31!) / 56!)
+ IF qx% < 56 * i% + 80 THEN
+ GOSUB setbymouse
+ ON i% - 5 GOSUB f.6, f.7, f.8, f.9, f.10
+ END IF
+ END IF
+ ELSEIF py% <= pymin% + 4 THEN
+ IF px% <= pxmin% + 4 THEN
+ dwndwfctr% = 1
+ GOSUB widewindowbymouse
+ ELSEIF px% >= pxmax% - 4 THEN
+ dwndwfctr% = -1
+ GOSUB widewindowbymouse
+ ELSE
+ GOSUB rollup
+ END IF
+ ELSEIF px% <= pxmin% + 4 THEN
+ GOSUB leftmost
+ ELSEIF px% >= pxmax% - 4 THEN
+ GOSUB rightmost
+ END IF
+ END IF
+ CursorDisplay pxold%, pyold%
+ CursorDisplay px%, py%
+LOOP
+' show or not show text
+stext:
+KeySwitch 0
+IF wtext% = 0 THEN
+ wtext% = 1
+ELSE
+ wtext% = 0
+END IF
+CL.R.edraw 0, 0
+KeySwitch 1
+RETURN
+' command by mouse
+setbymouse:
+IF py% - pyo% < windowy%(wndwfctr%) - INT(32! * wndwxy(wndwfctr%) + .9) THEN
+ func% = 0: func1% = 0: GOSUB fnctn1 'Top Line of Function row
+ELSEIF py% - pyo% < windowy%(wndwfctr%) - INT(16! * wndwxy(wndwfctr%) + .9) THEN
+ func% = 1: func1% = 1: GOSUB fnctn1 'Middle Line
+ELSE
+ func% = 2: func1% = 1: GOSUB fnctn1 'Bottom Line
+END IF
+
+RETURN
+' clear and reset
+clreset:
+LOCATE 12, 30: PRINT " Are you sure (Y/N) " '; CHR$(7);
+DO: a$ = KeyIsTouched$
+LOOP UNTIL a$ = CHR$(CR) OR (a$ <> "" AND INSTR("YyNn", a$) <> 0)
+IF UCASE$(a$) = "Y" THEN
+ nobj% = 0
+ CL.R.edraw 0, 0: SetInst -1
+ELSE
+ GOSUB redraw
+END IF
+ RETURN
+' ending
+quit:
+QUIT0
+RETURN
+'
+quit1:
+IF mouswitch% THEN MouseHide: MouseInit '<=== when Mouse is used
+KeySwitch 0: KEY(8) OFF: KEY(9) OFF: KEY(10) OFF: KEY(17) OFF: KEY(19) OFF
+RETURN
+'
+title:
+deg = 3.14 / 180
+IF ega% = 0 THEN
+ cf% = 12
+ cb% = 15
+ cs% = 1
+ cline% = 1
+ ytext% = 16
+ELSE
+ cf% = 4
+ cb% = 7
+ cs% = 0
+ cline% = 1
+ ytext% = 18
+END IF
+'cl% and cb% should never be the same'
+xlogo% = 50
+
+PAINT (xlogo% + 135, 100), cb%
+CIRCLE (xlogo% + 205, 100), 50, cline%, , , 1
+CIRCLE (xlogo% + 215, 105), 50, cline%, 70 * deg, 236 * deg, 1
+CIRCLE (xlogo% + 212, 103), 67, cline%, 250 * deg, 80 * deg, 1
+CIRCLE (xlogo% + 200, 100), 67, cline%, , , 1
+PAINT (xlogo% + 135, 100), cf%, cline%
+PAINT (xlogo% + 156, 100), cs%, cline%
+PAINT (xlogo% + 278, 103), cs%, cline%
+LINE (xlogo% + 205, 150)-(xlogo% + 240, 180), 2
+LINE (xlogo% + 190, 166)-(xlogo% + 240, 200), 2
+LINE (xlogo% + 240, 180)-(xlogo% + 290, 170), 2
+LINE (xlogo% + 240, 200)-(xlogo% + 290, 170), 2
+LINE (xlogo% + 205, 150)-(xlogo% + 190, 166), 2
+PAINT (xlogo% + 240, 198), cf%, 2
+LINE (xlogo% + 205, 150)-(xlogo% + 190, 166), cf%
+LINE (xlogo% + 205, 150)-(xlogo% + 240, 180), cline%
+LINE (xlogo% + 190, 166)-(xlogo% + 240, 200), cline%
+LINE (xlogo% + 240, 180)-(xlogo% + 290, 170), cline%
+LINE (xlogo% + 240, 200)-(xlogo% + 290, 170), cline%
+LINE -STEP(3, 8), cline%
+LINE -STEP(-50, 30), cline%
+LINE -STEP(-30, -25), cline%
+PAINT (xlogo% + 290, 172), cs%, cline%
+CIRCLE (xlogo% + 193, 165), 20, cline%, 48 * deg, 113 * deg, 1
+PAINT (xlogo% + 193, 147), cf%, cline%
+CIRCLE (xlogo% + 205, 100), 50, cf%, 250 * deg, 270 * deg, 1
+LINE (xlogo% + 280, 160)-(xlogo% + 285, 130), cline%
+LINE -STEP(-5, 0), cline%
+LINE -STEP(2, -8), cline%
+LINE -STEP(40, 0), cline%
+LINE -STEP(-3, 8), cline%
+LINE -STEP(-20, 0), cline%
+LINE -STEP(-1, 7), cline%
+LINE -STEP(15, 0), cline%
+LINE -STEP(-2, 6), cline%
+LINE -STEP(-13, 0), cline%
+LINE -STEP(-3, 17), cline%
+LINE -STEP(-14, 0), cline%
+PAINT (xlogo% + 282, 159), cf%, cline%
+LINE (xlogo% + 326, 160)-(xlogo% + 331, 122), cline%
+LINE -STEP(10, 0), cline%
+LINE -STEP(-5, 38), cline%
+LINE -STEP(-10, 0), cline%
+PAINT (xlogo% + 328, 158), cf%, cline%
+CIRCLE (xlogo% + 367, 140), 17, cline%, 36 * deg, 160 * deg, 1
+CIRCLE (xlogo% + 368, 138), 8, cline%, 25 * deg, 160 * deg, 1
+LINE (xlogo% + 350, 135)-(xlogo% + 348, 149), cline%
+LINE (xlogo% + 361, 135)-(xlogo% + 357, 147), cline%
+LINE (xlogo% + 375, 135)-(xlogo% + 382, 135), cline%
+LINE -STEP(-1, -4), cline%
+CIRCLE (xlogo% + 365, 143), 17, cline%, 200 * deg, 335 * deg, 1
+CIRCLE (xlogo% + 366, 144), 8, cline%, 200 * deg, 335 * deg, 1
+LINE (xlogo% + 373, 146)-(xlogo% + 367, 146), cline%
+LINE -STEP(2, -4), cline%
+LINE -STEP(20, 0), cline%
+LINE -STEP(-2, 4), cline%
+LINE -STEP(-6, 0), cline%
+LINE -STEP(0, 3), cline%
+PAINT (xlogo% + 377, 133), cf%, cline%
+
+PSET (xlogo% + 120, 210), cline%
+LINE -STEP(58, 0), cline%
+PSET (xlogo% + 120, 210), cline%
+LINE -STEP(12, 11), cline%
+LINE -STEP(-12, 11), cline%
+LINE -STEP(55, 0), cline%
+CIRCLE (xlogo% + 178, 213), 3, cline%, 270 * deg, 90 * deg, 1
+CIRCLE (xlogo% + 178, 219), 3, cline%, 90 * deg, 270 * deg, 1
+LINE (xlogo% + 181, 213)-(xlogo% + 181, 224), cline%
+LINE (xlogo% + 175, 219)-(xlogo% + 175, 250), cline%
+CIRCLE (xlogo% + 250, 0), 234, cline%, 252 * deg, 288 * deg, 1
+PAINT (xlogo% + 126, 214), cf%, cline%
+PAINT (xlogo% + 176, 219), cf%, cline%
+PSET (xlogo% + 320, 210), cline%
+LINE -STEP(60, 0), cline%
+PSET (xlogo% + 380, 210), cline%
+LINE -STEP(-12, 11), cline%
+LINE -STEP(12, 11), cline%
+LINE -STEP(-57, 0), cline%
+CIRCLE (xlogo% + 320, 219), 3, cline%, 270 * deg, 90 * deg, 1
+CIRCLE (xlogo% + 320, 213), 3, cline%, 90 * deg, 270 * deg, 1
+LINE (xlogo% + 317, 213)-(xlogo% + 317, 225), cline%
+LINE (xlogo% + 323, 219)-(xlogo% + 323, 250), cline%
+CIRCLE (xlogo% + 250, 0), 260, cline%, 253.5 * deg, 286.4 * deg, 1
+PAINT (xlogo% + 321, 219), cf%, cline%
+PAINT (xlogo% + 320, 226), cf%, cline%
+PAINT (xlogo% + 376, 212), cf%, cline%
+s$ = "Version 1.1a"
+DIM inRegs AS RegType, outRegs AS RegType
+LOCATE ytext%, 27 + INT(xlogo% / 8)
+inRegs.bx = &H80 + (cf%)
+FOR i = 1 TO LEN(s$)
+ inRegs.ax = &HE00 + ASC(MID$(s$, i, 1))
+ CALL INTERRUPT(&H10, inRegs, outRegs)
+NEXT i
+SLEEP 1
+CLS 0: RETURN
+
+' alternative functions
+fnctn:
+func% = (func% + 1) MOD 3
+fnctn1:
+LOCATE line2%, 2: PRINT " "; : COLOR 7
+LOCATE line1%, 2: PRINT " "; : COLOR 7
+LOCATE line1% + 1, 2: PRINT " "; : COLOR 7
+LOCATE line2% + func%, 2: COLOR 6: PRINT "@"; : RETURN
+'LOCATE line2% + func1%, 2: PRINT " "; : COLOR 7: RETURN
+
+'fnctn: SWAP func%, func1%
+'LOCATE line2% + func%, 2: COLOR 6: PRINT "@";
+'LOCATE line2% + func1%, 2: PRINT " "; : COLOR 7: RETURN
+
+' need help?
+Help: Help.Me: RETURN
+' redraw
+redraw: CL.R.edraw 0, 0: RETURN
+' grouping
+'grouping: G.Group: GOTO f.end
+' rollup/down screen
+rollup:
+IF pymin% - vscroll% < 0 THEN RETURN
+ipy% = -vscroll%: GOTO updown
+rolldown:
+IF pymax% + vscroll% > REGIONYMAX THEN RETURN
+ipy% = vscroll%
+updown:
+pyo% = pyo% + ipy%: py% = py% + ipy%
+row% = row% + ipy%: pyold% = pyold% + ipy%
+pymin% = pyo% + INT(margin% * wndwxy(wndwfctr%) + .9)
+pymax% = pyo% + windowy%(wndwfctr%) - INT(margin% * wndwxy(wndwfctr%) + .9)
+pymax2% = pyo% + windowy%(wndwfctr%) - INT(margin% * wndwxy(wndwfctr%) + .9) - texth% * 3 * INT(wndwxy(wndwfctr%) + .9) - 21
+GOTO rst.scrn
+' move left/right screen
+leftmost:
+IF pxmin% - hscroll% < 0 THEN RETURN
+ipx% = -hscroll%: GOTO leftright
+rightmost:
+IF pxmax% + hscroll% > REGIONXMAX THEN RETURN
+ipx% = hscroll%
+leftright:
+pxo% = pxo% + ipx%: px% = px% + ipx%
+col% = col% + ipx%: pxold% = pxold% + ipx%
+pxmin% = pxo% + INT(margin% * wndwxy(wndwfctr%) + .9)
+pxmax% = pxo% + windowx%(wndwfctr%) - INT(margin% * wndwxy(wndwfctr%) + .9)
+' reset screen
+rst.scrn:
+IF mouswitch% THEN '<=== when Mouse is used
+ MouseBorder pymin%, pxmin%, pymax%, pxmax% '|
+END IF '<=== when Mouse is used
+WINDOW SCREEN (pxo%, pyo%)-(pxo% + windowx%(wndwfctr%), pyo% + windowy%(wndwfctr%))
+CL.R.edraw 0, 0
+RETURN
+' widen window by mouse
+widewindowbymouse:
+wndwfctr% = wndwfctr% + dwndwfctr%
+IF wndwfctr% > UBOUND(wndwxy) THEN wndwfctr% = 0
+IF wndwfctr% < LBOUND(wndwxy) THEN wndwfctr% = UBOUND(wndwxy)
+GOTO windowide
+' widen window
+widewindow:
+KeySwitch 0
+KEY(17) OFF: KEY(19) OFF 'Also disable Help, Quit
+CLS 0
+PRINT "Reduction rate:"
+FOR i% = 0 TO 3: PRINT TAB(4); i%; " : "; INT(1000 / wndwxy(i%)) / 10;
+PRINT TAB(16); "%": NEXT i%
+PRINT "Select one [0-3]"
+DO: a$ = INKEY$: LOOP UNTIL a$ <> "" AND INSTR("0123", a$) <> 0
+wndwfctr% = VAL(a$)
+windowide:
+pxmin% = pxo% + INT(margin% * wndwxy(wndwfctr%) + .9)
+pxmax% = pxo% + windowx%(wndwfctr%) - INT(margin% * wndwxy(wndwfctr%) + .9)
+pymin% = pyo% + INT(margin% * wndwxy(wndwfctr%) + .9)
+pymax% = pyo% + windowy%(wndwfctr%) - INT(margin% * wndwxy(wndwfctr%) + .9)
+pymax2% = pyo% + windowy%(wndwfctr%) - INT(margin% * wndwxy(wndwfctr%) + .9) - texth% * 3 * INT(wndwxy(wndwfctr%) + .9) - 21
+IF px% > pxmax% OR px% < pxmin% THEN
+ IF px% > pxmax% THEN
+ px% = INT(CSNG(pxmax%) / 4!) * 4
+ ELSE
+ px% = INT(CSNG(pxmin%) / 4! + .9) * 4
+ END IF
+ pxold% = px%: col% = px%
+END IF
+IF py% > pymax% OR py% < pymin% THEN
+ IF py% > pymax% THEN
+ py% = INT(CSNG(pymax% - INT(48! * wndwxy(wndwfctr%))) / 4!) * 4
+ ELSE
+ py% = INT(CSNG(pymin%) / 4! + .9) * 4
+ END IF
+ pyold% = py%: row% = py%
+END IF
+KEY(17) ON: KEY(19) ON 'Renable Help, Quit
+KeySwitch 1
+GOTO rst.scrn
+' straight lines / move
+f.1:
+seljob% = 1
+KEY(1) OFF
+IF kswitch% = 1 AND func% = 0 THEN
+ linesel% = 0
+ G.Curve 1, 0
+ELSEIF kswitch% = 1 AND func% = 1 THEN
+ linesel% = 1
+ MoveObj 0
+ELSE
+ FillPattern
+ COLOR 10
+ LOCATE line1% + 1, 7: PRINT fill%;
+ LOCATE line1% + 1, 3: PRINT "Fil-P";
+ COLOR 7
+ IF inbox% = 1 THEN
+ IF fill% <> 0 THEN
+ LINE (sxg%, syg%)-(px%, py%), 2, B
+ PAINT ((sxg% + px%) / 2, (syg% + py%) / 2), 0, 2
+ END IF
+ LINE (sxg%, syg%)-(px%, py%), 0, BF
+ LINE (sxg%, syg%)-(px%, py%), 0, BF
+ IF fill% = 0 THEN
+ LINE (sxg%, syg%)-(px%, py%), 7, B
+ ELSE
+ LINE (sxg%, syg%)-(px%, py%), 2, B
+ PAINT ((sxg% + px%) / 2, (syg% + py%) / 2), tlp$(fill%), 2
+ END IF
+ ELSEIF inbox% = 2 THEN
+ obj%(nobj%, 6) = fill%
+ LINE (INT(xx(nobj%, 0)), INT(yy(nobj%, 0)))-(INT(xx(nobj%, 1)), INT(yy(nobj%, 1))), 0, BF
+ D.Lines INT(xx(nobj%, 0)), INT(yy(nobj%, 0)), INT(xx(nobj%, 1)), INT(yy(nobj%, 1)), 7, 2, obj%(nobj%, 4), 0, obj%(nobj%, 6), 0
+ END IF
+END IF
+seljob% = 0
+KEY(1) ON
+GOTO f.end
+' curves / copy
+f.2:
+KEY(2) OFF
+IF kswitch% = 1 AND func% = 0 THEN
+ seljob% = 2
+ linesel% = 0
+ G.Curve 2, 0
+ seljob% = 0
+ELSEIF kswitch% = 1 AND func% = 1 THEN
+ seljob% = 2
+ linesel% = 1
+ MoveObj 1
+ seljob% = 0
+ELSE
+ chartype% = chartype% + 1: IF chartype% > UBOUND(chartype$) THEN chartype% = 0
+ COLOR 10: LOCATE line1% + 1, 10: PRINT chartype$(chartype%); : COLOR 7
+END IF
+KEY(2) ON
+GOTO f.end
+' circle+ellipse/ symmetric copy
+f.3:
+KEY(3) OFF
+IF kswitch% = 1 AND func% = 0 THEN
+ seljob% = 3
+ linesel% = 0
+ G.Crcl.Ellps
+ seljob% = 0
+ELSEIF kswitch% = 1 AND func% = 1 THEN
+ seljob% = 3
+ linesel% = 1
+ CopySymm
+ seljob% = 0
+ELSE 'Just added
+ SELECT CASE charpt%
+ CASE 10
+ charpt% = 12
+ CASE 12
+ charpt% = 10
+ END SELECT
+ COLOR 10: LOCATE line1% + 1, 17: PRINT charpt%;
+ LOCATE line1% + 1, 20: PRINT "pt."; : COLOR 7
+END IF
+KEY(3) ON
+GOTO f.end
+' arc/ rotate
+f.4:
+seljob% = 4
+IF func% = 0 THEN
+ linesel% = 0
+ G.Arc
+ELSEIF func% = 1 THEN
+ linesel% = 1
+ Rotate
+ELSE
+ COLOR 7
+ GOSUB widewindow
+END IF
+seljob% = 0
+GOTO f.end
+' box/ edit
+f.5:
+seljob% = 5
+IF func% = 0 THEN
+ linesel% = 0
+ G.Box
+ELSEIF func% = 1 THEN
+ linesel% = 1
+ EditObject
+ELSE
+ GOSUB stext
+ SELECT CASE wtext%
+ CASE 0
+ COLOR 3: LOCATE line1% + 1, 31: PRINT "T_Hide"; : COLOR 7
+ CASE 1
+ COLOR 3: LOCATE line1% + 1, 31: PRINT "T_Show"; : COLOR 7
+ END SELECT
+END IF
+seljob% = 0
+GOTO f.end
+' polygon/ cut
+f.6:
+seljob% = 6
+IF func% = 0 THEN
+ linesel% = 0
+ G.Curve 1, 1
+ELSEIF func% = 1 THEN
+ linesel% = 1
+ DispCut
+ELSE
+ CL.R.edraw 0, 0
+END IF
+seljob% = 0
+GOTO f.end
+' closed curve/ kill
+f.7:
+seljob% = 7
+IF func% = 0 THEN
+ linesel% = 0
+ G.Curve 2, 1
+ELSEIF func% = 1 THEN
+ linesel% = 1
+ KillObject
+ELSE
+ COLOR 7
+ GOSUB clreset
+END IF
+seljob% = 0
+GOTO f.end
+' arrow/ line type
+f.8:
+IF kswitch% = 1 AND func% = 0 THEN
+ seljob% = 8
+ KEY(8) OFF
+ linesel% = 0
+ G.Arrows
+ seljob% = 0
+ KEY(8) ON
+ GOTO f.end
+ELSE
+ ltype% = ltype% + 1: IF ltype% > UBOUND(ltp$) THEN ltype% = 0
+ kky$(18) = ltp$(ltype%)
+ COLOR 10: LOCATE line1%, 61: PRINT kky$(18); : COLOR 7
+ RETURN
+END IF
+' strings/ thickness
+f.9:
+IF kswitch% = 1 AND func% = 0 THEN
+ seljob% = 9
+ KEY(9) OFF
+ linesel% = 0
+ G.Char
+ seljob% = 0
+ KEY(9) ON
+ GOTO f.end
+ELSE
+ thick% = thick% + 1: IF thick% > UBOUND(lth$) THEN thick% = 0
+ kky$(19) = lth$(thick%)
+ COLOR 10: LOCATE line1%, 68: PRINT kky$(19); : COLOR 7
+ RETURN
+END IF
+' file operations/ pitch
+f.10:
+IF kswitch% = 1 AND func% = 0 THEN
+ IO.File
+ GOTO f.end
+ELSE
+ SELECT CASE s%
+
+ CASE 1
+ s% = 4
+ kky$(20) = "Pitch4"
+ CASE 4
+ s% = 8
+ kky$(20) = "Pitch8"
+ CASE 8
+ s% = 1
+ kky$(20) = "Pitch1"
+ END SELECT
+
+ COLOR 10: LOCATE line1%, 75: PRINT kky$(20); : COLOR 7
+ RETURN
+END IF
+'
+f.end: pxold% = px%: pyold% = py%
+RETURN
+
+somethingwrong:
+CLOSE : OPEN "$panic$.qfg" FOR OUTPUT AS #1
+wrong% = 1
+CLS 0
+IO.Save 3: CLOSE
+wrong% = 0
+COLOR 14: PRINT : PRINT
+PRINT TAB(10); CHR$(7); "Ummm... Something wrong happened..."; CHR$(7)
+COLOR 7: PRINT : PRINT TAB(10); "Error code is #"; ERR
+SELECT CASE ERR
+ CASE 7
+ PRINT : PRINT TAB(10); "Out of memory. Free some more conventional memory"
+ CASE 9
+ PRINT : PRINT TAB(10); "A subscript is out of range"
+ CASE 52
+ PRINT : PRINT TAB(10); "Illegal DOS filename"
+ CASE 64
+ PRINT : PRINT TAB(10); "Illegal DOS filename"
+
+END SELECT
+PRINT : PRINT TAB(10); "Objects are saved into '$panic$.qfg'"
+PRINT : PRINT
+SLEEP 3
+GOSUB quit1: KEY ON: END
+
+' data
+DATA 88,00,00,00,88,00,00,00
+DATA CC,00,33,00,CC,00,33,00,CC,33,CC,33,CC,33,CC,33
+'--------------------------------------------------------------------------
+tex.pitch:
+'set by \wd and \ht of \box of each character; 7/24/1992
+' roman 10pt
+DATA 333,278,500,833,500,833,778,250,389,389,500,778,167,778,278,500
+DATA 500,500,500,500,500,500,500,500,500,500,278,278,778,778,778,472
+DATA 778,750,708,722,764,681,653,785,750,386,514,778,625,917,750,778
+DATA 681,778,736,556,722,750,750,1028,750,750,611,278,333,278,525,360
+DATA 333,500,556,444,556,444,292,500,556,278,306,528,278,833,556,525
+DATA 556,528,392,394,389,556,528,722,528,528,444,500,278,500,525
+' bold 10pt
+DATA 383,350,603,958,575,958,894,301,447,447,575,894,192,778,319,575
+DATA 575,575,575,575,575,575,575,575,575,575,319,319,778,894,778,543
+DATA 894,869,818,831,882,756,724,904,900,465,594,901,692,1092,900,864
+DATA 786,864,862,639,800,885,869,1189,869,869,703,319,383,319,525,414
+DATA 383,559,639,511,639,527,335,575,639,319,351,607,319,958,639,604
+DATA 639,607,474,454,447,639,607,831,607,607,511,500,278,500,525
+' italic 10pt
+DATA 358,307,514,818,500,818,767,257,409,409,511,767,170,778,307,511
+DATA 511,511,511,511,511,511,511,511,511,511,307,307,778,767,778,511
+DATA 767,743,704,716,755,678,653,774,743,386,525,769,627,897,743,767
+DATA 678,767,729,562,716,743,743,999,743,743,613,307,358,307,525,368
+DATA 358,511,460,414,511,414,307,460,511,307,307,460,302,818,562,465
+DATA 511,460,422,409,332,537,460,664,464,486,409,500,278,500,525
+' bold-italic 10pt
+DATA 414,386,621,944,548,944,886,310,473,473,591,886,197,852,356,591
+DATA 591,591,591,591,591,591,591,591,591,591,356,356,852,886,852,591
+DATA 886,866,817,827,876,757,727,895,896,472,611,895,698,1073,896,855
+DATA 787,855,859,650,796,881,866,1160,866,866,709,356,414,356,575,426
+DATA 414,591,532,479,591,479,378,532,591,356,356,532,350,944,650,538
+DATA 591,532,502,487,385,621,532,768,561,562,491,548,304,548,575
+'
+
+REM $STATIC
+SUB Chr.Input (aci$)
+' ----- character input -----
+' allow to use left/right arrows, back space and delete
+' presumably all other char's are visible and no longer than 2 lines
+aci$ = RTRIM$(aci$)
+lciold% = POS(0): mciold% = CSRLIN: cci% = LEN(aci$) + 1
+LOCATE mciold%, lciold%, 1, 14, 15
+DO
+ LOCATE mciold%, lciold%: PRINT SPACE$(LEN(aci$) + 4);
+ length% = LEN(aci$)
+ LOCATE mciold%, lciold%: PRINT aci$;
+' LOCATE , , 1, 0, 7
+ mci% = mciold%
+ kci% = lciold% - 1
+ IF cci% = length% + 1 THEN kci% = kci% + 1
+ FOR ici% = 1 TO cci%
+ kkci% = LEN(MID$(aci$, ici%, 1))
+ IF kkci% = 2 AND kci% = 79 THEN kci% = kci% + 1
+ kci% = kci% + kkci%
+ NEXT ici%
+ IF kci% > 80 THEN kci% = kci% - 80: mci% = mci% + 1
+ IF cci% <> length% + 1 AND LEN(MID$(aci$, cci%, 1)) = 2 THEN kci% = kci% - 1
+ LOCATE mci%, kci%
+ DO: cci$ = INKEY$: LOOP WHILE cci$ = ""
+
+ SELECT CASE cci$
+ CASE CHR$(&H8) ' back-space
+ IF cci% <> 1 THEN
+ aci$ = MID$(aci$, 1, cci% - 2) + MID$(aci$, cci%)
+ cci% = cci% - 1
+ END IF
+ CASE CHR$(&H0) + CHR$(&H4B)' left-arrow
+ IF cci% <> 1 THEN
+ cci% = cci% - 1
+ END IF
+ CASE CHR$(&H0) + CHR$(&H53)' delete
+ IF length% > 0 THEN
+ aci$ = MID$(aci$, 1, cci% - 1) + MID$(aci$, cci% + 1)
+ END IF
+ CASE CHR$(&H0) + CHR$(&H4D)' right-arrow
+ IF cci% < length% + 1 THEN
+ cci% = cci% + 1
+ END IF
+ CASE IS >= CHR$(&H20) ' visible characters
+ IF (length% < nodemax% - 1) THEN
+ aci$ = MID$(aci$, 1, cci% - 1) + cci$ + MID$(aci$, cci%)
+ cci% = cci% + 1
+ END IF
+ END SELECT
+toolong:
+LOOP UNTIL cci$ = CHR$(&HD)
+LOCATE , , 0, 0, 15
+'
+END SUB
+
+SUB CursorDisplay (ppxx%, ppyy%)
+' cursor mark on and off
+xyshift% = INT(5! * wndwxy(wndwfctr%))
+PUT (ppxx% - xyshift%, ppyy% - xyshift%), curs%, XOR
+IF mouswitch% THEN MouseLocate ppyy%, ppxx% '<=== when Mouse is used
+aa = ppxx% * .25: bb = ppyy% * .25
+ad = aa - INT(aa) + .001: bd = bb - INT(bb) + .001
+aa = INT(aa): bb = INT(bb)
+a$ = "<" + RIGHT$(" " + STR$(aa), 3) + ":"
+a$ = a$ + RIGHT$(" " + STR$(bb), 3) + ">"
+b$ = "(" + MID$(STR$(ad), 2, 3) + ":" + MID$(STR$(bd), 2, 3) + ")"
+COLOR 7
+LOCATE line2%, 38: PRINT a$;
+LOCATE line1%, 38: PRINT b$;
+PUT (ppxx% - 2, 3 + pyo%), markx%, XOR
+PUT (3 + pxo%, ppyy% - 2), marky%, XOR
+'
+END SUB
+
+SUB CursorMotion (keyin%)
+' cursor motion with cursor mark on and off
+pxold% = px%: pyold% = py%
+keyin% = KeyIsTyped%
+IF job% <> 0 AND pyold% > pymax2% THEN
+pyold% = pymax2%
+CursorDisplay pxold%, pyold%
+END IF
+CursorDisplay pxold%, pyold%
+CursorDisplay px%, py%
+'
+END SUB
+
+SUB KeyDisplay
+' function-key instruction displayed
+COLOR 3
+FOR i% = 1 TO 5: LOCATE line2%, i% * 7 - 4: PRINT kky$(i%);
+LOCATE line1%, i% * 7 - 4: PRINT kky$(i% + 10); : NEXT i%
+SELECT CASE wtext%
+ CASE 0
+ LOCATE line1% + 1, 31: PRINT "T_Hide";
+ CASE 1
+ LOCATE line1% + 1, 31: PRINT "T_Show";
+END SELECT
+
+LOCATE line1% + 1, 24: PRINT " Zoom";
+LOCATE line1% + 1, 47: PRINT "Redraw";
+LOCATE line1% + 1, 55: PRINT "Reset";
+
+
+COLOR 14: LOCATE line1% + 1, 64: PRINT "[CTRL+h=HELP]";
+'COLOR 12: LOCATE line1% + 1, 64: PRINT "[QFIG ver. 1.1a]";
+
+COLOR 10
+LOCATE line1% + 1, 7: PRINT fill%;
+LOCATE line1% + 1, 3: PRINT "Fil-P";
+LOCATE line1% + 1, 10: PRINT chartype$(chartype%);
+LOCATE line1% + 1, 17: PRINT charpt%;
+LOCATE line1% + 1, 20: PRINT "pt."; : COLOR 3
+
+
+FOR i% = 6 TO 7: LOCATE line2%, 5 + i% * 7: PRINT kky$(i%);
+LOCATE line1%, 5 + i% * 7: PRINT kky$(i% + 10); : NEXT i%
+FOR i% = 8 TO 10: COLOR 3: LOCATE line2%, 5 + i% * 7: PRINT kky$(i%);
+COLOR 10: LOCATE line1%, 5 + i% * 7: PRINT kky$(i% + 10); : NEXT i%: COLOR 7
+LOCATE line2% + func%, 2: COLOR 6: PRINT "@"; : COLOR 7
+
+COLOR 6
+LOCATE line3%, 20: PRINT "L-but(SPC)|R-but(RET)";
+'LOCATE line3%, 19: PRINT "L-but=SPC/y|R-but=RET/n";
+LOCATE line3%, 60: PRINT "L+R (DEL)"; : COLOR 7
+
+CursorDisplay px%, py%
+'
+END SUB
+
+FUNCTION KeyIsTouched$
+'
+IF mouswitch% THEN MousePoll row%, col%, lbut%, rbut% '<=== when Mouse is used
+KeyIsTouched$ = INKEY$
+'
+END FUNCTION
+
+FUNCTION KeyIsTyped%
+' which key has been typed so far
+' 1:motion 2:space or left button
+' 3:return or right button 4:delete or both button (sensitive)
+keyin% = 0
+DO
+ DO
+ IF Help% = 1 AND mouswitch% <> 0 THEN
+ keyin% = 1: Help% = 0
+ EXIT DO
+ END IF
+ q$ = KeyIsTouched$
+ LOOP UNTIL q$ <> "" OR row% <> py% OR col% <> px% OR lbut% <> 0 OR rbut% <> 0
+ SELECT CASE q$
+ CASE CHR$(&H0) + CHR$(UP)
+ IF py% - s% >= pymin% THEN py% = py% - s%: keyin% = 1
+ CASE CHR$(&H0) + CHR$(DOWN)
+ IF py% + s% <= pymax% THEN py% = py% + s%: keyin% = 1
+ CASE CHR$(&H0) + CHR$(LEFT)
+ IF px% - s% >= pxmin% THEN px% = px% - s%: keyin% = 1
+ CASE CHR$(&H0) + CHR$(RIGHT)
+ IF px% + s% <= pxmax% THEN px% = px% + s%: keyin% = 1
+ CASE CHR$(SP)
+ keyin% = 2
+ CASE CHR$(CR)
+ keyin% = 3
+ CASE CHR$(&H0) + CHR$(DEL)
+ keyin% = 4
+ CASE CHR$(&H0) + CHR$(&H49) 'CTRL + PGUP
+ keyin% = 5
+ CASE CHR$(&H0) + CHR$(&H51) 'CTRL + PGDN
+ keyin% = 6
+ CASE CHR$(&H0) + CHR$(&H73) 'CTRL + LEFT
+ keyin% = 7
+ CASE CHR$(&H0) + CHR$(&H74) 'CTRL + RIGHT
+ keyin% = 8
+ CASE ""
+ IF mouswitch% THEN
+ IF lbut% <> 0 THEN
+ keyin% = 2
+ DO
+ MousePoll row%, col%, lbut%, rbut% '<=== when Mouse is used
+ LOOP UNTIL lbut% = 0 OR rbut% <> 0
+ IF rbut% <> 0 THEN keyin% = 4
+ END IF
+ IF rbut% <> 0 THEN
+ keyin% = 3
+ DO
+ MousePoll row%, col%, lbut%, rbut% '<=== when Mouse is used
+ LOOP UNTIL rbut% = 0 OR lbut% <> 0
+ IF lbut% <> 0 THEN keyin% = 4
+ END IF
+ IF row% - py% THEN
+ IF row% > pymax% THEN row% = pymax%
+ IF row% < pymin% THEN row% = pymin%
+ py% = row%
+ IF keyin% = 0 THEN keyin% = 1
+ END IF
+ IF col% - px% THEN
+ IF col% > pxmax% THEN col% = pxmax%
+ IF col% < pxmin% THEN col% = pxmin%
+ px% = col%
+ IF keyin% = 0 THEN keyin% = 1
+ END IF
+ IF keyin% = 4 THEN
+ DO
+ MousePoll row%, col%, lbut%, rbut% '<=== when Mouse is used
+ LOOP UNTIL rbut% = 0 AND lbut% = 0
+ END IF
+ END IF
+ END SELECT
+ IF (job% <> 0) AND py% > pymax2% THEN py% = pymax2%
+ IF (py% + texth% - 5) > pymax2% AND job% = 5 THEN py% = pymax2% - texth% + 5
+IF Help% = 1 THEN keyin% = 1
+IF ((keyin% > 4) AND (job% <> 0) AND (keyin% <> 9)) THEN keyin% = 0
+LOOP UNTIL keyin% <> 0
+KeyIsTyped% = keyin%
+Help% = 0
+'
+END FUNCTION
+
+SUB KeySwitch (ksw%)
+' key on/off switch
+kswitch% = ksw% '<-- global definition ?
+IF kswitch% = 1 THEN
+ KEY(1) ON: KEY(2) ON: KEY(3) ON: KEY(4) ON: KEY(5) ON: KEY(6) ON
+ KEY(7) ON: KEY(15) ON: KEY(16) ON: KEY(18) ON
+ KEY(20) ON: KEY(21) ON: KEY(22) ON: KEY(23) ON: KEY(24) ON
+ELSE
+' KEY(3) OFF:
+ KEY(4) OFF: KEY(5) OFF: KEY(6) OFF
+ KEY(7) OFF: KEY(15) OFF: KEY(16) OFF: KEY(18) OFF
+ KEY(20) OFF: KEY(21) OFF: KEY(22) OFF: KEY(23) OFF: KEY(24) OFF
+END IF
+'
+END SUB
+
+SUB Preparation
+' preparations
+ltp%(0) = &HFFFF: ltp%(1) = &H8888: ltp%(2) = &HC3C3: ltp%(3) = &HA0A0
+ltp$(0) = " Solid": ltp$(1) = "Dotted"
+ltp$(2) = " Dash ": ltp$(3) = "D-Dash"
+
+lth$(0) = " Thin ": lth$(1) = "Thick1": lth$(2) = "Thick2"
+
+FOR i% = 1 TO 3: tlp$(i%) = ""
+FOR j% = 1 TO 8: READ tt$: tt = VAL("&H" + tt$)
+FOR k% = 1 TO 4: tlp$(i%) = tlp$(i%) + CHR$(tt): NEXT k%, j%, i%
+
+nocheat% = 0: IF INSTR(COMMAND$, "/NC") <> 0 THEN nocheat% = 1
+
+nofile% = 1: IF INSTR(COMMAND$, "/F") <> 0 THEN nofile% = 0
+
+'nofile% = 0
+wspec% = 0: IF INSTR(COMMAND$, "/S") <> 0 THEN wspec% = 1
+
+ega% = 0: IF INSTR(COMMAND$, "/E") <> 0 THEN ega% = 1
+'chartype$(0) = "Roman ": chartype$(1) = "Bold "
+'chartype$(2) = "Italic ": chartype$(3) = "Bold Italic "
+
+chartype$(0) = " Roman": chartype$(1) = " Bold "
+chartype$(2) = "Italic": chartype$(3) = "Bld-It"
+
+'original KEEP
+
+chartex$(0, 0) = "\xpt\rm ": chartex$(0, 1) = "\xpt\bf "
+chartex$(0, 2) = "\xpt\it ": chartex$(0, 3) = "\xpt\FonttenBI "
+chartex$(1, 0) = "\xiipt\rm ": chartex$(1, 1) = "\xiipt\bf "
+chartex$(1, 2) = "\xiipt\it ": chartex$(1, 3) = "\xiipt\FonttwlBI "
+charjtex$(0, 0) = "\tendm ": charjtex$(0, 1) = "\tendg "
+charjtex$(1, 0) = "\twelvedm ": charjtex$(1, 1) = "\twelvedg "
+
+'original end
+
+chartype% = 0: charpt% = 12
+chattr%(0, 0) = 7: chattr%(0, 1) = 0
+chattr%(1, 0) = 11: chattr%(1, 1) = 6
+chattr%(2, 0) = 7: chattr%(2, 1) = 11
+chattr%(3, 0) = 11: chattr%(3, 1) = 10
+
+' set by \wd \ht of \hbox at 10pt; 7/24/1992
+jpitch% = 915: jheight(0) = .77088: jheight(1) = .77088
+' set by \ht of height of "A" in each font at 10pt; 7/24/1992
+eheight(0) = .68333: eheight(1) = .68611
+eheight(2) = .68333: eheight(3) = .68611
+'
+RESTORE tex.pitch
+FOR i% = 0 TO 94: READ epitch%(0, i%): NEXT i%
+FOR i% = 0 TO 94: READ epitch%(1, i%): NEXT i%
+FOR i% = 0 TO 94: READ epitch%(2, i%): NEXT i%
+FOR i% = 0 TO 94: READ epitch%(3, i%): NEXT i%
+' scriptsize up/down motion in dot (* point * 0.25 mm)
+scrpt(0) = 0!: scrpt(1) = .5: scrpt(2) = -.2
+
+Ins(0).L = SPACE$(15): Ins(0).R = SPACE$(15): Ins(0).D = SPACE$(15)
+Ins(1).L = " mid-pts set": Ins(1).R = "last pt. set ": Ins(1).D = "cancel"
+Ins(2).L = "circle cnt/rads": Ins(2).R = "ellps diag.pts.": Ins(2).D = "cancel"
+Ins(3).L = " end points": Ins(3).R = "on the arc ": Ins(3).D = "cancel"
+Ins(4).L = " diagonal pts.": Ins(4).R = " diagonal pts. ": Ins(4).D = "cancel"
+Ins(5).L = " position": Ins(5).R = " position": Ins(5).D = "cancel"
+Ins(6).L = " <--- / --->": Ins(6).R = "<-----> ": Ins(6).D = "cancel"
+Ins(7).L = " object select": Ins(7).R = " region select": Ins(7).D = "cancel"
+Ins(8).L = " object select": Ins(8).R = " region select ": Ins(8).D = "cancel"
+Ins(9).L = " displace node": Ins(9).R = "cut node ": Ins(9).D = "cancel"
+Ins(10).L = " object select": Ins(10).R = " region select ": Ins(10).D = "cancel"
+Ins(11).L = "wrt hrzntl axis": Ins(11).R = "wrt vrtcl axius": Ins(11).D = "cancel"
+Ins(12).L = " rotate": Ins(12).R = "set(angle/obj) ": Ins(12).D = "cancel"
+Ins(13).L = " object select": Ins(13).R = " region select": Ins(13).D = "cancel"
+
+s% = 4: s1% = 1: px% = 320: py% = 200: mouswitch% = 0
+pxo% = 0: pyo% = 0: inbox% = 0
+func% = 0: func1% = 1: job% = 0: seljob% = 0: Help% = 0
+nobj% = 0: ltype% = 0: thick% = 0: fill% = 0
+xmin% = REGIONXMAX: xmax% = 0: ymin% = REGIONYMAX: ymax% = 0
+pi = 4! * ATN(1!): group% = 1: margin% = 7
+
+wndwfctr% = 0
+wndwxy(0) = 1!: wndwxy(1) = 1.3125: wndwxy(2) = 1.8: wndwxy(3) = 2.2
+IF ega% = 0 THEN
+ windowx%(0) = 639: windowy%(0) = 479: texth% = 16
+ scrtype% = 12: line1% = 29: line2% = 28: line3% = 27
+ELSE
+ windowx%(0) = 639: windowy%(0) = 349: texth% = 14
+ scrtype% = 9: line1% = 24: line2% = 23: line3% = 22
+END IF
+FOR i% = 1 TO 3: windowx%(i%) = INT(CSNG(windowx%(0) + 1) * wndwxy(i%) - 1)
+windowy%(i%) = INT(CSNG(windowy%(0) + 1) * wndwxy(i%) - 1): NEXT i%
+pxmin% = margin%: pxmax% = windowx%(0) - margin%
+pymin% = margin%: pymax% = windowy%(0) - margin%
+pymax2% = windowy%(0) - texth% * 4 - 5 - margin%
+winpy% = windowy%(0) - texth% * 4 - margin%
+' cursor marks
+SCREEN scrtype%
+LINE (320, 195)-STEP(0, 10): LINE (315, 200)-STEP(10, 0)
+GET (315, 195)-(325, 205), curs%: CLS
+LINE (318, 195)-(322, 195): LINE (317, 196)-(323, 196)
+LINE (317, 196)-(317, 197): LINE (323, 196)-(323, 197)
+LINE (318, 196)-(318, 198): LINE (322, 196)-(322, 198)
+LINE (320, 197)-(320, 200): LINE (319, 198)-(319, 200)
+LINE (321, 198)-(321, 200)
+LINE (315, 200)-(316, 200): LINE (324, 200)-(325, 200)
+LINE (317, 201)-(318, 201): LINE (322, 201)-(323, 201)
+LINE (318, 202)-(322, 202)
+LINE (315, 204)-(316, 204): LINE (324, 204)-(325, 204)
+LINE (317, 203)-(318, 203): LINE (322, 203)-(323, 203)
+GET (315, 195)-(325, 205), curs1%: CLS 'cursor mark for KILL
+CIRCLE (323, 197), 2: CIRCLE (323, 203), 2
+LINE (315, 196)-(323, 201): LINE (315, 204)-(323, 199)
+LINE (316, 196)-(324, 201): LINE (316, 204)-(324, 199)
+GET (315, 195)-(325, 205), curs2%: CLS 'cursor mark for CUT
+
+CIRCLE (3, 3), 3, 10: GET (0, 0)-(6, 6), mark%: CLS
+LINE (0, 0)-(6, 6), 10, BF: CIRCLE (3, 3), 3, 0
+GET (0, 0)-(6, 6), markg%: CLS
+
+LINE (2, 0)-(4, 4), 6: LINE -(0, 4), 6: LINE -(2, 0), 6: PAINT (2, 3), 6
+GET (0, 0)-(4, 4), markx%: CLS
+LINE (0, 2)-(4, 0), 6: LINE -(4, 4), 6: LINE -(0, 2), 6: PAINT (3, 2), 6
+GET (0, 0)-(4, 4), marky%: CLS
+
+kky$(1) = " Line ": kky$(2) = " Curve": kky$(3) = "CrcEll"
+kky$(4) = " Arc ": kky$(5) = " Box ": kky$(6) = " Poly "
+kky$(7) = "Cl-Crv": kky$(8) = " Arrow"
+kky$(9) = "String": kky$(10) = " File "
+kky$(11) = " Move ": kky$(12) = " Copy ": kky$(13) = "Sym.cp"
+kky$(14) = "Rotate": kky$(15) = " Edit ": kky$(16) = "DspCut"
+kky$(17) = " Kill ": kky$(18) = " Solid"
+kky$(19) = " Thin ": kky$(20) = "Pitch4"
+kky$(21) = " 12pt.": kky$(21) = "Roman "
+altpitch$ = "Pitch1"
+
+IF nofile% = 1 THEN mpath% = 0: GOTO inputusersettings
+' input user-definable data settings
+path0$ = ".;" + ENVIRON$("PATH")
+DO
+ mpath% = INSTR(path0$, ";")
+ IF mpath% = 0 THEN
+ path$ = path0$
+ path0$ = ""
+ ELSE
+ path$ = LEFT$(path0$, mpath% - 1)
+ path0$ = MID$(path0$, mpath% + 1)
+ END IF
+ IF path$ <> "" AND RIGHT$(path$, 1) <> "\" THEN path$ = path$ + "\"
+ ifile$ = path$ + "qfig_set.dat"
+ OPEN ifile$ FOR RANDOM AS #1
+ IF LOF(1) = 0 THEN
+ CLOSE #1
+ KILL ifile$
+ ELSE
+ mpath% = -1
+ EXIT DO
+ END IF
+LOOP UNTIL mpath% = 0
+
+inputusersettings:
+IF mpath% = 0 THEN
+' default
+ arrowhead = 8! 'arrow = arrowhead + darrowhead * obj%(n%, 4)
+ darrowhead = 1.5
+ arrowdirect = pi / 9! 'arrow is directed to \pm arrowdirect
+ arcarrowd = pi / 30! 'correction of inward direction on the arc
+ dpattern$(1) = "6pt, 3pt" 'dashpattern on PiCTeX
+ dpattern$(2) = "10pt, 3pt, 2pt, 3pt"
+ dpattern$(3) = "10pt, 3pt, 2pt, 3pt, 2pt, 3pt"
+ filler%(0) = 0 'filler color on N-Graph
+ filler%(1) = 2
+ filler%(2) = 6
+ filler%(3) = 1
+ eepicpattern$(1) = "\dottedline{3}"
+ eepicpattern$(2) = "\dashline[50]{10}"
+ eepicpattern$(3) = "\dashline[50]{10}[2]"
+ tpicshade$(1) = "[0.1]"
+ tpicshade$(2) = "[0.4]"
+ tpicshade$(3) = "[0.7]"
+ hscroll% = 200
+ vscroll% = 120
+ interpolcurve% = 10
+ interpolang% = 36 '5 degree
+ELSE
+ CLOSE #1
+ OPEN ifile$ FOR INPUT AS #1
+ arrowhead = VAL(Usetdata$)
+ darrowhead = VAL(Usetdata$)
+ arrowdirect = pi / VAL(Usetdata$)
+ arcarrowd = pi / VAL(Usetdata$)
+ dpattern$(1) = Usetdata$
+ dpattern$(2) = Usetdata$
+ dpattern$(3) = Usetdata$
+ filler%(0) = VAL(Usetdata$)
+ filler%(1) = VAL(Usetdata$)
+ filler%(2) = VAL(Usetdata$)
+ filler%(3) = VAL(Usetdata$)
+ eepicpattern$(1) = Usetdata$
+ eepicpattern$(2) = Usetdata$
+ eepicpattern$(3) = Usetdata$
+ tpicshade$(1) = Usetdata$
+ tpicshade$(2) = Usetdata$
+ tpicshade$(3) = Usetdata$
+ hscroll% = VAL(Usetdata$)
+ IF hscroll% <= 0 OR hscroll% > 200 THEN hscroll% = 200
+ vscroll% = VAL(Usetdata$)
+ IF vscroll% <= 0 OR vscroll% > 120 THEN vscroll% = 120
+ interpolcurve% = VAL(Usetdata$)
+ interpolang% = 180! / CSNG(VAL(Usetdata$))
+
+ chartex$(0, 0) = Usetdata$ + " "
+ chartex$(0, 1) = Usetdata$ + " "
+ chartex$(0, 2) = Usetdata$ + " "
+ chartex$(0, 3) = Usetdata$ + " "
+ chartex$(1, 0) = Usetdata$ + " "
+ chartex$(1, 1) = Usetdata$ + " "
+ chartex$(1, 2) = Usetdata$ + " "
+ chartex$(1, 3) = Usetdata$ + " "
+
+ CLOSE #1
+END IF
+'
+tpicshade% = 1
+'
+iomessages$(1) = "Load picture data from file [.qfg]"
+iomessages$(2) = "Merge picture data from file [.qfg]"
+iomessages$(3) = "Save this picture into file [.qfg] only"
+iomessages$(4) = "Save picture in [.qfg] & 'PiCTeX' code in [.tex]"
+iomessages$(5) = "Save picture in [.qfg] & 'eepic' code in [.tex]"
+iomessages$(6) = "Save picture in [.qfg] & 'eepicemu' code in [.tex]"
+iomessages$(7) = "Quit (Exit Program)"
+'
+END SUB
+
+SUB SetInst (ninstr%)
+' set instruction of left/right buttons (space/return)
+COLOR 7
+IF ninstr% > 0 THEN SWAP Ins(0), Ins(ninstr%)
+LOCATE line3%, 4: PRINT Ins(0).L; : LOCATE line3%, 42: PRINT Ins(0).R;
+LOCATE line3%, 70: PRINT Ins(0).D;
+'
+END SUB
+
+FUNCTION Usetdata$
+' get a line and strip comment
+DO
+LINE INPUT #1, a$
+a$ = LEFT$(a$, INSTR(a$, ";") - 1)
+LOOP UNTIL a$ <> ""
+i% = INSTR(a$, CHR$(9))
+DO UNTIL i% = 0
+ a$ = LEFT$(a$, i% - 1)
+ i% = INSTR(a$, CHR$(9))
+LOOP
+Usetdata$ = LTRIM$(RTRIM$(a$))
+'
+END FUNCTION
+
diff --git a/support/qfig/src/qfig.bi b/support/qfig/src/qfig.bi
new file mode 100644
index 0000000000..bb8c49e2a9
--- /dev/null
+++ b/support/qfig/src/qfig.bi
@@ -0,0 +1,130 @@
+' include file for qfig.bas
+
+DECLARE FUNCTION Angle! (x0!, y0!, x1!, y1!)
+DECLARE FUNCTION KeyIsTouched$ ()
+DECLARE FUNCTION KeyIsTyped% ()
+DECLARE FUNCTION Usetdata$ ()
+DECLARE FUNCTION yesno$ ()
+DECLARE SUB CL.R.edraw (simple%, show%)
+DECLARE SUB Chr.Input (a$)
+DECLARE SUB CopySymm ()
+DECLARE SUB CursorDisplay (ppxx%, ppyy%)
+DECLARE SUB CursorMotion (keyin%)
+DECLARE SUB D.Circles (cx%, cy%, rad!, ratio!, sang!, eang!, clr%, thickness%, simple%, wpatt%)
+DECLARE SUB D.Lines (sx%, sy%, ex%, ey%, clr%, box%, thickness%, linetype%, filltype%, simple%)
+DECLARE SUB D.Strings (n%, clr%, simple%)
+DECLARE SUB D.Str1 (n%, clr%, simple%)
+DECLARE SUB Disp.C (sobj%, snode%)
+DECLARE SUB Disp.D (sobj%, snode%)
+DECLARE SUB DispCut ()
+DECLARE SUB EditObject ()
+DECLARE SUB FillPattern ()
+DECLARE SUB G.Addnode (o%, n%, editcc%)
+DECLARE SUB G.Arc ()
+DECLARE SUB G.ArrowDirec (sobj%, snode%, n%)
+DECLARE SUB G.Arrows ()
+DECLARE SUB G.Arrowset (sobj%, snode%, already%)
+DECLARE SUB G.Box ()
+DECLARE SUB G.Char ()
+DECLARE SUB G.CharDisp ()
+DECLARE SUB G.Charset (ams$, n%)
+DECLARE SUB G.Crcl ()
+DECLARE SUB G.Crcl.Ellps ()
+DECLARE SUB G.Curve (curve%, closed%)
+DECLARE SUB G.Ellps ()
+DECLARE SUB G.Group ()
+DECLARE SUB G.Group1 (i%)
+DECLARE SUB G.XYparam (x0%, y0%, x1%, y1%, x2%, y2%, ax!, bx!, cx!, ay!, by!, cy!)
+DECLARE SUB Help.Me ()
+DECLARE SUB IO.Eepic ()
+DECLARE SUB IO.Export ()
+DECLARE SUB IO.File ()
+DECLARE SUB IO.Load (ifile%)
+DECLARE SUB IO.Save (ifile%)
+DECLARE SUB KeyDisplay ()
+DECLARE SUB KeySwitch (ksw%)
+DECLARE SUB Killer (i%, s%)
+DECLARE SUB KillObject ()
+DECLARE SUB L.Text (ipx%, ipy%)
+DECLARE SUB MarkEnds (c%)
+DECLARE SUB Marking (c%, n%)
+DECLARE SUB Marking.Chk (m%, sobj%, snode%)
+DECLARE SUB Marking.One (c%, i%)
+DECLARE SUB Marking.Reg (sx%, sy%, ex%, ey%, total%)
+DECLARE SUB MaxMin (ppxx%, ppyy%)
+DECLARE SUB MoveObj (c%)
+DECLARE SUB MoveObject (total%, c%)
+DECLARE SUB Object.Max.Check ()
+DECLARE SUB PPUT (xp, yp, markp%())
+DECLARE SUB Preparation ()
+DECLARE SUB Rotate ()
+DECLARE SUB SetInst (ninstr%)
+DECLARE SUB SetObject (n%, clr%, simple%)
+DECLARE SUB TeX.Characters (i%, j%, ams$, kanji%, special%, script%)
+DECLARE SUB ptext (x%, y%, s$, c%, m%)
+DECLARE SUB whelp ()
+DECLARE SUB QUIT0 ()
+
+TYPE Instruction
+ L AS STRING * 15
+ R AS STRING * 15
+ D AS STRING * 6
+END TYPE
+
+COMMON SHARED /Objects/ xx(), yy(), obj%(), mobj%()
+COMMON SHARED /Settings/ ltp%(), ltp$(), lth$(), tlp$(), dpattern$()
+COMMON SHARED /Settings/ chartype$(), chartex$(), charjtex$(), chattr%()
+COMMON SHARED /Settings/ epitch%(), eheight(), jheight(), scrpt()
+COMMON SHARED /Settings/ Ins() AS Instruction
+COMMON SHARED /Settings/ curs%(), curs1%(), curs2%()
+COMMON SHARED /Settings/ mark%(), markg%(), markx%(), marky%(), kky$()
+COMMON SHARED /Settings/ windowx%(), windowy%(), wndwxy()
+COMMON SHARED /Settings/ iomessages$()
+
+COMMON SHARED pxmin%, pxmax%, pymin%, pymax%
+COMMON SHARED charpt%, chartype%, jpitch%
+COMMON SHARED px%, py%, s%, s1%, mouswitch%, func%, func1%, job%, seljob%
+COMMON SHARED pxo%, pyo%, hscroll%, vscroll%, margin%, help%, linesel%, wkill%
+COMMON SHARED xmin%, xmax%, ymin%, ymax%, row%, col%, lbut%, rbut%, woldrad%
+COMMON SHARED nobj%, ltype%, thick%, fill%, kswitch%, altpitch$, pi, wtext%
+COMMON SHARED group%, emulation%, wndwfctr%, wnode%, wspec%, wrong%, selh%
+COMMON SHARED scrtype%, ega%, line1%, line2%, line3%, texth%, pymax2%
+COMMON SHARED winpy%, inbox%, sxg%, syg%
+
+COMMON SHARED arrowhead, darrowhead, arrowdirect, arcarrowd, filler%()
+COMMON SHARED eepicpattern$(), tpicshade$(), tpicshade%, nocheat%
+COMMON SHARED interpolcurve%, interpolang%
+
+COMMON SHARED wxx1!, wxx2!
+
+CONST nobjmax% = 300 '(maximum # of objects)-1 =300
+CONST nodemax% = 64 '(maximum # of nodes)-1 =64
+CONST UP = &H48, LEFT = &H4B, RIGHT = &H4D, DOWN = &H50
+CONST CR = &HD, SP = &H20, DEL = &H53, ESC = &H0, CLRHM = &H3E, HMCLR = &HAE
+CONST FILE.CHECK$ = "% Output of qfig.bas"
+CONST ptmm = .3515
+CONST REGIONXMAX = 840, REGIONYMAX = 880
+CONST msgload$ = " Now loading.... "
+CONST msgsave$ = " Now saving..... "
+CONST msgrdrw$ = " Now redrawing... "
+
+DIM xx(nobjmax%, nodemax%), yy(nobjmax%, nodemax%), obj%(nobjmax%, 6)
+DIM mobj%(nobjmax% / 2)
+DIM ltp%(3), ltp$(3), lth$(2), tlp$(1 TO 3), dpattern$(3)
+DIM chartype$(3), chartex$(1, 3), charjtex$(1, 1), chattr%(3, 1)
+DIM epitch%(3, 94), jheight(1), eheight(3), scrpt(2)
+DIM Ins(13) AS Instruction
+DIM curs%(92), curs1%(92), curs2%(92)
+DIM mark%(32), markg%(32), markx%(24), marky%(24)
+DIM kky$(1 TO 25)
+DIM filler%(3), eepicpattern$(1 TO 3), tpicshade$(1 TO 3)
+DIM windowx%(3), windowy%(3), wndwxy(3)
+DIM iomessages$(1 TO 7)
+
+DEF fno$ (a, b) = LTRIM$(STR$(INT(a * b)))
+DEF fnor$ (a, b) = LTRIM$(STR$(INT(a * b * 1000! + .5) / 1000!))
+'DEF fnor$ (a, b) = LTRIM$(STR$(INT(a * b * 1000! + .5) / 1000!))
+DEF fnoo% (ob%) = obj%(ob%, 0) - INT(obj%(ob%, 0) / 100) * 100
+
+' end of qfig.bi
+
diff --git a/support/qfig/src/qfig.mak b/support/qfig/src/qfig.mak
new file mode 100644
index 0000000000..ed8f83b483
--- /dev/null
+++ b/support/qfig/src/qfig.mak
@@ -0,0 +1,6 @@
+QFIG.BAS
+QFIGSUB1.BAS
+QFIGSUB2.BAS
+QFIGSUB3.BAS
+QFIGSUB4.BAS
+MOUSE.BAS
diff --git a/support/qfig/src/qfigsrc.txt b/support/qfig/src/qfigsrc.txt
new file mode 100644
index 0000000000..4e76c5d2a2
--- /dev/null
+++ b/support/qfig/src/qfigsrc.txt
@@ -0,0 +1,66 @@
+
+ QFIG (Ver.1.1a : 3/24/1997)
+
+QFIG is a DOS graphics program for LaTeX for use on IBM Compatible PCs. This is a version of
+the NEC PC9801 qfig 0.9c for IBM/J-3100 PCs.
+The NEC version was written by MR T. Iwakuma (bear@hashi1.civil.tohoku.ac.jp) and
+modified for IBM/J-3100 PCs using Quick-Basic.
+
+ This program is free software; you can redistribute it and/or modify it at will,
+ however, if you make modifications/bug fixes to this program, please contact me
+ first for redistribution to prevent many different versions from appearing all
+ over at the same time and also to keep other users up to date with improvements
+ to QFIG. I would also appreciate it if my name are not removed from this document.
+ This is to enable people with questions, comments or suggestions to be able to contact us.
+ This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ Whoever uses it does so at her/his own risk. We cannot take any responsibility on correct
+ function or correct documentation.
+
+
+REQUIREMENTS:
+You will need Qbasic version 4.5 or compatible program to run this source code.
+If you are using Qbasic 4.5, you can start the program using "qfsrc.bat".
+
+To run it in, you might have to reduce the following two parameters
+in QFIG.BI to have sufficient memory to run the source code in Qbasic:
+
+nobjmax% and nodemax%
+
+
+GENERAL COMMENTS:
+The source code is mainly that from the original NEC version with modifications by me
+for improvements and for it to run on IBM Compatible PCs..
+I apologize for the fact that it is somewhat complicated to follow and there are
+portions of code remaining which are actually not utilized in the program.
+I am sorry, I couldn't make the time to make the source code more presentable.
+
+Questions and Comments:
+I will be able to provide very little help to you so I strongly recommend that
+you try by yourself to understand how the program works in order to modify it
+as you wish.
+
+Thank you for your consideration, and I will be very grateful if you send
+me information about changes you make.
+
+William Ofosu-Amaah
+e-mail: XI6W-OFSA@asahi-net.or.jp
+
+------------------
+Changes from Qfig 1.1 to Qfig 1.1a
+
+1. Fixed bug in Boxtext
+
+For those who have already modified the source code of Qfig 1.1,
+the bug fix can be implemented in your modified code by changing
+the following in the subroutine "SUB G.Box" in QFIGSUB1.BAS.
+
+donechar2:
+SetInst job%
+KeySwitch 0
+'Fixing the bug of boxtext job%=0---> job%=4
+job% = 4
+
+Refer to subrouting "SUB G.Box" in the QFIGSUB1.BAS of Qfig1.1a
+included with this file for further reference.
+
diff --git a/support/qfig/src/qfigsub1.bas b/support/qfig/src/qfigsub1.bas
new file mode 100644
index 0000000000..a0e55f751c
--- /dev/null
+++ b/support/qfig/src/qfigsub1.bas
@@ -0,0 +1,1242 @@
+' qfigsub.bas
+
+'$INCLUDE: 'QB.BI'
+'rem $INCLUDE: 'C:\QB45\USERLIB\GRAPH.BI'
+'REM $INCLUDE: 'MOUSE.BI'
+'$INCLUDE: 'QFIG.BI'
+
+FUNCTION Angle (x0, y0, x1, y1)
+' arc sin
+Angle = 0!: a = 0!
+rad = SQR((x1 - x0) ^ 2 + (y1 - y0) ^ 2)
+IF rad = 0! THEN EXIT FUNCTION
+IF x1 = x0 THEN
+ a = SGN(y0 - y1) * pi / 2!
+ IF a < 0! THEN a = a + 2! * pi
+ELSE
+ a = ATN((y1 - y0) / (x0 - x1))
+ IF x1 > x0 AND a < 0! THEN
+ a = a + 2! * pi
+ ELSEIF x1 < x0 THEN
+ a = a + pi
+ END IF
+END IF
+Angle = a
+'
+END FUNCTION
+
+SUB D.Circles (cx%, cy%, rad, ratio, sang, eang, clr%, thickness%, simple%, wpatt%)
+' circle/ellipse drawings with thickness
+IF ratio > 0 THEN
+ CIRCLE (cx%, cy%), INT(rad), clr%, , , ratio
+ IF simple% <> 1 THEN
+ IF ratio >= 1! THEN
+ rt1 = INT(rad): rt2 = INT(rad) / ratio
+ ELSE
+ rt1 = ratio * INT(rad): rt2 = INT(rad)
+ END IF
+ IF thickness% > 0 THEN CIRCLE (cx%, cy%), INT(rad) - 1, clr%, , , (rt1 - 1) / (rt2 - 1)
+ IF thickness% > 1 THEN CIRCLE (cx%, cy%), INT(rad) + 1, clr%, , , (rt1 + 1) / (rt2 + 1)
+ END IF
+ rrt1 = rad / ratio: rrt2 = rad
+ IF ratio < 1! THEN rrt2 = rad * ratio: rrt1 = rad
+ IF simple% = -1 THEN
+ MaxMin cx% + rrt1, cy% + rrt2: MaxMin cx% - rrt1, cy% - rrt2
+ END IF
+ELSE
+ sang1 = sang: eang1 = eang
+ IF sang < 0 THEN sang1 = 0!: eang1 = 2! * pi
+ CIRCLE (cx%, cy%), INT(rad), clr%, sang1, eang1, 1
+ IF simple% <> 1 THEN
+ IF thickness% > 0 THEN CIRCLE (cx%, cy%), INT(rad) - 1, clr%, sang1, eang1, 1
+ IF thickness% > 1 THEN CIRCLE (cx%, cy%), INT(rad) + 1, clr%, sang1, eang1, 1
+ END IF
+ IF simple% = -1 THEN
+ IF sang < 0 THEN
+ MaxMin cx% + rad, cy% + rad: MaxMin cx% - rad, cy% - rad
+ ELSE
+ MaxMin cx% + rad * COS(sang), cy% - rad * SIN(sang)
+ MaxMin cx% + rad * COS(eang), cy% - rad * SIN(eang)
+ IF sang < eang THEN
+ IF eang > pi / 2! AND sang < pi / 2! THEN MaxMin cx%, cy% - rad
+ IF eang > pi AND sang < pi THEN MaxMin cx% - rad, cy%
+ IF eang > 3! * pi / 2! AND sang < 3! * pi / 2! THEN MaxMin cx%, cy% + rad
+ ELSE
+ MaxMin cx% + rad, cy%
+ IF eang > pi / 2! OR (eang < pi / 2! AND sang < pi / 2!) THEN MaxMin cx%, cy% - rad
+ IF eang > pi OR (eang < pi AND sang < pi) THEN MaxMin cx% - rad, cy%
+ IF eang > 3! * pi / 2! OR (eang < 3! * pi / 2! AND sang < 3! * pi / 2!) THEN MaxMin cx%, cy% + rad
+ END IF
+ END IF
+ END IF
+END IF
+'
+END SUB
+
+SUB D.Lines (sx%, sy%, ex%, ey%, clr%, box%, thickness%, linetype%, filltype%, simple%)
+' line/box drawings with thickness/linetype/fill
+SELECT CASE box%
+ CASE 0
+ LINE (sx%, sy%)-(ex%, ey%), clr%, , ltp%(linetype%)
+ CASE 1
+ LINE (sx%, sy%)-(ex%, ey%), clr%, B, ltp%(linetype%)
+ CASE 2
+ LINE (sx%, sy%)-(ex%, ey%), 2, B
+ IF filltype% <> 0 AND (sx% - ex%) * (sy% - ey%) <> 0 THEN
+ IF clr% <> 0 THEN
+ PAINT ((sx% + ex%) / 2, (sy% + ey%) / 2), tlp$(filltype%), 2
+ ELSE
+ PAINT ((sx% + ex%) / 2, (sy% + ey%) / 2), 0, 2
+ END IF
+ END IF
+ IF wkill% = 1 AND clr% = 0 THEN
+ LINE (sx%, sy%)-(ex%, ey%), clr%, BF
+ wkill% = 0
+ ELSE
+ LINE (sx%, sy%)-(ex%, ey%), clr%, B
+ END IF
+END SELECT
+IF simple% <> 1 AND thickness% <> 0 THEN
+ SELECT CASE box%
+ CASE 0
+ dx% = 1: dy% = 0
+ IF ABS(ex% - sx%) > ABS(ey% - sy%) THEN dx% = 0: dy% = 1
+ LINE (sx% - dx%, sy% - dy%)-(ex% - dx%, ey% - dy%), clr%, , ltp%(linetype%)
+ IF thickness% > 1 THEN
+ LINE (sx% + dx%, sy% + dy%)-(ex% + dx%, ey% + dy%), clr%, , ltp%(linetype%)
+ END IF
+ CASE ELSE
+ dx% = SGN(ex% - sx%): dy% = SGN(ey% - sy%)
+ a% = ltp%(linetype%): IF box% = 2 THEN a% = ltp%(0)
+ LINE (sx% + dx%, sy% + dy%)-(ex% - dx%, ey% - dy%), clr%, B, a%
+ IF thickness% > 1 THEN
+ LINE (sx% - dx%, sy% - dy%)-(ex% + dx%, ey% + dy%), clr%, B, a%
+ END IF
+ END SELECT
+END IF
+'
+IF simple% = -1 THEN MaxMin sx%, sy%: MaxMin ex%, ey%
+'
+END SUB
+
+SUB D.Strings (n%, clr%, simple%)
+' display strings
+sx% = xx(n%, 0): sy% = yy(n%, 0)
+ipt = 0!: kanji% = 0: sylow% = 0: syhigh% = 0
+IF simple% <> 1 THEN
+ special% = 0: script% = 0 'KPUT is special
+ WINDOW SCREEN (0, 0)-(windowx%(wndwfctr%), windowy%(wndwfctr%))
+ wt% = obj%(n%, 1)
+ IF wtext% = 1 THEN wt% = 1
+ FOR i% = 1 TO wt%
+ IF yy(n%, i%) = 0! THEN
+ a$ = CHR$(xx(n%, i%))
+ IF special% = 0 AND a$ = "\" THEN special% = 1: GOTO one.char.done
+ IF INSTR("^\@_", a$) <> 0 THEN
+ IF special% = 0 AND INSTR("^@_", a$) <> 0 THEN
+ SELECT CASE a$
+ CASE "^"
+ script% = 1
+ syhigh% = INT(scrpt(1) * obj%(n%, 4) + .9)
+ CASE "_"
+ script% = 2
+ sylow% = -INT(scrpt(2) * obj%(n%, 4) + .9)
+ CASE ELSE
+ script% = 0
+ END SELECT
+ GOTO one.char.done
+ ELSE
+ special% = 0
+ END IF
+ ELSEIF special% = 1 THEN
+ special% = 0
+ END IF
+ IF ASC(a$) < &H20 OR ASC(a$) > &H7E THEN a$ = " "
+ scriptsize = 1!: IF script% <> 0 THEN scriptsize = .7
+ jpt = 8
+ ELSE
+ kanji% = 1
+ a$ = STRING$(1, VAL("&j" + HEX$(yy(n%, i%)) + HEX$(xx(n%, i%))))
+ jpt = CSNG(obj%(n%, 4) * jpitch%) / 250! * ptmm
+ END IF
+ ssx% = sx% + INT(ipt) - pxo%
+ ssy% = sy% - INT(scrpt(script%) * obj%(n%, 4)) - pyo%
+ ssx% = INT(CSNG(ssx%) / wndwxy(wndwfctr%))
+ ssy% = INT(CSNG(ssy%) / wndwxy(wndwfctr%))
+ IF ssx% + INT(jpt) > pxmax% - pxo% OR ssx% + INT(jpt) < pxmin% - pxo% THEN GOTO one.char.skipped
+ IF ssy% > pymax% - pyo% OR ssy% < pymin% - pyo% THEN EXIT FOR
+ IF clr% <> 0 THEN
+ ptext ssx%, ssy%, a$, chattr%(obj%(n%, 5), 0), 0
+ ELSE
+ ptext ssx%, ssy%, a$, 0, 0
+ END IF
+one.char.skipped:
+ ipt = ipt + jpt
+one.char.done:
+ NEXT i% 'retrieve
+ WINDOW SCREEN (pxo%, pyo%)-(pxo% + windowx%(wndwfctr%), pyo% + windowy%(wndwfctr%))
+ IF simple% = -1 THEN
+ MaxMin sx%, sy% - sylow%
+ sysy = eheight(obj%(n%, 5)): IF kanji% = 1 THEN sysy = jheight(obj%(n%, 5))
+ MaxMin sx% + INT(ipt), sy% + INT(sysy * obj%(n%, 4) * ptmm / .25) + syhigh%
+ END IF
+ELSE
+ ipt = 0!: special% = 0: script% = 0
+ FOR i% = 1 TO obj%(n%, 1)
+ IF yy(n%, i%) = 0! THEN
+ a$ = CHR$(xx(n%, i%))
+ IF special% = 0 AND a$ = "\" THEN special% = 1: GOTO one.simple.done
+ IF INSTR("^\@_", a$) <> 0 THEN
+ IF special% = 0 AND INSTR("^@_", a$) <> 0 THEN
+ SELECT CASE a$
+ CASE "^"
+ script% = 1
+ CASE "_"
+ script% = 2
+ CASE ELSE
+ script% = 0
+ END SELECT
+ GOTO one.simple.done
+ ELSE
+ special% = 0
+ END IF
+ ELSEIF special% = 1 THEN
+ special% = 0
+ END IF
+ IF ASC(a$) < &H20 OR ASC(a$) > &H7E THEN a$ = " "
+ scriptsize = 1!: IF script% <> 0 THEN scriptsize = .7
+ ipt = ipt + CSNG(INT(scriptsize * obj%(n%, 4)) * epitch%(obj%(n%, 5), ASC(a$) - &H20)) / 250! * ptmm
+ ELSE
+ ipt = ipt + CSNG(obj%(n%, 4) * jpitch%) / 250! * ptmm
+ kanji% = 1
+ END IF
+one.simple.done:
+ NEXT i%
+ sysy = eheight(obj%(n%, 5)): IF kanji% = 1 THEN sysy = jheight(obj%(n%, 5))
+ LINE (sx%, sy%)-(sx% + INT(ipt), sy% + INT(sysy * obj%(n%, 4) * ptmm / .25)), clr%, B
+END IF
+'
+END SUB
+
+SUB FillPattern
+' fill pattern set, silly isn't it?
+fill% = fill% + 1: IF fill% > UBOUND(filler%) THEN fill% = 0
+'
+END SUB
+
+SUB G.Addnode (o%, n%, editcc%)
+' add one node when even-nodes curve is input
+IF n% = 1 THEN
+ x.new% = (xx(o%, 0) + xx(o%, 1)) / 2!: y.new% = (yy(o%, 0) + yy(o%, 1)) / 2!
+ j% = 0
+ELSE
+ dist = 0!
+ FOR i% = 0 TO n% - 1
+ dist1 = SQR((xx(o%, i%) - xx(o%, i% + 1)) ^ 2 + (yy(o%, i%) - yy(o%, i% + 1)) ^ 2)
+ IF dist1 > dist THEN j% = i%: dist = dist1
+ NEXT i%: t% = 0: IF j% = n% - 1 THEN t% = 1
+ x0% = xx(o%, j% - t%): y0% = yy(o%, j% - t%)
+ x1% = xx(o%, j% + 1 - t%): y1% = yy(o%, j% + 1 - t%)
+ x2% = xx(o%, j% + 2 - t%): y2% = yy(o%, j% + 2 - t%)
+ G.XYparam x0%, y0%, x1%, y1%, x2%, y2%, ax, bx, cx, ay, by, cy
+ t = CSNG(t%) + .5
+ x.new% = ax * t * t + bx * t + cx: y.new% = ay * t * t + by * t + cy
+END IF
+FOR i% = n% TO j% + 1 STEP -1
+xx(o%, i% + 1) = xx(o%, i%): yy(o%, i% + 1) = yy(o%, i%): NEXT i%
+xx(o%, j% + 1) = x.new%: yy(o%, j% + 1) = y.new%
+'***** Mark Closed Curve which was originally a Poly ****
+IF editcc% = 1 THEN obj%(o%, 6) = j% + 1
+'********************************************************
+n% = n% + 1
+FOR i% = 1 TO 3: obj%(o%, i%) = obj%(o%, i%) + 1: NEXT i%
+'
+END SUB
+
+SUB G.Arc
+' arc
+job% = 3
+KeySwitch 0
+'LOCATE line2%, 24: COLOR 11: PRINT kky$(4);
+COLOR 7
+SetInst job%
+wx1% = 24 * 8 - 8
+wx2% = 24 * 8 + 40
+wy1% = line2% * texth% - texth%
+wy2% = line2% * texth%
+LINE (PMAP(wx1%, 2), PMAP(wy1%, 3))-(PMAP(wx2%, 2), PMAP(wy2%, 3)), 11, BF
+ptext PMAP(wx1%, 2) + 19, PMAP(wy1%, 3) + 1, kky$(4), 0, 1
+'
+startarc:
+DO
+ CursorMotion keyin%
+LOOP UNTIL keyin% <> 1
+VIEW SCREEN (0, 0)-(windowx%(0), winpy%)
+IF keyin% >= 3 THEN GOTO donearc
+pxold% = px%: pyold% = py%
+xx(nobj%, 0) = px%: yy(nobj%, 0) = py%
+DO
+ CursorMotion keyin%
+ CursorDisplay px%, py%
+ LINE (xx(nobj%, 0), yy(nobj%, 0))-(pxold%, pyold%), 0
+ IF keyin% = 4 THEN CursorDisplay px%, py%: GOTO donearc
+ LINE (xx(nobj%, 0), yy(nobj%, 0))-(px%, py%), 7
+ pxold% = px%: pyold% = py%
+ CursorDisplay px%, py%
+LOOP UNTIL keyin% <> 1
+xx(nobj%, 2) = px%: yy(nobj%, 2) = py%: ok% = 1
+DO
+ CursorMotion keyin%
+ tol = SQR((xx(nobj%, 0) - xx(nobj%, 2)) ^ 2 + (yy(nobj%, 0) - yy(nobj%, 2)) ^ 2)
+ tol1 = SQR((px% - xx(nobj%, 2)) ^ 2 + (py% - yy(nobj%, 2)) ^ 2)
+ tol1 = tol1 + SQR((px% - xx(nobj%, 0)) ^ 2 + (py% - yy(nobj%, 0)) ^ 2) - tol
+ IF tol <> 0 THEN tol = tol1 / tol
+ CursorDisplay px%, py%
+ IF ok% = 1 THEN
+ LINE (xx(nobj%, 0), yy(nobj%, 0))-(xx(nobj%, 2), yy(nobj%, 2)), 0
+ ELSE
+ CIRCLE (x0, y0), rad, 0, r1, r3, 1
+ END IF
+ IF keyin% = 4 THEN CursorDisplay px%, py%: GOTO donearc
+ IF tol < .001 THEN
+ LINE (xx(nobj%, 0), yy(nobj%, 0))-(xx(nobj%, 2), yy(nobj%, 2)), 7
+ ok% = 1
+ ELSE
+ ok% = 0
+ a = xx(nobj%, 0) - px%: B = yy(nobj%, 0) - py%
+ c = px% - xx(nobj%, 2): D = py% - yy(nobj%, 2)
+ E = xx(nobj%, 0) ^ 2 - CSNG(px%) * CSNG(px%)
+ f = yy(nobj%, 0) ^ 2 - CSNG(py%) * CSNG(py%)
+ G = CSNG(px%) * CSNG(px%) - xx(nobj%, 2) ^ 2
+ h = CSNG(py%) * CSNG(py%) - yy(nobj%, 2) ^ 2
+ y0 = ((E + f) * c - (G + h) * a) / (B * c - D * a) / 2!
+ IF a <> 0! THEN
+ x0 = (E + f - 2! * B * y0) / a / 2!
+ ELSE
+ x0 = (G + h - 2! * D * y0) / c / 2!
+ END IF
+ rad = SQR((xx(nobj%, 2) - x0) ^ 2 + (yy(nobj%, 2) - y0) ^ 2)
+ r3 = Angle(x0, y0, xx(nobj%, 2), yy(nobj%, 2))
+ r1 = Angle(x0, y0, xx(nobj%, 0), yy(nobj%, 0))
+ r2 = Angle(x0, y0, CSNG(px%), CSNG(py%))
+ IF (r3 < r2 AND r2 < r1) OR ((r1 < r3) AND (r2 < r1 OR r3 < r2)) THEN
+ SWAP r1, r3: SWAP xx(nobj%, 0), xx(nobj%, 2)
+ SWAP yy(nobj%, 0), yy(nobj%, 2)
+ END IF
+ CIRCLE (x0, y0), rad, 7, r1, r3, 1
+ END IF
+ CursorDisplay px%, py%
+LOOP UNTIL keyin% = 3
+CursorDisplay px%, py%
+IF ok% = 1 THEN
+ LINE (xx(nobj%, 0), yy(nobj%, 0))-(xx(nobj%, 2), yy(nobj%, 2)), 0
+ELSE
+ CIRCLE (x0, y0), rad, 0, r1, r3, 1
+END IF
+CursorDisplay px%, py%
+xx(nobj%, 0) = x0 + rad * COS(r1): yy(nobj%, 0) = y0 - rad * SIN(r1)
+xx(nobj%, 1) = x0: yy(nobj%, 1) = y0
+xx(nobj%, 2) = x0 + rad * COS(r3): yy(nobj%, 2) = y0 - rad * SIN(r3)
+xx(nobj%, 3) = rad: yy(nobj%, 3) = r1: yy(nobj%, 4) = r3
+obj%(nobj%, 0) = 6: obj%(nobj%, 1) = 4
+obj%(nobj%, 2) = 2: obj%(nobj%, 3) = -1
+obj%(nobj%, 4) = thick%: obj%(nobj%, 5) = 0: obj%(nobj%, 6) = 0
+CursorDisplay px%, py%
+SetObject nobj%, 7, 0
+CursorDisplay px%, py%
+nobj% = nobj% + 1
+Object.Max.Check
+GOTO startarc
+'
+donearc:
+SetInst job%
+KeySwitch 1
+job% = 0
+VIEW SCREEN (0, 0)-(windowx%(0), windowy%(0))
+LINE (PMAP(wx1%, 2), PMAP(wy1%, 3))-(PMAP(wx2%, 2), PMAP(wy2%, 3)), 0, BF
+LOCATE line2%, 24: COLOR 3: PRINT kky$(4); : COLOR 7
+'
+END SUB
+
+SUB G.ArrowDirec (sobj%, snode%, n%)
+' calculate the direction of arrow
+SELECT CASE fnoo%(sobj%)
+ CASE 1
+ IF snode% = 0 THEN
+ x3% = xx(sobj%, 1): y3% = yy(sobj%, 1)
+ ELSE
+ x3% = xx(sobj%, obj%(sobj%, 1) - 1)
+ y3% = yy(sobj%, obj%(sobj%, 1) - 1)
+ END IF
+ GOSUB arrowarrow
+ CASE 3
+ k% = 0: t = .2: IF snode% <> 0 THEN k% = snode% - 2: t = 1.8
+ x2% = xx(sobj%, k% + 2): y2% = yy(sobj%, k% + 2)
+ x1% = xx(sobj%, k% + 1): y1% = yy(sobj%, k% + 1)
+ x0% = xx(sobj%, k%): y0% = yy(sobj%, k%)
+ G.XYparam x0%, y0%, x1%, y1%, x2%, y2%, ax, bx, cx, ay, by, cy
+ x3% = ax * t * t + bx * t + cx: y3% = ay * t * t + by * t + cy
+ GOSUB arrowarrow
+ CASE 6
+ x1% = xx(sobj%, snode%): y1% = yy(sobj%, snode%)
+ s2 = yy(sobj%, 3) + 3! * pi / 2! + arcarrowd
+ IF snode% <> 0 THEN s2 = yy(sobj%, 4) + pi / 2! - arcarrowd
+END SELECT
+arrow = arrowhead + darrowhead * obj%(n%, 4)
+xx(n%, 2) = x1% - arrow * COS(s2 + arrowdirect)
+yy(n%, 2) = y1% + arrow * SIN(s2 + arrowdirect)
+xx(n%, 0) = x1% - arrow * COS(s2 - arrowdirect)
+yy(n%, 0) = y1% + arrow * SIN(s2 - arrowdirect)
+xx(n%, 1) = x1%: yy(n%, 1) = y1%
+EXIT SUB
+'
+arrowarrow:
+x1% = xx(sobj%, snode%): y1% = yy(sobj%, snode%)
+IF x1% = x3% THEN
+ s2 = SGN(y3% - y1%) * pi / 2!
+ELSE
+ s2 = ATN(CSNG(y3% - y1%) / CSNG(x1% - x3%))
+ IF x1% < x3% THEN s2 = s2 + pi
+END IF
+RETURN
+'
+END SUB
+
+SUB G.Arrows
+' set arrows
+MarkEnds c%: IF c% = 0 THEN EXIT SUB
+job% = 6
+KeySwitch 0
+SetInst job%
+wx1% = 61 * 8 - 8
+wx2% = 61 * 8 + 40
+wy1% = line2% * texth% - texth%
+wy2% = line2% * texth%
+LINE (PMAP(wx1% - 1, 2), PMAP(wy1%, 3))-(PMAP(wx2%, 2), PMAP(wy2%, 3)), 11, BF
+ptext PMAP(wx1%, 2) + 19, PMAP(wy1%, 3) + 1, kky$(8), 0, 1
+'
+startarrow:
+selh% = 1
+DO
+ CursorMotion keyin%
+LOOP UNTIL keyin% <> 1
+IF keyin% = 4 THEN GOTO donearrow
+sobj% = -1
+FOR i% = 0 TO nobj% - 1
+IF fnoo%(i%) <> 1 AND fnoo%(i%) <> 3 AND fnoo%(i%) <> 6 THEN GOTO nogetends
+selh% = 0
+dist = SQR((xx(i%, 0) - px%) ^ 2 + (yy(i%, 0) - py%) ^ 2)
+IF dist < 3 THEN snode% = 0: sobj% = i%: EXIT FOR
+dist = SQR((xx(i%, obj%(i%, 2)) - px%) ^ 2 + (yy(i%, obj%(i%, 2)) - py%) ^ 2)
+IF dist < 3 THEN snode% = obj%(i%, 2): sobj% = i%: EXIT FOR
+nogetends: NEXT i%
+IF sobj% < 0 THEN GOTO startarrow
+G.Arrowset sobj%, snode%, already%
+IF already% = 0 THEN nobj% = nobj% + 1: Object.Max.Check
+IF keyin% = 3 THEN
+ IF snode% = 0 THEN snode% = obj%(sobj%, 2) ELSE snode% = 0
+ G.Arrowset sobj%, snode%, already%
+ IF already% <> 0 THEN GOTO startarrow
+ nobj% = nobj% + 1
+ Object.Max.Check
+END IF
+GOTO startarrow
+'
+donearrow:
+MarkEnds c%
+SetInst job%
+KeySwitch 1
+job% = 0
+selh% = 0
+VIEW SCREEN (0, 0)-(windowx%(0), windowy%(0))
+LINE (PMAP(wx1% - 1, 2), PMAP(wy1%, 3))-(PMAP(wx2%, 2), PMAP(wy2%, 3)), 0, BF
+LOCATE line2%, 61: COLOR 3: PRINT kky$(8); : COLOR 7
+'
+END SUB
+
+SUB G.Arrowset (sobj%, snode%, already%)
+' arrow set & check
+already% = 0
+FOR i% = 0 TO nobj% - 1
+IF fnoo%(i%) <> 11 THEN GOTO skipsrchar
+IF obj%(i%, 5) = sobj% AND obj%(i%, 6) = snode% THEN
+ already% = 1
+ CursorDisplay px%, py%
+ PPUT xx(sobj%, snode%) - 3, yy(sobj%, snode%) - 3, mark%()
+ Killer i%, sobj%
+ SetObject sobj%, 7, 0
+ PPUT xx(sobj%, snode%) - 3, yy(sobj%, snode%) - 3, mark%()
+ CursorDisplay px%, py%
+ EXIT SUB
+END IF
+skipsrchar: NEXT i%
+'
+obj%(nobj%, 0) = 11: obj%(nobj%, 1) = 2: obj%(nobj%, 2) = -1
+obj%(nobj%, 3) = -2: obj%(nobj%, 4) = obj%(sobj%, 4)
+obj%(nobj%, 5) = sobj%: obj%(nobj%, 6) = snode%
+G.ArrowDirec sobj%, snode%, nobj%
+'
+CursorDisplay px%, py%
+PPUT xx(sobj%, snode%) - 3, yy(sobj%, snode%) - 3, mark%()
+SetObject nobj%, 7, 0
+PPUT xx(sobj%, snode%) - 3, yy(sobj%, snode%) - 3, mark%()
+CursorDisplay px%, py%
+'
+END SUB
+
+SUB G.Box
+' box
+job% = 4
+KeySwitch 0
+SetInst job%
+wx1% = 31 * 8 - 8
+wx2% = 31 * 8 + 40
+wy1% = line2% * texth% - texth%
+wy2% = line2% * texth%
+LINE (PMAP(wx1% - 1, 2), PMAP(wy1%, 3))-(PMAP(wx2%, 2), PMAP(wy2%, 3)), 11, BF
+ptext PMAP(wx1%, 2) + 19, PMAP(wy1%, 3) + 1, kky$(5), 0, 1
+'
+startbox:
+'fill% = 0
+DO
+ CursorMotion keyin%
+' IF keyin% = 3 THEN FillPattern
+LOOP UNTIL keyin% <> 1
+VIEW SCREEN (0, 0)-(windowx%(0), winpy%)
+IF keyin% = 4 THEN GOTO donebox
+sx% = px%: sy% = py%: pxold% = px%: pyold% = py%
+sxg% = sx%: syg% = sy%
+inbox% = 1
+DO
+ CursorMotion keyin%
+ CursorDisplay px%, py%
+ IF fill% <> 0 THEN
+ LINE (sx%, sy%)-(pxold%, pyold%), 2, B
+ PAINT ((sx% + pxold%) / 2, (sy% + pyold%) / 2), 0, 2
+ END IF
+ LINE (sx%, sy%)-(pxold%, pyold%), 0, BF
+ IF keyin% = 4 THEN CursorDisplay px%, py%: GOTO donebox
+' IF keyin% = 3 THEN FillPattern
+ LINE (sx%, sy%)-(px%, py%), 0, BF
+ IF fill% = 0 THEN
+ LINE (sx%, sy%)-(px%, py%), 7, B
+ ELSE
+ LINE (sx%, sy%)-(px%, py%), 2, B
+ PAINT ((sx% + px%) / 2, (sy% + py%) / 2), tlp$(fill%), 2
+ END IF
+ CursorDisplay px%, py%
+ pxold% = px%: pyold% = py%
+LOOP UNTIL keyin% = 2 OR keyin% = 3
+inbox% = 0
+CursorDisplay px%, py%
+IF fill% <> 0 THEN
+ LINE (sx%, sy%)-(px%, py%), 2, B
+ PAINT ((sx% + px%) / 2, (sy% + py%) / 2), 0, 2
+END IF
+LINE (sx%, sy%)-(px%, py%), 0, B
+CursorDisplay px%, py%
+xx(nobj%, 0) = sx%: yy(nobj%, 0) = sy%
+xx(nobj%, 1) = px%: yy(nobj%, 1) = py%
+obj%(nobj%, 0) = 8: obj%(nobj%, 1) = 1
+IF fill% <> 0 THEN obj%(nobj%, 0) = 9
+obj%(nobj%, 2) = 1: obj%(nobj%, 3) = -1
+obj%(nobj%, 4) = thick%: obj%(nobj%, 5) = ltype%
+obj%(nobj%, 6) = 0: obj%(nobj%, 6) = fill%
+IF fill% <> 0 THEN obj%(nobj%, 5) = 0
+CursorDisplay px%, py%
+SetObject nobj%, 7, 0
+CursorDisplay px%, py%
+nobj% = nobj% + 1
+Object.Max.Check
+
+' --------
+' Box Text, yes/no?
+ipy% = py%: ipx% = px%: L.Text ipx%, ipy%
+PRINT "Text(y/n)??";
+bkey$ = yesno$
+L.Text ipx%, ipy%: PRINT SPACE$(12);
+IF bkey$ = "n" THEN GOTO startbox
+'--------
+
+' string
+job% = 5
+KeySwitch 0
+LOCATE line2%, 68: COLOR 11: PRINT kky$(9); : COLOR 7
+SetInst job%
+wx1% = 68 * 8 - 8
+wx2% = 68 * 8 + 40
+wy1% = line2% * texth% - texth%
+wy2% = line2% * texth%
+LINE (PMAP(wx1% - 1, 2), PMAP(wy1%, 3))-(PMAP(wx2%, 2), PMAP(wy2%, 3)), 11, BF
+
+'
+pxold% = px%: pyold% = py%
+'------
+' Calculate Box center for Box text
+px% = sx% + (pxold% - sx%) / 2
+py% = sy% + (pyold% - sy%) / 2 - texth% + 4
+'------
+
+pxold% = px%: pyold% = py%
+CursorDisplay px%, py%
+
+startchar2:
+
+LINE (px%, py%)-(px% + epitch%(chartype%, 0) * charpt% / 250 * ptmm, py% + eheight(chartype%) * charpt% * ptmm / .25), 2, B
+CursorDisplay px%, py%
+
+
+LINE (pxold%, pyold%)-(pxold% + epitch%(chartype%, 0) * charpt% / 250 * ptmm, pyold% + eheight(chartype%) * charpt% * ptmm / .25), 0, B
+LINE (px%, py%)-(px% + epitch%(chartype%, 0) * charpt% / 250 * ptmm, py% + eheight(chartype%) * charpt% * ptmm / .25), 2, B
+pxold% = px%: pyold% = py%
+CursorDisplay px%, py%
+LINE (pxold%, pyold%)-(pxold% + epitch%(chartype%, 0) * charpt% / 250 * ptmm, pyold% + eheight(chartype%) * charpt% * ptmm / .25), 0, B
+CursorDisplay px%, py%
+IF px% + 10 - pxo% > pxmax% OR py% + 16 - pyo% > pymax% THEN GOTO donechar2
+xx(nobj%, 0) = px%: yy(nobj%, 0) = py%
+L.Text px%, py%: ams$ = "": PRINT "-> "; : Chr.Input ams$
+L.Text px%, py%: PRINT SPACE$(LEN(ams$) + 3);
+IF ams$ = "" THEN GOTO donechar2
+obj%(nobj%, 0) = 10: obj%(nobj%, 1) = LEN(ams$)
+obj%(nobj%, 2) = 0: obj%(nobj%, 3) = -1: obj%(nobj%, 4) = charpt%
+obj%(nobj%, 5) = chartype%
+
+'Put object number of Box + 1, i.e. string number in Obj(x,6)
+obj%(nobj%, 6) = nobj%
+
+G.Charset ams$, nobj%
+CursorDisplay px%, py%
+SetObject nobj%, 7, 0
+CursorDisplay px%, py%
+nobj% = nobj% + 1
+Object.Max.Check
+'
+donechar2:
+SetInst job%
+KeySwitch 0
+'Fixing the bug of boxtext job=0---> job=4
+job% = 4
+LINE (PMAP(wx1% - 1, 2), PMAP(wy1%, 3))-(PMAP(wx2%, 2), PMAP(wy2%, 3)), 0, BF
+LOCATE line2%, 68: COLOR 3: PRINT kky$(9); : COLOR 7
+
+CursorDisplay ipx%, ipy%
+
+
+' end box text section
+
+GOTO startbox:
+'
+donebox:
+SetInst job%
+KeySwitch 1
+job% = 0
+VIEW SCREEN (0, 0)-(windowx%(0), windowy%(0))
+wx1% = 31 * 8 - 8
+wx2% = 31 * 8 + 40
+wy1% = line2% * texth% - texth%
+wy2% = line2% * texth%
+LINE (PMAP(wx1% - 1, 2), PMAP(wy1%, 3))-(PMAP(wx2%, 2), PMAP(wy2%, 3)), 0, BF
+LOCATE line2%, 31: COLOR 3: PRINT kky$(5); : COLOR 7
+CL.R.edraw 0, 0
+'
+END SUB
+
+SUB G.Char
+' string
+job% = 5
+KeySwitch 0
+SetInst job%
+wx1% = 68 * 8 - 8
+wx2% = 68 * 8 + 40
+wy1% = line2% * texth% - texth%
+wy2% = line2% * texth%
+LINE (PMAP(wx1% - 1, 2), PMAP(wy1%, 3))-(PMAP(wx2%, 2), PMAP(wy2%, 3)), 11, BF
+ptext PMAP(wx1%, 2) + 19, PMAP(wy1%, 3) + 1, kky$(9), 0, 1
+'
+startchar:
+pxold% = px%: pyold% = py%
+CursorDisplay px%, py%
+LINE (px%, py%)-(px% + epitch%(chartype%, 0) * charpt% / 250 * ptmm, py% + eheight(chartype%) * charpt% * ptmm / .25), 2, B
+CursorDisplay px%, py%
+DO
+ CursorMotion keyin%
+ CursorDisplay px%, py%
+ LINE (pxold%, pyold%)-(pxold% + epitch%(chartype%, 0) * charpt% / 250 * ptmm, pyold% + eheight(chartype%) * charpt% * ptmm / .25), 0, B
+ LINE (px%, py%)-(px% + epitch%(chartype%, 0) * charpt% / 250 * ptmm, py% + eheight(chartype%) * charpt% * ptmm / .25), 2, B
+ pxold% = px%: pyold% = py%
+ CursorDisplay px%, py%
+LOOP UNTIL keyin% <> 1
+VIEW SCREEN (0, 0)-(windowx%(0), winpy%)
+CursorDisplay px%, py%
+LINE (pxold%, pyold%)-(pxold% + epitch%(chartype%, 0) * charpt% / 250 * ptmm, pyold% + eheight(chartype%) * charpt% * ptmm / .25), 0, B
+CursorDisplay px%, py%
+IF keyin% = 4 THEN GOTO donechar
+'IF keyin% = 3 THEN G.CharDisp: GOTO startchar
+IF px% + 10 - pxo% > pxmax% OR py% + 16 - pyo% > pymax% THEN GOTO donechar
+xx(nobj%, 0) = px%: yy(nobj%, 0) = py%
+L.Text px%, py%: ams$ = "": PRINT "-> "; : Chr.Input ams$
+L.Text px%, py%: PRINT SPACE$(LEN(ams$) + 3);
+IF ams$ = "" THEN GOTO startchar
+obj%(nobj%, 0) = 10: obj%(nobj%, 1) = LEN(ams$)
+obj%(nobj%, 2) = 0: obj%(nobj%, 3) = -1: obj%(nobj%, 4) = charpt%
+obj%(nobj%, 5) = chartype%: obj%(nobj%, 6) = 0
+G.Charset ams$, nobj%
+CursorDisplay px%, py%
+SetObject nobj%, 7, 0
+CursorDisplay px%, py%
+nobj% = nobj% + 1
+Object.Max.Check
+GOTO startchar
+'
+donechar:
+SetInst job%
+KeySwitch 1
+job% = 0
+VIEW SCREEN (0, 0)-(windowx%(0), windowy%(0))
+LINE (PMAP(wx1% - 1, 2), PMAP(wy1%, 3))-(PMAP(wx2%, 2), PMAP(wy2%, 3)), 0, BF
+LOCATE line2%, 68: COLOR 3: PRINT kky$(9); : COLOR 7
+'
+END SUB
+
+SUB G.CharDisp
+' character font selection display
+ipy% = py%: ipx% = px%
+L.Text ipx%, ipy%
+charptold% = charpt%: a$ = fno$(charpt%, 1)
+PRINT "Size (10 or 12 pt.) = "; : Chr.Input a$
+charpt% = VAL(a$)
+IF charpt% = 0 OR (charpt% <> 10 AND charpt% <> 12) THEN charpt% = charptold%
+L.Text ipx%, ipy%: PRINT SPACE$(28);
+DO
+ L.Text ipx%, ipy%
+ PRINT "Font= "; chartype$(chartype%) '; ".";
+ CursorMotion keyin%
+ IF keyin% = 2 THEN
+ chartype% = chartype% + 1: IF chartype% > UBOUND(chartype$) THEN chartype% = 0
+ END IF
+LOOP UNTIL keyin% = 3
+L.Text ipx%, ipy%
+PRINT SPACE$(5)
+L.Text ipx%, ipy%
+PRINT "'"; chartype$(chartype%); "' character in "; charpt%; "pt.";
+SLEEP 1: L.Text ipx%, ipy%
+PRINT SPACE$(5); SPACE$(10); SPACE$(25);
+'
+END SUB
+
+SUB G.Charset (ams$, n%)
+' character code decomposition
+FOR i% = 1 TO LEN(ams$): a$ = MID$(ams$, i%, 1): j% = LEN(a$)
+IF j% = 1 THEN
+ yy(n%, i%) = 0!: xx(n%, i%) = ASC(a$)
+ELSE
+ a$ = STR$(ASC(a$))
+ yy(n%, i%) = VAL("&H" + LEFT$(a$, 2))
+ xx(n%, i%) = VAL("&H" + RIGHT$(a$, 2))
+END IF
+NEXT i%
+'
+END SUB
+
+SUB G.Crcl
+' circle
+'LOCATE line3%, 42: PRINT "filler pattern"
+xx(nobj%, 0) = px%: yy(nobj%, 0) = py%
+sx% = px%: sy% = py%: rold = 1
+'fill% = 0
+DO
+ CursorMotion keyin%
+ CursorDisplay px%, py%
+ CIRCLE (sx%, sy%), rold, 0, , , 1
+ IF keyin% = 4 THEN CursorDisplay px%, py%: GOTO donecrcl
+ rad = SQR((px% - sx%) ^ 2 + (py% - sy%) ^ 2)
+ CIRCLE (sx%, sy%), rad, 2, , , 1
+'***********
+'For fillpattern for circle
+'
+' IF fill% = 0 THEN
+' PAINT ((sx% + px%) / 2, (sy% + py%) / 2), 0, 2
+' ELSE
+' PAINT ((sx% + px%) / 2, (sy% + py%) / 2), tlp$(fill%), 2
+' END IF
+'**************
+ rold = rad
+ CursorDisplay px%, py%
+LOOP UNTIL keyin% = 2
+CursorDisplay px%, py%
+CIRCLE (sx%, sy%), rad, 0, , , 1
+CursorDisplay px%, py%
+xx(nobj%, 1) = px%: yy(nobj%, 1) = py%: xx(nobj%, 2) = rad
+obj%(nobj%, 0) = 5: obj%(nobj%, 1) = 2
+obj%(nobj%, 2) = 1: obj%(nobj%, 3) = -1
+obj%(nobj%, 4) = thick%: obj%(nobj%, 5) = 0
+obj%(nobj%, 6) = 0
+CursorDisplay px%, py%
+SetObject nobj%, 7, 0
+CursorDisplay px%, py%
+nobj% = nobj% + 1
+Object.Max.Check
+'
+donecrcl:
+'
+END SUB
+
+SUB G.Crcl.Ellps
+' circle+ellpse
+job% = 2
+KeySwitch 0
+SetInst job%
+wx1% = 17 * 8 - 8
+wx2% = 17 * 8 + 40
+wy1% = line2% * texth% - texth%
+wy2% = line2% * texth%
+LINE (PMAP(wx1% - 1, 2), PMAP(wy1%, 3))-(PMAP(wx2%, 2), PMAP(wy2%, 3)), 11, BF
+ptext PMAP(wx1%, 2) + 19, PMAP(wy1%, 3) + 1, kky$(3), 0, 1
+'
+startcrclellps:
+DO
+ CursorMotion keyin%
+LOOP UNTIL keyin% <> 1
+VIEW SCREEN (0, 0)-(windowx%(0), winpy%)
+SELECT CASE keyin%
+ CASE 2
+ G.Crcl
+ CASE 3
+ G.Ellps
+ CASE 4
+ GOTO donecrclellps
+END SELECT
+GOTO startcrclellps
+'
+donecrclellps:
+SetInst job%
+KeySwitch 1
+job% = 0
+VIEW SCREEN (0, 0)-(windowx%(0), windowy%(0))
+LINE (PMAP(wx1% - 1, 2), PMAP(wy1%, 3))-(PMAP(wx2%, 2), PMAP(wy2%, 3)), 0, BF
+LOCATE line2%, 17: COLOR 3: PRINT kky$(3); : COLOR 7
+'
+END SUB
+
+SUB G.Curve (curve%, closed%)
+' straight/curved lines
+job% = 1
+KeySwitch 0
+SetInst job%
+wx1% = (curve% * 7 - 4 + closed% * 44) * 8 - 8
+wx2% = (curve% * 7 - 4 + closed% * 44) * 8 + 40
+wy1% = line2% * texth% - texth%
+wy2% = line2% * texth%
+LINE (PMAP(wx1%, 2), PMAP(wy1%, 3))-(PMAP(wx2%, 2), PMAP(wy2%, 3)), 11, BF
+ptext PMAP(wx1%, 2) + 19, PMAP(wy1%, 3) + 1, kky$(curve% + 5 * closed%), 0, 1
+'
+startcurve:
+node% = 0: nodeismax% = 0
+DO
+ CursorMotion keyin%
+LOOP UNTIL keyin% <> 1
+IF keyin% >= 3 THEN GOTO donest
+pxold% = px%: pyold% = py%
+xx(nobj%, 0) = px%: yy(nobj%, 0) = py%
+DO
+sx% = px%: sy% = py%
+node% = node% + 1
+IF node% + closed% + curve% - 1 = UBOUND(xx, 2) THEN nodeismax% = 1
+ DO
+ CursorMotion keyin%
+ CursorDisplay px%, py%
+ IF wnode% <> 0 AND node% > 1 THEN
+ PSET (xx(nobj%, 0), yy(nobj%, 0)), 7
+ FOR i% = 1 TO (node% - 1)
+ LINE -(xx(nobj%, i%), yy(nobj%, i%)), 7
+ NEXT i%
+ END IF
+ wnode% = 0
+ LINE (sx%, sy%)-(pxold%, pyold%), 0
+ LINE (sx%, sy%)-(px%, py%), 7
+ pxold% = px%: pyold% = py%
+ CursorDisplay px%, py%
+ LOOP UNTIL keyin% <> 1
+ CursorDisplay px%, py%
+ LINE (sx%, sy%)-(px%, py%), 7
+ CursorDisplay px%, py%
+ xx(nobj%, node%) = px%: yy(nobj%, node%) = py%
+ IF keyin% = 4 THEN EXIT DO
+ IF nodeismax% = 1 THEN keyin% = 3
+LOOP UNTIL keyin% = 3 AND node% >= 1 + closed%
+IF curve% = 1 THEN
+ obj%(nobj%, 0) = 1
+ELSE
+ obj%(nobj%, 0) = 3
+END IF
+obj%(nobj%, 1) = node%
+obj%(nobj%, 2) = node% - closed%: obj%(nobj%, 3) = node% - closed%
+obj%(nobj%, 4) = thick%: obj%(nobj%, 5) = ltype%: obj%(nobj%, 6) = 0
+CursorDisplay px%, py%
+PSET (xx(nobj%, 0), yy(nobj%, 0)), 0
+FOR i% = 1 TO node%: LINE -(xx(nobj%, i%), yy(nobj%, i%)), 0: NEXT i%
+CursorDisplay px%, py%
+IF keyin% = 4 THEN GOTO donest
+IF closed% <> 0 THEN
+ FOR i% = 0 TO 3: obj%(nobj%, i%) = obj%(nobj%, i%) + 1: NEXT i%
+ node% = node% + 1
+ xx(nobj%, node%) = xx(nobj%, 0): yy(nobj%, node%) = yy(nobj%, 0)
+END IF
+IF curve% = 2 AND INT(node% / 2) * 2 <> node% THEN G.Addnode nobj%, node%, 0
+CursorDisplay px%, py%
+SetObject nobj%, 7, 0
+CursorDisplay px%, py%
+nobj% = nobj% + 1
+Object.Max.Check
+GOTO startcurve
+'
+donest:
+SetInst job%
+KeySwitch 1
+job% = 0
+VIEW SCREEN (0, 0)-(windowx%(0), windowy%(0))
+LINE (PMAP(wx1%, 2), PMAP(wy1%, 3))-(PMAP(wx2%, 2), PMAP(wy2%, 3)), 0, BF
+LOCATE line2%, curve% * 7 - 4 + closed% * 44: COLOR 3
+PRINT kky$(curve% + 5 * closed%); : COLOR 7
+'
+END SUB
+
+SUB G.Ellps
+' ellipse
+rold = 1: rtold = 1:
+sx% = px%: sy% = py%: cx% = px%: cy% = py%
+DO
+ CursorMotion keyin%
+ CursorDisplay px%, py%
+ CIRCLE (cx%, cy%), rold, 0, , , rtold
+ IF keyin% = 4 THEN CursorDisplay px%, py%: GOTO donellps
+ cx% = (px% + sx%) / 2!: cy% = (py% + sy%) / 2!
+ rad = ABS(px% - sx%) / 2!: rt = ABS(py% - sy%) / 2!
+ IF rad = 0! OR rt = 0! THEN
+ rad = 0!: rt = 1!
+ ELSE
+ rt = rt / rad
+ IF rt > 1! THEN rad = rt * rad
+ END IF
+ CIRCLE (cx%, cy%), rad, 2, , , rt
+ '***********
+ 'For fillpattern for circle
+ '
+ ' IF fill% = 0 THEN
+ ' PAINT ((sx% + px%) / 2, (sy% + py%) / 2), 0, 2
+ ' ELSE
+ ' PAINT ((sx% + px%) / 2, (sy% + py%) / 2), tlp$(fill%), 2
+ ' END IF
+ '**************
+
+ rold = rad: rtold = rt
+ CursorDisplay px%, py%
+LOOP UNTIL keyin% = 3
+CursorDisplay px%, py%
+CIRCLE (cx%, cy%), rad, 0, , , rt
+CursorDisplay px%, py%
+xx(nobj%, 0) = cx%: yy(nobj%, 0) = cy%: xx(nobj%, 2) = rad
+xx(nobj%, 1) = cx%: yy(nobj%, 1) = cy%: yy(nobj%, 2) = rt
+IF rt < 1! THEN
+ xx(nobj%, 1) = cx% + rad
+ELSE
+ yy(nobj%, 1) = cy% - rad
+END IF
+obj%(nobj%, 0) = 7: obj%(nobj%, 1) = 2: obj%(nobj%, 2) = 1
+obj%(nobj%, 3) = -1: obj%(nobj%, 4) = thick%: obj%(nobj%, 5) = 0
+obj%(nobj%, 6) = 0
+CursorDisplay px%, py%
+SetObject nobj%, 7, 0
+CursorDisplay px%, py%
+nobj% = nobj% + 1
+Object.Max.Check
+'
+donellps:
+'
+END SUB
+
+SUB G.XYparam (x0%, y0%, x1%, y1%, x2%, y2%, ax, bx, cx, ay, by, cy)
+' parametric parabolic curve coefficients
+ax = -(-x0% + 2! * x1% - x2%) / 2!
+bx = -(3! * x0% - 4! * x1% + x2%) / 2!
+cx = x0%
+ay = -(-y0% + 2! * y1% - y2%) / 2!
+by = -(3! * y0% - 4! * y1% + y2%) / 2!
+cy = y0%
+'
+END SUB
+
+SUB L.Text (ipx%, ipy%)
+' locate on text screen
+jpx% = INT(CSNG(ipx% - pxo%) / wndwxy(wndwfctr%) / 8!) + 2
+jpy% = INT(CSNG(ipy% - pyo%) / wndwxy(wndwfctr%) / 16!) + 2
+IF jpy% > 22 THEN jpy% = jpy% - 3
+LOCATE jpy%, jpx%
+'
+END SUB
+
+SUB MaxMin (ppxx%, ppyy%)
+' set maximum/minimum
+IF ppxx% < xmin% THEN xmin% = ppxx%
+IF ppxx% > xmax% THEN xmax% = ppxx%
+IF ppyy% < ymin% THEN ymin% = ppyy%
+IF ppyy% > ymax% THEN ymax% = ppyy%
+'
+END SUB
+
+SUB MoveObj (c%)
+' move or copy objects
+job% = 7
+KeySwitch 0
+SetInst job%
+wx1% = (3 + 7 * c%) * 8 - 8
+wx2% = (3 + 7 * c%) * 8 + 40
+wy1% = line1% * texth% - texth%
+wy2% = line1% * texth%
+LINE (PMAP(wx1%, 2), PMAP(wy1%, 3))-(PMAP(wx2%, 2), PMAP(wy2%, 3)), 11, BF
+ptext PMAP(wx1%, 2) + 19, PMAP(wy1%, 3) + 1, kky$(11 + c%), 0, 1
+'
+startmovecopy:
+Marking 1, n%
+selh% = 1
+IF n% = 0 THEN Marking 1, n%: GOTO donemovecopy
+DO
+ CursorMotion keyin%
+LOOP UNTIL keyin% <> 1
+VIEW SCREEN (0, 0)-(windowx%(0), winpy%)
+woldrad% = 0
+SELECT CASE keyin%
+ CASE 2
+ selh% = 0
+ MoveObject 1, c%
+ CASE 3
+ MoveObject 0, c%
+ CASE ELSE
+ Marking 1, n%
+END SELECT
+woldrad% = 0
+IF keyin% <> 4 THEN GOTO startmovecopy
+'
+donemovecopy:
+SetInst job%
+KeySwitch 1
+job% = 0
+selh% = 0
+VIEW SCREEN (0, 0)-(windowx%(0), windowy%(0))
+LINE (PMAP(wx1%, 2), PMAP(wy1%, 3))-(PMAP(wx2%, 2), PMAP(wy2%, 3)), 0, BF
+LOCATE line1%, 3 + 7 * c%: COLOR 3: PRINT kky$(11 + c%); : COLOR 7
+'
+END SUB
+
+SUB MoveObject (total%, c%)
+' really moving objects
+sx% = px%: sy% = py%: pxold% = px%: pyold% = py%
+IF total% = 1 THEN
+ total% = 0
+ Marking.Chk 1, mobj%(total%), snode%
+ IF mobj%(total%) < 0 THEN Marking 1, n%: EXIT SUB
+ELSE
+ DO
+ CursorMotion keyin%
+ CursorDisplay px%, py%
+ LINE (sx%, sy%)-(pxold%, pyold%), 0, B
+ IF keyin% = 4 THEN CursorDisplay px%, py%: Marking 1, n%: EXIT SUB
+ LINE (sx%, sy%)-(px%, py%), 2, B
+ CursorDisplay px%, py%
+ pxold% = px%: pyold% = py%
+ LOOP UNTIL keyin% = 3
+ selh% = 0
+ CursorDisplay px%, py%
+ LINE (sx%, sy%)-(px%, py%), 0, B
+ CursorDisplay px%, py%
+ Marking.Reg sx%, sy%, px%, py%, total%
+ IF total% < 0 THEN Marking 1, n%: EXIT SUB
+END IF
+IF total% > UBOUND(mobj%) OR nobj% + total% > UBOUND(obj%, 1) THEN GOTO no.way.to.move
+' group check
+gtotal% = 0
+FOR k% = 0 TO total%
+IF fnoo%(mobj%(k%)) = obj%(mobj%(k%), 0) THEN GOTO movegroup2
+ggroup% = obj%(mobj%(k%), 0) - fnoo%(mobj%(k%))
+FOR i% = 0 TO nobj% - 1
+IF fnoo%(i%) = obj%(i%, 0) THEN GOTO movegroup1
+FOR j% = 0 TO total%
+IF i% = mobj%(j%) THEN GOTO movegroup1
+NEXT j%
+IF obj%(i%, 0) - fnoo%(i%) = ggroup% THEN
+ gtotal% = gtotal% + 1
+ IF total% + gtotal% > UBOUND(mobj%) THEN GOTO no.way.to.move
+ IF nobj% + total% + gtotal% > UBOUND(obj%, 1) THEN GOTO no.way.to.move
+ mobj%(total% + gtotal%) = i%
+END IF
+movegroup1:
+NEXT i%
+movegroup2:
+NEXT k%
+total% = total% + gtotal%
+Marking 1, n%
+'
+FOR i% = 0 TO total%
+FOR j% = 0 TO 6: obj%(nobj% + i%, j%) = obj%(mobj%(i%), j%): NEXT j%
+FOR j% = 0 TO obj%(mobj%(i%), 1)
+xx(nobj% + i%, j%) = xx(mobj%(i%), j%)
+yy(nobj% + i%, j%) = yy(mobj%(i%), j%)
+NEXT j%: NEXT i%: dx% = 0: dy% = 0
+'
+DO
+ CursorMotion keyin%
+ CursorDisplay px%, py%
+ IF keyin% = 4 THEN
+ FOR i% = 0 TO total%: wkill% = 1: SetObject nobj% + i%, 0, 1: NEXT i%
+ GOTO mvobj
+ END IF
+ ddx% = px% - pxold%: ddy% = py% - pyold%
+ dx% = dx% + ddx%: dy% = dy% + ddy%
+ a$ = KeyIsTouched$ 'check continuous motion, silly?
+ IF (mouswitch% = 0 AND a$ = "") OR (mouswitch% AND a$ = "" AND row% = py% AND col% = px%) THEN
+ IF c% = 0 OR dx% <> 0 OR dy% <> 0 THEN
+ FOR i% = 0 TO total%: wkill% = 1: SetObject nobj% + i%, 0, 1: NEXT i%
+ END IF
+ FOR i% = 0 TO total%: jlast% = obj%(nobj% + i%, 2)
+ IF fnoo%(nobj% + i%) = 2 OR fnoo%(nobj% + i%) = 4 THEN jlast% = jlast% + 1
+ FOR j% = 0 TO jlast%
+ xx(nobj% + i%, j%) = xx(nobj% + i%, j%) + dx%
+ yy(nobj% + i%, j%) = yy(nobj% + i%, j%) + dy%: NEXT j%
+ SetObject nobj% + i%, 3, 1
+ NEXT i%
+ dx% = 0: dy% = 0
+ END IF
+ CursorDisplay px%, py%
+ pxold% = px%: pyold% = py%
+LOOP UNTIL keyin% = 2 OR keyin% = 3
+'
+CursorDisplay px%, py%
+FOR i% = 0 TO total%: SetObject nobj% + i%, 0, 1: NEXT i%
+groupchk% = 0
+IF c% = 0 THEN
+ FOR i% = 0 TO total%: SetObject mobj%(i%), 0, 0: NEXT i%
+ FOR i% = 0 TO total%
+ FOR j% = 0 TO 6: obj%(mobj%(i%), j%) = obj%(nobj% + i%, j%): NEXT j%
+ FOR j% = 0 TO obj%(mobj%(i%), 1): xx(mobj%(i%), j%) = xx(nobj% + i%, j%)
+ yy(mobj%(i%), j%) = yy(nobj% + i%, j%): NEXT j%: NEXT i%
+ FOR i% = 0 TO total%: FOR j% = 0 TO nobj% - 1
+ IF fnoo%(j%) = 11 AND obj%(j%, 5) = mobj%(i%) THEN
+ SetObject j%, 0, 0
+ G.ArrowDirec obj%(j%, 5), obj%(j%, 6), j%
+ SetObject j%, 7, 0
+ END IF
+ NEXT j%: NEXT i%
+ELSE
+ arrow% = 0: arrowoverflow% = 0
+ FOR i% = 0 TO total%: SetObject nobj% + i%, 7, 0
+ IF obj%(nobj% + i%, 0) <> fnoo%(nobj% + i%) THEN
+ obj%(nobj% + i%, 0) = 100 * group% + fnoo%(nobj% + i%)
+ groupchk% = 1
+ ELSE
+ obj%(nobj% + i%, 0) = fnoo%(nobj% + i%)
+ END IF
+ FOR j% = 0 TO nobj% - 1
+ IF fnoo%(j%) = 11 AND obj%(j%, 5) = mobj%(i%) THEN
+ mmobj% = nobj% + total% + arrow% + 1
+ IF mmobj% > UBOUND(obj%, 1) THEN arrowoverflow% = arrowoverflow% + 1
+ IF arrowoverflow% = 0 THEN
+ FOR k% = 0 TO 6: obj%(mmobj%, k%) = obj%(j%, k%): NEXT k%
+ IF obj%(mmobj%, 0) <> fnoo%(mmobj%) THEN
+ obj%(mmobj%, 0) = 100 * group% + fnoo%(mmobj%)
+ ELSE
+ obj%(mmobj%, 0) = fnoo%(mmobj%)
+ END IF
+ FOR k% = 0 TO obj%(mmobj%, 1): xx(mmobj%, k%) = xx(j%, k%)
+ yy(mmobj%, k%) = yy(j%, k%): NEXT k%: obj%(mmobj%, 5) = nobj% + i%
+ G.ArrowDirec obj%(mmobj%, 5), obj%(mmobj%, 6), mmobj%
+ SetObject mmobj%, 7, 0: arrow% = arrow% + 1
+ END IF
+ END IF
+ NEXT j%: NEXT i%
+ IF groupchk% = 1 THEN group% = group% + 1
+ nobj% = nobj% + total% + arrow% + 1
+ IF arrowoverflow% > 0 THEN
+ COLOR 14: LOCATE 2, 25
+ PRINT CHR$(7); " "; arrowoverflow%; " arrow(s) NOT copied! ";
+ COLOR 7
+ END IF
+END IF
+mvobj:
+FOR i% = 0 TO total%: SetObject mobj%(i%), 7, 0: NEXT i%
+CursorDisplay px%, py%
+EXIT SUB
+'
+no.way.to.move:
+Marking 1, n%
+COLOR 14: LOCATE 2, 25
+PRINT CHR$(7); " No way to move/copy that many... ";
+COLOR 7
+'
+END SUB
+
+SUB PPUT (xp, yp, markp%())
+' conditional PUT
+IF xp < pxmax% AND xp > pxmin% AND yp < pymax2% AND yp > pymin% THEN
+ PUT (xp, yp), markp%, XOR
+END IF
+'
+END SUB
+
+SUB SetObject (n%, clr%, simple%)
+' set each object
+IF fnoo%(n%) < 1 THEN EXIT SUB
+ON fnoo%(n%) GOSUB ln, ln, cv, cv, crc, arc, ellps, box, fbox, str, arr
+EXIT SUB
+' line
+ln:
+FOR i% = 1 TO obj%(n%, 1)
+D.Lines INT(xx(n%, i% - 1)), INT(yy(n%, i% - 1)), INT(xx(n%, i%)), INT(yy(n%, i%)), clr%, 0, obj%(n%, 4), obj%(n%, 5), 0, simple%
+NEXT i%: RETURN
+' curve
+cv:
+IF simple% = 1 THEN GOTO ln
+FOR i% = 0 TO obj%(n%, 1) - 2
+x0% = xx(n%, i%): x1% = xx(n%, i% + 1): x2% = xx(n%, i% + 2)
+y0% = yy(n%, i%): y1% = yy(n%, i% + 1): y2% = yy(n%, i% + 2)
+G.XYparam x0%, y0%, x1%, y1%, x2%, y2%, ax, bx, cx, ay, by, cy
+jlast% = 4: IF i% = obj%(n%, 1) - 2 THEN jlast% = 9
+FOR j% = 0 TO jlast%
+t = j% / 5!: sx% = ax * t * t + bx * t + cx: sy% = ay * t * t + by * t + cy
+t = (j% + 1) / 5!: ex% = ax * t * t + bx * t + cx: ey% = ay * t * t + by * t + cy
+D.Lines sx%, sy%, ex%, ey%, clr%, 0, obj%(n%, 4), obj%(n%, 5), 0, simple%
+NEXT j%: NEXT i%
+RETURN
+' circle
+crc:
+D.Circles INT(xx(n%, 0)), INT(yy(n%, 0)), xx(n%, 2), -1, -1, 0, clr%, obj%(n%, 4), simple%, obj%(n%, 6)
+RETURN
+' arc
+arc:
+D.Circles INT(xx(n%, 1)), INT(yy(n%, 1)), xx(n%, 3), -1, yy(n%, 3), yy(n%, 4), clr%, obj%(n%, 4), simple%, obj%(n%, 6)
+RETURN
+' ellipse
+ellps:
+D.Circles INT(xx(n%, 0)), INT(yy(n%, 0)), xx(n%, 2), yy(n%, 2), -1, 0, clr%, obj%(n%, 4), simple%, obj%(n%, 6)
+RETURN
+' box
+box:
+D.Lines INT(xx(n%, 0)), INT(yy(n%, 0)), INT(xx(n%, 1)), INT(yy(n%, 1)), clr%, 1, obj%(n%, 4), obj%(n%, 5), 0, simple%
+RETURN
+' filled box
+fbox:
+D.Lines INT(xx(n%, 0)), INT(yy(n%, 0)), INT(xx(n%, 1)), INT(yy(n%, 1)), clr%, 2, obj%(n%, 4), 0, obj%(n%, 6), simple%
+RETURN
+' strings
+str:
+D.Strings n%, clr%, simple%
+RETURN
+' arrow
+arr:
+FOR i% = 0 TO 1
+D.Lines INT(xx(n%, i%)), INT(yy(n%, i%)), INT(xx(n%, i% + 1)), INT(yy(n%, i% + 1)), clr%, 0, obj%(n%, 4), 0, 0, simple%
+NEXT i%
+RETURN
+'
+END SUB
+
+ \ No newline at end of file
diff --git a/support/qfig/src/qfigsub2.bas b/support/qfig/src/qfigsub2.bas
new file mode 100644
index 0000000000..c967cc4cea
--- /dev/null
+++ b/support/qfig/src/qfigsub2.bas
@@ -0,0 +1,1206 @@
+' qfigsub2.bas
+
+'$INCLUDE: 'QFIG.BI'
+
+SUB CL.R.edraw (simple%, show%)
+' clear and redraw
+CLS 0
+i% = windowx%(wndwfctr%) + pxo%
+IF i% > REGIONXMAX THEN i% = REGIONXMAX
+LINE (pxo%, pyo%)-(i%, pyo%), 3
+i% = windowy%(wndwfctr%) + pyo%
+IF i% > REGIONYMAX THEN i% = REGIONYMAX
+LINE (pxo%, pyo%)-(pxo%, i%), 3
+FOR i% = pxo% TO windowx%(wndwfctr%) + pxo% STEP 4
+IF i% > REGIONXMAX THEN EXIT FOR
+LINE (i%, pyo%)-(i%, pyo% + 2), 3
+IF INT(i% / 20) * 20 = i% THEN LINE -(i%, pyo% + 4), 3
+IF INT(i% / 40) * 40 = i% THEN LINE -(i%, pyo% + 6), 3
+IF i% <> 0 AND INT(i% / 200) * 200 = i% THEN CIRCLE (i%, pyo% + 6), 3, 3, , , 1
+NEXT i%
+FOR i% = pyo% TO windowy%(wndwfctr%) + pyo% STEP 4
+IF i% > REGIONYMAX THEN EXIT FOR
+LINE (pxo%, i%)-(pxo% + 2, i%), 3
+IF INT(i% / 20) * 20 = i% THEN LINE -(pxo% + 4, i%), 3
+IF INT(i% / 40) * 40 = i% THEN LINE -(pxo% + 6, i%), 3
+IF i% <> 0 AND INT(i% / 200) * 200 = i% THEN CIRCLE (pxo% + 6, i%), 3, 3, , , 1
+NEXT i%
+IF nobj% <> 0 THEN
+ IF show% <> 0 THEN
+ LOCATE 12, 30: COLOR 10: PRINT msgrdrw$; : COLOR 7
+ END IF
+ xmin% = REGIONXMAX: xmax% = 0: ymin% = REGIONYMAX: ymax% = 0
+ FOR n% = 0 TO nobj% - 1
+ SetObject n%, 7, simple%
+ NEXT n%
+END IF
+LINE (PMAP(0, 2), PMAP(windowy%(0) - texth% * 4 - 5, 3))-(PMAP(639, 2), PMAP(windowy%(0), 3)), 0, BF
+KeyDisplay
+LINE (PMAP(0, 2), PMAP(windowy%(0) - texth% * 4 - 4, 3))-(PMAP(639, 2), PMAP(windowy%(0) - texth% * 4 - 4, 3)), 3
+'
+END SUB
+
+SUB CopySymm
+' symmetric copy
+job% = 11
+KeySwitch 0
+SetInst job%
+wx1% = 17 * 8 - 8
+wx2% = 17 * 8 + 40
+wy1% = line1% * texth% - texth%
+wy2% = line1% * texth%
+LINE (PMAP(wx1% - 1, 2), PMAP(wy1%, 3))-(PMAP(wx2%, 2), PMAP(wy2%, 3)), 11, BF
+ptext PMAP(wx1%, 2) + 19, PMAP(wy1%, 3) + 1, kky$(13), 0, 1
+'
+startcopysymm:
+selh% = 1
+Marking 2, n%
+IF n% = 0 THEN Marking 2, n%: GOTO donecopysymm
+DO
+ CursorMotion keyin%
+LOOP UNTIL keyin% <> 1
+Marking 2, n%
+IF keyin% = 4 THEN GOTO donecopysymm
+VIEW SCREEN (0, 0)-(windowx%(0), winpy%)
+Marking.Chk 2, sobj%, snode%
+IF sobj% < 0 THEN GOTO startcopysymm
+FOR i% = 0 TO 6: obj%(nobj%, i%) = obj%(sobj%, i%): NEXT i%
+FOR i% = 0 TO obj%(nobj%, 1): xx(nobj%, i%) = xx(sobj%, i%)
+yy(nobj%, i%) = yy(sobj%, i%): NEXT i%
+SELECT CASE keyin%
+ CASE 2
+ FOR i% = 0 TO obj%(nobj%, 1)
+ yy(nobj%, i%) = 2! * yy(sobj%, snode%) - yy(nobj%, i%)
+ NEXT i%
+ CASE 3
+ FOR i% = 0 TO obj%(nobj%, 1)
+ xx(nobj%, i%) = 2! * xx(sobj%, snode%) - xx(nobj%, i%)
+ NEXT i%
+END SELECT
+SetObject nobj%, 7, 0
+nobj% = nobj% + 1
+Object.Max.Check
+GOTO startcopysymm
+'
+donecopysymm:
+SetInst job%
+KeySwitch 1
+job% = 0
+VIEW SCREEN (0, 0)-(windowx%(0), windowy%(0))
+selh% = 0
+LINE (PMAP(wx1% - 1, 2), PMAP(wy1%, 3))-(PMAP(wx2%, 2), PMAP(wy2%, 3)), 0, BF
+LOCATE line1%, 17: COLOR 3: PRINT kky$(13); : COLOR 7
+'
+END SUB
+
+SUB Disp.C (sobj%, snode%)
+' cut nodes
+IF obj%(sobj%, 1) = 1 THEN EXIT SUB
+IF fnoo%(sobj%) = 2 AND obj%(sobj%, 1) = 3 THEN EXIT SUB
+CursorDisplay px%, py%
+FOR i% = 0 TO nobj% - 1
+IF fnoo%(i%) = 11 AND obj%(i%, 5) = sobj% AND obj%(i%, 6) = snode% THEN Killer i%, sobj%
+NEXT i%
+SetObject sobj%, 0, 0
+FOR i% = 1 TO 3: obj%(sobj%, i%) = obj%(sobj%, i%) - 1: NEXT i%
+IF snode% <> obj%(sobj%, 1) + 1 THEN
+ FOR i% = snode% + 1 TO obj%(sobj%, 1) + 1
+ xx(sobj%, i% - 1) = xx(sobj%, i%): yy(sobj%, i% - 1) = yy(sobj%, i%)
+ NEXT i%
+ IF fnoo%(sobj%) = 2 OR fnoo%(sobj%) = 4 THEN
+ xx(sobj%, obj%(sobj%, 1)) = xx(sobj%, 0)
+ yy(sobj%, obj%(sobj%, 1)) = yy(sobj%, 0)
+ END IF
+END IF
+IF fnoo%(sobj%) = 3 OR fnoo%(sobj%) = 4 THEN
+ snode% = obj%(sobj%, 1)
+ G.Addnode sobj%, snode%, 0
+ ' Next line resets a closed curve which was originally a Poly
+ 'but has just been edited
+ IF fnoo%(sobj%) = 4 AND obj%(sobj%, 6) <> 0 THEN obj%(sobj%, 6) = 0
+END IF
+FOR i% = 0 TO nobj% - 1
+IF fnoo%(i%) = 11 AND obj%(i%, 5) = sobj% THEN
+ SetObject i%, 0, 0
+ snode% = 0
+ IF obj%(i%, 6) <> 0 THEN snode% = obj%(sobj%, 1): obj%(i%, 6) = snode%
+ G.ArrowDirec sobj%, snode%, i%
+ SetObject i%, 7, 0
+END IF
+NEXT i%
+SetObject sobj%, 7, 0
+CursorDisplay px%, py%
+'
+END SUB
+
+SUB Disp.D (sobj%, snode%)
+' displace nodes
+pxold% = px%: pyold% = py%
+DO
+ CursorMotion keyin%
+ CursorDisplay px%, py%
+ IF snode% = obj%(sobj%, 1) THEN
+ LINE (pxold%, pyold%)-(xx(sobj%, snode% - 1), yy(sobj%, snode% - 1)), 0
+ ELSE
+ LINE (pxold%, pyold%)-(xx(sobj%, snode% + 1), yy(sobj%, snode% + 1)), 0
+ IF snode% <> 0 THEN
+ LINE (pxold%, pyold%)-(xx(sobj%, snode% - 1), yy(sobj%, snode% - 1)), 0
+ ELSEIF fnoo%(sobj%) = 2 OR fnoo%(sobj%) = 4 THEN
+ LINE (pxold%, pyold%)-(xx(sobj%, obj%(sobj%, 1) - 1), yy(sobj%, obj%(sobj%, 1) - 1)), 0
+ END IF
+ END IF
+ IF keyin% = 4 THEN GOTO donedisp
+ ' Next line resets a closed curve which was originally a Poly
+ 'but has just been edited
+ IF fnoo%(sobj%) = 4 AND obj%(sobj%, 6) <> 0 THEN obj%(sobj%, 6) = 0
+ IF snode% = obj%(sobj%, 1) THEN
+ LINE (px%, py%)-(xx(sobj%, snode% - 1), yy(sobj%, snode% - 1)), 2
+ ELSE
+ LINE (px%, py%)-(xx(sobj%, snode% + 1), yy(sobj%, snode% + 1)), 2
+ IF snode% <> 0 THEN
+ LINE (px%, py%)-(xx(sobj%, snode% - 1), yy(sobj%, snode% - 1)), 2
+ ELSEIF fnoo%(sobj%) = 2 OR fnoo%(sobj%) = 4 THEN
+ LINE (px%, py%)-(xx(sobj%, obj%(sobj%, 1) - 1), yy(sobj%, obj%(sobj%, 1) - 1)), 2
+ END IF
+ END IF
+ CursorDisplay px%, py%
+ pxold% = px%: pyold% = py%
+LOOP UNTIL keyin% = 2
+CursorDisplay px%, py%
+IF snode% = obj%(sobj%, 1) THEN
+ LINE (pxold%, pyold%)-(xx(sobj%, snode% - 1), yy(sobj%, snode% - 1)), 0
+ELSE
+ LINE (pxold%, pyold%)-(xx(sobj%, snode% + 1), yy(sobj%, snode% + 1)), 0
+ IF snode% <> 0 THEN
+ LINE (pxold%, pyold%)-(xx(sobj%, snode% - 1), yy(sobj%, snode% - 1)), 0
+ ELSEIF fnoo%(sobj%) = 2 OR fnoo%(sobj%) = 4 THEN
+ LINE (pxold%, pyold%)-(xx(sobj%, obj%(sobj%, 1) - 1), yy(sobj%, obj%(sobj%, 1) - 1)), 0
+ END IF
+END IF
+SetObject sobj%, 0, 0
+xx(sobj%, snode%) = px%: yy(sobj%, snode%) = py%
+IF (fnoo%(sobj%) = 2 OR fnoo%(sobj%) = 4) AND snode% = 0 THEN
+ xx(sobj%, obj%(sobj%, 1)) = px%: yy(sobj%, obj%(sobj%, 1)) = py%
+END IF
+' arrows
+FOR i% = 0 TO nobj% - 1
+IF fnoo%(i%) <> 11 THEN GOTO chkdisp
+IF obj%(i%, 5) <> sobj% THEN GOTO chkdisp
+SetObject i%, 0, 0
+G.ArrowDirec sobj%, obj%(i%, 6), i%
+SetObject i%, 7, 0
+chkdisp: NEXT i%
+'
+donedisp:
+SetObject sobj%, 7, 0
+CursorDisplay px%, py%
+'
+END SUB
+
+SUB DispCut
+' displace/cut nodes
+job% = 9
+CursorDisplay px%, py%
+FOR i% = 0 TO 92: SWAP curs%(i%), curs2%(i%): NEXT i%
+CursorDisplay px%, py%
+KeySwitch 0
+SetInst job%
+wx1% = 47 * 8 - 8
+wx2% = 47 * 8 + 40
+wy1% = line1% * texth% - texth%
+wy2% = line1% * texth%
+LINE (PMAP(wx1% - 1, 2), PMAP(wy1%, 3))-(PMAP(wx2%, 2), PMAP(wy2%, 3)), 11, BF
+ptext PMAP(wx1%, 2) + 19, PMAP(wy1%, 3) + 1, kky$(16), 0, 1
+'
+startdispcut:
+Marking 2, n%
+IF n% = 0 THEN Marking 2, n%: GOTO donedispcut
+selh% = 1
+DO
+ CursorMotion keyin%
+LOOP UNTIL keyin% <> 1
+Marking 2, n%
+IF keyin% = 4 THEN GOTO donedispcut
+VIEW SCREEN (0, 0)-(windowx%(0), winpy%)
+selh% = 0
+Marking.Chk 2, sobj%, snode%
+IF sobj% < 0 THEN GOTO startdispcut
+SELECT CASE keyin%
+ CASE 2
+ Disp.D sobj%, snode%
+ CASE 3
+ Disp.C sobj%, snode%
+END SELECT
+GOTO startdispcut
+'
+donedispcut:
+SetInst job%
+KeySwitch 1
+CursorDisplay px%, py%
+FOR i% = 0 TO 92: SWAP curs%(i%), curs2%(i%): NEXT i%
+CursorDisplay px%, py%
+job% = 0
+selh% = 0
+VIEW SCREEN (0, 0)-(windowx%(0), windowy%(0))
+LINE (PMAP(wx1% - 1, 2), PMAP(wy1%, 3))-(PMAP(wx2%, 2), PMAP(wy2%, 3)), 0, BF
+LOCATE line1%, 47: COLOR 3: PRINT kky$(16); : COLOR 7
+'
+END SUB
+
+SUB EditObject
+' edit one object
+job% = 8
+KeySwitch 0
+SetInst job%
+wx1% = 31 * 8 - 8
+wx2% = 31 * 8 + 40
+wy1% = line1% * texth% - texth%
+wy2% = line1% * texth%
+LINE (PMAP(wx1% - 1, 2), PMAP(wy1%, 3))-(PMAP(wx2%, 2), PMAP(wy2%, 3)), 11, BF
+ptext PMAP(wx1%, 2) + 19, PMAP(wy1%, 3) + 1, kky$(15), 0, 1
+'
+Marking 1, n%
+startediting:
+IF n% = 0 THEN Marking 1, n%: GOTO donediting
+selh% = 1
+startediting2:
+DO
+ CursorMotion keyin%
+ IF keyin% = 4 THEN Marking 1, n%: GOTO donediting
+LOOP UNTIL keyin% = 2 OR keyin% = 3
+Marking.Chk 1, sobj%, snode%
+IF sobj% < 0 THEN
+ IF keyin% = 3 THEN
+ G.Group1 1 '1 means change thickness
+ END IF
+ GOSUB donediting
+END IF
+VIEW SCREEN (0, 0)-(windowx%(0), winpy%)
+Marking.One 1, sobj%
+FOR i% = 0 TO 6: obj%(nobj%, i%) = obj%(sobj%, i%): NEXT i%
+FOR i% = 0 TO obj%(nobj%, 1): xx(nobj%, i%) = xx(sobj%, i%)
+yy(nobj%, i%) = yy(sobj%, i%): NEXT i%
+CursorDisplay px%, py%
+SetObject sobj%, 0, 0
+CursorDisplay px%, py%
+selh% = 0
+ON fnoo%(sobj%) GOSUB edline, edline, edline, edline, edcrcl, edarc, edellps, edbox, edbox, edstring, edarrw
+CursorDisplay px%, py%
+SetObject sobj%, 7, 0
+CursorDisplay px%, py%
+Marking.One 1, sobj%
+GOTO startediting
+'
+edline:
+obj%(sobj%, 4) = thick%: obj%(sobj%, 5) = ltype%
+IF keyin% = 3 AND fnoo%(sobj%) >= 2 THEN GOTO regularshape
+obj%(sobj%, 0) = obj%(sobj%, 0) + 4 - 2 * fnoo%(sobj%)
+IF fnoo%(sobj%) = 0 OR fnoo%(sobj%) = 2 THEN obj%(sobj%, 0) = obj%(sobj%, 0) + 2
+
+'**** added for converting poly to original shape ****
+IF (fnoo%(sobj%) = 1 OR fnoo%(sobj%) = 2) AND obj%(sobj%, 6) <> 0 THEN
+ FOR itemp% = obj%(sobj%, 6) TO (obj%(sobj%, 1) - 1)
+ xx(sobj%, itemp%) = xx(sobj%, itemp% + 1)
+ yy(sobj%, itemp%) = yy(sobj%, itemp% + 1)
+ NEXT itemp%
+ obj%(sobj%, 6) = 0
+ FOR itemp% = 1 TO 3: obj%(sobj%, itemp%) = obj%(sobj%, itemp%) - 1: NEXT itemp%
+END IF
+'****************************
+IF fnoo%(sobj%) > 2 AND INT(obj%(sobj%, 1) / 2) * 2 <> obj%(sobj%, 1) THEN
+ G.Addnode sobj%, obj%(sobj%, 1), 1
+ FOR i% = 0 TO nobj% - 1
+ IF fnoo%(i%) = 11 AND obj%(i%, 5) = sobj% AND obj%(i%, 6) <> 0 THEN obj%(i%, 6) = obj%(i%, 6) + 1
+ NEXT i%
+END IF
+GOSUB OKarrow: RETURN
+' keyin%=3 and closed line or curve
+regularshape:
+x0 = 0!: y0 = 0!
+FOR i% = 0 TO obj%(sobj%, 2): x0 = x0 + xx(sobj%, i%): y0 = y0 + yy(sobj%, i%)
+NEXT i%: x0 = x0 / (obj%(sobj%, 2) + 1): y0 = y0 / (obj%(sobj%, 2) + 1)
+IF fnoo%(sobj%) <> 3 THEN
+ x2 = 2! * pi / obj%(sobj%, 1)
+ELSE
+ x3 = x0: y3 = y0
+ x0 = (xx(sobj%, 0) + xx(sobj%, obj%(sobj%, 1))) / 2!
+ y0 = (yy(sobj%, 0) + yy(sobj%, obj%(sobj%, 1))) / 2!
+ x4 = xx(sobj%, 0) - xx(sobj%, obj%(sobj%, 1))
+ y4 = yy(sobj%, 0) - yy(sobj%, obj%(sobj%, 1))
+ x3 = x3 - x0: y3 = y3 - y0
+ x2 = pi / obj%(sobj%, 1)
+ IF x4 * y3 - y4 * x3 > 0 THEN x2 = -x2
+END IF
+SELECT CASE fnoo%(sobj%)
+CASE IS = 2
+ rad = SQR((xx(sobj%, snode%) - x0) ^ 2 + (yy(sobj%, snode%) - y0) ^ 2)
+ s1 = Angle(x0, y0, xx(sobj%, snode%), yy(sobj%, snode%))
+ xx(sobj%, 0) = xx(sobj%, snode%): yy(sobj%, 0) = yy(sobj%, snode%)
+ xx(sobj%, obj%(sobj%, 1)) = xx(sobj%, snode%)
+ yy(sobj%, obj%(sobj%, 1)) = yy(sobj%, snode%)
+ FOR i% = 1 TO obj%(sobj%, 2)
+ xx(sobj%, i%) = x0 + rad * COS(s1 + x2 * i%)
+ yy(sobj%, i%) = y0 - rad * SIN(s1 + x2 * i%)
+ NEXT i%
+CASE IS >= 3
+ r1 = -10000!: r3 = 10000!
+ FOR i% = 0 TO obj%(sobj%, 2)
+ rad = SQR((xx(sobj%, i%) - x0) ^ 2 + (yy(sobj%, i%) - y0) ^ 2)
+ IF rad > r1 THEN r1 = rad: s1 = Angle(x0, y0, xx(sobj%, i%), yy(sobj%, i%))
+ IF rad < r3 THEN r3 = rad
+ NEXT i%
+ IF fnoo%(sobj%) = 4 THEN
+ s1 = s1 + pi / 2!
+ ELSE
+ x1 = x4 * COS(s1) - y4 * SIN(s1): y1 = x4 * SIN(s1) + y4 * COS(s1)
+ x3 = SGN(y1) * SQR(ABS(4! * r1 * r1 - x1 * x1))
+ IF x1 > 0! THEN
+ s2 = -ATN(x3 / x1)
+ ELSEIF x1 < 0! THEN
+ s2 = -ATN(x3 / x1) - pi
+ ELSE
+ s2 = -SGN(x3) * pi / 2!
+ END IF
+ x3 = SIN(s2): IF x3 <> 0! THEN y3 = -y1 / 2! / x3: IF y3 > 1! THEN r3 = y3
+ END IF
+ FOR i% = 0 TO obj%(sobj%, 2)
+ IF fnoo%(sobj%) = 3 THEN
+ x3 = r1 * COS(i% * x2 + s2): y3 = -r3 * SIN(i% * x2 + s2)
+ ELSE
+ x3 = r3 * COS(i% * x2): y3 = -r1 * SIN(i% * x2)
+ END IF
+ xx(sobj%, i%) = x0 + x3 * COS(s1) + y3 * SIN(s1)
+ yy(sobj%, i%) = y0 - x3 * SIN(s1) + y3 * COS(s1)
+ NEXT i%
+ IF fnoo%(sobj%) = 4 THEN
+ xx(sobj%, obj%(sobj%, 1)) = xx(sobj%, 0)
+ yy(sobj%, obj%(sobj%, 1)) = yy(sobj%, 0)
+ END IF
+END SELECT
+RETURN
+'
+edcrcl:
+IF xx(nobj%, 1) > pxmax% OR xx(nobj%, 1) < pxmin% OR yy(nobj%, 1) > pymax2% OR yy(nobj%, 1) < pymin% THEN
+ RETURN
+END IF
+obj%(nobj%, 4) = thick%
+CursorDisplay px%, py%
+px% = xx(nobj%, 1): py% = yy(nobj%, 1)
+SetObject nobj%, 7, 0
+CursorDisplay px%, py%
+DO
+ CursorMotion keyin%
+ CursorDisplay px%, py%
+ SetObject nobj%, 0, 0
+ IF keyin% = 4 THEN
+ CursorDisplay px%, py%: GOTO edcrcldone
+ END IF
+ xx(nobj%, 1) = px%: yy(nobj%, 1) = py%
+ xx(nobj%, 2) = SQR((px% - xx(nobj%, 0)) ^ 2 + (py% - yy(nobj%, 0)) ^ 2)
+ SetObject nobj%, 7, 0
+ CursorDisplay px%, py%
+LOOP UNTIL keyin% = 2
+GOSUB editok
+edcrcldone:
+RETURN
+'
+edarc:
+obj%(nobj%, 4) = thick%
+CursorDisplay px%, py%
+SetObject nobj%, 7, 0
+px% = xx(nobj%, snode%): py% = yy(nobj%, snode%)
+CursorDisplay px%, py%
+pxold% = px%: pyold% = py%
+DO
+ CursorMotion keyin%
+ CursorDisplay px%, py%
+ SetObject nobj%, 0, 0
+ IF keyin% = 4 THEN CursorDisplay px%, py%: GOTO edarcdone
+ x0 = xx(nobj%, 1): y0 = yy(nobj%, 1): rad = xx(nobj%, 3)
+ x3 = xx(nobj%, 2): y3 = yy(nobj%, 2)
+ r1 = yy(nobj%, 3): r3 = yy(nobj%, 4)
+ x1 = xx(nobj%, 0): y1 = yy(nobj%, 0)
+ IF snode% = 1 THEN
+ cx = (x1 + x3) / 2!: cy = (y1 + y3) / 2!
+ IF x1 = x3 THEN
+ y0 = cy: x0 = px%
+ ELSEIF y1 = y3 THEN
+ x0 = cx: y0 = py%
+ ELSE
+ dx = x3 - x1: dy = y3 - y1
+ x0 = (dx * cx / dy + dy * px% / dx - py% + cy) / (dx / dy + dy / dx)
+ y0 = py% + dy * (x0 - px%) / dx
+ END IF
+ xx(nobj%, 3) = SQR((x0 - x1) ^ 2 + (y0 - y1) ^ 2)
+ yy(nobj%, 3) = Angle(x0, y0, xx(nobj%, 0), yy(nobj%, 0))
+ yy(nobj%, 4) = Angle(x0, y0, xx(nobj%, 2), yy(nobj%, 2))
+ xx(nobj%, 1) = x0: yy(nobj%, 1) = y0
+ px% = INT(x0): py% = INT(y0)
+ ELSE
+ IF snode% = 0 THEN x1 = px%: y1 = py% ELSE x3 = px%: y3 = py%
+ x4 = SQR((x1 - x3) ^ 2 + (y1 - y3) ^ 2) / 2!
+ IF x4 > rad THEN
+ px% = pxold%: py% = pyold%
+ ELSE
+ y4 = SQR(rad * rad - x4 * x4)
+ s2 = Angle(0!, 0!, y4, -x4)
+ IF (r3 > r1 AND r3 - r1 > pi) OR (r3 < r1 AND r3 - r1 > -pi) THEN s2 = pi - s2
+ s2 = 2! * s2
+ x4 = x3 - x1 * COS(s2) - y1 * SIN(s2)
+ y4 = y3 - y1 * COS(s2) + x1 * SIN(s2)
+ xx(nobj%, 1) = ((1! - COS(s2)) * x4 + SIN(s2) * y4) / 2! / (1! - COS(s2))
+ yy(nobj%, 1) = ((1! - COS(s2)) * y4 - SIN(s2) * x4) / 2! / (1! - COS(s2))
+ xx(nobj%, snode%) = px%: yy(nobj%, snode%) = py%
+ yy(nobj%, 3) = Angle(xx(nobj%, 1), yy(nobj%, 1), x1, y1)
+ yy(nobj%, 4) = Angle(xx(nobj%, 1), yy(nobj%, 1), x3, y3)
+ pxold% = px%: pyold% = py%
+ END IF
+ END IF
+ SetObject nobj%, 7, 0
+ px% = INT(CSNG(px%) / CSNG(s%)) * s%: py% = INT(CSNG(py%) / CSNG(s%)) * s%
+ CursorDisplay px%, py%
+LOOP UNTIL keyin% = 2
+xx(nobj%, 0) = xx(nobj%, 1) + xx(nobj%, 3) * COS(yy(nobj%, 3))
+yy(nobj%, 0) = yy(nobj%, 1) - xx(nobj%, 3) * SIN(yy(nobj%, 3))
+xx(nobj%, 2) = xx(nobj%, 1) + xx(nobj%, 3) * COS(yy(nobj%, 4))
+yy(nobj%, 2) = yy(nobj%, 1) - xx(nobj%, 3) * SIN(yy(nobj%, 4))
+GOSUB editok
+edarcdone:
+GOSUB OKarrow
+RETURN
+'
+edellps:
+IF xx(nobj%, 1) > pxmax% OR xx(nobj%, 1) < pxmin% OR yy(nobj%, 1) > pymax2% OR yy(nobj%, 1) < pymin% THEN
+ RETURN
+END IF
+obj%(nobj%, 4) = thick%
+CursorDisplay px%, py%
+px% = xx(nobj%, 0): py% = yy(nobj%, 0)
+IF yy(nobj%, 2) > 1 THEN
+ px% = px% + xx(nobj%, 2) / yy(nobj%, 2)
+ py% = py% - xx(nobj%, 2)
+ELSE
+ px% = px% + xx(nobj%, 2)
+ py% = py% - xx(nobj%, 2) * yy(nobj%, 2)
+END IF
+SetObject nobj%, 7, 0
+CursorDisplay px%, py%
+DO
+ CursorMotion keyin%
+ CursorDisplay px%, py%
+ SetObject nobj%, 0, 0
+ IF keyin% = 4 THEN CursorDisplay px%, py%: GOTO edellpsdone
+ rad = ABS(px% - xx(nobj%, 0)): rt = ABS(py% - yy(nobj%, 0))
+ IF rad > rt THEN
+ rt = rt / rad
+ ELSE
+ IF rad <> 0 THEN SWAP rad, rt: rt = rad / rt
+ END IF
+ xx(nobj%, 2) = rad: yy(nobj%, 2) = rt
+ SetObject nobj%, 7, 0
+ CursorDisplay px%, py%
+LOOP UNTIL keyin% = 2
+xx(nobj%, 1) = xx(nobj%, 0): yy(nobj%, 1) = yy(nobj%, 0)
+IF rt < 1! THEN
+ xx(nobj%, 1) = xx(nobj%, 1) + rad
+ELSE
+ yy(nobj%, 1) = yy(nobj%, 1) - rad
+END IF
+GOSUB editok
+edellpsdone:
+RETURN
+'
+edbox:
+fillnow% = fill%
+obj%(nobj%, 4) = thick%: obj%(nobj%, 5) = ltype%
+fill% = obj%(nobj%, 6)
+CursorDisplay px%, py%
+SetObject nobj%, 7, 0
+CursorDisplay px%, py%
+inbox% = 2
+DO
+ CursorMotion keyin%
+ CursorDisplay px%, py%
+ wkill% = 1
+ SetObject nobj%, 0, 0
+ IF keyin% = 4 THEN CursorDisplay px%, py%: GOTO edboxdone
+ obj%(nobj%, 6) = fill%
+ IF fill% <> 0 THEN
+ obj%(nobj%, 0) = obj%(nobj%, 0) - fnoo%(nobj%) + 9: obj%(nobj%, 5) = 0
+ ELSE
+ obj%(nobj%, 0) = obj%(nobj%, 0) - fnoo%(nobj%) + 8
+ END IF
+ xx(nobj%, snode%) = px%: yy(nobj%, snode%) = py%
+ SetObject nobj%, 7, 0
+ CursorDisplay px%, py%
+LOOP UNTIL keyin% = 2
+inbox% = 0
+'****add here for edit boxtext (NOT COMPLETE OR FUNCTIONAL!)
+ FOR ibt% = 0 TO nobj% - 1
+ IF obj%(ibt%, 0) = 10 THEN
+ IF (obj%(ibt%, 6) = (sobj% + 1)) THEN
+ tempx0% = xx(nobj%, 0)
+ tempx1% = xx(nobj%, 1)
+ tempy0% = yy(nobj%, 0)
+ tempy1% = yy(nobj%, 1)
+ 'recalculate coordinates for boxtext
+ SetObject ibt%, 0, 0
+ '------------
+ xx(ibt%, 0) = tempx1% - ((tempx1% - tempx0%) / 2)
+ yy(ibt%, 0) = tempy1% - ((tempy1% - tempy0%) / 2) - texth% + 4
+ '------------
+ '
+ SetObject ibt%, 7, 0
+ EXIT FOR
+ END IF
+ END IF
+ NEXT ibt%
+' **** End Edit Boxtext ****
+GOSUB editok
+edboxdone:
+fill% = fillnow%
+RETURN
+'
+edstring:
+chartypeold% = chartype%: charptold% = charpt%
+chartype% = obj%(nobj%, 5): charpt% = obj%(nobj%, 4)
+edstring1:
+CursorDisplay px%, py%
+SetObject nobj%, 7, 0
+pxold% = px%: pyold% = py%
+LINE (px%, py%)-(px% + epitch%(chartype%, 0) * charpt% / 250 * ptmm, py% + eheight(chartype%) * charpt% * ptmm / .25), 2, B
+CursorDisplay px%, py%
+CursorDisplay px%, py%
+LINE (pxold%, pyold%)-(pxold% + epitch%(chartype%, 0) * charpt% / 250 * ptmm, pyold% + eheight(chartype%) * charpt% * ptmm / .25), 0, B
+CursorDisplay px%, py%
+ams$ = ""
+FOR i% = 1 TO obj%(nobj%, 1)
+IF SGN(yy(nobj%, i%)) = 0 THEN
+ ams$ = ams$ + CHR$(xx(nobj%, i%))
+ELSE
+ ams$ = ams$ + STRING$(1, VAL("&j" + HEX$(yy(nobj%, i%)) + HEX$(xx(nobj%, i%))))
+END IF
+NEXT i%
+L.Text px%, py%: PRINT "-> "; : Chr.Input ams$
+L.Text px%, py%: PRINT SPACE$(LEN(ams$) + 3);
+CursorDisplay px%, py%
+SetObject nobj%, 0, 0
+CursorDisplay px%, py%
+obj%(nobj%, 4) = charpt%: obj%(nobj%, 5) = chartype%
+IF ams$ <> "" THEN
+ obj%(nobj%, 1) = LEN(ams$)
+ G.Charset ams$, nobj%
+END IF
+j% = 0: FOR i% = 1 TO obj%(nobj%, 1): j% = j% + yy(nobj%, i%): NEXT i%
+IF j% <> 0 AND chartype% > 1 THEN obj%(nobj%, 5) = obj%(nobj%, 5) - 2
+GOSUB editok
+edstringdone:
+chartype% = chartypeold%: charpt% = charptold%
+RETURN
+'
+edarrw: RETURN ' no edit for arrows
+'
+OKarrow:
+FOR i% = 0 TO nobj% - 1
+IF fnoo%(i%) = 11 AND obj%(i%, 5) = sobj% THEN
+ CursorDisplay px%, py%
+ SetObject i%, 0, 0
+ obj%(i%, 4) = obj%(sobj%, 4)
+ G.ArrowDirec sobj%, obj%(i%, 6), i%
+ SetObject i%, 7, 0
+ CursorDisplay px%, py%
+END IF
+NEXT i%
+RETURN
+'
+editok:
+FOR i% = 0 TO 6: obj%(sobj%, i%) = obj%(nobj%, i%): NEXT i%
+FOR i% = 0 TO obj%(sobj%, 1): xx(sobj%, i%) = xx(nobj%, i%)
+yy(sobj%, i%) = yy(nobj%, i%): NEXT i%
+RETURN
+'
+donediting:
+SetInst job%
+KeySwitch 1
+job% = 0
+selh% = 0
+VIEW SCREEN (0, 0)-(windowx%(0), windowy%(0))
+LINE (PMAP(wx1% - 1, 2), PMAP(wy1%, 3))-(PMAP(wx2%, 2), PMAP(wy2%, 3)), 0, BF
+LOCATE line1%, 31: COLOR 3: PRINT kky$(15); : COLOR 7
+CL.R.edraw 0, 0
+'
+END SUB
+
+SUB G.Group
+' get several objects grouped
+job% = 13
+KeySwitch 0
+LOCATE 2, 2: COLOR 11: PRINT "Setting Group No. "; group%; : COLOR 7
+SetInst job%
+'
+Marking 1, n%
+IF n% = 0 THEN Marking 1, n%: GOTO donegrouping
+c% = 0
+DO
+ CursorMotion keyin%
+ SELECT CASE keyin%
+ CASE 4
+ ggroup% = 100 * group%
+ FOR i% = 0 TO nobj% - 1
+ IF obj%(i%, 0) <> fnoo%(i%) THEN
+ IF obj%(i%, 0) - fnoo%(i%) = ggroup% THEN
+ Marking.One 1, i%
+ obj%(i%, 0) = fnoo%(i%)
+ Marking.One 1, i%
+ END IF
+ END IF
+ NEXT i%
+ GOTO donegrouping
+ CASE 2 TO 3
+ Marking.Chk 1, sobj%, snode%
+ IF sobj% >= 0 THEN
+ Marking.One 1, sobj%
+ IF fnoo%(sobj%) <> obj%(sobj%, 0) THEN
+ ggroup% = obj%(sobj%, 0) - fnoo%(sobj%)
+ IF ggroup% = 100 * group% THEN c% = 0
+ obj%(sobj%, 0) = fnoo%(sobj%)
+ FOR i% = 0 TO nobj% - 1
+ IF obj%(i%, 0) <> fnoo%(i%) THEN
+ IF obj%(i%, 0) - fnoo%(i%) = ggroup% THEN
+ Marking.One 1, i%
+ obj%(i%, 0) = fnoo%(i%)
+ Marking.One 1, i%
+ END IF
+ END IF
+ NEXT i%
+ ELSE
+ obj%(sobj%, 0) = 100 * group% + obj%(sobj%, 0)
+ c% = c% + 1
+ END IF
+ Marking.One 1, sobj%
+ END IF
+ END SELECT
+LOOP UNTIL keyin% = 3
+IF c% <> 0 THEN group% = group% + 1
+'
+donegrouping:
+Marking 1, n%
+SetInst job%
+LOCATE 2, 2: COLOR 0: PRINT SPACE$(25); : COLOR 7
+KeySwitch 1
+job% = 0
+'
+END SUB
+
+SUB Help.Me
+' help messages
+KEY(17) OFF: KEY(19) OFF
+SCREEN scrtype%
+VIEW PRINT 1 TO line3%
+CLS 0
+SCREEN scrtype%
+COLOR 7
+ON job% + 1 GOSUB h.0, h.1, h.2, h.3, h.4, h.5, h.6, h.7, h.8, h.9, h.10, h.11, h.12
+VIEW PRINT 1 TO line1%
+SCREEN scrtype%
+IF seljob% <> 0 THEN VIEW SCREEN (0, 0)-(windowx%(0), windowy%(0))
+CL.R.edraw 0, 0
+IF seljob% <> 0 AND py% > pymax2% THEN py% = pymax2%
+CursorDisplay px%, py%
+KeyDisplay
+SetInst 0
+SELECT CASE seljob%
+ CASE 0
+ linesel% = 0
+ CASE 1 TO 5
+ wx1% = (seljob% * 7 - 4) * 8 - 8
+ wx2% = (seljob% * 7 - 4) * 8 + 40
+ wy1% = (line2% + linesel%) * texth% - texth%
+ wy2% = (line2% + linesel%) * texth%
+ CASE 6 TO 9
+ wx1% = (5 + seljob% * 7) * 8 - 8
+ wx2% = (5 + seljob% * 7) * 8 + 40
+ wy1% = (line2% + linesel%) * texth% - texth%
+ wy2% = (line2% + linesel%) * texth%
+END SELECT
+COLOR 11
+IF seljob% <> 0 THEN
+ LINE (PMAP(wx1%, 2), PMAP(wy1%, 3))-(PMAP(wx2%, 2), PMAP(wy2%, 3)), 11, BF
+ ptext PMAP(wx1%, 2) + 19, PMAP(wy1%, 3) + 1, kky$(seljob% + linesel% * 10), 0, 1
+ COLOR 7
+ VIEW SCREEN (0, 0)-(windowx%(0), winpy%)
+END IF
+IF selh% = 1 THEN Marking 1, n%
+KEY(17) ON: KEY(19) ON
+help% = 1
+EXIT SUB
+'
+h.0:
+KeySwitch 0
+PRINT
+PRINT
+PRINT TAB(3); " FUNCTION KEY (A) ==> [ESC] ==> (B) ==> [ESC] ==> (C) ==> [ESC] ==> (A)"
+
+PRINT TAB(11); "(A)"; TAB(35); "(B)"; TAB(60); "(C)";
+PRINT TAB(1); " f.1: Straight Lines"; TAB(28); "to Move objects"; TAB(54); "to change Box Fill Pattern"
+PRINT TAB(1); " f.2: Curves"; TAB(28); "to Copy objects"; TAB(54); "to change font type"
+PRINT TAB(1); " f.3: Circles & Ellipses"; TAB(28); "to Copy symmetrically"; TAB(54); "to change font size"
+PRINT TAB(1); " f.4: Arcs"; TAB(28); "to Rotate objects"; TAB(54); "to Zoom"
+PRINT TAB(1); " f.5: Boxes w/wo filler"; TAB(28); "to Edit objects"; TAB(54); "to Hide/Show Text"
+PRINT TAB(1); " f.6: Polygons"; TAB(28); "to Cut or Move nodes"; TAB(54); "to Redraw screen"
+PRINT TAB(1); " f.7: Closed curves"; TAB(28); "to Kill objects"; TAB(54); "to Reset (clear) drawing"
+PRINT TAB(1); " f.8: Arrows"; TAB(28); "to change line Pattern"
+PRINT TAB(1); " f.9: Strings"; TAB(28); "to change line Thickness"
+PRINT TAB(1); "f.10: File operations"; TAB(28); "to change cursor pitch"
+PRINT
+PRINT TAB(2); "SPACE/RETURN/DEL ==> to set each choice";
+PRINT TAB(45); "ARROWS ==> to move the cursor";
+PRINT TAB(2); "PGUP/PGDN ==> Page-up/Page-down";
+PRINT TAB(45); "CTRL+w ==> Widen window (Zoom)"
+PRINT TAB(45); "CTRL+s ==> Reset all the objects";
+PRINT TAB(45); "CTRL+r ==> Redraw all the objects"
+PRINT TAB(2); "CTRL+q ==> Quit Program";
+PRINT TAB(45); "CTRL+h ==> Context sensitive help"
+PRINT TAB(2); "CTRL+LEFT/RIGHT ARROWS ==> Shift Region Right/Left"
+PRINT TAB(2); "CTRL+T ==> Hide/Show text toggle"
+GOSUB help.hit
+KeySwitch 1
+seljob% = 0
+RETURN
+'
+h.1:
+PRINT
+PRINT TAB(5); " Lines(f.1)/ Curves(f.2)/ Polygons(f.6)/ Closed Curves(f.7)"
+PRINT
+PRINT TAB(5); " SPACE = to set intermediate points"
+PRINT TAB(5); " RETURN = to set the last point"
+PRINT TAB(5); " DEL = to cancel drawing"
+PRINT
+PRINT TAB(5); " f.8/f.9 = to change Line Type/Thickness"
+
+wnode% = 1
+GOSUB help.hit
+RETURN
+'
+h.2:
+PRINT
+PRINT TAB(5); " Circles/ Ellipses(f.3)"
+PRINT
+PRINT TAB(5); " SPACE => Circles --- to set center and radius"
+PRINT TAB(5); " RETURN => Ellipses --- to set diagonal points"
+PRINT TAB(5); " DEL = to cancel drawing"
+PRINT
+PRINT TAB(5); " f.8/f.9 = to change Line Type/Thickness"
+GOSUB help.hit
+RETURN
+'
+h.3:
+PRINT
+PRINT TAB(5); " Arcs(f.4)"
+PRINT
+PRINT TAB(5); " SPACE = to set two end points"
+PRINT TAB(5); " RETURN = to set the last point on the arc"
+PRINT TAB(5); " DEL = to cancel drawing"
+PRINT
+PRINT TAB(5); " f.8/f.9 = to change Line Type/Thickness"
+GOSUB help.hit
+RETURN
+'
+h.4:
+PRINT
+PRINT TAB(5); " Boxes with or without filler(f.5)"
+PRINT
+PRINT TAB(5); " SPACE/RETURN = to set diagonal points"
+PRINT TAB(5); " DEL = to cancel drawing"
+PRINT
+PRINT TAB(5); "After drawing box you will be asked if you"
+PRINT TAB(5); "want to add centered text to the box "
+PRINT
+PRINT TAB(5); " f.1 = to change filler pattern"
+PRINT TAB(5); " f.8/f.9 = to change Line Type/Thickness"
+
+
+GOSUB help.hit
+RETURN
+'
+h.5:
+PRINT
+PRINT TAB(5); " Strings(f.9)"
+PRINT
+PRINT TAB(5); " SPACE/RETURN = to start the string (ended by RETURN)"
+PRINT TAB(5); " DEL = to cancel "
+PRINT
+PRINT TAB(5); " Use f.1 & f.2 to change size and font"
+GOSUB help.hit
+RETURN
+'
+h.6:
+PRINT
+PRINT TAB(5); " Arrows on Lines/ Curves/ Arcs(f.8)"
+PRINT
+PRINT TAB(5); " SPACE = to set/reset one arrow at that end"
+PRINT TAB(5); " RETURN = to set/reset arrows at both ends"
+PRINT TAB(5); " DEL = to cancel drawing"
+GOSUB help.hit
+RETURN
+'
+h.7:
+PRINT
+PRINT TAB(5); " Move or Copy objects(f.1)(f.2)"
+PRINT
+PRINT TAB(5); " SPACE = to move/copy individual object"
+PRINT TAB(5); " RETURN = to set region to be moved/copied"
+PRINT TAB(5); " DEL = to cancel operation"
+GOSUB help.hit
+RETURN
+'
+h.8:
+PRINT
+PRINT TAB(5); " Edit objects(f.5) -- Line thickness and pattern are updated"
+PRINT
+PRINT TAB(5); " SPACE/RETURN = to select object/area respectively"
+PRINT TAB(5); " DEL = to cancel operation"
+PRINT : PRINT
+PRINT TAB(5); " Lines, Polygons <== (SPACE) ==> Curves, Closed Curves"
+PRINT TAB(5); " Polygons, Curves == (RETURN) ==> Regular Polygons, Ellipses"
+PRINT TAB(5); " Circles and Ellipses (SPACE) : radii can be changed"
+PRINT TAB(5); " Arcs (SPACE) : end positions and radius can be changed"
+PRINT TAB(5); " Boxes (SPACE) : size can be changed"
+PRINT TAB(5); " (RETURN) : filler pattern can be changed"
+PRINT TAB(5); " Strings (RETURN) : To end editing"
+PRINT
+PRINT TAB(5); "NOTE: To change string(s) font/size select it in area to edit"
+COLOR 14
+PRINT
+PRINT TAB(5); "NOTE: To Move or Cut nodes of Lines/ Curves/ Polygons/ Closed Curves"
+PRINT TAB(5); " Use DspCut(f.6)"
+COLOR 7
+
+GOSUB help.hit
+RETURN
+'
+h.9:
+PRINT
+PRINT TAB(5); " Move or Cut nodes of Lines/ Curves/ Polygons/ Closed Curves(f.6)"
+PRINT
+PRINT TAB(5); " SPACE = to move the node"
+PRINT TAB(5); " RETURN = to cut the node"
+PRINT TAB(5); " DEL = to cancel operation"
+GOSUB help.hit
+RETURN
+'
+h.10:
+PRINT
+PRINT TAB(5); " Kill objects(f.7)"
+PRINT
+PRINT TAB(5); " SPACE/RETURN = to select the object/area respectively"
+PRINT TAB(5); " y = to confirm this choice"
+PRINT TAB(5); " n = to cancel operation"
+GOSUB help.hit
+RETURN
+'
+h.11:
+PRINT
+PRINT TAB(5); " Symmetric copy of Lines/ Curves/ Polygons/ Closed Curves(f.3)"
+PRINT
+PRINT TAB(5); " SPACE = to copy symmetrically with respect to the horizontal axis"
+PRINT TAB(5); " RETURN = to copy symmetrically with respect to the vertical axis"
+PRINT TAB(5); " DEL = to cancel operation"
+GOSUB help.hit
+RETURN
+'
+h.12:
+PRINT
+PRINT TAB(5); " Rotate Lines/ Curves/ Polygons/ Closed Curves(f.4)"
+PRINT
+PRINT TAB(5); " Before any operation:"
+PRINT TAB(5); " RETURN = to enter the incremental angle"
+PRINT
+PRINT TAB(5); " After the set:"
+PRINT TAB(5); " ARROWS, SPACE = anticlockwise rotation"
+PRINT TAB(5); " RETURN = to set the position and copy"
+PRINT TAB(5); " DEL = to cancel operation"
+GOSUB help.hit
+RETURN
+'
+help.hit:
+PRINT : PRINT TAB(60); : COLOR 10: PRINT "< Hit any key >"; : COLOR 7
+DO: res$ = INKEY$: LOOP UNTIL res$ <> ""
+RETURN
+'
+END SUB
+
+SUB Killer (i%, s%)
+' kill i%
+wkill% = 1
+SetObject i%, 0, 0
+IF i% <> nobj% - 1 THEN
+ FOR j% = i% + 1 TO nobj% - 1
+ FOR k% = 0 TO 6: obj%(j% - 1, k%) = obj%(j%, k%): NEXT k%
+ FOR k% = 0 TO obj%(j% - 1, 1): xx(j% - 1, k%) = xx(j%, k%)
+ yy(j% - 1, k%) = yy(j%, k%): NEXT k%
+ IF fnoo%(j% - 1) = 11 AND obj%(j% - 1, 5) <> s% AND obj%(j% - 1, 5) > i% THEN obj%(j% - 1, 5) = obj%(j% - 1, 5) - 1
+ NEXT j%
+END IF
+nobj% = nobj% - 1
+'
+END SUB
+
+SUB KillObject
+' kill one object
+job% = 10
+CursorDisplay px%, py%
+FOR i% = 0 TO 92: SWAP curs%(i%), curs1%(i%): NEXT i%
+CursorDisplay px%, py%
+KeySwitch 0
+SetInst job%
+wx1% = 54 * 8 - 8
+wx2% = 54 * 8 + 40
+wy1% = line1% * texth% - texth%
+wy2% = line1% * texth%
+LINE (PMAP(wx1% - 1, 2), PMAP(wy1%, 3))-(PMAP(wx2%, 2), PMAP(wy2%, 3)), 11, BF
+ptext PMAP(wx1%, 2) + 19, PMAP(wy1%, 3) + 1, kky$(17), 0, 1
+'
+Marking 1, n%
+startkilling:
+IF n% = 0 THEN Marking 1, n%: GOTO donekilling
+selh% = 1
+DO
+ CursorMotion keyin%
+ IF keyin% = 4 THEN Marking 1, n%: GOTO donekilling
+LOOP UNTIL keyin% <> 1
+IF keyin% = 2 THEN
+selh% = 0
+VIEW SCREEN (0, 0)-(windowx%(0), winpy%)
+Marking.Chk 1, sobj%, snode%
+IF sobj% < 0 THEN Marking 1, n%: GOTO donekilling
+ipy% = py%: ipx% = px%: L.Text ipx%, ipy%
+PRINT "Sure(y/n)??";
+bkey$ = yesno$
+L.Text ipx%, ipy%: PRINT SPACE$(12);
+IF bkey$ = "n" THEN Marking 1, n%: SetObject sobj%, 7, 0: GOTO donekilling
+CursorDisplay px%, py%
+grp% = obj%(sobj%, 0) - fnoo%(sobj%)
+DO
+ Marking.One 1, sobj%
+ i% = sobj% 'arrow deleting
+ DO UNTIL i% = nobj% - 1
+ i% = i% + 1
+ IF fnoo%(i%) = 11 AND obj%(i%, 5) = sobj% THEN
+ Killer i%, sobj%
+ i% = i% - 1
+ END IF
+ LOOP
+ Killer sobj%, sobj% 'kill THAT object
+ sobj% = -1
+ IF grp% <> 0 THEN 'group killing
+ FOR i% = 0 TO nobj% - 1
+ IF obj%(i%, 0) - fnoo%(i%) = grp% THEN sobj% = i%: EXIT FOR
+ NEXT i%
+ END IF
+LOOP UNTIL sobj% < 0
+CursorDisplay px%, py%
+IF nobj% <> 0 THEN GOTO startkilling
+'=======================
+ ELSEIF keyin% = 3 THEN
+ G.Group1 0 ' 0 means kill
+'==========================
+END IF
+'
+donekilling:
+SetInst job%
+KeySwitch 1
+CursorDisplay px%, py%
+FOR i% = 0 TO 92: SWAP curs%(i%), curs1%(i%): NEXT i%
+CursorDisplay px%, py%
+job% = 0
+selh% = 0
+VIEW SCREEN (0, 0)-(windowx%(0), windowy%(0))
+LINE (PMAP(wx1% - 1, 2), PMAP(wy1%, 3))-(PMAP(wx2%, 2), PMAP(wy2%, 3)), 0, BF
+LOCATE line1%, 54: COLOR 3: PRINT kky$(17); : COLOR 7
+'
+END SUB
+
+SUB MarkEnds (c%)
+' marking end points only
+c% = 0
+xyshift% = INT(3! * wndwxy(wndwfctr%))
+FOR i% = 0 TO nobj% - 1
+IF fnoo%(i%) <> 1 AND fnoo%(i%) <> 3 AND fnoo%(i%) <> 6 THEN GOTO nomarkends
+c% = c% + 1
+PPUT xx(i%, 0) - xyshift%, yy(i%, 0) - xyshift%, mark%()
+PPUT xx(i%, obj%(i%, 2)) - xyshift%, yy(i%, obj%(i%, 2)) - xyshift%, mark%()
+nomarkends: NEXT i%
+'
+END SUB
+
+SUB Marking (c%, n%)
+' marking1 or marking2 (c%=1,2)
+IF nobj% = 0 THEN EXIT SUB
+n% = 0
+FOR i% = 0 TO nobj% - 1
+IF obj%(i%, c% + 1) < 0 THEN GOTO nomarking
+Marking.One c%, i%: n% = n% + 1
+nomarking: NEXT i%
+'
+END SUB
+
+SUB Marking.Chk (m%, sobj%, snode%)
+' get object # chosen (marking.m%)
+sobj% = -1: snode% = -1
+more% = 0
+FOR i% = 0 TO nobj% - 1
+IF obj%(i%, m% + 1) < 0 THEN GOTO nomarkchk
+FOR j% = 0 TO obj%(i%, m% + 1)
+dist = SQR((xx(i%, j%) - CSNG(px%)) ^ 2 + (yy(i%, j%) - CSNG(py%)) ^ 2)
+IF dist < 3! * wndwxy(wndwfctr%) THEN
+ sobj% = i%: snode% = j%
+ SetObject sobj%, 3, 0
+'------------------
+' check for for next
+'
+FOR i1% = i% + 1 TO nobj% - 1
+ FOR j1% = 0 TO obj%(i1%, m% + 1)
+ dist = SQR((xx(i1%, j1%) - CSNG(px%)) ^ 2 + (yy(i1%, j1%) - CSNG(py%)) ^ 2)
+ IF dist < 3! * wndwxy(wndwfctr%) THEN
+ more% = 1
+ EXIT FOR
+ END IF
+ NEXT j1%
+ IF more% = 1 THEN EXIT FOR
+NEXT i1%
+IF more% = 1 THEN
+ ipy% = py%: ipx% = px%: L.Text ipx%, ipy%
+ PRINT "y/n?";
+ bkey$ = yesno$
+ L.Text ipx%, ipy%: PRINT SPACE$(5);
+ELSE
+ bkey$ = "y"
+END IF
+'------------
+IF bkey$ = "y" THEN EXIT SUB
+ SetObject sobj%, 7, 0
+ sobj% = -1: snode% = -1
+END IF
+NEXT j%
+nomarkchk: NEXT i%
+'
+END SUB
+
+SUB Marking.One (c%, i%)
+' mark one object
+xyshift% = INT(3! * wndwxy(wndwfctr%))
+FOR j% = 0 TO obj%(i%, c% + 1)
+ IF fnoo%(i%) = obj%(i%, 0) THEN
+ PPUT xx(i%, j%) - xyshift%, yy(i%, j%) - xyshift%, mark%()
+ ELSE
+ PPUT xx(i%, j%) - xyshift%, yy(i%, j%) - xyshift%, markg%()
+ END IF
+NEXT j%
+'
+END SUB
+
+SUB Marking.Reg (sx%, sy%, ex%, ey%, total%)
+' get objects # chosen
+total% = -1
+FOR i% = 0 TO nobj% - 1: IF obj%(i%, 2) < 0 THEN GOTO nomarkreg
+FOR j% = 0 TO obj%(i%, 1)
+IF (xx(i%, j%) - sx%) * (xx(i%, j%) - ex%) > 0 THEN GOTO nomarkreg1
+IF (yy(i%, j%) - sy%) * (yy(i%, j%) - ey%) > 0 THEN GOTO nomarkreg1
+total% = total% + 1: mobj%(total%) = i%: GOTO nomarkreg
+nomarkreg1: NEXT j%
+nomarkreg: NEXT i%
+'
+END SUB
+
+SUB Object.Max.Check
+' only warn the maximum
+IF nobj% < UBOUND(xx, 1) THEN EXIT SUB
+LOCATE 2, 25
+IF nobj% = UBOUND(xx, 1) THEN
+ COLOR 14
+ PRINT CHR$(7); " The next one will be the last object. ";
+ELSE
+ COLOR 10
+ PRINT CHR$(7); " This one is the very very last one!!! ";
+END IF
+COLOR 7
+'
+END SUB
+
+SUB Rotate
+' rotate object
+job% = 12
+KeySwitch 0
+SetInst job%
+s2 = pi / 90!
+wx1% = 24 * 8 - 8
+wx2% = 24 * 8 + 40
+wy1% = line1% * texth% - texth%
+wy2% = line1% * texth%
+LINE (PMAP(wx1% - 1, 2), PMAP(wy1%, 3))-(PMAP(wx2%, 2), PMAP(wy2%, 3)), 11, BF
+ptext PMAP(wx1%, 2) + 19, PMAP(wy1%, 3) + 1, kky$(14), 0, 1
+'
+startrotate:
+Marking 2, n%
+selh% = 1
+IF n% = 0 THEN Marking 2, n%: GOTO donerotate1
+DO
+ CursorMotion keyin%
+LOOP UNTIL keyin% <> 1
+Marking 2, n%
+IF keyin% = 4 THEN CursorDisplay px%, py%: GOTO donerotate
+VIEW SCREEN (0, 0)-(windowx%(0), winpy%)
+IF keyin% = 3 THEN
+ L.Text px%, py%
+ a$ = fno$(90, 1): PRINT "Angle (PI/n) : n = ";
+ Chr.Input a$: s2 = VAL(a$): IF s2 <= 0! THEN s2 = 90!
+ s2 = pi / s2
+ L.Text px%, py%: PRINT SPACE$(30);
+ GOTO startrotate
+END IF
+Marking.Chk 2, sobj%, snode%
+IF sobj% < 0 THEN GOTO startrotate
+selh% = 0
+FOR i% = 0 TO 6: obj%(nobj%, i%) = obj%(sobj%, i%): NEXT i%
+FOR i% = 0 TO obj%(nobj%, 1): xx(nobj%, i%) = xx(sobj%, i%)
+yy(nobj%, i%) = yy(sobj%, i%): NEXT i%
+DO
+ CursorMotion keyin%
+ CursorDisplay px%, py%
+ IF keyin% <> 3 THEN
+ SetObject nobj%, 0, 1
+ FOR i% = 0 TO obj%(nobj%, 1)
+ s1 = Angle(xx(nobj%, snode%), yy(nobj%, snode%), xx(nobj%, i%), yy(nobj%, i%))
+ rad = SQR((xx(nobj%, i%) - xx(nobj%, snode%)) ^ 2 + (yy(nobj%, i%) - yy(nobj%, snode%)) ^ 2)
+ xx(nobj%, i%) = xx(nobj%, snode%) + rad * COS(s1 + s2)
+ yy(nobj%, i%) = yy(nobj%, snode%) - rad * SIN(s1 + s2)
+ NEXT i%
+ IF keyin% = 4 THEN GOTO donerotate
+ SetObject nobj%, 3, 1
+ END IF
+ CursorDisplay px%, py%
+LOOP UNTIL keyin% = 3
+CursorDisplay px%, py%
+SetObject nobj%, 0, 1
+SetObject nobj%, 7, 0
+nobj% = nobj% + 1
+Object.Max.Check
+'
+donerotate:
+IF sobj% >= 0 THEN
+ SetObject sobj%, 0, 0
+ SetObject sobj%, 7, 0
+END IF
+CursorDisplay px%, py%
+donerotate1:
+SetInst job%
+KeySwitch 1
+job% = 0
+selh% = 0
+VIEW SCREEN (0, 0)-(windowx%(0), windowy%(0))
+LINE (PMAP(wx1% - 1, 2), PMAP(wy1%, 3))-(PMAP(wx2%, 2), PMAP(wy2%, 3)), 0, BF
+LOCATE line1%, 24: COLOR 3: PRINT kky$(14); : COLOR 7
+'
+END SUB
+
diff --git a/support/qfig/src/qfigsub3.bas b/support/qfig/src/qfigsub3.bas
new file mode 100644
index 0000000000..9232e56c5f
--- /dev/null
+++ b/support/qfig/src/qfigsub3.bas
@@ -0,0 +1,620 @@
+' qfigsub3.bas
+
+'$INCLUDE: 'QB.BI'
+'REM $INCLUDE: 'MOUSE.BI'
+'$INCLUDE: 'QFIG.BI'
+
+SUB IO.Eepic
+' eepic format
+PRINT #1, "% Output of qfig.bas in eepic format"
+PRINT #1, "% \hspace{"; fnor$(xmax% - xmin%, .25); "mm}"
+PRINT #1, "% \vspace{"; fnor$(ymax% - ymin% + 10, .25); "mm}"
+PRINT #1, "\unitlength=.25mm"
+IF emulation% = 0 AND nocheat% = 0 THEN 'define \shade[]
+ PRINT #1, "\makeatletter"
+ PRINT #1, "\def\shade{\@ifnextchar[{\shade@special}{\@killglue\special{sh}\ignorespaces}}"
+ PRINT #1, "\def\shade@special[#1]{\@killglue\special{sh #1}\ignorespaces}"
+ PRINT #1, "\makeatother"
+END IF
+PRINT #1, "\begin{picture}("; fnor$(xmax% - xmin%, 1!); ",";
+PRINT #1, fnor$(ymax% - ymin% + 10, 1!); ")(";
+PRINT #1, fnor$(xmin%, 1!); ","; fnor$(-5!, 1!); ")"
+PRINT #1, "\thinlines"
+PRINT #1, "\typeout{\space\space\space eepic-ture exported by 'qfig'.";
+IF emulation% = 0 THEN PRINT #1, "}" ELSE PRINT #1, " (emulated)}"
+PRINT #1, "\font\FonttenBI=cmbxti10\relax"
+PRINT #1, "\font\FonttwlBI=cmbxti10 scaled \magstep1\relax"
+FOR i% = 0 TO nobj% - 1
+ON fnoo%(i%) GOSUB eepline, eepline, eepline, eepline, eepcirc, eeparc, eepellps, eepbox, eepbox, eepmsgs, eepline
+NEXT i%: PRINT #1, "%"
+PRINT #1, "\end{picture}": EXIT SUB
+' line object
+eepline:
+PRINT #1, "% object #"; i%;
+SELECT CASE fnoo%(i%)
+ CASE 1, 2
+ PRINT #1, " (line)"
+ CASE 3, 4
+ PRINT #1, " (curve)"
+ CASE 11
+ PRINT #1, " (arrow of #"; STR$(obj%(i%, 5)); " at"; STR$(obj%(i%, 6)); ")"
+END SELECT
+GOSUB eeplinethickness
+IF fnoo%(i%) = 11 OR obj%(i%, 5) = 0 THEN
+ PRINT #1, "\path ";
+ELSE
+ PRINT #1, eepicpattern$(obj%(i%, 5));
+END IF
+IF fnoo%(i%) = 3 OR fnoo%(i%) = 4 THEN
+ FOR k% = 0 TO obj%(i%, 1) - 2
+ x0% = xx(i%, k%): x1% = xx(i%, k% + 1): x2% = xx(i%, k% + 2)
+ y0% = yy(i%, k%): y1% = yy(i%, k% + 1): y2% = yy(i%, k% + 2)
+ G.XYparam x0%, y0%, x1%, y1%, x2%, y2%, ax, bx, cx, ay, by, cy
+ jlast% = interpolcurve% - 1
+ IF k% = obj%(i%, 1) - 2 THEN jlast% = 2 * interpolcurve%
+ FOR j% = 0 TO jlast%: t = CSNG(j%) / CSNG(interpolcurve%)
+ sx = ax * t * t + bx * t + cx: sy = ay * t * t + by * t + cy
+ PRINT #1, "("; fnor$(sx, 1!); ","; fnor$(ymax% - sy, 1!); ")";
+ IF j% <> jlast% AND INT((j% + 1) / 5) * 5 = j% + 1 THEN PRINT #1,
+ NEXT j%: PRINT #1, : NEXT k%
+ELSE
+ FOR j% = 0 TO obj%(i%, 1)
+ PRINT #1, "("; fnor$(xx(i%, j%), 1!); ","; fnor$(ymax% - yy(i%, j%), 1!); ")";
+ IF j% <> obj%(i%, 1) AND INT((j% + 1) / 5) * 5 = j% + 1 THEN PRINT #1,
+ NEXT j%: PRINT #1,
+END IF
+GOSUB eepobjectdone: RETURN
+' circle object
+eepcirc: PRINT #1, "% object #"; i%; " (circle)": GOSUB eeplinethickness
+PRINT #1, "\put("; fnor$(xx(i%, 0), 1!); ","; fnor$(ymax% - yy(i%, 0), 1!); ")";
+PRINT #1, "{\circle{"; fnor$(xx(i%, 2), 2!); "}}"
+GOSUB eepobjectdone: RETURN
+' arc object
+eeparc: PRINT #1, "% object #"; i%; " (arc)": GOSUB eeplinethickness
+emu$ = "": IF nocheat% = 0 AND emulation% = 1 THEN emu$ = "%"
+rr13 = yy(i%, 4) - yy(i%, 3): IF rr13 < 0! THEN rr13 = 2! * pi + rr13
+PRINT #1, emu$; "\put("; fnor$(xx(i%, 1), 1!); ","; fnor$(ymax% - yy(i%, 1), 1!); ")";
+PRINT #1, "{\arc{"; fnor$(xx(i%, 3), 2!); "}{"; fnor$(2! * pi - yy(i%, 4), 1!);
+PRINT #1, "}{"; fnor$(2! * pi - yy(i%, 4) + rr13, 1!); "}}"
+IF nocheat% = 0 AND emulation% = 1 THEN
+ PRINT #1, "\path"; 'approximation
+ rad = xx(i%, 3): rr1 = yy(i%, 3): rr3 = yy(i%, 4)
+ IF rr1 > rr3 THEN rr1 = rr1 - 2! * pi
+ jj% = INT((rr3 - rr1) / (pi / CSNG(interpolang%))) 'every 5-degrees
+ FOR j% = 0 TO jj%: t = rr1 + j% * (rr3 - rr1) / jj%
+ x1 = xx(i%, 1) + rad * COS(t): y1 = yy(i%, 1) - rad * SIN(t)
+ PRINT #1, "("; fnor$(x1, 1!); ","; fnor$(ymax% - y1, 1!); ")";
+ IF j% <> jj% AND INT((j% + 1) / 4) * 4 = j% + 1 THEN PRINT #1,
+ NEXT j%: PRINT #1,
+END IF
+GOSUB eepobjectdone: RETURN
+' ellipse object
+eepellps: PRINT #1, "% object #"; i%; " (ellipse)": GOSUB eeplinethickness
+IF yy(i%, 2) > 1! THEN
+ rrty = xx(i%, 2): rrtx = xx(i%, 2) / yy(i%, 2)
+ELSE
+ rrtx = xx(i%, 2): rrty = xx(i%, 2) * yy(i%, 2)
+END IF
+emu$ = "": IF nocheat% = 0 AND emulation% = 1 THEN emu$ = "%"
+PRINT #1, emu$; "\put("; fnor$(xx(i%, 0), 1!); ","; fnor$(ymax% - yy(i%, 0), 1!); ")";
+PRINT #1, "{\ellipse{";
+IF emulation% = 0 THEN
+ PRINT #1, fnor$(rrtx, 2!); "}{"; fnor$(rrty, 2!);
+ELSE
+ PRINT #1, fno$(rrtx, 2!); "}{"; fno$(rrty, 2!);
+END IF
+PRINT #1, "}}"
+IF nocheat% = 0 AND emulation% = 1 THEN 'approximation
+ PRINT #1, "\path";
+ x1 = xx(i%, 0) + rrtx: y1 = yy(i%, 0)
+ FOR jj% = 0 TO 2 * interpolang%
+ t = jj% * pi / CSNG(interpolang%) 'every 5 degrees
+ x1 = xx(i%, 0) + rrtx * COS(t): y1 = yy(i%, 0) - rrty * SIN(t)
+ PRINT #1, "("; fnor$(x1, 1!); ","; fno$(ymax% - y1, 1!); ")";
+ IF jj% <> 2 * interpolang% AND INT((jj% + 1) / 5) * 5 = jj% + 1 THEN PRINT #1,
+ NEXT jj%: PRINT #1,
+END IF
+GOSUB eepobjectdone: RETURN
+' box object with or w/o filling
+eepbox: PRINT #1, "% object #"; i%; " (rectangle)";
+IF fnoo%(i%) = 8 THEN PRINT #1, ELSE PRINT #1, " with filling"
+GOSUB eeplinethickness
+IF fnoo%(i%) = 9 THEN
+ PRINT #1, "\shade";
+ IF emulation% = 0 AND nocheat% = 0 THEN PRINT #1, tpicshade$(tpicshade%);
+END IF
+IF obj%(i%, 5) = 0 THEN
+ PRINT #1, "\path ";
+ELSE
+ PRINT #1, eepicpattern$(obj%(i%, 5));
+END IF
+PRINT #1, "("; fnor$(xx(i%, 0), 1!); ","; fnor$(ymax% - yy(i%, 0), 1!); ")";
+PRINT #1, "("; fnor$(xx(i%, 0), 1!); ","; fnor$(ymax% - yy(i%, 1), 1!); ")"
+PRINT #1, "("; fnor$(xx(i%, 1), 1!); ","; fnor$(ymax% - yy(i%, 1), 1!); ")";
+PRINT #1, "("; fnor$(xx(i%, 1), 1!); ","; fnor$(ymax% - yy(i%, 0), 1!); ")";
+PRINT #1, "("; fnor$(xx(i%, 0), 1!); ","; fnor$(ymax% - yy(i%, 0), 1!); ")"
+'
+IF nocheat% = 0 AND fnoo%(i%) = 9 AND obj%(i%, 6) <> 0 THEN
+ emu$ = "": IF emulation% = 0 THEN emu$ = "%" 'for ecleepic.sty
+ ji% = 5 - obj%(i%, 6)
+ ij% = ji% * SGN(yy(i%, 1) - yy(i%, 0))
+ jj% = INT(ABS(yy(i%, 0) - yy(i%, 1)) / ji% - .4)
+ jk% = ji% * SGN(xx(i%, 1) - xx(i%, 0)) / 2
+ IF jj% <= 1 THEN
+ jj% = 1
+ ij% = (yy(i%, 1) - yy(i%, 0)) / 2
+ END IF
+ PRINT #1, emu$; "\thinlines % substitute for shade pattern"
+ FOR j% = 1 TO jj%
+ PRINT #1, emu$; "\dottedline{"; fno$(ji%, 1); "}";
+ PRINT #1, "("; fnor$(xx(i%, 0) + jk%, 1!); ","; fnor$(ymax% - yy(i%, 0) - j% * ij%, 1!); ")";
+ PRINT #1, "("; fnor$(xx(i%, 1) - jk%, 1!); ","; fnor$(ymax% - yy(i%, 0) - j% * ij%, 1!); ")"
+ NEXT j%
+END IF
+GOSUB eepobjectdone: RETURN
+' messages
+eepmsgs: PRINT #1, "% object #"; i%; " (string)"
+ams$ = "": kanji% = 0: special% = 0: script% = 0
+FOR j% = 1 TO obj%(i%, 1)
+ IF wspec% = 1 THEN
+ TeX.Characters i%, j%, ams$, kanji%, special%, script%
+ ELSE
+ IF yy(i%, j%) = 0! THEN
+ a$ = CHR$(xx(i%, j%))
+ ams$ = ams$ + a$
+ END IF
+ END IF
+ NEXT j%
+IF script% <> 0 THEN ams$ = ams$ + "}}$"
+IF kanji% = 0 THEN
+ xy% = eheight(obj%(i%, 5)) * obj%(i%, 4) * ptmm / .25
+ELSE
+ xy% = jheight(obj%(i%, 5)) * obj%(i%, 4) * ptmm / .25
+END IF
+PRINT #1, "\put("; fnor$(xx(i%, 0), 1!); ",";
+PRINT #1, fnor$(ymax% - yy(i%, 0) - xy%, 1!); ")";
+IF obj%(i%, 6) <> 0 THEN
+ PRINT #1, "{\makebox(0,0)[cc]{"; chartex$((obj%(i%, 4) - 10) / 2, obj%(i%, 5));
+ELSE
+ PRINT #1, "{{"; chartex$((obj%(i%, 4) - 10) / 2, obj%(i%, 5));
+END IF
+IF kanji% <> 0 THEN PRINT #1, charjtex$((obj%(i%, 4) - 10) / 2, obj%(i%, 5));
+PRINT #1, ams$; "}}"
+RETURN
+' line thickness / line pattern set
+eeplinethickness:
+IF fnoo%(i%) = 9 THEN tpicshade% = obj%(i%, 6)
+'
+IF obj%(i%, 4) = 0 THEN RETURN
+IF obj%(i%, 4) = 1 THEN PRINT #1, "\thicklines": RETURN
+PRINT #1, "\Thicklines": RETURN
+' object save done : it is tedious but ..... OK
+eepobjectdone:
+IF obj%(i%, 4) = 0 THEN RETURN
+PRINT #1, "\thinlines": RETURN
+'
+END SUB
+
+SUB IO.Export
+' PiCTeX format
+PRINT #1, "% Output of qfig.bas in PiCTeX format"
+PRINT #1, "% \hspace{"; fno$(xmax% - xmin%, .25); "mm}"
+PRINT #1, "% \vspace{"; fno$(ymax% - ymin% + 10, .25); "mm}"
+PRINT #1, "\mbox{\beginpicture"
+PRINT #1, "\setcoordinatesystem units <.25mm,.25mm>"
+PRINT #1, "\unitlength=.25mm"
+PRINT #1, "\linethickness = .5pt"
+PRINT #1, "\setplotsymbol({\fiverm .})"
+PRINT #1, "\setplotarea x from "; xmin%; " to "; xmax%; ", y from ";
+PRINT #1, "0 to "; ymax% - ymin% + 10 'approx. 7pt is added for spacing
+PRINT #1, "\typeout{\space\space\space Picture exported by 'qfig'.}"
+PRINT #1, "\font\FonttenBI=cmbxti10\relax"
+PRINT #1, "\font\FonttwlBI=cmbxti10 scaled \magstep1\relax"
+FOR i% = 0 TO nobj% - 1
+ON fnoo%(i%) GOSUB expline, expline, expline, expline, expcirc, exparc, expellps, expbox, expbox, expmsgs, expline
+NEXT i%: PRINT #1, "%"
+PRINT #1, "\endpicture}": EXIT SUB
+' line object
+expline:
+PRINT #1, "% object #"; i%;
+SELECT CASE fnoo%(i%)
+ CASE 1, 2
+ PRINT #1, " (line)"
+ CASE 3, 4
+ PRINT #1, " (curve)"
+ CASE 11
+ PRINT #1, " (arrow of #"; STR$(obj%(i%, 5)); " at"; STR$(obj%(i%, 6)); ")"
+END SELECT
+GOSUB linethickness
+IF fnoo%(i%) = 3 OR fnoo%(i%) = 4 THEN
+ PRINT #1, "\setquadratic": PRINT #1, "\plot ";
+ FOR k% = 0 TO obj%(i%, 1) - 2
+ x0% = xx(i%, k%): x1% = xx(i%, k% + 1): x2% = xx(i%, k% + 2)
+ y0% = yy(i%, k%): y1% = yy(i%, k% + 1): y2% = yy(i%, k% + 2)
+ G.XYparam x0%, y0%, x1%, y1%, x2%, y2%, ax, bx, cx, ay, by, cy
+ jlast% = 4: IF k% = obj%(i%, 1) - 2 THEN jlast% = 10
+ FOR j% = 0 TO jlast%
+ t = j% / 5!: sx = ax * t * t + bx * t + cx: sy = ay * t * t + by * t + cy
+ PRINT #1, sx; ymax% - sy;
+ IF INT((j% + 1) / 5) * 5 = j% + 1 THEN PRINT #1,
+ NEXT j%: NEXT k%: PRINT #1, "/"
+ELSE
+ PRINT #1, "\setlinear"
+ FOR j% = 0 TO obj%(i%, 1) - 1: k% = j% + 1
+ IF xx(i%, j%) = xx(i%, k%) OR yy(i%, j%) = yy(i%, k%) THEN
+ PRINT #1, "\putrule from "; xx(i%, j%); ymax% - yy(i%, j%); " to "; xx(i%, k%); ymax% - yy(i%, k%)
+ ELSE
+ PRINT #1, "\plot "; xx(i%, j%); ymax% - yy(i%, j%); xx(i%, k%); ymax% - yy(i%, k%); "/"
+ END IF
+ NEXT j%
+END IF
+GOSUB objectdone: RETURN
+' circle object
+expcirc: PRINT #1, "% object #"; i%; " (circle)": GOSUB linethickness
+PRINT #1, "\circulararc 360 degrees from "; xx(i%, 1); ymax% - yy(i%, 1);
+PRINT #1, " center at "; xx(i%, 0); ymax% - yy(i%, 0)
+GOSUB objectdone: RETURN
+' arc object
+exparc: PRINT #1, "% object #"; i%; " (arc)": GOSUB linethickness
+rr13 = (yy(i%, 4) - yy(i%, 3)) * 180! / pi
+IF rr13 < 0! THEN rr13 = 360! + rr13
+PRINT #1, "\circulararc "; rr13; " degrees from ";
+PRINT #1, xx(i%, 0); ymax% - yy(i%, 0); " center at ";
+PRINT #1, xx(i%, 1); ymax% - yy(i%, 1)
+GOSUB objectdone: RETURN
+' ellipse object
+expellps: PRINT #1, "% object #"; i%; " (ellipse)": GOSUB linethickness
+IF yy(i%, 2) > 1! THEN
+ rrtx = 1!: rrty = yy(i%, 2)
+ELSE
+ rrty = 1!: rrtx = 1! / yy(i%, 2)
+END IF
+PRINT #1, "\ellipticalarc axes ratio "; MID$(STR$(rrtx), 2); ":"; MID$(STR$(rrty), 2);
+PRINT #1, " 360 degrees from "; xx(i%, 1); ymax% - yy(i%, 1)
+PRINT #1, "center at "; xx(i%, 0); ymax% - yy(i%, 0)
+GOSUB objectdone: RETURN
+' box object with or w/o filling
+expbox: PRINT #1, "% object #"; i%; " (rectangle)";
+IF fnoo%(i%) = 8 THEN PRINT #1, ELSE PRINT #1, " with filling"
+GOSUB linethickness
+IF fnoo%(i%) = 9 THEN
+ PRINT #1, "\setshadegrid span <"; SQR(2 ^ (3 - obj%(i%, 6))); "pt>"
+ PRINT #1, "\shaderectangleson"
+END IF
+PRINT #1, "\putrectangle ";
+PRINT #1, "corners at "; xx(i%, 0); ymax% - yy(i%, 0); " and "; xx(i%, 1); ymax% - yy(i%, 1)
+IF fnoo%(i%) = 9 THEN PRINT #1, "\shaderectanglesoff"
+GOSUB objectdone: RETURN
+' messages
+expmsgs: PRINT #1, "% object #"; i%; " (string)"
+ams$ = "": kanji% = 0: special% = 0: script% = 0
+FOR j% = 1 TO obj%(i%, 1)
+ IF wspec% = 1 THEN
+ TeX.Characters i%, j%, ams$, kanji%, special%, script%
+ ELSE
+ IF yy(i%, j%) = 0! THEN
+ a$ = CHR$(xx(i%, j%))
+ ams$ = ams$ + a$
+ END IF
+ END IF
+NEXT j%
+IF script% <> 0 THEN ams$ = ams$ + "}}$"
+PRINT #1, "\put{{"; chartex$((obj%(i%, 4) - 10) / 2, obj%(i%, 5));
+IF kanji% <> 0 THEN PRINT #1, charjtex$((obj%(i%, 4) - 10) / 2, obj%(i%, 5));
+'bbbbbbbbbbbbbbbbbbb
+IF kanji% = 0 THEN
+ xy% = eheight(obj%(i%, 5)) * obj%(i%, 4) * ptmm / .25
+ELSE
+ xy% = jheight(obj%(i%, 5)) * obj%(i%, 4) * ptmm / .25
+END IF
+IF obj%(i%, 6) <> 0 THEN
+ PRINT #1, ams$; "}}[cc] at "; xx(i%, 0); ymax% - yy(i%, 0) - xy%
+ELSE
+ PRINT #1, ams$; "}}[lt] at "; xx(i%, 0); ymax% - yy(i%, 0)
+END IF
+RETURN
+' line thickness / line pattern set
+linethickness:
+IF obj%(i%, 4) = 0 THEN GOTO dashpattern
+x1 = obj%(i%, 4): IF x1 = 0 THEN x1 = .5
+PRINT #1, "\linethickness ="; x1; "pt"
+IF fnoo%(i%) = 8 OR fnoo%(i%) = 9 THEN GOTO dashpattern
+' plotsymbol stolen from "xfig" on UNIX
+PRINT #1, "\setplotsymbol({\makebox(0,0)[l]{\tencirc\symbol{'16";
+PRINT #1, RIGHT$(STR$(obj%(i%, 4) - 1), 1); "}}})"
+dashpattern:
+IF obj%(i%, 5) = 0 OR fnoo%(i%) = 11 THEN RETURN
+PRINT #1, "\setdashpattern < "; dpattern$(obj%(i%, 5)); " >"
+RETURN
+' object save done : it is tedious but ..... OK
+objectdone:
+IF obj%(i%, 4) = 0 THEN GOTO objectdone1
+PRINT #1, "\linethickness = .5pt"
+PRINT #1, "\setplotsymbol({\fiverm .})"
+objectdone1:
+IF obj%(i%, 5) <> 0 AND fnoo%(i%) <> 11 THEN PRINT #1, "\setsolid"
+RETURN
+'
+END SUB
+
+SUB IO.File
+' file operation
+STATIC nfilenoext$
+'
+KeySwitch 0
+KEY(17) OFF: KEY(19) OFF
+CursorDisplay px%, py%: SCREEN scrtype%
+CLS 0
+SCREEN scrtype%
+COLOR 7
+PRINT "File Operations: Select one or [ESC] to quit": PRINT
+FOR i% = 1 TO UBOUND(iomessages$)
+PRINT TAB(20); fno$(i%, 1); ". "; iomessages$(i%): NEXT i%
+'
+ifile% = 1: jfile% = 1
+rowold% = row%: colold% = col%
+savepx% = px%: savepy% = py%: savepxold% = pxold%: savepyold% = pyold%
+px% = pxo% + windowx%(wndwfctr%) / 2: py% = pyo% + windowy%(wndwfctr%) / 2
+col% = px%: row% = py%: rowrow% = row%
+'IF mouswitch% THEN MouseLocate py%, px% '<=== when Mouse is used
+'
+LOCATE 3, 19: COLOR 3: PRINT " 1.";
+COLOR 3: PRINT " "; iomessages$(1); : COLOR 7
+DO: a$ = KeyIsTouched$
+ IF jfile% <> ifile% THEN
+ LOCATE 2 + jfile%, 19: PRINT " "; fno$(jfile%, 1); ". "; iomessages$(jfile%);
+ LOCATE 2 + ifile%, 19: COLOR 3: PRINT " "; fno$(ifile%, 1); ".";
+ COLOR 3: PRINT " "; iomessages$(ifile%); : COLOR 7: jfile% = ifile%
+ END IF
+ SELECT CASE a$
+ CASE CHR$(&H0) + CHR$(UP)
+ IF ifile% > 1 THEN ifile% = ifile% - 1 ELSE ifile% = UBOUND(iomessages$)
+ CASE CHR$(&H0) + CHR$(DOWN)
+ IF ifile% < UBOUND(iomessages$) THEN ifile% = ifile% + 1 ELSE ifile% = 1
+ CASE CHR$(SP)
+ EXIT DO
+ CASE CHR$(CR)
+ EXIT DO
+ CASE IS >= CHR$(&H31)
+ IF a$ <= CHR$(&H37) THEN
+ ifile% = VAL(a$)
+ LOCATE 2 + jfile%, 19: PRINT " "; fno$(jfile%, 1); ". "; iomessages$(jfile%);
+ LOCATE 2 + ifile%, 19: COLOR 11: PRINT " "; fno$(ifile%, 1); ".";
+ COLOR 3: PRINT " "; iomessages$(ifile%);
+ COLOR 7: EXIT DO
+ END IF
+ CASE CHR$(&H1B)
+ GOTO filedone
+ CASE ""
+ IF mouswitch% THEN
+' MousePoll row%, col%, lbut%, rbut% '<=== when Mouse is used
+ IF lbut% <> 0 OR rbut% <> 0 THEN
+ EXIT DO
+ END IF
+ IF ABS(row% - rowrow%) > 4 THEN
+ IF row% > rowrow% THEN
+ IF ifile% < UBOUND(iomessages$) THEN ifile% = ifile% + 1 ELSE ifile% = 1
+ END IF
+ IF row% < rowrow% THEN
+ IF ifile% > 1 THEN ifile% = ifile% - 1 ELSE ifile% = UBOUND(iomessages$)
+ END IF
+ rowrow% = row%
+ END IF
+ END IF
+ END SELECT
+LOOP
+'
+LOCATE 4 + UBOUND(iomessages$), 1
+'
+SELECT CASE ifile%
+CASE 1 TO 3
+ shlcmd$ = "dir *.qfg /w"
+CASE 4 TO 6 'ELSE
+ shlcmd$ = "dir *.tex /w"
+CASE 7
+ QUIT0
+ EXIT SUB
+END SELECT
+'
+displaydirectory:
+SHELL shlcmd$
+PRINT : PRINT "Enter the file name : "; : Chr.Input nfilenoext$
+nfile$ = nfilenoext$
+IF nfile$ = "" THEN nfile$ = "$$gifq$$"
+i% = INSTR(nfile$, ":")
+pfile$ = LEFT$(nfile$, i%): nfile$ = MID$(nfile$, i% + 1)
+DO UNTIL INSTR(nfile$, "\") = 0
+ i% = INSTR(nfile$, "\")
+ pfile$ = pfile$ + LEFT$(nfile$, i%)
+ nfile$ = MID$(nfile$, i% + 1)
+LOOP
+i% = INSTR(nfile$, ".")
+IF i% <> 0 THEN
+ nfilenoext$ = LEFT$(LEFT$(nfile$, i% - 1), 8)
+ nfile$ = nfilenoext$ + LEFT$(MID$(nfile$, i%), 4)
+ IF ifile% >= 4 THEN nfile1$ = nfilenoext$: nfile1$ = nfile1$ + ".tex"
+ELSE
+ nfilenoext$ = LEFT$(nfile$, 8): nfile$ = nfilenoext$
+ nfile1$ = nfile$
+ IF ifile% >= 3 THEN nfile$ = nfile$ + ".qfg"
+ IF ifile% >= 4 THEN nfile1$ = nfile1$ + ".tex"
+END IF
+'
+nfilenoext$ = pfile$ + nfilenoext$: nfile$ = pfile$ + nfile$
+IF INSTR(nfile$, "*") <> 0 THEN
+ shlcmd$ = "dir /w " + nfile$
+ nfilenoext$ = nfile$
+ GOTO displaydirectory
+END IF
+'
+both% = 1
+ notexist% = 0: OPEN nfile$ FOR RANDOM AS #1 ' check the existence
+ IF LOF(1) = 0 THEN notexist% = 1: both% = 0 ' non-existent
+ CLOSE : IF notexist% = 1 THEN KILL nfile$
+
+ IF ifile% > 3 THEN
+ OPEN nfile1$ FOR RANDOM AS #1 ' check the existence
+ IF LOF(1) <> 0 THEN notexist% = 0: both% = both% + 2 ' existent
+ CLOSE : IF both% < 2 THEN KILL nfile1$
+ END IF
+
+IF notexist% = 0 AND ifile% < 3 THEN
+ OPEN nfile$ FOR INPUT AS #1
+ IO.Load ifile%: CLOSE
+ELSEIF ifile% > 2 THEN
+ IF notexist% = 0 THEN
+ PRINT : PRINT : PRINT TAB(10); "The file(s) '"; : COLOR 14
+ SELECT CASE both%
+ CASE 1
+ PRINT nfile$; : COLOR 7: PRINT "' already exists.": PRINT
+ CASE 2
+ PRINT nfile1$; : COLOR 7: PRINT "' already exists.": PRINT
+ CASE 3
+ PRINT nfile$; " & "; nfile1$; : COLOR 7: PRINT "' already exist.": PRINT
+ END SELECT
+ PRINT TAB(25); " ..... Do you want to overwrite (y/n)? ";
+ DO: res$ = INKEY$
+ LOOP UNTIL UCASE$(res$) = "Y" OR UCASE$(res$) = "N"
+ IF UCASE$(res$) = "N" THEN GOTO filedone
+ END IF
+ IF ifile% = 3 THEN
+ OPEN nfile$ FOR OUTPUT AS #1
+ IO.Save 3: CLOSE
+ ELSEIF ifile% >= 4 THEN
+ OPEN nfile$ FOR OUTPUT AS #1
+ IO.Save 3: CLOSE
+ OPEN nfile1$ FOR OUTPUT AS #1
+ IO.Save ifile%: CLOSE
+ END IF
+END IF
+filedone:
+row% = rowold%: col% = colold%
+px% = savepx%: py% = savepy%: pxold% = savepxold%: pyold% = savepyold%
+KeySwitch 1
+SCREEN scrtype%: CL.R.edraw 0, 0: CursorDisplay px%, py%
+KeyDisplay
+KEY(17) ON: KEY(19) ON
+'
+END SUB
+
+SUB IO.Load (ifile%)
+' load data
+
+IF nobj% <> 0 THEN
+ PRINT : PRINT CHR$(7); "Are you sure you don't want to save"
+ PRINT "current file...(y/n)"
+ DO: aaa$ = INKEY$: LOOP UNTIL (aaa$ <> "" AND INSTR("yYnN", aaa$))
+ IF (aaa$ = "n") OR (aaa$ = "N") THEN EXIT SUB
+END IF
+
+nobjstart% = 0: IF ifile% = 2 THEN nobjstart% = nobj%
+INPUT #1, aaa$
+IF aaa$ <> FILE.CHECK$ THEN
+ PRINT : PRINT CHR$(7); "This is not a QFIG file."
+ PRINT "hit any key...": CLOSE
+ DO: aaa$ = INKEY$: LOOP UNTIL aaa$ <> ""
+ELSE
+ nobj% = nobjstart%
+ CLS 0
+ IF ifile% = 2 THEN
+ INPUT #1, i%, j%, k%, L%
+' CLS 0
+ ELSE
+ INPUT #1, xmin%, xmax%, ymin%, ymax%
+ END IF
+ LOCATE 12, 30: COLOR 10: PRINT msgload$; : COLOR 7
+ SLEEP 1
+ DO UNTIL EOF(1)
+ INPUT #1, obj%(nobj%, 0), obj%(nobj%, 1), obj%(nobj%, 2), obj%(nobj%, 3), obj%(nobj%, 4), obj%(nobj%, 5), obj%(nobj%, 6)
+ IF obj%(nobj%, 0) = 11 THEN obj%(nobj%, 5) = obj%(nobj%, 5) + nobjstart%
+ 'check to see if loaded string is boxtext.
+ IF obj%(nobj%, 0) = 10 THEN
+ IF obj%(nobj%, 6) <> 0 THEN
+ obj%(nobj%, 6) = obj%(nobj%, 6) + nobjstart%
+ END IF
+ END IF
+ FOR i% = 0 TO obj%(nobj%, 1)
+ INPUT #1, xx(nobj%, i%), yy(nobj%, i%): NEXT i%
+ nobj% = nobj% + 1
+ LOOP
+END IF
+'
+END SUB
+
+SUB IO.Save (ifile%)
+' save data
+IF wrong% <> 1 THEN
+ CL.R.edraw -1, 1
+ CursorDisplay px%, py%
+END IF
+CLS 0
+LOCATE 12, 30: COLOR 10: PRINT msgsave$; : COLOR 7
+SELECT CASE ifile%
+ CASE 3
+' simple format
+ PRINT #1, FILE.CHECK$
+ PRINT #1, xmin%; xmax%; ymin%; ymax%
+ FOR i% = 0 TO nobj% - 1
+ PRINT #1, fnoo%(i%); obj%(i%, 1); obj%(i%, 2); obj%(i%, 3); obj%(i%, 4); obj%(i%, 5); obj%(i%, 6)
+ FOR j% = 0 TO obj%(i%, 1): PRINT #1, xx(i%, j%); yy(i%, j%): NEXT j%
+ NEXT i%
+ CASE 4
+ IO.Export
+ CASE 5
+ emulation% = 0
+ IO.Eepic
+ CASE 6
+ emulation% = 1
+ IO.Eepic
+END SELECT
+'
+END SUB
+
+SUB TeX.Characters (i%, j%, ams$, kanji%, special%, script%)
+' output TeX Special Characters
+kanji% = kanji% + INT(yy(i%, j%))
+IF yy(i%, j%) = 0! THEN
+ a$ = CHR$(xx(i%, j%))
+ IF special% = 0 AND a$ = "\" THEN special% = 1: EXIT SUB
+ IF INSTR("^\@_", a$) <> 0 THEN
+ IF special% = 0 AND INSTR("^@_", a$) <> 0 THEN
+ SELECT CASE a$
+ CASE "@"
+ IF script% = 0 THEN EXIT SUB
+ a$ = "}}$"
+ script% = 0
+ CASE ELSE
+ IF a$ = "^" AND script% = 1 THEN EXIT SUB
+ IF a$ = "_" AND script% = 2 THEN EXIT SUB
+ IF a$ = "^" THEN script% = 1 ELSE script% = 2
+ a$ = "$" + a$ + "{\mbox{"
+ IF obj%(i%, 4) = 10 THEN a$ = a$ + "\viipt " ELSE a$ = a$ + "\viiipt "
+ END SELECT
+ ELSE
+ special% = 0
+ IF a$ = "^" THEN
+ a$ = "{\tt\symbol{'136}}"
+ ELSEIF a$ = "\" THEN
+ a$ = "{\tt\symbol{'134}}"
+ ELSEIF a$ = "_" THEN
+ a$ = "\_"
+ END IF
+ END IF
+ ELSE
+ IF special% = 1 THEN special% = 0
+ IF INSTR("#$%&{}", a$) <> 0 THEN
+ a$ = "\" + a$
+ ELSEIF INSTR("<>-|", a$) <> 0 THEN
+ a$ = "$" + a$ + "$"
+ ELSEIF a$ = "~" THEN
+ a$ = "{\tt\symbol{'176}}"
+ END IF
+ END IF
+ IF ASC(a$) < &H20 OR ASC(a$) > &H7E THEN a$ = " "
+ ams$ = ams$ + a$
+ELSE
+ ams$ = ams$ + STRING$(1, VAL("&j" + HEX$(yy(i%, j%)) + HEX$(xx(i%, j%))))
+END IF
+'
+END SUB
+
diff --git a/support/qfig/src/qfigsub4.bas b/support/qfig/src/qfigsub4.bas
new file mode 100644
index 0000000000..1f573b9240
--- /dev/null
+++ b/support/qfig/src/qfigsub4.bas
@@ -0,0 +1,347 @@
+DECLARE SUB MouseHide ()
+DECLARE SUB MouseInit ()
+DECLARE SUB MousePoll (row%, col%, lbutton%, rbutton%)
+'$INCLUDE: 'QB.BI'
+'$INCLUDE: 'QFIG.BI'
+'----------------------------------------------------
+
+SUB G.Group1 (kth%) 'if kth% = 0, then kill. If = 1 then change thickness.
+' get several objects grouped
+job% = 13
+KeySwitch 0
+
+SetInst job%
+'
+Marking 1, n%
+IF n% = 0 THEN Marking 1, n%: GOTO donegrouping
+c% = 0
+GOTO From.Kill
+DO
+ CursorMotion keyin%
+ SELECT CASE keyin%
+ CASE 4
+ ggroup% = 100 * group%
+ FOR i% = 0 TO nobj% - 1
+ IF obj%(i%, 0) <> fnoo%(i%) THEN
+ IF obj%(i%, 0) - fnoo%(i%) = ggroup% THEN
+ Marking.One 1, i%
+ obj%(i%, 0) = fnoo%(i%)
+ Marking.One 1, i%
+ END IF
+ END IF
+ NEXT i%
+ GOTO donegrouping
+ CASE 3
+' ----------------------------------------------------------------------
+From.Kill:
+total% = 0
+sx% = px%: sy% = py%: pxold% = px%: pyold% = py%
+ DO
+ CursorMotion keyin%
+ CursorDisplay px%, py%
+ LINE (sx%, sy%)-(pxold%, pyold%), 0, B
+ IF keyin% = 4 THEN CursorDisplay px%, py%: GOTO donegrouping
+ LINE (sx%, sy%)-(px%, py%), 2, B
+ CursorDisplay px%, py%
+ pxold% = px%: pyold% = py%
+ LOOP UNTIL keyin% = 3
+ selh% = 0
+ CursorDisplay px%, py%
+ LINE (sx%, sy%)-(px%, py%), 0, B
+ CursorDisplay px%, py%
+ Marking.Reg sx%, sy%, px%, py%, total%
+ IF total% < 0 THEN GOTO donegrouping
+IF total% > UBOUND(mobj%) OR nobj% + total% > UBOUND(obj%, 1) THEN GOTO no.way.to.move
+' group check
+FOR k% = 0 TO total%
+ obj%(mobj%(k%), 0) = 100 * group% + obj%(mobj%(k%), 0)
+ c% = c% + 1
+NEXT k%
+'--------------------
+ipy% = py%: ipx% = px%: L.Text ipx%, ipy%
+'**************
+sobj1% = mobj%(0)
+grp1% = obj%(sobj1%, 0) - fnoo%(sobj1%)
+ FOR i% = 0 TO nobj% - 1
+ IF obj%(i%, 0) - fnoo%(i%) = grp1% THEN SetObject i%, 3, 1
+ NEXT i%
+
+'**************
+PRINT "Sure(y/n)??";
+bkey$ = yesno$
+L.Text ipx%, ipy%: PRINT SPACE$(12);
+IF bkey$ = "y" THEN
+CursorDisplay px%, py%
+sobj% = mobj%(0)
+grp% = obj%(sobj%, 0) - fnoo%(sobj%)
+
+'*******if change thickness then
+IF kth% = 1 THEN
+ L.Text ipx%, ipy%
+ PRINT "Edit text font/type in area (y/n)??";
+ bkey$ = yesno$
+ L.Text ipx%, ipy%: PRINT SPACE$(17);
+ FOR i% = 0 TO nobj% - 1
+ IF obj%(i%, 0) - fnoo%(i%) = grp1% THEN
+ IF fnoo%(i%) <> 10 THEN 'If not string (text)
+ obj%(i%, 4) = thick%
+ ELSEIF bkey$ = "y" THEN 'If string (text)
+ obj%(i%, 5) = chartype%
+ END IF
+' Changing arrow thickness in Group Edit
+ SELECT CASE fnoo%(i%)
+ CASE 1, 3, 6
+ i1% = i%
+ DO UNTIL i1% = nobj% - 1
+ i1% = i1% + 1
+ IF fnoo%(i1%) = 11 AND obj%(i1%, 5) = i% THEN
+ obj%(i1%, 4) = thick%
+ END IF
+ LOOP
+ END SELECT
+ '
+' Change Line type in Group Edit
+ SELECT CASE fnoo%(i%)
+ CASE 1, 2, 3, 4, 8
+ obj%(i%, 5) = ltype%
+ END SELECT
+ obj%(i%, 0) = fnoo%(i%)
+ END IF
+ NEXT i%
+ EXIT SUB
+END IF
+'************then return********
+
+DO
+ Marking.One 1, sobj%
+ i% = sobj% 'arrow deleting
+ DO UNTIL i% = nobj% - 1
+ i% = i% + 1
+ IF fnoo%(i%) = 11 AND obj%(i%, 5) = sobj% THEN
+ Killer i%, sobj%
+ i% = i% - 1
+ END IF
+ LOOP
+ Killer sobj%, sobj% 'kill THAT object
+ sobj% = -1
+ IF grp% <> 0 THEN 'group killing
+ FOR i% = 0 TO nobj% - 1
+ IF obj%(i%, 0) - fnoo%(i%) = grp% THEN sobj% = i%: EXIT FOR
+ NEXT i%
+ END IF
+LOOP UNTIL sobj% < 0
+ELSE
+' Marking.Chk 1, sobj%, snode%
+ sobj% = mobj%(0)
+ IF sobj% >= 0 THEN
+ Marking.One 1, sobj%
+ IF fnoo%(sobj%) <> obj%(sobj%, 0) THEN
+ ggroup% = obj%(sobj%, 0) - fnoo%(sobj%)
+ IF ggroup% = 100 * group% THEN c% = 0
+ obj%(sobj%, 0) = fnoo%(sobj%)
+ FOR i% = 0 TO nobj% - 1
+ IF obj%(i%, 0) <> fnoo%(i%) THEN
+ IF obj%(i%, 0) - fnoo%(i%) = ggroup% THEN
+ Marking.One 1, i%
+ obj%(i%, 0) = fnoo%(i%)
+ Marking.One 1, i%
+ END IF
+ END IF
+ NEXT i%
+ ELSE
+ obj%(sobj%, 0) = 100 * group% + obj%(sobj%, 0)
+ c% = c% + 1
+ END IF
+ Marking.One 1, sobj%
+ END IF
+Marking 1, n%: GOTO donegrouping
+END IF
+'------------------------------
+'
+GOTO end.new.grouping
+no.way.to.move:
+Marking 1, n%
+COLOR 14: LOCATE 2, 25
+PRINT CHR$(7); " No way to move/copy that many... ";
+COLOR 7
+end.new.grouping:
+'
+'-------------------------------------------------------------------------
+ END SELECT
+
+LOOP UNTIL keyin% = 3
+
+donegrouping:
+Marking 1, n%
+SetInst job%
+CL.R.edraw 0, 0
+LOCATE 2, 2: COLOR 0: PRINT SPACE$(25); : COLOR 7
+KeySwitch 1
+job% = 0
+'
+END SUB
+
+SUB ptext (ix%, iy%, s$, c%, m%)
+ x! = ix%: y! = iy%
+
+ DIM tarry1(256), tarry2(256), tarry3(256)
+ IF m% = 1 THEN
+ viewmax% = windowy%(0)
+ ELSE
+ viewmax% = winpy% - 5
+ END IF
+ 'determine if the window is "screen" type or not
+ IF PMAP(0, 3) < PMAP(10, 3) THEN
+ 'this is a "screen" type window
+ 'determine if the destination coordinates will be legal.
+ IF s$ <> "" AND PMAP(x! - LEN(s$) * 4 + 1, 0) >= 0 AND PMAP(y! - 7, 1) >= 0 AND PMAP(x! + LEN(s$) * 4, 0) <= 639 AND PMAP(y! + texth% - 5, 1) <= viewmax% THEN
+ 'back up the work area
+ GET (PMAP(0, 2), PMAP(texth%, 3))-(PMAP(8 * LEN(s$) - 1, 2), PMAP(2 * texth% - 1, 3)), tarry1
+ 'make the mask
+ LOCATE 2, 1: COLOR 7
+ PRINT s$;
+ GET (PMAP(0, 2), PMAP(texth%, 3))-(PMAP(8 * LEN(s$) - 1, 2), PMAP(2 * texth% - 1, 3)), tarry3
+ PUT (PMAP(0, 2), PMAP(texth%, 3)), tarry3, PRESET
+ GET (PMAP(0, 2), PMAP(texth%, 3))-(PMAP(8 * LEN(s$) - 1, 2), PMAP(2 * texth% - 1, 3)), tarry3
+ 'make the color characters to print
+ LOCATE 2, 1: COLOR c%
+ PRINT s$;
+ GET (PMAP(0, 2), PMAP(texth%, 3))-(PMAP(8 * LEN(s$) - 1, 2), PMAP(2 * texth% - 1, 3)), tarry2
+ 'restore the work area with the backup
+ PUT (PMAP(0, 2), PMAP(texth%, 3)), tarry1, PSET
+ 'mask out the area for the characters
+ PUT (x! + 4 - LEN(s$) * 4 + 1, y! + 6 - 7), tarry3, AND
+ 'put the color characters in the masked out spot
+ PUT (x! + 4 - LEN(s$) * 4 + 1, y! + 6 - 7), tarry2, OR
+ END IF
+ END IF
+ COLOR 7
+ ERASE tarry1, tarry2
+
+END SUB
+
+'----------------------------------------------------
+SUB QUIT0
+
+qfigtitle$ = "qfig Ver.1.1a (3/24/1997)"
+qfigtitle2$ = "by: William Ofosu-Amaah"
+qfigtitle5$ = "(XI6W-OFSA@asahi-net.or.jp)"
+
+quit:
+CLS 0: COLOR 14
+rowold% = row%: colold% = col%
+KeySwitch 0
+KEY(8) OFF: KEY(9) OFF: KEY(10) OFF: KEY(17) OFF: KEY(19) OFF
+' first check
+LOCATE 12, 30: PRINT " Are you sure (Y/[N]) " '; CHR$(7);
+DO: a$ = KeyIsTouched$
+LOOP UNTIL a$ = CHR$(CR) OR (a$ <> "" AND INSTR("YyNn", a$) <> 0)
+IF a$ = CHR$(CR) OR UCASE$(a$) = "N" THEN
+IF seljob% <> 0 THEN VIEW SCREEN (0, 0)-(windowx%(0), windowy%(0))
+CL.R.edraw 0, 0: row% = rowold%: col% = colold%
+IF seljob% <> 0 AND py% > pymax2% THEN py% = pymax2%
+CursorDisplay px%, py%
+KeyDisplay
+SetInst 0
+SELECT CASE seljob%
+ CASE 0
+ linesel% = 0
+ CASE 1 TO 5
+ wx1% = (seljob% * 7 - 4) * 8 - 8
+ wx2% = (seljob% * 7 - 4) * 8 + 40
+ wy1% = (line2% + linesel%) * texth% - texth%
+ wy2% = (line2% + linesel%) * texth%
+ CASE 6 TO 9
+ wx1% = (5 + seljob% * 7) * 8 - 8
+ wx2% = (5 + seljob% * 7) * 8 + 40
+ wy1% = (line2% + linesel%) * texth% - texth%
+ wy2% = (line2% + linesel%) * texth%
+END SELECT
+COLOR 11
+IF seljob% <> 0 THEN
+ LINE (PMAP(wx1%, 2), PMAP(wy1%, 3))-(PMAP(wx2%, 2), PMAP(wy2%, 3)), 11, BF
+ ptext PMAP(wx1%, 2) + 19, PMAP(wy1%, 3) + 1, kky$(seljob% + linesel% * 10), 0, 1
+ COLOR 7
+ VIEW SCREEN (0, 0)-(windowx%(0), winpy%)
+END IF
+IF selh% = 1 THEN Marking 1, n%
+ help% = 1
+ KeySwitch 1
+ KEY(8) ON: KEY(9) ON: KEY(10) ON: KEY(17) ON: KEY(19) ON
+ EXIT SUB
+END IF
+' second check
+COLOR 11
+LOCATE 12, 24: PRINT " Need to save this figure (Y/[N]) " '; CHR$(7);
+DO: a$ = KeyIsTouched$
+LOOP UNTIL a$ = CHR$(CR) OR (a$ <> "" AND INSTR("YyNn", a$) <> 0)
+IF UCASE$(a$) = "Y" THEN
+ CLOSE : SCREEN scrtype% ', , 0, 1
+ INPUT "Enter Filename [default is $_qfig_$.qfg]:", nfile$
+ IF nfile$ = "" THEN nfile$ = "$_qfig_$.qfg"
+ OPEN nfile$ FOR OUTPUT AS #1
+ IO.Save 3: CLOSE
+END IF
+' no way to recover
+COLOR 7: GOSUB quit1: GOSUB title1: KEY ON: END
+'
+quit1:
+IF mouswitch% THEN MouseHide: MouseInit '<=== when Mouse is used
+KeySwitch 0: KEY(8) OFF: KEY(9) OFF: KEY(10) OFF: KEY(17) OFF: KEY(19) OFF
+RETURN
+
+title1:
+CLS 0: LOCATE 8, 40 - LEN(qfigtitle$) / 2: COLOR 7: PRINT qfigtitle$;
+COLOR 10
+LOCATE 12, 40 - LEN(qfigtitle2$) / 2: PRINT qfigtitle2$;
+LOCATE 14, 40 - LEN(qfigtitle5$) / 2: PRINT qfigtitle5$;
+COLOR 3
+COLOR 7: SLEEP 2: CLS 0: RETURN
+
+END SUB
+
+SUB whelp
+PRINT
+PRINT TAB(3); " qfig [/e] [/s] [/f] " '[/nc] "
+PRINT
+PRINT TAB(5); "/e"; : PRINT TAB(10); "Use for EGA (default is VGA)"
+PRINT TAB(5); "/s"; : PRINT TAB(10); "For Special Characters in output .TEX file"
+PRINT TAB(5); "/f"; : PRINT TAB(10); "To use user data settings (qfig_set.dat)"
+PRINT TAB(11); "instead of default settings"
+END SUB
+
+FUNCTION yesno$
+KEY(17) OFF
+save$ = Ins(0).R
+LOCATE line3%, 42: PRINT "L-but=y|R-but=n";
+bkey$ = "X"
+DO
+ bkey$ = KeyIsTouched$
+LOOP UNTIL bkey$ = "y" OR bkey$ = "n" OR lbut% <> 0 OR rbut% <> 0
+
+' which key has been typed so far
+' 1:motion 2:space or left button
+' 3:return or right button 4:delete or both button (sensitive)
+
+IF bkey$ <> "" THEN
+ yesno$ = bkey$
+ KEY(17) ON
+ EXIT FUNCTION
+ELSEIF mouswitch% THEN
+ IF lbut% <> 0 THEN
+ yesno$ = "y"
+ DO
+ MousePoll row%, col%, lbut%, rbut% '<=== when Mouse is used
+ LOOP UNTIL lbut% = 0
+ END IF
+ IF rbut% <> 0 THEN
+ yesno$ = "n"
+ DO
+ MousePoll row%, col%, lbut%, rbut% '<=== when Mouse is used
+ LOOP UNTIL rbut% = 0
+ END IF
+END IF
+LOCATE line3%, 42: PRINT save$;
+KEY(17) ON
+END FUNCTION
+
diff --git a/support/qfig/src/qfsrc.bat b/support/qfig/src/qfsrc.bat
new file mode 100644
index 0000000000..e0ba326caa
--- /dev/null
+++ b/support/qfig/src/qfsrc.bat
@@ -0,0 +1 @@
+qb qfig /l /AH