\chapter{Picture Drawing}
\markboth{Picture Drawing}{}

\section{Basic paradigm and requirements}
\markright{Basic paradigm and requirements}

Compared to other picture drawing programs, the major advantage of 
\program{WD-pic} is its GUI. Not only does this GUI provide both WYSIWYG and 
textual views of the picture to users, but also it provides grid and gravity, 
external and internal text editors, syntax checking,  \etc\ The novel UI 
requirements of \program{WD-pic} are that:

\begin{itemize} 
\item All styles of input, \ie\ by mouse or by keyboard, are fully 
interchangeable, without the need to inform the application from where its 
next input is coming.
\item There is no need to move the mouse to the canvas or the EW except to 
explicitly and directly identify a point or an object; therefore, mouse 
movement is minimized. 
\item When inputting text that is expected and that has an algorithmically 
detectable end, there is no need to move the mouse to a text window to input 
the text and to confirm at the end. 
\item The internal representation should be as much as possible what a human 
would write in the \program{pic} language to achieve the picture shown on the 
canvas.
\end{itemize}

The first three are achieved by virtue of the fact that the user is viewed as 
inputting internal representation rather than building a picture per se. This 
view permits the grammar of the internal representation to guide the program's 
acceptance of the user's input.

\section{User interface}
\markright{User interface}

This section lists the elements of the user's interface at a fairly abstract 
level. Details of each element's behavior are described in the 
user's manual in Appendix C.

\subsection{Screen layout}
\program{WD-pic} starts up with the screen layout illustrated in Figure 2.1.  
\begin{figure}
\begin{center}
\epsfig{figure=screenlayout.eps, width=6.5in}
\end{center}
\caption{Screen layout of \program{WD-pic}}
\end{figure}

The main window is made up of six main parts:
\begin{itemize}
\item the menu bar
\item the tool bar
\item the palette
\item the canvas
\item the edit window (EW)
\item the status bar
\end{itemize}
The red star on the canvas represents the current insertion point (CIP).

The attribute area is empty in the start up screen layout. It is filled with 
attribute token buttons when the CIP is at some object. These attribute 
buttons change according to the object where the CIP is at. Figure 2.2 
illustrates the screen layout when the CIP is just after \code{box}.

\begin{figure}
\begin{center}
\epsfig{ figure=boxmain.eps, width=6.0in, height=4.5in}
\end{center}
\caption{Screen layout with \token{box} attribute buttons}
\end{figure}
 
\subsection{Menu bar}
The menu bar is used for operating and adjusting current session, made up of 
the \wid{File}, \wid{Edit}, \wid{Tools}, and \wid{Help} menus. Details on each 
of these are found in the manual in the appendix.

\subsubsection{File menu}
The \wid{File} menu has the following items: 
\begin{itemize}
\item \wid{New} - to start a new picture file, 
\item \wid{Open} - to open an existing file, which is assumed to contain 
\program{pic} code, 
\item \wid{Save} - to save the current complete file, 
\item \wid{Save As} - to establish a new current file name and save the 
current complete IR in the named file, 
\item \wid{Recent File} - to re-open a recently opened file without having to 
specify the full path of the file,
\item \wid{Exit} - to exit the program.
\end{itemize}

\subsubsection{Edit menu}
The \wid{Edit} menu has the following items:
\begin{itemize}
\item \wid{Undo} - to undo the last action in the edit window, 
\item \wid{Redo} - to redo the last action in the edit window, 
\item \wid{Copy} - to copy the selected content in the edit window to the 
clipboard, 
\item \wid{Paste} - to paste the content in the clipboard to the edit window, 
\item \wid{Cut} - to cut the selected content in the edit window, 
\item \wid{Change Attribute} - to change the attributes of the selected 
object, 
\item \wid{Reset Font} - to reset the font of the selected object,
\item \wid{Set CIP} - to set CIP after the selected object, 
\item \wid{Run External Editor} - to run the external editor.
\end{itemize}

\wid{Undo} and \wid{Redo} are not always available. \wid{Undo} is enabled only 
when there has been some change made to the IR, \eg\ adding, deleting text. 
The user can wid{Undo} to the beginning of the session. \wid{Redo} is enabled 
when \wid{Undo} has been done.

\subsubsection{Tools menu}
The standard pull-down \wid{Tools} menu has the following items, each of which brings up its own dialog.
\begin{itemize}
\item \wid{Font} - to change the font of the selected text on the canvas, 
\item \wid{Set External Editor} - to set the external editor to an accessible 
text editor on the user's system, 
\item \wid{Define Grid} - to define a new grid or modify an existing grid, 
\item \wid{Activate Grid} - to activate a previously saved grid, 
\item \wid{Set Gravity} - to set the gravity values, 
\item \wid{Preferences} - to set the preferences of \program{pic} objects.
\end{itemize}

\subsubsection{Help menu}
The \wid{Help} menu brings up the help information of \program{WD-pic}. It has 
\wid{Contents} and \wid{About} items.

\subsection{Pop-up menu}
The pop-up menu is made up of the \wid{Set CIP}, \wid{Change Attribute}, 
\wid{Reset Font}, \wid{Activate Grid} and \wid{Set Gravity} items. These menu 
items are shortcuts to the same items in the menu bar. 
 
\subsection{Tool bar}
The tool bar is made up of the \wid{New}, \wid{Open}, \wid{Save}, \wid{Copy}, 
\wid{Paste}, \wid{Cut}, \wid{Undo}, \wid{Redo}, \wid{Grid Activate} and 
\wid{Help} buttons. These buttons are shortcuts to the related menu items. 
Tips are provided for users who are not sure about the usages of buttons. By 
moving the mouse over a button, a small tip of what the button is for shows up.

The tool bar can be dragged out of the current position and floated 
horizontally or vertically in the main window.

\subsection{Palette}
The palette is used for causing input to the IR. The \wid{box}, \wid{circle}, 
\wid{ellipse}, \wid{line}, \wid{arrow}, \wid{spline}, \wid{arc}, \wid{;}, 
\widquote, \wid{Constructs}, \wid{Copy}, \wid{Macros}, \wid{Label}, and 
\wid{Variables} buttons are always available in the palette. If the name of a 
button begins with a lower-case letter, \eg\ \wid{box} and \wid{circle}, it is 
a \program{pic} token. LMCing this button inserts the token into the IR at the 
CIP. LMCing a button beginning with an upper case letter, \eg\ 
\wid{Constructs} and \wid{Macros}, invokes a dialog for inputting the parts of 
the \program{pic} statements not beginning with \program{pic} primitives, such 
as conditionals, loops, and macros. 

The attribute buttons are available when the CIP is at some object. As shown 
in Figure 2.2, there are three kinds of attribute buttons in the attribute 
area:
\begin{itemize}
\item an independent button, \eg\ \wid{fill} and \wid{invis}. LMCing one of 
these buttons will add its token, \eg\ \code{fill} and \code{invis}, to the IR 
at the CIP. 
\item a button with a value field, \eg\ \wid{wid} and \wid{ht}. After filling 
in the corresponding value field, LMCing one of these buttons causes the 
addition of both the selected token and the value shown in its value field to 
the IR. 
\item a button in a set of buttons connected with \(\|\)s, \eg\ \wid{solid} 
\(\|\) \wid{dashed} \(\|\) \wid{dotted}. LMCing one of them to add its token 
to the IR. At most one of these buttons can be selected.
\end{itemize}

\subsection{Canvas}
The canvas is used for displaying the picture corresponding to the complete 
current IR and directly manipulating objects, such as selecting an object and 
indicating a point. The CIP is always shown on the canvas. It helps the user 
to track the location of the CIP in the IR.

The objects are painted in two colors on the canvas: black and light purple 
(RGB 204x204x255). Black is for normal objects. Light purple is for selected 
objects. In order that the user easily locate the selected objects on the 
canvas and in the edit window, the same selection color is used in the edit 
window. 

The divider between the canvas and the edit window is adjustable. It can be 
moved up and down to adjust the sizes of the canvas and the edit window.  

\subsection{Edit window}
The edit window (EW) is implemented as a text editor, with which the user can 
view and edit the IR, copy, paste, cut, undo, redo like a normal text editor. 
It also helps the user to do syntax checking. The text in EW is shown in three 
colors: black, light purple, and red. Normal text is in black. Selected text 
is in light purple. Text with a syntax error is in red. 

\subsection{Status bar}
The status bar is used for displaying error information and the coordinates of 
the point, if any, on the canvas at which the mouse is pointed. If a user runs 
some session command and does not see any change on the canvas, there might be 
some error message shown in the status bar. For example, if a user activates a 
grid, but the grid is not drawn on the canvas, there might be some information 
in the status bar telling the user what is wrong.

The coordinates of the mouse's position on the canvas might be displayed as a 
grid point or as an object's corner (a \program{pic} concept explained 
Section 2.3.6), if it is available. Otherwise, it is shown in a pair of 
real numbers, the (\emph{x, y}) coordinates of the mouse's position.

\section{High level design (modules)}
\markright{High level design (modules)}

Figure 2.3 illustrates the system architecture of \program{WD-pic}. It is made 
up of the following modules: \module{UI}, \module{File}, 
\module{ExternalEditor}, \module{EditWindow}, \module{Canvas}, 
\module{PICObject}, \module{PICCompiler}, \module{Grid}, \module{Gravity}, 
\module{History}, \module{Font}, and \module{Help}.

\begin{figure}
\begin{center}
\scalebox{0.8}[0.8]{\includegraphics{arch.ps}}
\end{center}
\caption{\program{WD-pic} system architecture}
\end{figure}

\subsection{User Interface}
The \module{UI} module is responsible for the user interface of 
\program{WD-pic}, including the screen layout mentioned in Section 2.2 and all 
the dialogs that the user sees. It consists of the \class{WDPic} class, the 
\module{AttrPane} package, and the \module{MyDialog} package. \class{WDPic} 
implements the main frame of \program{WD-pic}. \module{AttrPane} contains the 
attribute pane for each \program{pic} primitive. \module{MyDialog} contains 
all the dialogs. 

Each element, \eg\ a menu item and a button, on the user interface is 
assigned an action command. If two elements implement the same function, 
they are assigned the same action command. \class{WDPic} itself implements 
\class{ActionListener}, which is a standard class in \program{Java}. 
Therefore, when \class{WDPic} hears an action, it checks the action 
command and calls the related method. Thus, it does not need to care 
whether the action is from a menu item or a tool button. For example, both 
the \wid{New} item in the \wid{File} menu and the \wid{New} button in the 
tool bar create a new file. They are assigned the same action 
\jvar{file.new}. If a user selects \wid{New} from the \wid{File} menu, 
\class{WDPic} gets the \jvar{file.new} action, the \method{new()} method 
of the \class{File} class is called. If the user LMCs the \wid{New} button 
in the tool bar, \program{WD-pic} also gets the \jvar{file.new} action and 
calls the \method{new()} method. 

\subsection{File}
The \module{File} module handles all the actions that are invoked by the 
\wid{File} menu, including creating a new file, opening an existing file, 
saving current complete file, establishing a new current file name, saving the 
current complete IR in the named file, and exiting the program. These actions 
are done by \method{doNew()}, \method{doOpen()}, \method{doSave()}, 
\method{doSaveAs()}, and \method{doExit()}. 

\method{doOpen()} calls \class{EditWindow} to import the file as to-be-edited 
IR. It also looks up in the history database file to see whether there are 
previously saved grids. If so, it retrieves the grid information and activates 
the grid. It then updates and saves the history database file, records the 
just opened file as the most recently opened file.

\method{doSave()} calls \class{History} to update and save the history 
database file. 

For details of \class{History}, please refer to Section 2.4.2. 

\subsection{ExternalEditor}
The \module{ExternalEditor} module handles actions of the external editor, 
including getting the name of the system default editor, setting a specific 
editor that is accessible from the system to be the external editor, and 
running the specified external editor. These actions are done by 
\method{getExtEditor()}, \method{setExtEditor(\mvar{editor})}, and 
\method{runExtEditor()}.  

Because the \class{Runtime} class in \program{Java}\ cannot run non-windowed 
application, \eg\ \program{pico} and \program{vi}, from a GUI program, a 
\program{C} program is written for the \program{Unix} version of 
\program{WD-pic} to run non-windowed programs in a standard terminal window. 
For details, please refer to Section 2.4.3. 

\subsection{EditWindow}
The \module{EditWindow} module handles the following actions: 
\begin{itemize}
\item composing, importing, and exporting the IR, 
\item sending the IR to the \program{pic} compiler to compile,
\item dealing with actions of the built-in text editor, \eg\ \usecase{copy}, 
\usecase{paste}, \usecase{cut}, \usecase{undo}, and \usecase{redo},
\item checking  syntax, and 
\item setting the CIP.
\end{itemize} 

The main methods of this class are \method{importIR(\mvar{file})}, 
\method{exportIR(\mvar{file})}, \method{insertPrimitive(\mvar{s})}, 
\method{insertModifier(\mvar{s})},  \method{isAtPosCtlPhrase()}, 
\method{isAtObjectPhrase()}, \method{setSelected(\mvar{idx})}, 
\method{setCIPAfterSelected()}, and \method{renewLooking()}.

\method{importIR(\mvar{file})} is used for importing the file \mvar{file} as 
the IR to the edit window. \method{exportIR(\mvar{file})} is used for 
exporting the IR to a file named \mvar{file}. These two methods are mainly 
used by \module{File} when the user opens and saves a file.

\method{insertPrimitive(\mvar{s})} is called when a user LMCs the 
\program{pic} primitive tokens, \eg\ \wid{box}, \wid{circle}, \wid{ellipse}, 
\wid{arc}, \wid{line}, \wid{spline}, \wid{arrow}, and \wid{move}, on the 
palette. It first calculates the CIP. Then, it inserts the string \mvar{s} at 
the beginning of a new line into the IR and calls \method{renewLooking()} to 
renew the look of the EW and the canvas. 

\method{insertModifier(\mvar{s})} is similar to 
\method{insertPrimitive(\mvar{s})}. It is used to insert \wid{up}, 
\wid{down}, \wid{right}, \wid{left}, \widquote, \wid{;}, and the 
attribute tokens. The difference is that when the string \mvar{s} is added to 
the IR, it is not added in a new line, but following the previous existing 
text and with a white space in the front and after.

\method{isAtPostCtlPhrase()} is used to check whether the CIP is after an 
\token{at}, \token{from}, or \token{to}. 

\method{setSelected(\mvar{idx})} sets the object with the index \mvar{idx} to 
be selected. \mvar{idx} is restored for future use. The related text in the IR 
is marked in selection color. The canvas is repainted.

\method{setCIPAfterSelected()} is called when a user selects an object on the 
canvas and runs the \wid{setCIP} action. This method first retrieves the index 
of the selected object and calculates the position of the text of the object 
in the IR. It then sets the cursor in the EW to point to the end of the 
selected object's text. Finally, the canvas is repainted.

\method{renewLooking()} is called whenever there is any change in the IR. It 
renews the look of the text in the EW, calls the canvas to adjust and update 
the attribute area in the palette. Refer to Section 2.4.3. 

\subsection{Canvas}
The \module{Canvas} module handles all the painting actions and the mouse 
events.  Because ``Canvas" is a key word in \program{Java}, ``MyCanvas" is 
used instead as the class name. The main methods in \class{MyCanvas} are 
\method{paint()}, \method{processMouseEvent(\mvar{e})}, 
\method{processMouseMotionEvent(\mvar{me})}, and \method{adjustCavnas()}.

\method{paint()} draws everything on the canvas, including the picture, grid, 
and CIP \etc

All the mouse events can be classified into two categories: 
\begin{itemize}
\item \class{MouseEvent}, including \constant{MOUSE\_CLICKED}, 
\constant{MOUSE\_PRESSED}, \\
\constant{MOUSE\_EXITED}, and \constant{MOUSE\_RELEASED}.
 
\item \class{MouseMotionEvent}, including \constant{MOUSE\_MOVED} and 
\constant{MOUSE\_DRAGGED}.
\end{itemize}

\method{processMouseEvent(\mvar{e})} handles the former category. \mvar{e} is 
one of the four mouse events.

\method{processMouseMotionEvent(\mvar{me})} handle the later. \mvar{me} is one 
of the two mouse motion events.   

\method{adjustCanvas()} is used to adjust the overall layout of the picture in 
the canvas.

\subsection{PICObject}
The \module{PICObject} module is responsible for all \program{pic} objects. 
The architecture of the \module{PICObject} module is illustrated in Figure 
2.4. \class{PICObject} is the base class of \class{PICBoundObject}, 
\class{PICLine}, \class{PICArc}, and \class{PICText}. \class{PICBox}, 
\class{PICCircle}, and \class{PICEllipse} are subclasses of 
\class{PICBoundObject}. \class{PICSpline} is a subclass of \class{PICLine}.
These classes handle the attribute values of \program{pic} objects as well as 
other information that is needed when drawing.
 
\begin{figure}
\begin{center}
\scalebox{0.8}[0.8]{\includegraphics{PicObject.ps}}
\end{center}
\caption{\class{PICObject} class diagram}
\end{figure}

The main methods in \class{PICObject} are \method{set(\mvar{attr})}, 
\method{distance(\mvar{p})}, \method{draw()} and \method{getCorner()}. 

The \method{set(\mvar{attr})} method is invoked by the 
\module{PICCompiler} module. After the IR is compiled, all the information 
of the picture is stored in an object array. Refer to Section 2.4.1. When 
\module{PICCompiler} is requested for the information of an object 
\mvar{o}, it calls \mvar{o}.\method{set(\mvar{attr})} to assign the 
attribute values \mvar{attr} of the specific object \mvar{o}. 

\method{distance(\mvar{p})}, \method{draw()}, and \method{getCorner()} are 
implemented in different subclasses of \class{PICObject}. 
\mvar{o}.\method{distance(\mvar{p})} calculates the distance from a specific 
point \mvar{p} to the object \mvar{o}. The distance between a point \mvar{p} 
and an object \mvar{o} is defined as the shortest distance from \mvar{p} to 
any point on the object \mvar{o}. If \mvar{p} is on the object \mvar{o}, then 
the distance is 0. 

\mvar{o}.\method{draw()} draws the object \mvar{o} on the canvas. 

\mvar{o}.\method{getCorner()} gets the coordinates of a specific corner of an 
object \mvar{o}. Each object in \program{pic} has 9 corners \token{c}, 
\token{n}, \token{ne}, \token{e}, \token{se}, \token{s}, \token{sw}, 
\token{w}, and \token{nw} (Yes, \program{pic} calls the center a ``corner''.). 
Lines and arrows have a \token{start}, an \token{end} and a \token{center} in 
addition to corners. Figure 2.5 illustrates an ellipse and its corners. 
\begin{figure}
\begin{center}
\scalebox{0.8}[.8]{\includegraphics{ellipsecorners.ps}}
\caption{Corners of an ellipse}
\end{center}
\end{figure}

\subsection{PICCompiler}
\module{PICCompiler} is the \program{pic} compiler. The original 
\program{pic} source code is converted into a library file working with 
other \program{Java} code. \module{PICCompiler} is responsible for 
compiling the IR and calculating the values of variables and grids. The 
main methods in \module{PICCompiler} are native methods 
\method{compile(\mvar{ir}, \mvar{center}, \mvar{dx}, \mvar{dy})}, 
\method{getGrid(\mvar{idx}, \mvar{center}, \mvar{size})}, and 
\method{getVariable(\mvar{idx}, \mvar{var})}. 

\method{compile(\mvar{ir}, \mvar{center}, \mvar{dx}, \mvar{dy})} compiles 
the IR, stores the objects' information in a list for future use. Refer to 
Section 2.4.1. A grid's determinants \ie\ \mvar{center}, \mvar{dx} and 
\mvar{dy}, are \program{pic} expressions made of constants, object 
attributes, and variables. When the IR changes, the determinants' values 
change too. Therefore, every time when the IR is compiled, the values of the 
currently active grid is calculated and stored. 

\method{getGrid(\mvar{idx}, \mvar{center}, \mvar{size})} gets the grid 
values at the object whose index in the object list is \mvar{idx}, and 
stores the values into \mvar{center} and \mvar{size}.

There are 20 variables in \program{pic} ~\cite{bk:pic}, \eg\ 
\token{boxwid} and \token{boxht}. \method{getVariable(\mvar{idx}, 
\mvar{var})} gets the value of variable \mvar{var} at the object 
\mvar{idx}. 

\method{getAttributes(\mvar{obj})} gets the attributes of an object 
\mvar{obj} from the IR and stores them into a hashtable. Finally, it 
returns the hashtable.

\method{getLabel(\mvar{obj})} gets the label of an object \mvar{obj}. The 
method first gets the text phrase in the IR of the object, then searches for 
``:'' in the phrase. If there is a ``:" in the phrase, the method returns the 
text before the ``:'' as the label. Otherwise an empty string is returned.

\subsection{Grid}
The \module{Grid} module deals with the actions of grids, including defining 
and activating a grid. It consists of \class{GridAction} and 
\class{GridElement}. In \program{WD-pic}, a session can have as many grids as 
the user likes, but only one is active at a time. These grids are stored in a 
grid list. Refer to Section 2.4.2. Each grid has a unique name and is 
determined by its \widvar{center}, \widvar{dx}, and \widvar{dy}. 

The main methods in this module are \method{defineGrid()}, 
\method{activateGrid()}, and \method{getActiveGrid()}. \method{defineGrid()} 
invokes the \wid{Grid Define} dialog for the user to define new or existing 
grids. \method{activateGrid()} invokes the \wid{Grid Activate} dialog for the 
user to activate an existing grid. If there is no previously saved grid, it 
shows a warning message. \method{getActiveGrid()} gets the name of the active 
grid. 

\subsection{Gravity}
The \module{Gravity} module is responsible for the gravity settings, \eg\ 
on and off, the gravity tightness radius, gravitating to a grid point, and 
gravitating to a \program{pic} corner. The main methods in this module are 
\method{enableGravity(\mvar{rad}, \mvar{grid}, \mvar{corner})}, 
\method{disableGravity()}, and \method{gravitateTo(\mvar{p})}.

\method{enableGravity(\mvar{rad}, \mvar{grid}, \mvar{corner})} enables 
gravity with the tightness radius \mvar{rad}. The parameters \mvar{gird} 
and \mvar{corner} are Booleans, specifying whether to gravitate to grid 
points and to gravitate to \program{pic} corners, respectively. 
\method{disableGravity()} disables gravity. If gravity is disabled, a pair of 
real numbers is taken as the indicated point. 

If \wid{gravitate to grid point} and \wid{gravitate to pic corner} in the 
\wid{Gravity Setting} dialog are selected, \method{gravitateTo(\mvar{p})} 
returns the grid point or the object corner that is closest to \mvar{p}. 
\mvar{p} is the point at which the mouse was LMCed. If the object is not 
labeled, the \wid{Label} dialog is invoked for the user to enter a label for 
the object. Refer to Section 2.4.2 for details.

\subsection{History}
\module{History} is programmed to record the last four recently opened files 
history and the files' grids. Refer to Section 2.4.2. Since there is no grid 
information in the IR, these grids are saved in a \file{.wdpicrc} file. 
Therefore, the next time that the user opens the same picture file, the grids 
are not lost.

When \program{WD-pic} is first launched, the file \file{.wdpicrc} is created 
in the user's home directory. The created file, \file{.wdpicrc}, serves as the 
recently-opened-file history database. The names of the recently opened files 
and their grids, if any, are stored. The \class{History} class maintains this 
history. It has \method{loadHistory()}, \method{saveHistory()}, 
\method{lookupHistory()}, and \method{updateHistory()}.

When \program{WD-pic} opens a file, \method{loadHistory()} is called. It 
retrieves the history information from the database file and updates the 
\wid{Recent File} list in the \wid{File} menu.

\method{saveHistory()} saves the history information into the database file.

\method{lookupHistory()} looks in the database file to see if the most 
recently opened file is in the database. If so, it gets the grid information 
from the database.

\method{updateHistory()} keeps the recently-opened-file list up to date and 
makes sure that there is no duplicate records in the list. When the just 
opened file is in the list, it deletes the oldest record, adds a new one as 
the most recently opened file, and re-orders the remaining records by creation 
time. 

\subsection{Font}
The \module{Font} module deals with font setting. There are two classes in 
this module, \class{PICFont} and \class{PICFontString}. As there is no font 
information in the IR, all the font information is stored in a list of 
\class{PICFontString}. Refer to Section 2.4.2.  

\class{PICFont} handles the font settings, \eg\ setting the font, style, 
and size. The main methods in this class are 
\method{setFont(\mvar{font})}, \method{setStyle(\mvar{style})}, 
\method{setSize(\mvar{size})}, and \method{setInvisible()}. 

\class{PICFontString} deals with the relationship between the position of text 
in the IR and its font. When the IR is changed, the positions of some 
characters are changed too. \method{revalidate()} is used to keep the 
positions of the text in the font list updated.

\subsection{Help}
The \module{Help} module is responsible for the help information.

\section{Implementation}
\markright{Implementation}

\subsection{pic code reuse}
The original \program{pic} code is reused with some modifications. The 
original \program{pic} code works fine when there is no syntax error in the 
IR, but if there are errors in the IR, it stops at the first error without 
compiling the rest of the IR. We changed the code to make the compiler work in 
a way that it can finish compiling an IR with errors, and it returns a correct 
IR. Then by comparing this IR and the original one, we report the errors to 
the user. When the IR is sent to the compiler, instead of compiling the whole 
IR at once, the compiler compiles it phrase by phrase. If an error occurs, the 
compiler replaces the error phrase with white spaces, and then restarts the 
compilation from the beginning. Figure 2.6 illustrates how the compiler works.
 
\begin{figure}
\begin{center}
\scalebox{0.8}[0.8]{\includegraphics{compile.ps}}
\end{center}
\caption{Compiling process}
\end{figure}

These changes are implemented in the newly added files in the \program{pic} 
source code package: \file{Compiler.c}, \file{Compiler.h}, \file{Variables.h} 
and \file{PICObjects.h}. These files together with \file{Compiler.java} 
implement the following functions:

\begin{enumerate}
\item converting the object array generated by the \program{pic} compiler to a 
\program{Java} format object data structure for the GUI to use, and 
\item getting the current values of the 20 \program{pic} variables and grid 
determinants.
\end{enumerate}

After the \program{pic} compiler compiles the IR, an object array of the  
picture elements is generated. Each element in the array contains a 
pointer to an \jvar{obj} structure. The following is the \program{C} code 
for the \jvar{obj} structure:

\begin{verbatim}
typedef struct obj {	
	int	o_type;		/* type of object */
	int	o_count;	/* number of things */
	int	o_nobj;		/* index in objlist */
	int	o_mode;		/* hor or vert */
	float	o_x;		/* coord of "center" */
	float	o_y;
	int	o_nt1;		/* 1st index in text[] for this object */
	int	o_nt2;		/* 1st index in text[] for the next object */
	int	o_attr;		/* HEAD, CW, INVIS, etc., go here */
	int	o_size;		/* linesize, reserved */
	int	o_nhead;	/* arrowhead style */
	struct	symtab	*o_symtab; /* symtab for block [...] */
	float	o_ddval;	/* value of dot/dash expression */
	float	o_fillval;	/* gray scale value */
	ofloat	o_val[1];	/* height, width etc. */
				/* actually this will be >1 in general */
				
	/* Liz: indicate which piece of text in the IR generated this object */
	int	o_srcFrom;	/* start position of the obj in the IR */
	int	o_srcTo;	/* end position of the obj in the IR */			
} obj;
\end{verbatim}

All the information of an object is stored in this structure, such as the  
type of the object, the coordinates of the object's center, the type of 
arrowhead, and a gray scale value. The fields \jvar{o\_srcFrom} 
and \jvar{o\_srcTo} are added to the \jvar{obj} structure to indicate which piece of text in the IR generated the object. 
 
A new structure \jvar{VarSet} is defined in \file{Variables.h} to store the grid and the 20 variables values. The following is the \program{C} code \jvar{VarSet} structure.

\begin{verbatim}
typedef struct _VarSet
{
	double			picVar[20];
	double			gridX0, gridY0, gridDX, gridDY;
	int			idx0, idx1;
	struct _VarSet	*next;
} VarSet;
\end{verbatim}

We mentioned before that the IR is compiled phrase by phrase, so when the 
compiler compiles an IR phrase, it generates and adds an object to the object 
list. At the same time, it also gets the grid and variable values and adds an 
element to the variable list. \jvar{idx0} and \jvar{idx1} are used to locate 
the start and the end of the phrase in the IR. When the CIP moves in the IR, 
we search in the variable list, to get the \jvar{VarSet} where \jvar{idx0} 
\(\leq\) \jvar{cip} \(<\) \jvar{idx1}.

For details of other \program{pic} data structures, please refer to 
\cite{fs:wdpic}.

\subsection{Data structures and algorithms}

\subsubsection{\program{pic} data structures}
Two variables are added to the original \program{pic} \jvar{obj} structure and 
a new structure \jvar{VarSet} is added, as mentioned in Section 2.4.1. 

\subsubsection{Euclidean coordinate \& screen coordinates}
The \program{pic} compiler calculates a position, \( (x_{p}, y_{p}) \),  by 
Euclidean coordinates. However, when \program{WD-pic} draws the position on 
the canvas, screen coordinates \( (x_{c}, y_{c}) \) are used. The difference 
between the Euclidean coordinates and the screen coordinates is illustrated in 
Figure 2.7. The origin of the screen coordinates is at the top left corner of 
the screen, while the origin of the Euclidean coordinates is at the center. 
Furthermore, the Y axis in the screen coordinates goes downward, while the Y 
axis in the Euclidean coordinates goes upward.

\begin{figure}
\begin{center}
\scalebox{0.8}[0.8]{\includegraphics{coordinates.ps}}
\end{center}
\caption{Euclidean coordinate \& the screen coordinate}
\end{figure}

The following formulae are used to do the translation:
\[ \begin{array}{ll}
    x_{c} = x_{p}*Z_{x} + x_{0}, \\
    y_{c} = y_{p}*Z_{y} + y_{0}.
    \end{array}
\]
\( Z_{x}, Z_{y}, x_{0}, y_{0} \) are constants. \( |Z_{x}| \) and \( |Z_{y}| 
\) are used to adjust the length of unit on the canvas. Since the Y axis in 
the Euclidean coordinates goes in the direction opposite of that of the Y axis 
in the screen coordinates, \( Z_{y}<0 \). 

A unit in \program{pic} is 1 inch. A unit on screen is 1 pixel. To make a unit 
in \program{pic} look like a unit on a 17 inch monitor with 1024x768 
resolution,

 \[ Z_{x}=-Z_{y}= \sqrt{1024^{2}+768^{2}}/17 = 75.294117647 \]

\( x_{0}, y_{0} \) are used to adjust the position on the canvas. In this 
version of \program{WD-pic}, 
\[ \begin{array}{ll}
		x_{0}=canvasWidth/2, \\
		y_{0}=canvasHeight/2. 
   \end{array}
\]

\subsubsection{History}
The recently opened files names and their grid information are stored in a 
vector.  In order to keep the information when \program{WD-pic} exits, it is 
saved into the  \file{.wdpicrc} file on the disk. Then the next time 
\program{WD-pic} launches, it retrieves the history information from the 
\file{.wdpicrc} file. The following is a sample record in the \file{.wdpicrc} 
file:
\begin{verbatim}
E:\WDpic\PicObject.pic
Grid1;(0,0);movewid;moveht 
\end{verbatim}

The first line is the full path name of the file.  A grid's \widvar{name}, 
\widvar{center}, \widvar{dX}, and \widvar{dY} are separated by ``;'' in the 
second line.

\subsubsection{Grid}
A hashtable \jvar{GridList} is used to store the grids of a picture file. It 
is defined as following. 
\begin{verbatim}
GridList ::= Hashtable(GridName, GridDef);
GridName ::= String;
GridDef ::= (Center, dX, dY);
Center ::= pic expression;
dX ::= pic expression;
dY ::= pic expression
\end{verbatim}
The name of the grid is the key of the hashtable. A \verb+pic expression+ is a 
piece of \program{pic} source code specifying a distance.

When \method{activateGrid()} is called, it searches for the contents of 
\jvar{GridName} in the \jvar{GridList}, then calls 
\class{EditWindow}.\method{renewLooking()}. 
\class{EditWindow}.\method{renewLooking()} sends the grid determinants 
together with the IR to compile and calls \class{MyCanvas} to repaint. 
\class{MyCanvas}.\method{paint()} calls \class{Compiler}.\method{getGrid()} to 
get the grid values from the \jvar{VarSet} list and draws the grid lines. 
Refer to Section 2.4.1.

\subsubsection{Gravity}
The following is the pseudocode of the algorithm in the key method 
\method{gravitateTo()} in \class{Gravity}:
\begin{enumerate}
\item If gravity is off, return the pair of real numbers as the indicated 
point. 

\item If gravitating-to-\program{pic}-corner is selected, 
\method{gravitateTo(\jvar{p})} does the following :\\
\code{minDis =} \(\infty\) ; \\
\code{q = p;} \\
\code{for each object o in the object list do} \\
\{ \\
\hspace*{.3in}\code{for each corner c of o do} \\
\hspace*{.3in}	 \{ \\
\hspace*{.6in}	\code{dis = p.distance(c);} \\ 
\hspace*{.6in}	\code{if dis \textless\ minDis} \\
\hspace*{.6in}		\{ \\
\hspace*{.9in}		\code{q = c;} \\
\hspace*{.9in}		\code{minDis = dis;}\\
\hspace*{.6in}		\} \\
\hspace*{.3in} \} \verb+/* end of loop for corner c */+ \\
\hspace*{.3in} \code{if p.distance(c)} \textgreater\ \code{gravity tightness 
radius} \\
\hspace*{.6in}\code{return p} \\
\hspace*{.3in}\code{else return q} \\
\} \verb+/* end of loop for object o */+

\item If gravitating-to-grid-point is selected, the point \jvar{p} that 
the user LMCed on the canvas must be located in some grid cell, as illustrated in 
Figure~\ref{fig:gravitateto}~\footnote{Figure~\ref{fig:gravitateto} was not 
produced by \program{WD-pic}, because it shows grid lines, whose 
specifications are not stored in the IR. Instead, the figure is a portion of a 
screen snapshot.}. 

\begin{figure}
\begin{center}
\scalebox{0.8}[0.8]{\includegraphics{gravitateto.eps}}
\end{center}
\caption{gravitate to}\label{fig:gravitateto}
\end{figure}

To figure out the values of \jvar{m} and \jvar{n}, we get the following 
inequalities from Figure~\ref{fig:gravitateto}, 

\[ \left\{ \begin{array}{ll}
           x_{0} + \cmath{n}*dx \leq x_{\cmath{p}} < x_{0} + (\cmath{n}+1) * 
dx \\
           y_{0} + \cmath{m}*dy \leq y_{\cmath{p}} < y_{0} + (\cmath{m}+1) * dy
          \end{array}
   \right. \]

\jvar{p} \( ( x_{\cmath{p}}, y_{\cmath{p}} ) \) is the point that the user 
LMCed on the canvas. \( ( x_{0}, y_{0} ) \) is the center of the grid. The 
other two determinants of the grid are \jvar{dx} and \jvar{dy}. 

Therefore, we can get the following formula:
\[ \left\{ \begin{array}{ll}
           \cmath{n} = \lfloor \frac{x_{\cmath{p}} - x_{0}}{dx} \rfloor \\
           \cmath{m} = \lfloor \frac{y_{\cmath{p}} - y_{0}}{dy} \rfloor
          \end{array}
   \right. \]

The four corners of the grid cell, in which \( ( x_{\cmath{p}}, y_{\cmath{p}} 
) \) is located, are the closest grid points to \jvar{p}. Their coordinates 
are: \\
\( (x_{0} + \cmath{n}*dx, y_{0} + \cmath{m}*dy) \), \hspace{.5in} \((x_{0} + 
\cmath{n}*dx, y_{0} + (\cmath{m}+1)*dy)\) \\   
\( (x_{0} + (\cmath{n}+1)*dx, y_{0} + \cmath{m}*dy) \), \hspace{.1in} \((x_{0} 
+ (\cmath{n}+1)*dx, y_{0} + (\cmath{m}+*dy)\)

The distances from \( ( x_{\cmath{p}}, y_{\cmath{p}} ) \) to the four points 
are calculated. The closest point is chosen. If the distance from \jvar{p} to 
the closest grid point is greater than the gravity tightness radius, then 
\jvar{p} is returned as the indicated point. Otherwise the expression of the 
grid point is returned.

The returned grid point expression is optimized to appear more like what a 
human being would write. For example, it is more natural for a human to write 
the expression \( x_{0} + 1 * dx \) as \( x_{0} + dx \).  

\item If both gravitating-to-\program{pic}-corner and 
gravitating-to-grid-point are selected, choose the closer \program{pic} corner 
or grid point. 

\end{enumerate}

\subsubsection{Adjusting the position of text}
By default, the alignment attribute of text in \program{pic} is 
\token{center}. This attribute can be changed to \token{above} or 
\token{below} vertically or \token{ljust} or \token{rjust} horizontally. 
\token{center} means the text is centered at the geometric center of the 
object with which it is associated. The attribute \token{ljust} causes the 
left end of the text to be at the specified point, and \token{rjust} causes 
the right end of the text to be at the specified point. \token{above} and 
\token{below} cause the text to be centered one half line space in the given 
direction.

There are several horizontal lines indicating the position of a text item, 
as illustrated in Figure~\ref{fig:text}~\footnote{Figure~\ref{fig:text} 
was produced from a screen clump rather than by \program{WD-pic}, because it 
involves graphics not specified in the IR.}. 
\begin{figure}
\begin{center}
\scalebox{.8}[.8]{\includegraphics{text.eps}}
\end{center}
\caption{Adjust text position}\label{fig:text}
\end{figure}

In \program{Java}, the position of a text item is indicated by its base line. 
If the text attribute is \token{center}, \( y_{c} \) is given by 
\program{pic}. To draw a text item whose center line is at \space\( y_{c} \), 
the following formula is used to calculate the base line y (All the 
calculations in this section are in the screen coordinates.):
\[ y = y_{c} + ( \frac{TextHeight}{2} - dsc ) 
     = y_{c} + ( \frac{asc + dsc}{2} - dsc ) 
     = y_{c} + \frac{asc - dsc}{2} \] 
If the text attribute is \token{above}, \space\( y_{b} \) is given. To draw a 
text item whose bottom line is at \space\( y_{b} \), \[ y = y_{b} - dsc \;. 
\]
If the text attribute is \token{below}, \space\( y_{t} \) is given. To draw a 
text item whose base line is at \space\( y_{b} \), \[ y = y_{t} + asc \;. 
\]

The value of \jvar{asc} and \jvar{dsc} are given by a \program{Java} standard 
API. \space\( y_{c}, \; y_{b}, \; y_{t} \) are as shown in 
Figure~\ref{fig:text}.

The horizontal attributes \token{center}, \token{ljust}, and \token{rjust} are 
similar. The \program{Java} default is \token{ljust}. Instead of using 
\jvar{asc} and \jvar{dsc}, we calculate the width of the text layout. To draw 
a text item whose center is at \space\( x_{c} \), 
\[ x = x_{c} - wid/2 \;. \]

To draw an \token{rjust} text item, 
\[ x = x_{c} - wid \;. \]  

\subsubsection{Font}
A vector is used to store the font information of a picture file. The 
structure is defined as follows.
\begin{verbatim}
FontList ::= vector of FontElement
FontElement ::= (Font, from, to)
Font ::= (font, style, size)
from ::= document position
to ::= document position
\end{verbatim}

\jvar{FontElement} is implemented as \class{PICFontString}. The 
\jvar{from} and \jvar{to} record the positions where this font setting 
starts and ends. 
Figure~\ref{fig:fontstring1}~\footnote{Figure~\ref{fig:fontstring1} was 
produced from a screen clump rather than by \program{WD-pic}, because it 
involves graphics not specified in the IR.} illustrates a sample picture on 
the canvas. Letter ``e'' is set to font Arial Bold, size 18. Letter ``o'' is 
set to Font Courier Oblique, size 24. ``World'' is set to Times Italic, size 
10. The rest text is in default font, default size. The related data 
structures of this picture are shown in Figure~\ref{fig:fontstring2}.

\begin{figure}
\begin{center}
\includegraphics{fontstring1.eps}
\end{center}
\caption{A sample of font setting}\label{fig:fontstring1}

\begin{center}
\scalebox{0.8}[0.8]{\includegraphics{fontstring2.ps}}
\end{center}
\caption{Font related data structure}\label{fig:fontstring2}
\end{figure}

Every time there is a change in the IR, the positions of the text items 
change. Therefore, the \jvar{FontList} needs to be updated.  

\subsection{Miscellaneous implementation details}
\subsubsection{Run external editor}
Because \program{Java}\ \class{Runtime} cannot run a non-windowed application, 
\eg\ \program{pico}, and \program{vi}, from a GUI program, the  approach for 
\method{runExtEditor()} depends on the underlying operating system. If the 
current operating system is \program{Windows}, \program{Java} 
\class{Runtime}.\method{exec(\jvar{editor})} is called to run the external 
editor \jvar{editor}. If the current operating system is \program{Unix}, 
\program{Java JNI} is used to run the external editor code in \program{C}, 
which is built into a library file. The \program{Unix} system calls 
\method{fork()} and \method{exec()} are used~\cite{unixprog2:book, 
unixprog1:book}.

When \method{runExtEditor()} method is called, it first creates a temporary 
file \mvar{file} in the system's default temporary folder. Then it calls 
\class{EditWindow}.\method{exportIR(\mvar{file})} to copy the current complete 
IR to the temporary file \mvar{file}. It then calls \method{exec} to run the 
external editor with the temporary file as the to-be-edited file. After the 
external editor finishes, it calls 
\class{EditWindow}.\method{importIR(\mvar{file})} to copy the contents of the 
temporary file back to the edit window as the IR.

\subsubsection{Edit window renewlooking}
\method{renewLooking()} is a very important method in \class{EditWindow}. It 
executes in the following steps:
\begin{enumerate}
\item get the active grid, 
\item send the IR and grid values to compile,
\item update the font list, 
\item inform \class{MyCanvas} to adjust ,
\item set the text in the EW to one of the three different attributes: normal, 
erroneous, and selected,
\item get the position of the CIP and call \method{isAtObjectPhrase()} to 
determine in which kind of object the CIP is, 
\item update the attribute area by showing different attribute panes for 
different objects. 
\end{enumerate}

The syntax error checking is implemented based on the result of compiling IR. 
The compiler compiles IR phrase by phrase, and returns a correct IR with error 
phrases set to white spaces. The original IR is gotten directly from the edit 
window, and is stored in the variable \jvar{ir0}. 
\class{Compiler}.\method{compile()} returns a syntax-error-free IR and stores 
it in the variable \jvar{ir}. The differences between the \jvar{ir0} and 
\jvar{ir} are marked as syntax errors. 

\subsubsection{Canvas repaint}
\method{paint()} is an  important method in \class{MyCanvas}. It first calls 
\method{drawGrid()} to draw the grid. \method{drawGrid()} checks whether there 
is an active grid. It then gets the grid values by calling 
\method{Compiler.getGrid()} with CIP as a parameter and draws the grid. Next, 
\method{paint()} calls \method{PICObject.draw()} to draw different objects. 
Finally, \method{paint()} calls \method{drawSelected()} to draw the selected 
objects, and \method{drawCIP()} to draw the CIP on the canvas.
 
\section{Evaluation}
\markright{Evaluation}
\program{pic} is targeted to draw diagrams in computer science documents. As 
an enhancement of \program{pic}, \program{WD-pic} certainly does better than 
\program{pic}. 
The author used \program{WD-pic} to draw all the diagrams in this thesis 
except those containing screen shots. The \program{pic} code of the figures 
are listed in the appendix. The author did not know too much about 
\program{pic} grammar. But she found out that \program{WD-pic} was very easy 
to use without too much knowledge of \program{pic}. The token buttons and the 
attribute buttons on the palette are very straightforward. Furthermore, the 
internal representation of the diagrams are very similar to what a human would 
write.


Shpilberg did a comparison between \program{WD-pic} and \program{xfig} 
in~\cite{fs:wdpic}. It shows that \program{WD-pic} is more comfortable to use 
to draw simple flow diagrams, because by default \program{pic} produces chains 
of drawing elements with default sizes and positions. Furthermore, once a flow 
diagram is drawn, it is straightforward to edit it. On the other hand, 
\program{WD-pic} is more limited than \program{xfig} in drawing complex 
non-regular pictures. \program{WD-pic}'s set of primitive elements is poorer. 
It doesn't have the full set of element manipulations that \program{xfig} has.

Compared to \program{dotty}, which was mentioned in Section 1.1.3, 
\program{WD-pic} seems more user friendly to this author. One has to know 
the \program{dot} language well in order to draw a desired picture. On the 
other hand, one needs to know \program{pic} to use \program{WD-pic}. However, it 
appears to this author that one needs to know less \program{pic} to 
effectively 
use \program{WD-pic} than he or she needs to know \program{dot} to effectively 
use \program{dotty}. However, \program{dotty} does a better job than 
\program{WD-pic} on the layout of hierarchical diagrams.

Besides the limitations of \program{pic}, the current version of 
\program{WD-pic} has the following shortcomings:
\begin{enumerate}
\item One cannot change the sizes of objects by direct mouse manipulations, 
but he or she can change the sizes of objects in the edit window.

\item One cannot change the locations of objects by direct mouse 
manipulations, but he or she can change the locations of objects in the edit 
window.

\item \usecase{Copy}, \usecase{paste}, \usecase{cut}, \usecase{undo},  and 
\usecase{redo} do not work with the canvas, but they work with the edit 
window. 
\item One cannot do \usecase{search} and \usecase{replace} in the edit window, 
but he or she can do \usecase{search} and \usecase{replace} in an external 
editor.

\item Font information of the text is not saved, because \program{pic} does 
not have this feature. 

\item One cannot directly manipulate constructs, \eg\ \token{for}, \token{if}, 
and block, on the canvas, but he or she can manipulate them in the edit window.

\item One cannot output pictures in a standard graph format, \eg\ 
\program{gif} and \program{png}, or print from \program{WD-pic}, but he or she 
can submit the saved IR to \program{pic | troff} to get output.
  
\end{enumerate}

\subsection{Evaluation of \program{WD-pic} relative to the pros and cons of 
batch and of WYSIWYG}
\program{WD-pic} fixes the disadvantages of WYSIWYG picture drawing program 
that were mentioned in Section 1.1.1:

\begin{itemize}
\item Changing one object in the picture does not destroy the entire picture, 
because the layout is done by \program{pic}.  

\item It is easy to manipulate the objects of a category as a group. For 
example, the user can use an external editor to search for all occurrences 
of ``box" in the IR and replace them with ``circle".  
\end{itemize}

\program{WD-pic} also fixes the disadvantages of the batch programs that were 
mentioned in Section 1.1.1:
\begin{itemize}
\item The user can see the picture while composing its description.
\item Instant feedback on the canvas reduces the errors.
\end{itemize}

\subsection{Future work}
\program{WD-pic} has met all the requirements of the customer, the author's 
advisor. However, it still has certain shortcomings. Some of them are easy to 
eliminate. Some are difficult, given the current implementation of 
\program{WD-pic}. 

More direct manipulations to the objects on the canvas can be added to the 
program, such as \usecase{copy}, \usecase{past}, \usecase{cut}, changing sizes 
and locations. They are not very difficult to implement based on the current 
implementation of \program{WD-pic}, since we can track the objects on the 
canvas and their related positions in the IR.

\usecase{Search} and \usecase{replace} are not difficult to add to the 
built-in text editor in the edit window. This would be a nice feature for 
\program{WD-pic} to have.

\program{pic} does nothing on font settings. There is no font information in 
the internal representation of a picture. Because in different systems, the 
same font could have different names, saving font information in 
\program{WD-pic} is difficult. Directly manipulating the conditional and 
loop 
constructs is difficult too, because a construct can be nested in another 
construct. To output pictures in standard formats such as \program{.ps} and  
\program{.jpg} requires good knowledge of these formats. These are the 
challenging features to implement.


