summaryrefslogtreecommitdiff
path: root/graphics/gapfill
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 /graphics/gapfill
Initial commit
Diffstat (limited to 'graphics/gapfill')
-rw-r--r--graphics/gapfill/GaPDoc1.pdfbin0 -> 339840 bytes
-rw-r--r--graphics/gapfill/GaPDoc1.tex1632
-rw-r--r--graphics/gapfill/GaPDoc2.pdfbin0 -> 148778 bytes
-rw-r--r--graphics/gapfill/GaPDoc2.tex514
-rwxr-xr-xgraphics/gapfill/Mac_OS_only/CABebez.pl935
-rwxr-xr-xgraphics/gapfill/Mac_OS_only/CABpict.pl958
-rw-r--r--graphics/gapfill/README105
-rwxr-xr-xgraphics/gapfill/Various_OSs/OOopict.pl918
8 files changed, 5062 insertions, 0 deletions
diff --git a/graphics/gapfill/GaPDoc1.pdf b/graphics/gapfill/GaPDoc1.pdf
new file mode 100644
index 0000000000..df42a922d0
--- /dev/null
+++ b/graphics/gapfill/GaPDoc1.pdf
Binary files differ
diff --git a/graphics/gapfill/GaPDoc1.tex b/graphics/gapfill/GaPDoc1.tex
new file mode 100644
index 0000000000..6215cc90dd
--- /dev/null
+++ b/graphics/gapfill/GaPDoc1.tex
@@ -0,0 +1,1632 @@
+\documentclass[12pt]{amsart}
+\usepackage{amsfonts,a4}
+\usepackage{ebezier}
+\newcommand{\D}{\displaystyle}
+\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+\setlength{\headsep}{25pt}
+\setlength{\parskip}{1.5ex plus0.5ex minus0.5ex}
+\setlength{\parindent}{0em}
+\pagestyle{myheadings}
+
+\begin{document}
+\markboth{ \;\; \hrulefill \: Herbert M\"oller
+\,\hrulefill}
+{\hrulefill \; How to Generate \LaTeX{} Picture Environments
+Using the GaPFilL Method
+\,\hrulefill \;\quad }
+
+\vspace*{-15mm}
+\begin{center}
+\Large{\textbf{How to Generate \LaTeX{} Picture Environments
+Using the GaPFilL Method}}\\[7mm]
+\large{Herbert M\"oller\footnote[1]{\mbox{\rule[0mm]{0mm}{5mm}}\copyright{}
+Copyright 2006 by H. M\"oller
+(\texttt{mollerh@math.uni-muenster.de}). This documentation may be
+distributed and/or modified under the conditions of the LaTeX Project
+Public License.}}\\[7mm]
+\end{center}
+
+\begin{quote}
+ {\small
+\textsc{Abstract.} Drawing programs or geometry software and Perl
+filter programs are used to create conveniently even complicated
+figures with the \LaTeX{} \texttt{picture} environment. The filter
+programs parse PostScript files and generate \LaTeX\ code ready for
+use. The new method will be explained with two filter programs for
+the geometry software Cabri-g\'{e}om\`{e}tre$^{\mathrm{TM}}$ II. The
+first program only requires the package \texttt{ebezier} \cite{Ba}.
+Therefore the output is driver independent. The second filter in
+addition supplies the new package \texttt{pict2e} \cite{GaNi}.}
+
+\end{quote}
+
+\section{Introduction}
+
+\setlength{\baselineskip}{17pt}
+The package \texttt{pict2e}, created by \textsc{Hubert
+G\"a}{\ss}\textsc{lein} and \textsc{Rolf Niepraschk}, e\-lim\-inates
+the most serious restrictions of the \LaTeX{} \texttt{picture}
+environment. Henceforth, essentially the problem of positioning the
+objects remains. An important suggestion, using the package
+$\mathrm{P_{\D I}C}$\TeX{} of \textsc{Michael J. Wichura} \cite{Wi},
+was introduced in 1999 by \textsc{Robert W.D. Nickalls} with the
+MS\,DOS filter program `Maths\-PIC' \cite{Ni}. Afterwards, it was
+extended by him and by \textsc{Apostolos Syropoulos} to a Perl filter
+program \cite{NiSy}. However, the convenient input achieved is on the
+expence of about 90 further commands.
+
+Hence the question arose whether \LaTeX{} figures can also be
+constructed without using control commands. This seemed to be
+feasible because the PostScript files generated by graphic programs
+and used by the \LaTeX{} command \verb|\special| evidently contain
+all necessary information. The answer is a method which consists of
+four steps:
+
+\begin{enumerate}
+ \item Generating the desired figure with a drawing program or with
+ geometry software;
+
+ \item ``Printing'' (or exporting) the construction as a
+ PostScript file;
+
+ \item Applying a filter program to the PostScript text;
+
+ \item Copying the resulting code or parts of it into a \LaTeX{}
+ document.
+\end{enumerate}
+
+Because of this structure, the method is called ``GaPFilL''
+(\emph{Graphics as PostScript Filtered for \LaTeX}). Since the steps
+(1) and (2) and the packages used in the \LaTeX{} document may vary,
+it is necessary to apply different filter programs. In the following
+the context will be described as an example by means of two
+prototypes: \texttt{CABebez.pl} only requires the macro package
+\texttt{ebezier}; \texttt{CABpict.pl} in addition uses the above
+mentioned package \texttt{pict2e}.
+
+\section{The Drawing Program or Geometry Software}
+
+Most programs which generate graphical objects are suited for the
+GaPFilL meth\-od. To create diagrams and simple illustrations, it is
+sufficient to use draw\-ing programs belonging to office packages. The
+fine drawing program \texttt{Draw} of \texttt{OpenOffice.org} is even
+free of charge. For the representation of geometrical facts, geometry
+software is preferable since, apart from the construction of the objects,
+it offers a lot of transformations and combinations such as
+reflection, bisection of angles, transfer of measurement and
+generation of loci.
+
+In the educational system, Cabri-g\'{e}om\`{e}tre$^{\mathrm{TM}}$ II
+(in the following: Cabri Geometry) is a powerful ``dynamic''
+geometry software with wide distribution for the operating systems
+Windows$^{\D \circledR}$ and Mac$^{\D \circledR}$OS. Since 1987 it was
+developed by \textsc{Jean-Marie Laborde} and \textsc{Franck Bellemain}
+at the `Institut d'Informa\-tique et Math\'{e}matiques Appliqu\'{e}es'
+of the Joseph Fourier University in Grenoble. Among other things, due
+to numerous courses of further education for teachers and due to the
+implementation of adapted versions in the hand-held computers TI-92,
+Voyage$^{\mathrm{TM}}$ 200 and other calculators of Texas
+Instruments$^{\D \circledR}$ it is widely used.
+
+Since many people are familiar with these programs, we
+will only describe the pecularities which are important for the
+generation of \LaTeX{} figures. In 2004, improved versions
+Cabri-g\'{e}om\`{e}tre$^{\mathrm{TM}}$ II plus both for Windows and
+Macintosh computers were published. The differences will be mentioned
+where appropriate.
+
+\section{The Use of Colours}
+
+With the aid of colours additional information is conveyed to the
+filter program. Colouring of objects in the \LaTeX{} \texttt{picture}
+environment objects is carried out on demand with commands of the
+\texttt{color} package when the work is to be finished (see Section
+8). The names of the colours used in the following come from the
+Macintosh version of Cabri Geometry, where only eleven colours are
+available. The Mac\,OS version of Cabri Geometry II plus has a
+palette with 36 colours. In both new versions the RGB values of
+colours may be set by the user. In Section 7 it will be described how
+to change the assignment of colours in the filter program. \\[-8mm]
+
+\begin{list}{$\bullet$}{
+ \setlength{\labelwidth}{3mm}
+ \setlength{\leftmargin}{7mm}
+ }
+ \item All \emph{straight lines, rays, line segments, circles and
+ conic sections} which are coloured \fbox{yellow} serve as
+ \emph{drawing aids} because they are ignored by the filter program.
+ The red points shown by Cabri Geometry will be disregarded by the
+ filter program too. Straight lines, rays, parabolas and hyperbolas
+ are cut off at the boundary of the drawing section. Since the filter
+ program calculates the exact ``bounding box'', these figures should
+ only be used as drawing aid if the resulting shape is not the
+ desired one.\vspace{1mm}
+
+ \item \emph{Continuous lines and polygons} have to be
+ \fbox{green}.\vspace{1mm}
+
+ \item \emph{Arrows} must be drawn in \fbox{violet}.\vspace{1mm}
+
+ \item \emph{Dotted objects (line segments, arrow lines, polygons,
+ circles, arcs)} are obtained by using the colour \fbox{dark green}.
+ \vspace{1mm}
+
+ \item \emph{Quadratic} and \emph{cubic B\'ezier curves} are entered as
+ \fbox{blue} polygons with three respectively four corners (see Figures
+ 1 and 2). The corresponding curves may be viewed with Cabri Geometry
+ by using macros. This will be explained in Section 4.
+
+%Figures 1 and 2
+\begin{figure}[tbh]
+ \setlength{\unitlength}{1pt}
+ \begin{minipage}[b]{8.0cm}
+ \setlength{\unitlength}{1pt}
+\begin{picture}(147,84)(-19,19)
+\linethickness{0.8pt}
+\thicklines
+%Lines, polygons and Bˇzier curves
+%Dotted line
+\linethickness{1.2pt}
+\Lbezier[23](71.811024,96.377953)(30.236220,30.23622)
+\Lbezier[42](30.236220,30.23622)(168.188976,54.80315)
+\Lbezier[31](168.188976,54.80315)(71.811024,96.377953)
+%Quadratic Bˇzier curve
+\Qbezier[279](71.811024,96.377953)(30.236220,30.23622)(168.188976,54.80315)
+\put(60.968504,93.543307){1}
+\put(21.566929,29.84252){2}
+\put(163.905512,44.464567){3}
+\put(77,18){Figure 1}
+\end{picture}
+ \end{minipage}\hfill
+\raisebox{6mm}{
+\begin{minipage}[b]{5.0cm}
+\begin{picture}(138,68)(33,14)
+\linethickness{0.8pt}
+\thicklines
+%Lines, polygons and Bˇzier curves
+%Dotted line
+\linethickness{1.2pt}
+\Lbezier[37](28.346457,16.062992)(152.125984,14.173228)
+\Lbezier[30](152.125984,14.173228)(59.527559,55.748031)
+\Lbezier[25](59.527559,55.748031)(139.842520,81.259843)
+\Lbezier[38](139.842520,81.259843)(28.346457,16.062992)
+%Cubic Bˇzier curve
+\cbezier[280](28.346457,16.062992)(152.125984,14.173228)(59.527559,55.748031)(139.842520,81.259843)
+\put(23.622047,20.566929){1}
+\put(150.236220,18.732283){2}
+\put(50.078740,53.188976){3}
+\put(137.952756,70.866142){4}
+\put(69,-4){Figure 2}
+\end{picture}
+ \end{minipage}}
+ \end{figure}
+
+ \item \emph{Polygons} have to be \emph{closed} by clicking on the
+ starting point or by double clicking. Using the colour \fbox{navy
+ blue}, the last line of the polygon will be suppressed so that
+ \emph{open polygons} can also be entered conveniently.\vspace{1mm}
+
+ \item \emph{Text or formula places} are positioned by using \fbox{blue}
+ polygons with two corners. For the bounding box to be calculated
+ correctly, the marking line should approximately be the diagonal
+ beginning at the lower left corner of the smallest rectangle
+ enclosing the text or formula. In the \LaTeX{} output a serial
+ number will be written at the position of the starting point.\vspace{1mm}
+
+ \item The remaining five colours are used for the \emph{filling,
+ hatching and dotting} of areas bordered by \emph{polygons.} For that
+ the filter program cuts up the polygon area into triangles which have
+ the starting point of the polygon as a common corner. To avoid
+ overlap, the given area must be devided by polygons such that for
+ each polygon the triangles which arise from connecting the starting
+ point with the other corners have at most one side in common with
+ the other triangles (see Figures 3 and 4).\\[-7mm]
+
+%Figures 3 and 4
+\begin{figure}[tbh]
+ \setlength{\unitlength}{1pt}
+ \begin{minipage}[b]{8.0cm}
+ \setlength{\unitlength}{1pt}
+\begin{picture}(110,95)(-38,12)
+\linethickness{0.8pt}
+\thicklines
+%Lines, polygons and Bˇzier curves
+\Lbezier[153](37.795276,19.84252)(25.511811,95.433071)
+\Lbezier[80](25.511811,95.433071)(51.023622,64.251969)
+\Lbezier[112](51.023622,64.251969)(86.929134,107.716535)
+\Lbezier[94](86.929134,107.716535)(76.535433,61.417323)
+\put(76.535433,61.417323){\line(4,-1){60.472441}}
+\Lbezier[205](137.007874,46.299213)(37.795276,19.84252)
+%Dotted line
+\linethickness{1.2pt}
+\Lbezier[13](37.795276,19.84252)(51.023622,64.251969)
+\Lbezier[30](37.795276,19.84252)(86.929134,107.716535)
+\Lbezier[17](37.795276,19.84252)(76.535433,61.417323)
+\put(27.732283,16.897638){A}
+\put(22.007874,98.212598){B}
+\put(37.795276,59.582677){C}
+\put(89.598425,104.992126){D}
+\put(80.761464,63.360815){E}
+\put(135.503937,34.795276){F}
+\put(60,1){Figure 3}
+\end{picture}
+ \end{minipage}\hfill
+\raisebox{2mm}{
+\begin{minipage}[b]{5.0cm}
+\begin{picture}(150,102)(21,9)
+\linethickness{0.8pt}
+\thicklines
+%Lines, polygons and Bˇzier curves
+\Lbezier[128](64.251969,108.661417)(116.372861,70.793372)
+\Lbezier[128](116.372861,70.793372)(96.464452,9.521588)
+\put(96.464452,9.521588){\line(-1,0){64.424967}}
+\Lbezier[128](32.039485,9.521588)(12.131076,70.793372)
+\Lbezier[128](12.131076,70.793372)(64.251969,108.661417)
+\Lbezier[49](51.817323,66.028346)(76.422047,66.292913)
+\Lbezier[49](76.422047,66.292913)(76.686614,41.688189)
+\Lbezier[49](76.686614,41.688189)(52.081890,41.423622)
+\Lbezier[49](52.081890,41.423622)(51.817323,66.028346)
+%Dotted line
+\linethickness{1.2pt}
+\Lbezier[14](12.131076,70.793372)(51.817323,66.028346)
+\Lbezier[17](12.131076,70.793372)(52.081890,41.423622)
+\Lbezier[14](32.039485,9.521588)(52.081890,41.423622)
+\Lbezier[14](76.686614,41.688189)(96.464452,9.521588)
+\Lbezier[16](51.817323,66.028346)(64.251969,108.661417)
+\Lbezier[16](64.251969,108.661417)(76.422047,66.292913)
+\Lbezier[15](76.422047,66.292913)(116.372861,70.793372)
+\Lbezier[17](116.372861,70.793372)(76.686614,41.688189)
+%Dotted triangle
+\linethickness{0.8pt}
+\multiput(36,68)(4,0){5}{\line(1,0){0.8}}
+\multiput(22,70)(4,0){8}{\line(1,0){0.8}}
+\multiput(16,72)(4,0){10}{\line(1,0){0.8}}
+\multiput(18,74)(4,0){10}{\line(1,0){0.8}}
+\multiput(20,76)(4,0){9}{\line(1,0){0.8}}
+\multiput(26,78)(4,0){8}{\line(1,0){0.8}}
+\multiput(28,80)(4,0){7}{\line(1,0){0.8}}
+\multiput(30,82)(4,0){7}{\line(1,0){0.8}}
+\multiput(32,84)(4,0){7}{\line(1,0){0.8}}
+\multiput(34,86)(4,0){6}{\line(1,0){0.8}}
+\multiput(36,88)(4,0){6}{\line(1,0){0.8}}
+\multiput(42,90)(4,0){5}{\line(1,0){0.8}}
+\multiput(44,92)(4,0){4}{\line(1,0){0.8}}
+\multiput(46,94)(4,0){4}{\line(1,0){0.8}}
+\multiput(48,96)(4,0){4}{\line(1,0){0.8}}
+\multiput(50,98)(4,0){3}{\line(1,0){0.8}}
+\multiput(56,100)(4,0){2}{\line(1,0){0.8}}
+\multiput(58,102)(4,0){2}{\line(1,0){0.8}}
+\multiput(60,104)(4,0){1}{\line(1,0){0.8}}
+\multiput(62,106)(4,0){1}{\line(1,0){0.8}}
+\multiput(64,108)(4,0){1}{\line(1,0){0.8}}
+%Dotted triangle
+\multiput(54,42)(4,0){0}{\line(1,0){0.8}}
+\multiput(52,44)(4,0){1}{\line(1,0){0.8}}
+\multiput(46,46)(4,0){2}{\line(1,0){0.8}}
+\multiput(44,48)(4,0){3}{\line(1,0){0.8}}
+\multiput(42,50)(4,0){3}{\line(1,0){0.8}}
+\multiput(40,52)(4,0){3}{\line(1,0){0.8}}
+\multiput(38,54)(4,0){4}{\line(1,0){0.8}}
+\multiput(36,56)(4,0){4}{\line(1,0){0.8}}
+\multiput(30,58)(4,0){6}{\line(1,0){0.8}}
+\multiput(28,60)(4,0){6}{\line(1,0){0.8}}
+\multiput(26,62)(4,0){7}{\line(1,0){0.8}}
+\multiput(24,64)(4,0){7}{\line(1,0){0.8}}
+\multiput(22,66)(4,0){8}{\line(1,0){0.8}}
+\multiput(16,68)(4,0){5}{\line(1,0){0.8}}
+\multiput(14,70)(4,0){2}{\line(1,0){0.8}}
+%Dotted triangle
+\multiput(34,10)(4,0){0}{\line(1,0){0.8}}
+\multiput(32,12)(4,0){1}{\line(1,0){0.8}}
+\multiput(34,14)(4,0){1}{\line(1,0){0.8}}
+\multiput(32,16)(4,0){2}{\line(1,0){0.8}}
+\multiput(30,18)(4,0){2}{\line(1,0){0.8}}
+\multiput(32,20)(4,0){2}{\line(1,0){0.8}}
+\multiput(30,22)(4,0){3}{\line(1,0){0.8}}
+\multiput(28,24)(4,0){4}{\line(1,0){0.8}}
+\multiput(30,26)(4,0){4}{\line(1,0){0.8}}
+\multiput(28,28)(4,0){4}{\line(1,0){0.8}}
+\multiput(26,30)(4,0){5}{\line(1,0){0.8}}
+\multiput(28,32)(4,0){5}{\line(1,0){0.8}}
+\multiput(26,34)(4,0){6}{\line(1,0){0.8}}
+\multiput(24,36)(4,0){7}{\line(1,0){0.8}}
+\multiput(26,38)(4,0){6}{\line(1,0){0.8}}
+\multiput(24,40)(4,0){7}{\line(1,0){0.8}}
+\multiput(22,42)(4,0){8}{\line(1,0){0.8}}
+\multiput(24,44)(4,0){7}{\line(1,0){0.8}}
+\multiput(22,46)(4,0){6}{\line(1,0){0.8}}
+\multiput(20,48)(4,0){6}{\line(1,0){0.8}}
+\multiput(22,50)(4,0){5}{\line(1,0){0.8}}
+\multiput(20,52)(4,0){5}{\line(1,0){0.8}}
+\multiput(18,54)(4,0){5}{\line(1,0){0.8}}
+\multiput(20,56)(4,0){4}{\line(1,0){0.8}}
+\multiput(18,58)(4,0){3}{\line(1,0){0.8}}
+\multiput(16,60)(4,0){3}{\line(1,0){0.8}}
+\multiput(18,62)(4,0){2}{\line(1,0){0.8}}
+\multiput(16,64)(4,0){2}{\line(1,0){0.8}}
+\multiput(14,66)(4,0){2}{\line(1,0){0.8}}
+\multiput(16,68)(4,0){0}{\line(1,0){0.8}}
+\multiput(14,70)(4,0){0}{\line(1,0){0.8}}
+%Dotted triangle
+\multiput(98,10)(4,0){0}{\line(1,0){0.8}}
+\multiput(96,12)(4,0){1}{\line(1,0){0.8}}
+\multiput(94,14)(4,0){1}{\line(1,0){0.8}}
+\multiput(96,16)(4,0){1}{\line(1,0){0.8}}
+\multiput(94,18)(4,0){2}{\line(1,0){0.8}}
+\multiput(92,20)(4,0){2}{\line(1,0){0.8}}
+\multiput(90,22)(4,0){3}{\line(1,0){0.8}}
+\multiput(88,24)(4,0){4}{\line(1,0){0.8}}
+\multiput(90,26)(4,0){3}{\line(1,0){0.8}}
+\multiput(88,28)(4,0){4}{\line(1,0){0.8}}
+\multiput(86,30)(4,0){5}{\line(1,0){0.8}}
+\multiput(84,32)(4,0){5}{\line(1,0){0.8}}
+\multiput(82,34)(4,0){6}{\line(1,0){0.8}}
+\multiput(84,36)(4,0){6}{\line(1,0){0.8}}
+\multiput(82,38)(4,0){6}{\line(1,0){0.8}}
+\multiput(80,40)(4,0){7}{\line(1,0){0.8}}
+\multiput(78,42)(4,0){8}{\line(1,0){0.8}}
+\multiput(80,44)(4,0){7}{\line(1,0){0.8}}
+\multiput(86,46)(4,0){6}{\line(1,0){0.8}}
+\multiput(88,48)(4,0){6}{\line(1,0){0.8}}
+\multiput(90,50)(4,0){5}{\line(1,0){0.8}}
+\multiput(92,52)(4,0){5}{\line(1,0){0.8}}
+\multiput(94,54)(4,0){5}{\line(1,0){0.8}}
+\multiput(100,56)(4,0){3}{\line(1,0){0.8}}
+\multiput(102,58)(4,0){3}{\line(1,0){0.8}}
+\multiput(104,60)(4,0){3}{\line(1,0){0.8}}
+\multiput(106,62)(4,0){2}{\line(1,0){0.8}}
+\multiput(108,64)(4,0){2}{\line(1,0){0.8}}
+\multiput(110,66)(4,0){2}{\line(1,0){0.8}}
+\multiput(116,68)(4,0){0}{\line(1,0){0.8}}
+\multiput(118,70)(4,0){0}{\line(1,0){0.8}}
+%Dotted triangle
+\multiput(78,42)(4,0){0}{\line(1,0){0.8}}
+\multiput(80,44)(4,0){0}{\line(1,0){0.8}}
+\multiput(78,46)(4,0){2}{\line(1,0){0.8}}
+\multiput(80,48)(4,0){2}{\line(1,0){0.8}}
+\multiput(78,50)(4,0){3}{\line(1,0){0.8}}
+\multiput(80,52)(4,0){3}{\line(1,0){0.8}}
+\multiput(78,54)(4,0){4}{\line(1,0){0.8}}
+\multiput(80,56)(4,0){5}{\line(1,0){0.8}}
+\multiput(78,58)(4,0){6}{\line(1,0){0.8}}
+\multiput(80,60)(4,0){6}{\line(1,0){0.8}}
+\multiput(78,62)(4,0){7}{\line(1,0){0.8}}
+\multiput(80,64)(4,0){7}{\line(1,0){0.8}}
+\multiput(78,66)(4,0){8}{\line(1,0){0.8}}
+\multiput(92,68)(4,0){6}{\line(1,0){0.8}}
+\multiput(110,70)(4,0){2}{\line(1,0){0.8}}
+%Dotted triangle
+\multiput(76,68)(4,0){4}{\line(1,0){0.8}}
+\multiput(78,70)(4,0){8}{\line(1,0){0.8}}
+\multiput(76,72)(4,0){10}{\line(1,0){0.8}}
+\multiput(78,74)(4,0){9}{\line(1,0){0.8}}
+\multiput(76,76)(4,0){9}{\line(1,0){0.8}}
+\multiput(74,78)(4,0){9}{\line(1,0){0.8}}
+\multiput(76,80)(4,0){7}{\line(1,0){0.8}}
+\multiput(74,82)(4,0){7}{\line(1,0){0.8}}
+\multiput(72,84)(4,0){7}{\line(1,0){0.8}}
+\multiput(74,86)(4,0){6}{\line(1,0){0.8}}
+\multiput(72,88)(4,0){6}{\line(1,0){0.8}}
+\multiput(70,90)(4,0){5}{\line(1,0){0.8}}
+\multiput(72,92)(4,0){4}{\line(1,0){0.8}}
+\multiput(70,94)(4,0){4}{\line(1,0){0.8}}
+\multiput(68,96)(4,0){4}{\line(1,0){0.8}}
+\multiput(70,98)(4,0){3}{\line(1,0){0.8}}
+\multiput(68,100)(4,0){3}{\line(1,0){0.8}}
+\multiput(70,102)(4,0){1}{\line(1,0){0.8}}
+\multiput(68,104)(4,0){1}{\line(1,0){0.8}}
+\multiput(66,106)(4,0){1}{\line(1,0){0.8}}
+\multiput(68,108)(4,0){0}{\line(1,0){0.8}}
+%Hatched triangle
+\Lbezier[7](65.2359207037011,105.235920811786)(62.4363140016148,102.4363141097)
+\Lbezier[15](66.1285055587812,102.1285056742)(60.7892551048443,96.7892552202636)
+\Lbezier[22](67.0210904138612,99.0210905366148)(59.1421962080738,91.1421963308273)
+\put(67.9136752689413,95.9136753990291){\line(-1,-1){10.4185379576379}}
+\put(68.8062601240213,92.8062602614434){\line(-1,-1){12.9581817094884}}
+\put(69.6988449791014,89.6988451238577){\line(-1,-1){15.497825461339}}
+\put(70.5914298341814,86.591429986272){\line(-1,-1){18.0374692131895}}
+\put(71.4840146892615,83.4840148486863){\line(-1,-1){17.4316358238517}}
+\put(72.3765995443415,80.3765997111006){\line(-1,-1){14.2807424059155}}
+\put(73.2691843994216,77.2691845735149){\line(-1,-1){11.1298489879793}}
+\Lbezier[22](74.1617692545016,74.1617694359292)(66.1828136844585,66.1828138658861)
+\Lbezier[13](75.0543541095817,71.0543542983436)(70.2262919574748,66.2262921462366)
+\Lbezier[4](75.9469389646618,67.9469391607579)(74.269770230491,66.2697704265871)
+%Hatched triangle
+\Lbezier[10](53.4382060465256,41.438206152038)(49.8144047931543,37.8144048986667)
+\put(57.4816843197205,41.4816844416667){\line(-1,-1){14.4271554953665}}
+\put(61.5251625929154,41.5251627312953){\line(-1,-1){25.2305097373617}}
+\put(65.5686408661102,41.5686410209239){\line(-1,-1){28.2271651916524}}
+\put(69.6121191393051,41.6121193105525){\line(-1,-1){17.9612717829661}}
+\Lbezier[21](73.6555974125,41.6555976001812)(65.9602190382202,33.9602192259014)
+%Hatched triangle
+\Lbezier[10](33.521588,9.52158800460102)(37.3414757050646,13.3414757096656)
+\put(37.521588,9.52158801701857){\line(1,1){14.1292594695494}}
+\put(41.521588,9.52158802943611){\line(1,1){24.4386312340343}}
+\put(45.521588,9.52158804185366){\line(1,1){31.5463756065196}}
+\put(49.521588,9.5215880542712){\line(1,1){29.0693750607577}}
+\put(53.521588,9.52158806668875){\line(1,1){26.5923745149957}}
+\put(57.521588,9.5215880791063){\line(1,1){24.1153739692337}}
+\put(61.521588,9.52158809152384){\line(1,1){21.6383734234717}}
+\put(65.521588,9.52158810394139){\line(1,1){19.1613728777097}}
+\put(69.521588,9.52158811635893){\line(1,1){16.6843723319477}}
+\put(73.521588,9.52158812877648){\line(1,1){14.2073717861858}}
+\put(77.521588,9.52158814119403){\line(1,1){11.7303712404238}}
+\Lbezier[26](81.521588,9.52158815361157)(90.7749586946618,18.7749588482734)
+\Lbezier[19](85.521588,9.52158816602912)(92.2979581488998,16.2979583149289)
+\Lbezier[12](89.521588,9.52158817844666)(93.8209576031378,13.8209577815845)
+\Lbezier[5](93.521588,9.52158819086421)(95.3439570573758,11.3439572482401)
+\put(2.503937,67.19685){1}
+\put(55.692913,55.748031){2}
+\put(120.834646,67.307087){3}
+\put(19.393701,7.559055){4}
+\put(48,-8){Figure 4}
+\end{picture}
+ \end{minipage}}
+ \end{figure}\vspace{2mm}
+
+ \hspace{-4mm}\fbox{Red} \emph{polygons} are \emph{filled} without
+ boundery. For the \emph{hatching with visible boundary lines} the colour
+ \fbox{orange} has to be chosen for the polygon; \emph{without boundary
+ lines} the colour \fbox{brown} will do it. If the polygon is coloured
+ \fbox{purple}, the area will be \emph{dotted with visible boundary lines};
+ with the colour \fbox{violet} an area can be \emph{dotted without boundary
+ lines}. The previous assignments of colours are summarized in the
+ following table.\vspace{3mm}
+
+\begin{center}
+ \begin{tabular}{|c|c|}
+ \hline
+ \rule[-1mm]{0mm}{4.5mm}
+ Type & Colour \\
+ \hline
+ \rule[0mm]{0mm}{4mm}
+ auxiliary line & yellow \\
+ unbroken object & green \\
+ arrow & violet \\
+ dotted object & dark green \\
+ B\'ezier curve or text & blue \\
+ open polygon & navy blue \\
+ filling without border & red \\
+ hatching with border & orange \\
+ hatching without border & brown \\
+ dotting with border & purple \\
+ dotting without border & dark brown \\
+ \hline
+ \end{tabular}\\
+\end{center}\vspace{3mm}
+
+ \item With Cabri Geometry semicircles and quadrants of a circle,
+ which in \LaTeX{} are also connected with the \verb|\oval| command,
+ must be constructed as circular arcs determined by three points on a
+ circle. For those circular arcs which have at their ends radii
+ parallel to the coordinate axes, the input is simplified by using
+ coloured circles. The next table contains the assigned colours. With
+ the Macintosh version of Cabri Geometry, the respective colours of
+ the objects can be preset in the ``standard settings''.
+ \vspace{3mm}
+
+\begin{center}
+ \begin{tabular}{|c|c|}
+ \hline
+ \rule[-1mm]{0mm}{4.5mm}
+ Type & Colour \\
+ \hline
+ \rule[0mm]{0mm}{4mm}
+ auxiliary circle & yellow \\
+ unbroken circle & navy blue \\
+ dotted arc or circle & dark green \\
+ left semicircle & purple \\
+ right semicircle & red \\
+ bottom semicircle & orange \\
+ top semicircle & dark brown \\
+ left bottom quadrant of a circle & blue \\
+ left top quadrant of a circle & green \\
+ right bottom quadrant of a circle & brown \\
+ right top quadrant of a circle & violet \\
+ \hline
+ \end{tabular}
+\end{center}
+\end{list}\vspace{2mm}
+
+\section{Macros for B\'ezier Curves with Cabri Geometry}
+
+In contrast to many drawing programs, Cabri Geometry does not offer
+the tool `B\'ezier curve' which yields a substantial part of the
+efficiency of \LaTeX{} figures. This deficiency can be compensated by
+``loci'' which are generated with the aid of macros described in the
+following.
+
+In the mathematical representation we use vectors instead of the
+spanning points because the geometrical meaning is better known from
+vector geometry than from complex numbers.
+
+If $t$ with $0 \le t \le 1$ is the running parameter, then the
+\emph{quadratic B\'ezier curve} spanned by
+$\vec{x}_{1},\,\vec{x}_{2},\,\vec{x}_{3}$ can be written in the
+following form with the abbreviation $t_{1}:\,=1-t$:
+\[\vec{x}(t)=t_{1}\left(t_{1}\vec{x}_{1}+t\,\vec{x}_{2}\right)+
+t\left(t_{1}\vec{x}_{2}+t\,\vec{x}_{3}\right).\]\\[-5mm]
+Since all three linear combinations belonging to the plus signs have
+the same coefficients $t_{1}$ and $t$, each point of the quadratic
+B\'ezier curve can be obtained by dividing three line segments with
+the same division ratio $t:t_{1}.$ Since
+\[t_{1}\vec{x}_{i}+t\,\vec{x}_{i+1}
+=\vec{x}_{i}+t\left(\vec{x}_{i+1}-\vec{x}_{i}\right),\;i=1,\,2,\]\\[-6mm]
+at first the two ``connecting line segments'' from $\vec{x}_{1}$ to
+$\vec{x}_{2}$ and from $\vec{x}_{2}$ to $\vec{x}_{3}$ are divided with
+ratio $t:t_{1}.$ If
+$\vec{x}\;\!'_{\!i}:\,=t_{1}\vec{x}_{i}+t\,\vec{x}_{i+1},\;i=1,\,2,$
+are the accompanying ``division vectors'', then the division of the
+connecting line segment from $\vec{x}\;\!'_{\!1}$ to
+$\vec{x}\;\!'_{\!2}$ with ratio $t:t_{1}$ yields the vector
+$\vec{x}(t)$ belonging to the parameter $t.$
+
+Correspondingly, the quadratic B\'ezier curve can be constructed as
+locus. After the input of three different points $P_{1},\,P_{2},\,P_{3},$
+the line segment connecting $P_{1}$ and $P_{3}$ is drawn as ``track''
+of the locus, and a point $T$ is placed on it $\:\:$(see Figure 5).\mbox{}
+\vspace{-7.2mm}\\
+
+%Figur 5
+\begin{figure}[tbh]
+ \setlength{\unitlength}{1pt}
+\raisebox{6mm}
+{\begin{minipage}[b]{7.5cm}
+ \setlength{\unitlength}{1pt}
+\begin{picture}(150,84)(0,19)
+\linethickness{0.8pt}
+\thicklines
+%Lines, polygons and Bˇzier curves
+%Dotted line
+\linethickness{1.2pt}
+\Lbezier[42](30.236220,30.23622)(168.188976,54.80315)
+\linethickness{0.8pt}
+\Lbezier[209](168.188976,54.80315)(71.811024,96.377953)
+\Lbezier[144](71.811024,96.377953)(33.429250,35.31604)
+\Lbezier[268](30.236220,30.23622)(162.281911,53.751207)
+\Lbezier[141](44.502084,52.931913)(114.874262,46.886839)
+%Filled triangle
+\linethickness{0.1pt}
+\put(30.3016,30.43622){\line(1,0){0.0603}}
+\put(30.367,30.63622){\line(1,0){0.1206}}
+\put(30.4325,30.83622){\line(1,0){0.1809}}
+\put(30.4979,31.03622){\line(1,0){0.2412}}
+\put(30.5633,31.23622){\line(1,0){0.3015}}
+\put(30.6288,31.43622){\line(1,0){0.3617}}
+\put(30.6942,31.63622){\line(1,0){0.422}}
+\put(30.7596,31.83622){\line(1,0){0.4823}}
+\put(30.8251,32.03622){\line(1,0){0.5426}}
+\put(30.8905,32.23622){\line(1,0){0.6029}}
+\put(30.9559,32.43622){\line(1,0){0.6632}}
+\put(31.0214,32.63622){\line(1,0){0.7234}}
+\put(31.0868,32.83622){\line(1,0){0.7837}}
+\put(31.1522,33.03622){\line(1,0){0.844}}
+\put(31.2177,33.23622){\line(1,0){0.9043}}
+\put(31.2831,33.43622){\line(1,0){0.9646}}
+\put(31.3485,33.63622){\line(1,0){1.0248}}
+\put(31.4139,33.83622){\line(1,0){1.0851}}
+\put(31.4794,34.03622){\line(1,0){1.1454}}
+\put(31.5448,34.23622){\line(1,0){1.2057}}
+\put(31.6102,34.43622){\line(1,0){1.266}}
+\put(31.6757,34.63622){\line(1,0){1.3263}}
+\put(31.7411,34.83622){\line(1,0){1.3865}}
+\put(31.8065,35.03622){\line(1,0){1.4468}}
+\put(31.872,35.23622){\line(1,0){1.5071}}
+\put(31.9374,35.43622){\line(1,0){1.4644}}
+\put(32.0028,35.63622){\line(1,0){1.3534}}
+\put(32.0683,35.83622){\line(1,0){1.2423}}
+\put(32.1337,36.03622){\line(1,0){1.1313}}
+\put(32.1991,36.23622){\line(1,0){1.0203}}
+\put(32.2646,36.43622){\line(1,0){0.9092}}
+\put(32.33,36.63622){\line(1,0){0.7982}}
+\put(32.3954,36.83622){\line(1,0){0.6871}}
+\put(32.4609,37.03622){\line(1,0){0.5761}}
+\put(32.5263,37.23622){\line(1,0){0.465}}
+\put(32.5917,37.43622){\line(1,0){0.354}}
+\put(32.6572,37.63622){\line(1,0){0.2429}}
+\put(32.7226,37.83622){\line(1,0){0.1319}}
+\put(32.788,38.03622){\line(1,0){0.0208}}
+\linethickness{0.8pt}
+%Filled triangle
+\linethickness{0.1pt}
+\put(30.4447,30.43622){\line(-1,0){0.0828}}
+\put(30.6532,30.63622){\line(-1,0){0.1656}}
+\put(30.8617,30.83622){\line(-1,0){0.2483}}
+\put(31.0702,31.03622){\line(-1,0){0.3311}}
+\put(31.2786,31.23622){\line(-1,0){0.4139}}
+\put(31.4871,31.43622){\line(-1,0){0.4966}}
+\put(31.6956,31.63622){\line(-1,0){0.5794}}
+\put(31.9041,31.83622){\line(-1,0){0.6621}}
+\put(32.1125,32.03622){\line(-1,0){0.7449}}
+\put(32.321,32.23622){\line(-1,0){0.8277}}
+\put(32.5295,32.43622){\line(-1,0){0.9104}}
+\put(32.738,32.63622){\line(-1,0){0.9932}}
+\put(32.9464,32.83622){\line(-1,0){1.0759}}
+\put(33.1549,33.03622){\line(-1,0){1.1587}}
+\put(33.3634,33.23622){\line(-1,0){1.2415}}
+\put(33.5719,33.43622){\line(-1,0){1.3242}}
+\put(33.7803,33.63622){\line(-1,0){1.407}}
+\put(33.9888,33.83622){\line(-1,0){1.4897}}
+\put(34.1973,34.03622){\line(-1,0){1.5725}}
+\put(34.4058,34.23622){\line(-1,0){1.6553}}
+\put(34.6142,34.43622){\line(-1,0){1.738}}
+\put(34.8227,34.63622){\line(-1,0){1.8208}}
+\put(35.0312,34.83622){\line(-1,0){1.9035}}
+\put(35.2397,35.03622){\line(-1,0){1.9863}}
+\put(35.4481,35.23622){\line(-1,0){2.0691}}
+\put(35.6566,35.43622){\line(-1,0){1.7004}}
+\put(35.8651,35.63622){\line(-1,0){1.032}}
+\put(36.0736,35.83622){\line(-1,0){0.3635}}
+\linethickness{0.8pt}
+%Filled triangle
+\linethickness{0.1pt}
+\put(161.11,51.6315371){\line(-1,0){0.3069}}
+\put(161.5564,51.8315371){\line(-1,0){0.6138}}
+\put(162.0028,52.0315371){\line(-1,0){0.9206}}
+\put(162.4492,52.2315371){\line(-1,0){1.2275}}
+\put(162.8956,52.4315371){\line(-1,0){1.5344}}
+\put(163.342,52.6315371){\line(-1,0){1.8412}}
+\put(163.7884,52.8315371){\line(-1,0){2.1481}}
+\put(164.2348,53.0315371){\line(-1,0){2.455}}
+\put(164.6812,53.2315371){\line(-1,0){2.7618}}
+\put(165.1276,53.4315371){\line(-1,0){3.0687}}
+\put(165.574,53.6315371){\line(-1,0){3.3756}}
+\put(166.0204,53.8315371){\line(-1,0){3.2874}}
+\put(166.4668,54.0315371){\line(-1,0){2.6107}}
+\put(166.9132,54.2315371){\line(-1,0){1.934}}
+\put(167.3596,54.4315371){\line(-1,0){1.2574}}
+\put(167.806,54.6315371){\line(-1,0){0.5807}}
+\linethickness{0.8pt}
+%Filled triangle
+\linethickness{0.1pt}
+\put(161.9952,53.9512072){\line(1,0){1.4098}}
+\put(161.7085,54.1512072){\line(1,0){2.8195}}
+\put(161.4219,54.3512072){\line(1,0){4.2293}}
+\put(161.1352,54.5512072){\line(1,0){5.639}}
+\put(160.8485,54.7512072){\line(1,0){7.0488}}
+\put(160.5619,54.9512072){\line(1,0){5.4768}}
+\put(160.2752,55.1512072){\line(1,0){2.8587}}
+\put(159.9885,55.3512072){\line(1,0){0.2406}}
+\linethickness{0.8pt}
+%Filled triangle
+\linethickness{0.1pt}
+\put(112.948,45.2653501){\line(1,0){1.0074}}
+\put(113.1856,45.4653501){\line(1,0){2.0148}}
+\put(113.4231,45.6653501){\line(1,0){3.0221}}
+\put(113.6607,45.8653501){\line(1,0){4.0295}}
+\put(113.8983,46.0653501){\line(1,0){5.0369}}
+\put(114.1359,46.2653501){\line(1,0){6.0442}}
+\put(114.3735,46.4653501){\line(1,0){5.4074}}
+\put(114.6111,46.6653501){\line(1,0){2.8416}}
+\put(114.8487,46.8653501){\line(1,0){0.2757}}
+\linethickness{0.8pt}
+%Filled triangle
+\linethickness{0.1pt}
+\put(120.2697,46.573321){\line(-1,0){1.7457}}
+\put(119.687,46.773321){\line(-1,0){3.4913}}
+\put(119.1044,46.973321){\line(-1,0){4.303}}
+\put(118.5218,47.173321){\line(-1,0){3.8887}}
+\put(117.9392,47.373321){\line(-1,0){3.4744}}
+\put(117.3565,47.573321){\line(-1,0){3.0602}}
+\put(116.7739,47.773321){\line(-1,0){2.6459}}
+\put(116.1913,47.973321){\line(-1,0){2.2316}}
+\put(115.6087,48.173321){\line(-1,0){1.8173}}
+\put(115.026,48.373321){\line(-1,0){1.4031}}
+\put(114.4434,48.573321){\line(-1,0){0.9888}}
+\put(113.8608,48.773321){\line(-1,0){0.5745}}
+\put(113.2782,48.973321){\line(-1,0){0.1603}}
+\linethickness{0.8pt}
+\put(56.0,93.543307){$P_{1}$}
+\put(16.566929,28.84252){$P_{2}$}
+\put(162.0,43.464567){$P_{3}$}
+\put(28.125984,51.07874){$Q_{1}$}
+\put(133.338583,73.425197){$T$}
+\put(116.220472,35.795276){$Q_{2}$}
+\put(90.818898,52.637795){$S$}
+\put(135.118110,69.069013){\circle*{3}}
+\put(94.653661,48.623818){\circle*{3}}
+\put(77,16){Figure 5}
+\end{picture}
+ \end{minipage}}\hfill
+ \begin{minipage}[b]{6.5cm}
+ \setlength{\baselineskip}{17pt}
+The distances of $P_{1}$ and $T$ and of $P_{1}$ and $P_{3}$
+determined with the tool ``dis\-tance and length'' must be
+transferred into the window of the tool ``calculator''. They have to
+be divided. After putting the value of the ratio into the drawing
+window, it has
+ \end{minipage}\\[-5mm]
+\end{figure}
+
+to be multiplied with the distances of $P_{1}$ and $P_{2}$
+and of $P_{2}$ and $P_{3}$. To get the right division points $Q_{1}$
+and $Q_{2}$, these resulting lengths have to be marked off on the
+vectors from $P_{1}$ to $P_{2}$ and from $P_{2}$ to $P_{3}$ with the
+tool ``transfer of measurement''. In the same way, the point $S$ of the
+quadratic B\'ezier curve is constructed as division point on the vector
+from $Q_{1}$ to $Q_{2}.$
+
+Calling the tool ``locus'' and clicking on the points $S$ and $T$ (in
+this order) the preset number of points of the quadratic B\'ezier curve
+will be drawn. Then, in the tool box ``macros'' the three points $P_{1},
+\,P_{2},\,P_{3}$ and the locus have to be chosen respectively as
+source objects and as target object by clicking. Finally, with the
+tool ``macro name'' the macro can be saved.
+
+The \emph{cubic B\'ezier curve} determined by the vectors
+$\vec{y}_{1},\,\vec{y}_{2},\,\vec{y}_{3},\,\vec{y}_{4}$ is obtained
+quite similar by six divisions of line segments with the same ratio
+$t:t_{1}$ because the abbreviations\vspace{-1mm}
+\[\vec{y}\;\!'_{\!j}:\,=
+t_{1}\vec{y}_{j}+t\,\vec{y}_{j+1},\;j=1,\,2,\,3,\:\mbox{ and }\:
+\vec{y}\;\!''_{\!k}:\,=
+t_{1}\vec{y}\;\!'_{\!k}+t\,\vec{x}\;\!'_{\!k+1},\;k=1,\,2,\]\\[-7mm]
+enable the representation
+\vspace{-1mm}
+\[\vec{y}(t)=t_{1}\vec{y}\;\!''_{\!1}+t\,\vec{y}\;\!''_{\!2}.\]\\[-4mm]
+Therefore, the cubic B\'ezier curve can be constructed as locus in a
+way analogous to that one of the quadratic B\'ezier curve. At first,
+four different points have to be entered. Then the connecting line segment
+of the first and the last point is drawn as track of the locus. A
+point $T$ which has to be put on the track determines the division ratio
+of all six vectors occurring later. The first three vectors connect
+each of two points entered successively. The next two vectors lie
+between the three division points. The corresponding division of the
+sixth connecting vector yields the locus point belonging to $T$.
+
+The source objects of the macro are the four starting points, the
+target object is the locus. The Macintosh version of the two macros
+can be found in the Section ``Programs'' of the author's web site
+called \emph{Mathcompass} \cite{Mo}.
+
+\section{PostScript Files}
+
+The inclusion of graphics with the \LaTeX{} command \verb|\special| is
+extremely device dependent. This deficiency is reduced considerably by
+suitable \TeX{} macros which support many important drivers processing
+PostScript code. The \LaTeX{} packages \texttt{graphicx, color} and
+\texttt{pstricks} are examples which, among other possibilities, are
+described in \cite{GRM}.
+
+Compared with the programming of such \TeX{} macros, the writing of
+filter programs for the extraction of data from EPS files (EPS\,=\,
+Encapsulated PostScript) relevant for \LaTeX{} requires only little
+knowledge of PostScript, for example from \cite{Ad}. For the
+application with a fitting filter program, a standard EPS printer
+driver can be used without understanding PostScript. Suitable drivers
+can be downloaded free of charge from the driver web site of the
+Adobe Company (\texttt{http://www.adobe.com/support/downloads/main.html}).
+
+The following explanations are given for people who want to
+change or rewrite a filter program. PostScript files can be opened
+and edited with editor programs like \emph{Alpha} or \emph{BBEdit}
+with MacOS, \emph{WinEdt} with Windows or \emph{Emacs} with Unix.
+Frequently these files have more than 1000 lines. But even in this case,
+only a very small part lying between `EndProlog' and `EOF' contains
+\LaTeX{} relevant data.
+
+For the application of filter programs it is advantageous that all
+lines containing required numerical values are unambiguously marked
+at the line end. However, for the individual PostScript generators
+the marking may be quite different. The lines with the colour data
+end, among other things, with `setrgbcolor' or with `:F4'. The
+object data follow one to three lines later. Here too, the marking
+may be ``concrete'' or ``abstract''. In case of a line segment, it
+is, for example, `lineto stroke' respectively `@b'. In the
+second case, the concrete assignment can be found in the `Prolog'
+section.
+
+The meaning and the order of the numerical values from different
+PostScript generators are not uniform either. For example, a circle
+can be determined by its centre and radius or by two diagonal corners
+of its bounding box. Sometimes the x- and y-coordinates of points
+are exchanged. Furthermore, the numerical values do not always belong
+to the same unit. Usually it is `pt' which fits the \texttt{picture}
+environment of \LaTeX. There may also occur integer values which have
+to be multiplied with 0.25 in order to receive the point size.
+
+All these differences can be clarified through systematic trials. At
+first, each of the different objects has to be constructed with the
+graphic program. After noting the measurements, the drawing must be
+exported as a PostScript file. Most of the graphic programs indicate
+coordinates and lengths in millimetres. The conversion factor to pt
+is 2.845. Through choice of suitable lattice points or through
+variation of the figure, the position of the data in question can be
+determined. If it turns out that the y-coordinates in the
+PostScript file are opposed to those in the graphic program,
+either the drawing has to be reflected vertically before saving, or
+in the filter program, each y-coordinate must be multiplied by -1.
+
+\section{Perl}
+
+The interpreter language Perl (as abbreviation of ``\textbf{P}ractical
+\textbf{E}xtraction and \textbf{R}eport \textbf{L}anguage'') was
+developed around 1988 by \textsc{Larry Wall} at first for scanning
+arbitrary text files in order to extract and process information. It
+may be considered as a younger brother of the \TeX{} system published
+around 1978 by \textsc{Donald E. Knuth} because many persons are
+improving the systems since the beginning and because both systems
+with numerous modules and aids are available free of charge in the
+``Comprehensive \TeX{} Archive Network'' (CTAN) and in the ``Comprehensive
+Perl Archive Network'' (\texttt{http://www.Perl.com/CPAN}) respectively.
+Meanwhile Perl has become a universal script language with which many
+kinds of recurring tasks can be automated, for example in the system
+man\-age\-ment of computers and of their peripherals. Along with the
+great power of Perl since Version 5, it is specially advantageous for
+the application together with \LaTeX{} that Perl systems are available
+on all platforms with wide distribution. Therefore it is not surprising
+that the CTAN already contains numerous Perl programs.
+
+Whoever has learned a higher programming language (like C, for
+example) will hardly have difficulties writing or changing Perl filter
+programs with the aid of some of the online manuals and looking at
+examples like the ones described in the following section. As with
+\LaTeX, it may be expected that, now having reached the Perl version
+number 5.8.7, there won't be considerable changes with respect to text
+filtering. Therefore it is reasonable to provide and to maintain Perl
+filter programs at this time also for further combinations of graphic
+programs, PostScript versions and \LaTeX{} packages. That can be
+achieved in the interest of the \LaTeX{} community by a few persons
+because the main work has been accomplished developing
+the filter structure and the subroutines.
+
+\section{The filter programs \texttt{CABpict.pl} and \texttt{CABebez.pl}}
+
+The Perl program \texttt{CABpict.pl}, which is 32 kB large, has 964
+lines including the comment lines beginning with `\#' and the
+lines with closing braces `\}'. The program \texttt{CABebez.pl} is
+only 29 lines shorter. Therefore in the following only those lines
+and blocks are commented which are important for better understanding
+or which may play a part in modifications.
+
+In case of matching, the lines from \texttt{CABpict.pl} are taken. The
+line numbers, which in both cases don't belong to the programs, may
+be different even for matching lines. In this documentation, the lines of
+\texttt{CABebez.pl} are marked by a colon behind the numbers.
+
+\begin{small}
+\begin{verbatim}
+ 1 #!perl -w
+ 2 # CABpict.pl
+\end{verbatim}
+\vspace{-4mm}
+\texttt{\mbox{\quad} 3 \# (c) Copyright 2006 H. M\"oller
+(mollerh@math.uni-muenster.de).\\
+\mbox{\quad} 4 \# Version 1.1 for Cabri-g\'eom\`etre II with MacOS
+9.x, \ldots \mbox{ }.\\
+\mbox{\quad} 5 \# This program may be distributed and/or modified under the\\
+\mbox{\quad \quad} conditions of the LaTeX Project Public License, \ldots
+\mbox{ }.\\
+\mbox{\quad} \ldots}
+\vspace{-4mm}
+\begin{verbatim}
+ 9 use POSIX('ceil','floor');
+\end{verbatim}
+\end{small}
+
+The first line doesn't represent a comment line because it begins with
+`\#!'. This line may be missing in some Perl versions, for example,
+if Perl programs are called by command line input or if no options are
+used. The option `\verb|-w|' causes Perl to print error messages. It
+can also be necessary to place the complete path name before
+`\texttt{perl}', for example `\texttt{/usr/bin/perl}'.
+
+Lines 2 to 8 are destined for version references. Line 9 provides two
+procedures from the Perl modul `POSIX'. They serve for rounding and
+can be replaced (with caution) by own (sub-) routines using the
+command `\texttt{int}'.
+
+\begin{small}
+\begin{verbatim}
+ 11 # Definable by the user:
+ 12 # Unitlength in pt:
+ 13 $ul = 1.0;
+ 14 # Fill factor (for filling with magnification up to 500 %)
+ 15 $fillf = 5;
+ 16 # Point factor:
+ 17 $pointf = 0.3;
+ 18 # Flag for dotting parabolic arcs (1: Dotting)
+ 19 $Qbezflag = 0;
+
+\end{verbatim}
+\vspace{-4mm}
+\hspace{5.5pt}\texttt{16:\mbox{ }\# B\'ezier factor:}
+\vspace{-4mm}
+\begin{verbatim}
+ 17: $bezf = 2.0;
+\end{verbatim}
+\end{small}
+
+Each of these five parameters may be changed before applying the
+respective program. Afterwards all parameters should get their
+original values unless the program is stored under a different name.
+
+Varying the `unitlength' \verb|$ul| and using a saved PostScript
+representation, each drawing can be reduced or magnified in the
+\LaTeX{} \texttt{picture} environment. The value \verb|$ul=1.0|
+yields the figure in its original size from Cabri Geometry.
+
+The `fill factor' \verb|$fillf| settles the distance of the horizontal
+line segments filling polygons. With \verb|$fillf=5| figures appear
+completely filled with screen magnification up to 500 \% .
+
+With \texttt{pict2e} alone, dotted curves can't be represented because
+\texttt{pict2e} ignores the number of points of B\'ezier objects.
+Therefore in \texttt{CABpict.pl} the plot commands \verb|\Lbezier| and
+\verb|\Qbezier| from the package \texttt{ebezier} are used
+additionally. With that the `point factor'\verb|$ pointf= 0.3| yields
+the normal point distance (like in Figures 1 to 3). To dot a
+curve, setting the flag \verb|$Qbezflag=1| one can approximate
+with arcs of parabolas for which possibly in the \LaTeX{}
+\texttt{picture} environment the number of points at \verb|\Qbezier|
+is to be adjusted. In the normal case \verb|$Qbezflag=0|, the
+parabolic arc is drawn with the plot command \verb|\qbezier| from
+\texttt{pict2e}.
+
+In \texttt{CABebez.pl} the `B\'ezier factor' \verb|$bezf= 2.0| yields a
+point distance which with normal magnification and in print lets the
+corresponding line appear closed. Since the memory need of B\'ezier
+curves with \texttt{ebezier} is often eight times as large as
+with \texttt{pict2e}, \verb|$bezf| may be reduced in case of tight
+memory.
+
+\begin{small}
+\begin{verbatim}
+ 21 # Constants:
+ 22 # Colour names:
+ 23 $yellow = "0.9843900.9511410.020249";
+ 24 $orange = "1.0000000.3927370.009949";
+ 25 $red = "0.8649270.0342110.025910";
+ 26 $purple = "0.9486080.0325630.519234";
+ 27 $violet = "0.2769050.0000000.645487";
+ 28 $navy = "0.0000000.0000000.828138";
+ 29 $blue = "0.0088040.6692610.917967";
+ 30 $green = "0.1215990.7170980.078874";
+ 31 $darkgreen = "0.0000000.3933010.069093";
+ 32 $darkbrown = "0.3359430.1742730.020081";
+ 33 $brown = "0.5657890.4428780.227359";
+\end{verbatim}
+\end{small}
+
+Cabri Geometry writes the three RGB values into the PostScript file
+with six decimal places and one digit before the decimal point.
+Through Lines 45 to 47, \texttt{CABpict.pl} looks for these lines
+ending with \verb*| setrgbcolor | and removes the spaces as well as the
+last word \verb|setrgbcolor|. In this way the corresponding line
+yields a single ``word'' which is placed before the respective
+character strings later. Through the assignment of easily remembered
+colour names to this ``digit words'' it is easy to use other or
+further colour names. The names of 68 (DVIPS-) colours with CMYK
+values can be found in the header file `\verb|color.pro|'. Without
+colour values they also appear in the files `\verb|colordvi.sty|' and
+`\verb|colordvi.tex|' (see \cite{Car}).
+
+\begin{small}
+\begin{verbatim}
+ 35 # Further Constants:
+ 36 # Pi:
+ 37 $Pi = "3.14159265358979";
+ 38 # Constants in dotted figures:
+ 39 $uli = sp(4 / $ul);
+ 40 $ule = sp(0.8 / $ul);
+
+\end{verbatim}
+\vspace{-5mm}
+\hspace{5.5pt}\texttt{38:\mbox{ }\# Constant in cubic B\'ezier curves for quarters of a circle:}
+\vspace{-3mm}
+\begin{verbatim}
+ 39: $l90 = "0.552284749830794";
+\end{verbatim}
+\end{small}
+
+To be able to dot areas which are contained in arbitrary closed
+polygons, the points get absolute coordinates $(x,y)$ with regard to
+the respective \verb|picture| environment, where $x$ and $y$ are even
+integers and $x+y$ is divisible by 4. Then \verb|$uli| and
+\verb|$ule| deliver the horizontal distance and the length of the 0.8
+pt thick line segments which form a point.
+
+Like the ``circular number'' \verb|$Pi|, \verb|$l90| also represents a
+number constant which is required for the approximation of circular arcs
+through cubic B\'ezier curves. It is deduced in \cite{Ba} (Page 6).
+
+\begin{small}
+\begin{verbatim}
+ 42 @lines = <>;
+ 43 do {
+ 44 $_ = $lines[$i++];
+ 45 if (/ setrgbcolor \s/o) {
+ 46 s/ //go;
+ 47 s/setrgbcolor\s/ /o;
+ 48 $c = $_;
+ 49 $_ = $lines[$i++];
+ 50 s/ moveto//o;
+ 51 s/lineto stroke/stroke/o;
+ 52 s/curveto stroke/curveto/o;
+ 53 s/ setlinewidth stroke//o;
+ 54 s/ lineto//go;
+ 55 if (/stroke/o) {
+ 56 $line[++$#line] = $c.$_;
+ 57 }
+ 58 elsif (/closepath fill/o) {
+ 59 $vector[++$#vector] = $c.$_;
+ 60 }
+ 61 elsif (/arc /o) {
+ 62 $circle[++$#circle] = $c.$_;
+ 63 }
+ 64 elsif (/arcn/o) {
+ 65 $arc[++$#arc] = $c.$_;
+ 66 }
+ 67 elsif (/curveto/o) {
+ 68 do {
+ 69 $conic[++$#conic] = $c.$_;
+ 70 $_ = $lines[$i++];
+ 71 s/ moveto//o;
+ 72 s/curveto stroke/curveto/o;
+ 73 }
+ 74 until $_ !~ /curveto/o;
+ 75 }
+ 76 }
+ 77 }
+ 78 until $i == $#lines;
+\end{verbatim}
+\end{small}
+
+With Lines 42 to 78, the required data are extracted from the
+PostScript file. Initially the array \verb|@lines| contains all
+lines. The successive assignment of each individual line to the
+general ``last result variable'' \verb|$_| takes place with Line 44.
+Next, the ``colour lines'' are looked for and condensed as described
+above. With Line 48, the result is assigned to the variable \verb|$c|.
+
+In the present version, only the next line has to be analysed
+subsequently. The commands for searching and replacing in Lines 50 to
+54 care for unambiguity and for pure number sequences (apart from the
+last word). With PostScript versions which contain the data in a
+later line, it is helpful to attach the intermediate lines and the
+data line by removing the line breaks.
+
+Depending on the different line endings, the data are collected in
+five arrays. For example, Line 56 means that the array \verb|@line|,
+whose last element has the index \verb|$#line|, is extended by one
+field which holds the preceding colour variable \verb|$c| and the
+character string of the coordinates of the starting point and the end
+point of a line segment.
+
+For any arrow, Cabri Geometry writes the coordinates of the four
+arrowhead corners of a PSTricks style arrow into the
+PostScript file. With \texttt{CABpict.pl} these data are not needed
+if the colour of the arrow is violet because the plot command
+\verb|\vector| is then available. Otherwise the arrowhead consists of two
+filled triangles, and the arrow line is drawn as an unbroken or dotted
+line segment according to the colouring.
+
+The data of circles can be found in the lines ending with \verb*|arc |.
+Additionally a full circle is characterized by 0 and 360 as fourth
+and fifth value respectively. Therefore, circular arcs entered
+clockwise in Cabri Geometry can also be rec\-og\-nized in lines ending with
+\verb*|arc | because they contain the starting angle and the ending
+angle instead of 0 and 360. Lines with the data of circular arcs
+entered anticlockwise end with \verb|arcn|.
+
+The Macintosh version of Cabri Geometry offers the possibility of
+drawing con\-ic sections determined by five points. In the linked
+PostScript file, the data of approximating cubic B\'ezier curves are
+stored, namely nine for ellipses and four for each open branch. The
+values from the corresponding lines ending with \verb|curveto stroke|
+are stored in the array \verb|@conic|. These data can be
+processed directly with the plot command \verb|\cbezier|.
+
+\begin{small}
+\begin{verbatim}
+ 80 $pflag = 1;
+ 81 $sflag = 1;
+ 82 $thicknessflag = 1;
+ 83 $coun = 0;
+ 84 $xtex = "";
+ 85 $mtex = "";
+
+ 86: $bmax = 500;
+ 89: $btex = "\\documentclass{article}\n\\usepackage{ebezier}\n\n";
+\end{verbatim}
+\end{small}
+
+These initialisations begin with flags for the starting corner of
+polygons, for the starting values of the bounding box and for the
+currently selected thickness of line segments. The parameter \verb|$coun|
+yields the numbers for the places of text and formulas. With
+\verb|$xtex|, the character string is set up which finally is written
+as \LaTeX{} text into the Perl output window through a \texttt{print}
+command. Since, in any case, the text markers have to be edited finally,
+temporary storing in \verb|$mtex| enables the positioning at the end
+of the \LaTeX{} text where they can easily be found.
+
+If B\'ezier curves with more than 500 points are generated with the
+package \verb|ebezier|, it is necessary to enlarge the \LaTeX{} value
+500 of \verb|\qbeziermax|. Therefore, with the aid of the variable
+\verb|$bmax| the maximum number of points of B\'ezier curves is
+determined. If \verb|$bmax| exceeds 500, the value of
+\verb|\qbeziermax| is adjusted with \verb|\renewcommand| in the
+character string \verb|$btex| which contains the beginning of the
+corresponding \LaTeX{} program. The insertion of \verb|$btex| and
+\verb|$mtex| in \verb|$xtex| is described on page \pageref{Frame}.
+
+\begin{small}
+\begin{verbatim}
+ 87 # Lines and polygons
+ 88 $cflag = 1;
+ 89 foreach (@line) {
+ 90 @coo = split;
+ 91 $co0 = $coo[0];
+ 92 $co2 = (-1) * $coo[2];
+ 93 $co4 = (-1) * $coo[4];
+ 94 if (($co0 ne $violet) and ($co0 ne $yellow)) {
+ 95 if ($cflag) {
+\end{verbatim}
+\vspace{-4mm}
+\texttt{\mbox{\quad}96}\hspace{14mm}\verb|$xtex .= "%Lines, arrows, polygons and |
+\texttt{B\'ezier}\verb| curves\n";|
+\vspace{-4mm}
+\begin{verbatim}
+ 97 $cflag = 0;
+ 98 }
+ 99 if ($co0 ne $blue) {
+ 100 bound($coo[1],$co2);
+ 101 bound($coo[3],$co4);
+ 102 }
+ 103 if (($co0 ne $red) and ($co0 ne $blue) and ($co0 ne $brown)
+ 104 and ($co0 ne $darkbrown) and ($co0 ne $navy)) {
+ 105 lin($co0,$coo[1],$co2,$coo[3],$co4);
+\end{verbatim}
+\end{small}
+
+Here begins the processing of the data of the arrays. Since these
+longer parts have a similar structure for most combinations of graphic
+programs, PostScript versions and \LaTeX{} packages, only essential or
+typical sections are explained as follows.
+
+The flag \verb|$cflag| ensures that in the \LaTeX{} program, the
+commentaries point\-ing out each of the emerging objects don't repeat
+permanently. With the \texttt{split} command the character strings
+delivered by \texttt{foreach} are transformed into lists of character
+strings which in our case are the numbers and the last words of the
+evaluated PostScript lines. In the shortened form of \texttt{split}
+used here, the spaces cause the separation of the character string of
+the last result value \verb|$_|.
+
+Since most branchings depend on at least one colour, first the list
+element with index 0 which contains the colour, is abbreviated.
+Subsequently the ``vertical reflection'' which is necessary in this
+version takes place multiplying each y-coordinate by -1.
+
+Line 96 yields a typical \LaTeX{} comment line because the character
+string which is added to \verb|$xtex| by \verb|.=| begins with the
+\verb|%| sign and ends with the line feed command \verb|\n| of Perl .
+
+With each of the Lines 100 and 101, the subroutine `\texttt{bound}' for
+the determination of the bounding box coordinates is called. It is
+defined in the Lines 944 to 957. In this case the coordinates of the
+starting point and the end point of line segments are evaluated.
+Objects with colour `\texttt{blue}' are excluded because the diagonal
+marking text or formulas is a two point polygon, and because
+for B\'ezier curves 51 points are considered.
+
+There are nine subroutines which can be found
+from Line 390 on (356 with \texttt{CABebez.pl}). The order of the
+subroutines plays no role. Therefore most of these
+procedures are described at their first appearance.
+
+The subroutine `\texttt{lin}' generates all line segments which have
+to be drawn. In \texttt{CABpict.pl}, the extended \verb|\line|
+command from \verb|pict2e| is available for unbroken line segments,
+whereas dotted line segments have to be drawn with the command
+\verb|\Lbezier| from the \texttt{ebezier} package. In
+\texttt{CABebez.pl} also all line segments which don't fulfill the
+\LaTeX{} conditions for slopes or lengths must be built up with the
+aid of \verb|\Lbezier|.
+
+\begin{small}
+\begin{verbatim}
+ 107 if (($co0 ne $green) and ($co0 ne $darkgreen)) {
+ 108 if ($pflag) {
+ 109 $cb1 = $coo[1];
+ 110 $cb2 = $co2;
+ 111 $pol = $co0." ".$cb1." ".$cb2;
+ 112 $pflag = 0;
+ 113 }
+ 114 else {
+ 115 $pol .= " ".$coo[1]." ".$co2;
+ 116 if (abs($coo[3] - $cb1) + abs($co4 - $cb2) < 2.0E-6) {
+ 117 $poly[++$#poly] = $pol;
+ 118 $pflag = 1;
+\end{verbatim}
+\end{small}
+
+Here, for each polygon which has to be filled, dotted or hatched, the
+array \verb|@poly| emerges which contains the coordinates of
+the corners.
+
+\begin{small}
+\begin{verbatim}
+ 123 if ($co0 eq $violet) {
+ 124 $xtex .= "%Arrow\n";
+ ...
+ 127 $dx = $coo[3] - $coo[1];
+ 128 $dy = $co4 - $co2;
+ 129 $len = sp(abs($dx));
+ 130 if ($len > 1.0E-3) {
+ 131 @p = best(abs($dy / $dx));
+ 132 $psx = sp($p[1]) * ($dx <=> 0);
+ 133 $psy = sp($p[0]) * ($dy <=> 0);
+ ...
+ 140 $xb = sp($coo[1]);
+ 141 $yb = sp($co2);
+ 142 if (not $thicknessflag) {
+ 143 $xtex .= "\\linethickness{0.8pt}\n";
+ 144 $thicknessflag = 1;
+ 145 }
+ 146 $xtex .= "\\put(".$xb.",".$yb."){\\vector(".$psx.",".$psy.
+ "){".$len."}}\n";
+\end{verbatim}
+\end{small}
+
+For the generation of unbroken line segments respectively of
+complete arrows with the package \texttt{pict2e}, the subroutine
+\texttt{best} is provided which yields the best possible numerators and
+denominators for the rational approximations of the slope with the aid of
+a continued fraction algorithm. Since, particularly, both components are
+relatively prime, it is practically no restraint that
+they must lie in the interval $[-1000,\,1000]$.
+
+With the two-line subroutine \texttt{sp}, the numbers which Cabri
+Geometry hands over to the PostScript file with six decimal places, as
+well as all other decimal numbers appearing in the \LaTeX{}
+\texttt{picture} environment, are rounded off to three places
+with removal of all concluding zeros.
+
+\begin{small}
+\begin{verbatim}
+ 150 foreach (@poly) {
+ 151 @po = split;
+ 152 $p0 = $po[0];
+ 153 $pon = $#po;
+ 154 if (($p0 eq $red) or ($p0 eq $purple) or ($p0 eq $darkbrown)
+ 155 or ($p0 eq $orange) or ($p0 eq $brown)) {
+\end{verbatim}
+\end{small}
+
+The evaluation of the data of the array \verb|@poly| depends on
+the colour and on the index \verb|$pon=$#po| of the last element.
+
+\begin{small}
+\begin{verbatim}
+ 156 if ($pon == 6) {
+ 157 tri($p0,$po[1],$po[2],$po[3],$po[4],$po[5],$po[6]);
+\end{verbatim}
+\end{small}
+
+If \verb|$pon = 6|, then the subroutine \texttt{tri} is
+called which settles the filling, dotting and hatching of triangles .
+
+\begin{small}
+\begin{verbatim}
+ 159 elsif ($pon == 8) {
+ 160 ($p0,$u1,$v1,$u2,$v2,$u3,$v3,$u4,$v4) = @po;
+ 161 $s1 = abs($u1 - $u4) + abs($u2 - $u3) + abs($v1 - $v2) +
+ abs($v3 -$v4);
+ 162 $s2 = abs($u1 - $u2) + abs($u3 - $u4) + abs($v1 - $v4) +
+ abs($v2 -$v3);
+ 163 if (($s1 < 4.0E-6) or ($s2 < 4.0E-6)) {
+ ...
+ 166 rect($p0,$u1,$v1,$u2,$v2,$u3,$v3,$u4,$v4);
+ 167 }
+ 168 else {
+ ...
+ 173 tri($p0,$u1,$v1,$u2,$v2,$u3,$v3);
+ 174 tri($p0,$u1,$v1,$u3,$v3,$u4,$v4);
+ 175 }
+ 176 }
+ 177 elsif ($pon > 8) {
+ ...
+ 179 for (my $j = 3; $j <= $pon - 3; $j += 2) {
+ ...
+ 181 tri($p0,$po[1],$po[2],$po[$j],$po[$j + 1],$po[$j +
+ 2],$po[$j + 3]);
+\end{verbatim}
+\end{small}
+
+In case of \verb|$pon = 8|, rectangles with sides parallel to the axes
+are treated with the aid of the subroutine \texttt{rect}. This is
+simpler than the procedure for all other polygons which first have
+to be cut up in triangles.
+
+\begin{small}
+\begin{verbatim}
+ 191 elsif ($p0 eq $blue) {
+ 192 if ($pon == 4) {
+\end{verbatim}
+\vspace{-3.5mm}
+\hspace{5.5pt}\texttt{193\mbox{ }\# Text marker and B\'ezier curves:}
+\vspace{-3.5mm}
+\begin{verbatim}
+ 194 $coun++;
+ ...
+ 201 $mtex .= "\\put(".$po1.",".$po2."){".$coun."}\n";
+ 202 }
+ 203 elsif ($pon == 6) {
+\end{verbatim}
+\vspace{-3.5mm}
+\hspace{6pt}\texttt{204}\hspace{14mm}\verb|$xtex .= "%Quadratic |
+\texttt{B\'ezier}\verb| curve\n";|
+\vspace{-3.5mm}
+\begin{verbatim}
+ 205 qbez($po[1],$po[2],$po[3],$po[4],$po[5],$po[6]);
+ 206 }
+ 207 elsif ($pon == 8) {
+\end{verbatim}
+\vspace{-3.5mm}
+\hspace{6pt}\texttt{208}\hspace{14mm}\verb|$xtex .= "%Cubic |
+\texttt{B\'ezier}\verb| curve\n";|
+\vspace{-3.5mm}
+\begin{verbatim}
+ 209 cbez($po[1],$po[2],$po[3],$po[4],$po[5],$po[6],$po[7],
+ $po[8]);
+\end{verbatim}
+\end{small}
+
+With colour \verb|$blue|, \verb|$pon = 4| yields the text markers,
+whereas \verb|$pon = 6| and \verb|$pon = 8| lead to the call of the
+subroutines \texttt{qbez} for quadratic B\'ezier curves and
+\texttt{cbez} for cubic B\'ezier curves respectively.
+
+\begin{small}
+\begin{verbatim}
+ 214 # Arrows
+ 215 foreach (@vector) {
+ 216 @ve = split;
+ 217 if ($ve[0] eq $darkgreen) {
+ ...
+ 235 tri($red,$vu0,$vu1,$vu2,$vu3,$ve[5],$ve[6]);
+ 236 tri($red,$vu0,$vu1,$vu6,$vu7,$ve[5],$ve[6]);
+\end{verbatim}
+\end{small}
+
+Here, as already mentioned above, for arrows with a
+dotted arrow line (and always for arrows in \texttt{CABebez.pl})
+the arrowhead is put together joining two filled triangles.
+
+\begin{small}
+\begin{verbatim}
+ 258 # Circles, halves and quarters of circles
+ 259 $cflag = 1;
+ 260 $aflag = 1;
+ 261 foreach (@circle) {
+ 262 @po = split;
+ 263 $p0 = $po[0];
+ 264 if ($p0 ne $yellow) {
+ 265 $po[2] = (-1) * $po[2];
+ 266 $di = 2 * $po[3];
+ 267 if ($po[4] > 1.0E-3 or abs($po[5] - 360) > 1.0E-3) {
+ 268 if ($aflag) {
+ 269 $xtex .= "%Arcs\n";
+ 270 $aflag = 0;
+ 271 }
+ 272 $arce = ($po[4] > 0) ? 360 - $po[4] : 0;
+ 273 $arcb = ($po[5] > 0) ? 360 - $po[5] : 0;
+ 274 $darc = $arce - $arcb;
+ 275 if ($darc < 0) {$darc += 360}
+ 276 $quar = int($darc / 90);
+ 277 if ($quar > 0) {
+ 278 for (my $k = 1; $k <= $quar; $k++) {
+ 279 arc($p0,$po[1],$po[2],$po[3],$arcb,$arcb + 90);
+ 280 $arcb += 90;
+ 281 if ($arcb > 360) {$arcb -= 360}
+ 282 }
+ 283 }
+ 284 if ($darc > $quar * 90) {
+ 285 arc($p0,$po[1],$po[2],$po[3],$arcb,$arce);
+ 286 }
+ 287 }
+ 288 else {
+ 289 if ($cflag) {
+ 290 $xtex .= "%Circles, halves and quarters of circles\n";
+ 291 $cflag = 0;
+ 292 }
+ 293 if ($p0 eq $navy) {
+ 294 $xtex .= "\\put(".$po[1].",".$po[2]."){\\circle{".$di.
+ "}}\n";
+ ...
+ 299 }
+ 300 elsif ($p0 eq $purple) {
+ 301 $xtex .= "\\put(".$po[1].",".$po[2]."){\\oval[".$di."]
+ (".$di.",".$di.")[l]}\n";
+ ...
+ 340 elsif ($p0 eq $darkgreen) {
+ 341 $r = $po[3];
+ 342 $le = int(2 * $pointf * $ul * $Pi * $r);
+ 343 $xtex .= "\\cCircle[".$le."](".$po[1].",".$po[2].")
+ {".$r."}[f]\n";
+\end{verbatim}
+\end{small}
+
+Circular arcs are cut up to quadrants of a circle and to a shorter
+remaining arc. In \texttt{CABebez.pl} the subroutine \texttt{quart}
+approximates all quadrants of a circle (and with that, also circles and
+semicircles) by a cubic B\'ezier curve. With \texttt{pict2e}, the plot
+commands \verb|\oval| and \verb|\circle| are available without
+restraints. For all remaining circular arcs the subroutine
+\texttt{arc} supplies the approximation by a cubic B\'ezier curve. The
+plot command \verb|\cCircle| of the package \texttt{ebezier} is used
+to get dotted circles in \texttt{CABpict.pl}.
+
+\label{Frame}
+\begin{small}
+\begin{verbatim}
+ 379 # Frame
+ 380 if ($xtex . $mtex ne "") {
+ 381 $xtex = "\\documentclass{article}\n\\usepackage{ebezier}\n".
+ 382 "\\usepackage[pdftex,pstarrows]{pict2e}\n\n
+ \\begin{document}\n\n".
+ 383 "\\setlength{\\unitlength}{".$ul."pt}\n".
+ 384 "\\begin{picture}(".ceil(($xmax - $xmin)).",".
+ 385 ceil(($ymax - $ymin)).")(".floor($xmin).",".floor($ymin).")\n".
+ 386 "\\linethickness{0.8pt}\n"."\\thicklines\n".$xtex;
+ 387 $xtex .= $mtex."\\end{picture}\n\n\\end{document}";
+ 388 }
+ 389 print $xtex."\n";
+
+342: if ($bmax > 500) {
+343: $bmax = 100 * ceil($bmax / 100);
+344: $btex .= "\\renewcommand{\\qbeziermax}{".$bmax."}\n";
+345: }
+346: if ($xtex . $mtex ne "") {
+347: $xtex = $btex."\\begin{document}\n\n\\setlength{\\unitlength}{".
+348: $ul."pt}\n"."\\begin{picture}(".ceil(($xmax - $xmin)).",".
+349: ceil(($ymax - $ymin)).")(".floor($xmin).",".floor($ymin).")\n".
+\end{verbatim}
+\end{small}
+
+Here the different parts of the character string \verb|$xtex|
+are united and written into the Perl output window by the \verb|print|
+command.
+
+Since the subsequently assembled subroutines can be used in other
+versions large\-ly unchanged, now follow only comments which explain the
+underlying theory. In the main part of \texttt{best}, the entered
+decimal number is transformed into a continued fraction. Then, among
+all principal and intermediate convergents which are ``best
+approximations'', the one with the greatest possible numerator or
+denominator is determined.
+
+\begin{small}
+\begin{verbatim}
+ 536 # Triangles
+ 537 sub tri {
+ 538 my ($q0,$qx1,$qy1,$qx2,$qy2,$qx3,$qy3) = @_;
+ ...
+ 545 if ($q0 eq $red) {
+ 546 # Filled triangle
+ 547 %ha = ($qx1,$qy1,$qx2+1e-07,$qy2+1e-07,$qx3+2e-07,
+ $qy3+2e-07);
+ 548 @hb = ();
+ 549 @hc = ();
+ 550 foreach (sort { $ha{$a} <=> $ha{$b} } keys %ha) {
+ 551 $hb[++$#hb] = $_;
+ 552 $hc[++$#hc] = $ha{$_};
+ 553 }
+ 554 ($qx1,$qx2,$qx3) = @hb;
+ 555 ($qy1,$qy2,$qy3) = @hc;
+\end{verbatim}
+\end{small}
+
+Each of the three parts of \texttt{tri} begins with sorting out
+corners: For filling and dott\-ing, they are ordered according to the
+size of the $y$-coordinates and for hatching, the order depends on the
+difference of both coordinates. For the sorting method used by Perl
+for the data type ``hash'', it should be taken into account that in
+our case, each of the two associated arrays must consist of different
+elements. Here, this is achieved by changing the seventh place behind
+the decimal point.
+
+If, after sorting, one imagines a straight line passing through the
+first and third corner, linear algebra yields the half-plane bordered
+by the straight line and containing the second corner. Then, starting with
+the connecting line segment of the first and third corner and
+with distinction of cases concerning the second point,
+the objects which have to be inserted are constructed.
+
+The intermediate points of quadratic and cubic B\'ezier curves needed
+for their bounding box are calculated with the formulas of Section 4.
+The coefficients of cubic B\'ezier curves which approximate parts of
+quadrants of circles in the subroutine \texttt{arc} are
+derived in \cite{Ba} (Pages 11\,f).
+
+\section{The \texttt{picture} environment of \LaTeX}
+
+Using the capacity of geometry software or of drawing programs,
+also further advantages of the \LaTeX{} \texttt{picture} environment
+compared with the \verb|\special| command come into effect:
+\\[-6mm]
+
+\begin{list}{$\bullet$}{
+ \setlength{\labelwidth}{3mm}
+ \setlength{\leftmargin}{7mm}
+ }
+ \item All graphic data are integrated in the \TeX{} file. Particularly,
+ no graphic files can get lost during dissemination.\vspace{1mm}
+
+ \item \LaTeX{} proves its flexibility mainly with the positioning
+ using \texttt{minipages} or \texttt{floats} (sliding objects).
+ Since the filter programs yield the size of the bound\-ing box as
+ well as the offset value (for the upper left corner), each figure
+ can directly be placed in a \texttt{minipage}. Using that it
+ can be moved horizontally and vertically, for example, applying
+ the commands \verb|\hspace| and \verb|\raisebox| (see Figures
+ 1 to 5).\vspace{1mm}
+
+ \item The final processing of figures can be done in the usual
+ cycle edit-typeset-preview.\vspace{1mm}
+
+ \item Even in documents with numerous complicated figures,
+ memory requirements can well be estimated and, particularly, applying
+ \texttt{pict2e}, they are surpris\-ing\-ly low. But also with the
+ \texttt{ebezier} package, in \textsc{Big}\TeX{} versions no lack of
+ memory has to be expected.\vspace{1mm}
+
+ \item If PDF files are generated from \LaTeX{} productions, the
+ figures are taken over automatically.
+
+ \end{list}
+
+The completion of the \LaTeX{} \texttt{picture} environment with
+commands from the \texttt{color} package mentioned in Section 3 is
+possible only with restraints. Due to a technical difficulty,
+\TeX{} possibly inserts vertical space at each change of colour (see
+\cite{Car}, Page 6). Therefore, without complicated corrections, only
+figures can be coloured for which all connected parts have the same
+colour.
+
+The development of filter programs for \LaTeX{} was initiated by the
+author's wish to take over about 80 figures created with the drawing
+program STAD on Atari computers into a book designed with \LaTeX{} on
+Macintosh computers. The figures were traced with the drawing program
+ClarisDraw, and the PostScript versions were transformed to \LaTeX{}
+\texttt{picture} environments with an AppleScript program. This first
+functioning PostScript filter program can be found in \cite{Mo} in the
+section `Programme'.
+
+\begin{thebibliography}{9}
+ \setlength{\baselineskip}{18pt}
+ \bibitem{Ad} Adobe, Systems Incorporated: PostScript Language
+ Reference Manual. Addison-Wesley, 2nd edition, 1995.
+
+ \bibitem{Ba} Bachmaier, Gerhard A.: Using \texttt{ebezier}.
+ Package in CTAN:\texttt{/macros/latex/contrib/ebe-} \texttt{zier}, 2002.
+
+ \bibitem{Car} Carlisle, David P.: Packages in the `graphics' bundle.
+ CTAN:\texttt{/macros/latex/required} \texttt{/graphics/grfguide.pdf},
+ 1999/2004.
+
+ \bibitem{GaNi} G\"a{\ss}lein, Hubert and Niepraschk, Rolf: The
+ \texttt{pict2e}-package. Package in
+ CTAN:\texttt{/macros} \texttt{/latex/contrib/pict2e/pict2e.dtx}, 2003.
+
+ \bibitem{GRM} Goossens, Michel, Rahtz, Sebastian and Mittelbach,
+ Frank: The \LaTeX{} Graphics Compan\-ion. Addison-Wesley, Reading MA,
+ 1997.
+
+ \bibitem{Mo} M\"oller, Herbert: \emph{Mathcompass}
+ (\texttt{http://wwwmath1.uni-muenster.de/u/mollerh}).
+
+ \bibitem{Ni} Nickalls, Richard W.D.: MathsPIC.
+ CTAN:\texttt{/graphics/pictex/mathspic}, 1999.
+
+ \bibitem{NiSy} Nickalls, Richard W.D. and Apostolos Syropoulos:
+ $mathsPIC_{Perl}.$ CTAN:\texttt{/graphics} \texttt{/pictex/mathspic/Perl},
+ 2005.
+
+ \bibitem{Wi} Wichura, Michael J.: The $\mathrm{P_{\D I}CT_{\D E}X}$
+ Manual, 1992. Package in CTAN:\texttt{/graphics/pictex}.
+
+\end{thebibliography}
+\end{document}
diff --git a/graphics/gapfill/GaPDoc2.pdf b/graphics/gapfill/GaPDoc2.pdf
new file mode 100644
index 0000000000..485faa3707
--- /dev/null
+++ b/graphics/gapfill/GaPDoc2.pdf
Binary files differ
diff --git a/graphics/gapfill/GaPDoc2.tex b/graphics/gapfill/GaPDoc2.tex
new file mode 100644
index 0000000000..4bbe43a34c
--- /dev/null
+++ b/graphics/gapfill/GaPDoc2.tex
@@ -0,0 +1,514 @@
+\documentclass[12pt]{amsart}
+\usepackage{amsfonts,a4}
+\usepackage[pdftex,pstarrows]{pict2e}
+\newcommand{\lfrac}[2]{\mbox{\raisebox{-0.6pt}{{\large$\frac{#1}{#2}$}}}}
+\renewcommand{\thefootnote}{\fnsymbol{footnote}}
+\setlength{\headsep}{25pt}
+\setlength{\oddsidemargin}{10.1mm}
+\setlength{\evensidemargin}{9.9mm}
+\setlength{\parskip}{1.5ex plus0.5ex minus0.5ex}
+\setlength{\parindent}{0em}
+\pagestyle{myheadings}
+
+\begin{document}
+\markboth{ \;\; \hrulefill \: Herbert M\"oller
+\,\hrulefill}
+{\hrulefill \; How to Generate \LaTeX\ Picture Environments
+Using OpenOffice.org 3 Draw
+\,\hrulefill \;\quad }
+
+\vspace*{-15mm}
+\begin{center}
+\Large{\textbf{How to Generate \LaTeX\ Picture\vspace{2mm} Environments
+Using OpenOffice.org 3 Draw}}\\[7mm]
+\large{Herbert M\"oller\footnote[1]{\mbox{\rule[0mm]{0mm}{5mm}}\copyright{}
+Copyright 2009 by H. M\"oller
+(\texttt{mollerh@math.uni-muenster.de}). This documentation may be
+distributed and/or modified under the conditions of the \LaTeX\ Project
+Public License.}}\\[7mm]
+\end{center}
+
+\begin{quote}
+ {\small
+\textsc{Abstract.} The powerful free drawing software
+\texttt{OpenOffice.org 3 Draw} (abbreviated \texttt{OOoDraw} in the
+following) and a Perl filter program are used to conveniently create
+even complicated figures with the \LaTeX\ \texttt{picture}
+environment. Parsing PostScript files exported by \texttt{OOoDraw},
+the filter program \texttt{OOopict.pl} generates \LaTeX\ code ready
+for use. Along with other advantages \texttt{OOoDraw} has its own
+PostScript translator, which does not depend on the operating systems
+supported by \texttt{OpenOffice.org}, namely Linux, Mac OS, Unix, and
+Windows. Therefore, \texttt{OOopict.pl} can be applied to PostScript
+files of \texttt{OOoDraw} on all these operating systems. Moreover,
+all curves constructed with \texttt{OOoDraw} are represented in the
+PostScript files as cubic B\'{e}zier curves which can be directly used
+by the package \texttt{pict2e} \cite{GaNi} to produce vector graphics
+with \LaTeX.}
+\end{quote}
+
+\section{Introduction}
+
+\setlength{\baselineskip}{17pt}
+Three years ago a new method for the creation of figures with the \LaTeX\
+\texttt{picture} environment was published in the Comprehensive \TeX\
+Archive Network (CTAN) \cite{GaP}. It is called ``GaPFilL'' (\emph{Graphics
+as PostScript Filtered for \LaTeX}) because it consists of the following
+four steps:
+
+\begin{enumerate}
+ \item Generating the figures with a drawing program or geometry software;
+
+ \item ``Printing'' or exporting the construction as a PostScript
+ file;
+
+ \item Applying a filter program to the PostScript text;
+
+ \item Copying the resulting code or parts of it into a \LaTeX\
+ document.
+\end{enumerate}
+
+Since steps (1) and (2) and the packages used in the \LaTeX\ document
+may vary, it is necessary to apply different filter programs. Until now the only
+two filter programs \texttt{CABebez.pl} and \texttt{CABpict.pl} in the CTAN have
+been developed for the Macintosh version of the geometry software
+\texttt{Cabri-g\'{e}om\`{e}tre}$^{\mathrm{TM}}$ \texttt{II}. The first one
+requires the macro package \texttt{ebezier} \cite{Ba}, the second additionally uses
+the new package \texttt{pict2e} \cite{GaNi}.
+
+The website \emph{Mathkompass} \cite{Mo} contains two filter programs
+\texttt{CDTex} and \texttt{CDebez.pl} for use in conjunction with the drawing
+software \texttt{ClarisDraw}. They were not published in the CTAN because
+\texttt{ClarisDraw} was abandoned when the office program \texttt{AppleWorks}
+was released. The first filter is an AppleScript program written in 2002 mainly
+for tracing already existing figures with the layer technique of
+\texttt{ClarisDraw}. The filter program \texttt{CDebez.pl} is based on
+\texttt{CABebez.pl}, but profits from the fact that \texttt{ClarisDraw}
+has its own PostScript translator which represents cubic B\'{e}zier curves
+directly usable with the package \texttt{ebezier}.
+
+The documentation GaPDoc1.pdf in \cite{GaP} contains the description of the
+GaPFilL method by means of the two prototypes \texttt{CABebez.pl} and
+\texttt{CABpict.pl}. In the next two sections we will concentrate on those
+features of \texttt{OOoDraw} that are useful for the generation of \LaTeX\
+figures. Then the application of the perl system with Mac OS and Windows
+will be described. The last section contains some explanations of the
+characteristics of the filter program \texttt{OOopict.pl} different
+from those of \texttt{CABpict.pl}.
+
+\section{The Drawing Program}
+
+\texttt{OOoDraw} is part of the open-source office software suite
+\texttt{OpenOffice.org 3} which can be downloaded free of charge
+(\texttt{http://www.openoffice.org}, 424 MB). Compared with \texttt{ClarisDraw}
+it is even more powerful. Here only some hints are given which are
+difficult to find in the online help.
+
+\textbf{Customizing Toolbars}
+
+If \texttt{OOoDraw} is mainly used for generating \LaTeX\ figures,
+the entries `Drawing', `Edit Points', `Line and Filling', `Options', `Standard',
+and `Color bar'
+should be selected in the submenu `Toolbars' of the `View' menu. The
+index item `customizing; toolbars' describes how to add or change
+buttons in the toolbars. The `Drawing' bar should visibly contain the
+buttons `Select', `Line', `Square, Unfilled', `Rectangle, Unfilled',
+`Circle, Unfilled', `Ellipse, Unfilled', `Circle Arc', `Arc', `Polygon',
+`Dimension Line', `Curve', `Close B\'{e}zier', `Points', and `Position and
+Size'. The filter program will not process filled objects or arrows.
+
+\textbf{Drawing Curves}
+
+`Drawing' is the most helpful tool because \texttt{OOoDraw} and the
+package \texttt{pict2e} permit to draw arbitrary curves as
+vector graphics with \LaTeX. The help entries `curves; drawing' and
+`curves; editing' describe how to handle these cubic B\'{e}zier
+curves. The filter program \texttt{OOopict.pl} recognises lines
+and curves by the respective line endings in the PostScript file.
+\textbf{Therefore, it is not possible to continue a curve segment with a line.}
+
+Since the packages \texttt{ebezier} and \texttt{pict2e} don't offer
+dotted cubic B\'{e}zier curves, the filter \texttt{OOopict.pl}
+approximates these curves by four quadratic B\'{e}zier curves which
+can be dotted. \texttt{OOopict.pl} generates quadratic B\'{e}zier curves
+from blue or green polygons consisting of two segments. These
+curves which represent parabolas are not visible in the slides of
+\texttt{OOoDraw}. The fact that each quadratic B\'{e}zier curve is a
+special cubic one, may be used to produce visible parabolas
+(see \textsc{Figure} 1).\vspace{2mm}
+
+%Figure 1
+\begin{figure}[tbh]
+ \centering
+\setlength{\unitlength}{0.5pt}
+\begin{picture}(513,559)(93,-694)
+\linethickness{0.8pt}
+%Lines, arrows, polygons and quadratic Bˇzier curves
+\put(120.213,-628.379){\line(6553,16382){188.955}}
+\put(309.168,-156.006){\line(2943,-9131){167.473}}
+\put(246.23,-313.606){\line(12598,-1723){358.448}}
+\put(101.605,-613.584){\line(6463,16156){183.89}}
+\put(101.605,-613.584){\line(6463,16156){183.89}}
+\put(117.567,-627.326){\line(-5,2){23.758}}
+\put(306.522,-154.954){\line(-5,2){23.758}}
+\put(327.776,-170.802){\line(-1017,-2540){57.873}}
+\put(327.776,-170.802){\line(-1017,-2540){57.873}}
+\put(311.814,-157.059){\line(167,-67){23.758}}
+\put(248.876,-314.289){\line(167,-67){23.758}}
+\put(120.213,-628.379){\line(12527,-1660){356.428}}
+%Arrows
+\linethickness{1.2pt}
+\multiput(475.616,-675.611)(2.551,6.236){50}{\line(1,0){2.4}}
+\put(604.5,-362.63){\vector(9,22){0}}
+\put(99.016,-619.872){\vector(-263,-657){0}}
+\put(287.942,-147.641){\vector(113,288){0}}
+\put(330.137,-164.542){\vector(200,521){0}}
+\put(267.314,-321.573){\vector(-58,-135){0}}
+%Cubic Bˇzier curve
+\linethickness{0.8pt}
+\cbezier(120.213,-628.379)(246.23,-313.236)(364.992,-330.536)(476.641,-675.611)
+%\put(109.515,-648.097){$A$}
+\put(109.515,-651){$A$}
+\put(244,-340.393){$B$}
+\put(344,-351.973){$C$}
+\put(470,-696.479){$D$}
+\put(311.586,-149.576){$E$}
+\put(575,-382){$F$}
+\put(171.826,-388.153){$s$}
+\put(301,-261){$\lfrac{1}{3}\:\!s$}
+\end{picture}
+ \caption{Visualization of quadratic B\'{e}zier curves}
+ \label{f.1}\vspace{2mm}
+\end{figure}
+
+The quadratic B\'{e}zier curve generated by the polygon $AED$ is
+exactly the same as the cubic B\'{e}zier curve with the control\vspace{1mm}
+points $A,\ B,\ C,$ and $D$, where $|BE|=\lfrac{1}{3}\,|AE|$, and $ADFB$
+is a parallelogram. The length\vspace{1mm} of segments can be determined with
+the tool `Dimension Line' of \texttt{OOoDraw}.
+
+Some useful drawing aids will be mentioned in the following explanation of how
+to close curves or polygons. The direct way is to double-click the
+starting point and to observe the number of points shown on the
+left-hand side of the `Status Bar' at the bottom of the window. In case it proves
+difficult to snap an object point, you should enlarge the `Snap
+range' in the Menu `Grid' of the \texttt{OOoDraw} `Preferences', or
+zoom in with the sliding control on the right-hand side of
+the Status Bar. The simplest method is presented by the tool `Close
+B\'{e}zier' which closes curves and polygons with a line. As
+explained above, in the case of a curve this line must be converted
+to a curve segment. This can be done with the tools `Smooth
+Transition' or `Symmetric Transition' on the `Edit Points Bar'.
+
+\textbf{Layers and PostScript}
+
+Most drawing programs support layers for the arrangement of elements
+on a page. The objects on each layer can be hidden from view, excluded
+from printing, or locked. For the GaPFilL method the most important
+application is copying pictures by tracing. \texttt{OOoDraw} provides
+three predefined layers: Layout, Controls, and Dimension Lines. The
+Layout layer is the default workspace. Therefore, when opening a file,
+its contents
+is inserted on this layer. Since \texttt{OOoDraw} accepts the
+jpg-format, even photos taken by a digital camera may be traced.
+
+For the traced version you have to add at least one layer by choosing
+`Insert - Layer' or by right-clicking the layer tab area at the
+bottom. At first, tracing should be done with colours that are
+easy to distinguish from the original. Before saving, colours must
+be changed according to the information they have to carry described
+in the next section.
+
+Since the PostScript translator takes into account the contents of all layers,
+even if they are invisible or locked, all but the added
+layers must be emptied before exporting to an eps-file via the menu
+`\texttt{File/Export\ldots}'. In the window `\texttt{EPS Export
+Options}' which opens when you click on `\texttt{Save}', you have to
+select No Preview, Level 2, Color, and No Compression.
+
+\section{The Use of Colours}
+
+With the aid of colours additional information is conveyed to the
+filter program. \texttt{OOoDraw} offers several colour lists. In
+the following we use twelve of the first fourteen colours in the list
+`standard.soc'. All colours of the list are shown in the `Color Bar'.
+Moving the cursor over any of the coloured squares, the name of the colour appears.
+Since most of the names of the same colours in the list `html.soc' are
+more customary, they are also used internally in the filter program. These
+names are added in parentheses to the ``standard names'' in the table at the
+end of this section.\vspace{-1mm}
+
+\setlength{\baselineskip}{16pt}
+There are three methods to colour a line or curve. A colour may be
+preselected by clicking on the corresponding area in the menu `Line
+color' of the toolbar `Line and Filling'. The colour of a selected
+line or curve can be changed by right-clicking on the area of the new
+colour in the `Color Bar'. Finally, dragging a colour of the `Color Bar' to an arbitrary
+line or curve changes its colour if it is different.\vspace{-1mm}
+
+In the following an ``object'' may be a line, a polygon, a circle, an
+arc of a circle, an ellipse, an arc of an ellipse, or a cubic B\'{e}zier curve.
+\vspace{-2mm}
+
+\begin{list}{$\bullet$}{
+ \setlength{\labelwidth}{3mm}
+ \setlength{\leftmargin}{7mm}
+ }
+ \item \emph{Unbroken objects} are drawn with the default colour
+ \fbox{black}.\vspace{1mm}
+
+ \item \emph{Dotted objects} are obtained by using the colour \fbox{light
+ green}.\vspace{1mm}
+
+ \item \emph{Unbroken arrows} must be drawn as a \fbox{turquoise} line.
+ A \fbox{blue} line generates an \emph{arrow with a dotted shank}.
+ \vspace{1mm}
+
+ \item \emph{Unbroken quadratic B\'ezier curves} are entered as\vspace{1mm}
+ \fbox{light blue} polygons with two segments. A \emph{dotted
+ parabola} results from \fbox{green} polygons.\vspace{1mm}
+
+ \item \emph{Text or formula positions} are defined by using\vspace{1mm}
+ lines coloured in \fbox{light cyan}. For the bounding box to be calculated
+ correctly, the marking line should approximately be the diagonal of the
+ smallest rectangle
+ enclosing the text or formula beginning at the lower left corner. In the \LaTeX\ output a serial
+ number will be written at the position of the starting point.\vspace{1mm}
+
+ \item The remaining five colours are used for \emph{filling,
+ hatching} or \emph{dotting} areas bordered by \emph{polygons.} For this purpose
+ the filter program splits the polygon area into triangles which have
+ the starting point of the polygon as a common corner. To avoid
+ overlapping, the given area must be devided into polygons in such a way that
+ for each polygon the triangles arising from connecting the starting
+ point with the other corners have no more than one side in common with
+ the other triangles (see \cite{GaP}).\vspace{1mm}
+
+ \hspace{-4mm}\fbox{Light red} \emph{polygons} will be \emph{filled} without
+ boundary. For \emph{hatching with visible boundary lines} the colour
+ \fbox{red} must be chosen for the polygon;\vspace{1mm} \emph{without boundary
+ lines} the colour \fbox{brown}. If the polygon is \fbox{magenta}-coloured,
+ its area will be \emph{dotted with visible boundary
+ lines};\vspace{0.5mm}
+ using the colour \fbox{light magenta} an area can be \emph{dotted without
+ boundary lines}. The previous assignments of colours are summarized in the
+ following table.\vspace{1mm}
+
+ \item All \emph{drawing elements} coloured in\vspace{0.5mm} \fbox{other
+ colours} may serve as \emph{drawing aids} because they are ignored by the
+ filter program.
+
+\end{list}
+\begin{table}[h]
+ \centering
+ \begin{tabular}{|c|c|}
+ \hline
+ \rule[-2mm]{0mm}{6mm} Type & Colour \\
+ \hline
+ \rule[0mm]{0mm}{4mm} unbroken object & black (black) \\
+ dotted object & light green (lime) \\
+ unbroken arrow & turquoise (teal) \\
+ dotted arrow & blue (navy) \\
+ unbroken quad. B\'ezier curve & light blue (blue) \\
+ dotted quad. B\'ezier curve & green (green) \\
+ text marker & light cyan (cyan) \\
+ filled without border & light red (red) \\
+ hatched with border & red (maroon) \\
+ hatched without border & brown (olive) \\
+ dotted with border & magenta (purple) \\
+ \rule[-2mm]{0mm}{4mm} dotted without border & light magenta (magenta) \\
+ \hline
+ \end{tabular}
+\end{table}\vspace{-3mm}
+
+\section{Application of the Perl system}\vspace{-1mm}
+
+To apply the filter program \texttt{OOopict.pl}, you
+need the Perl system and a text editor able to run a
+script or a command line while a text file is open in its primary window.
+
+\textbf{Mac OS X}
+
+The operating system provides the native Perl system. As a suitable
+source editor \texttt{TextWrangler\ 2.3} is available free of charge
+(\texttt{http://www.barebones.com/\linebreak
+products/textwrangler}). It is a general purpose text editor developed as
+a by-product of the professional HTML and text editor
+\texttt{BBEdit}$^{\mathrm{TM}}$ \texttt{9} of Bare Bones Software, Inc.
+\texttt{TextWrangler} works directly with the Perl system as a Unix
+scripting environment. Therefore, it is accessed via the menu `\verb|#!|'
+which gets its ``name'' from the beginning of the first line in each Unix
+script.
+
+\texttt{OOopict.pl} must be placed in the subdirectory `Unix Filters'
+which is opened by the command `Open Filters Folder' in the submenu
+`Unix Filters' of the menu `\verb|#!|'. With a \texttt{OOoDraw} PostScript
+file open in the primary window, you only have to select
+\texttt{OOopict.pl} from the submenu `Unix Filters'. As if by magic,
+the PostScript text will then be replaced by the corresponding \LaTeX\
+program.
+
+\textbf{Windows and other Operating Systems}
+
+\setlength{\baselineskip}{17pt}
+The complete, ready-to-install Perl distribution \texttt{ActivePerl}
+for Windows, Linux, Mac OS X, Solaris, AIX and HP-UX is available for free
+from ActiveState Software, Inc.
+(\texttt{http://www.activestate.com/activeperl}). This company also offers
+the free and open source editor \texttt{Komodo Edit 5.1}
+(\texttt{http://www.active-\linebreak
+state.com/komodo\_edit}) based on the
+professional \texttt{Komodo}$^{\mathrm{TM}}$ \texttt{IDE}.
+
+After \texttt{ActivePerl} is installed, \texttt{OOopict.pl} can be saved,
+for example, in the directory `\verb|C:\Perl\eg\|'. Having
+opened an \texttt{OOoDraw} PostScript file for the first time and
+typed `ctrl-A', you can select `Run Command' in the menu `Tools'.
+In the command line you will have to enter `\verb|C:\Perl\eg\OOopict.pl|'
+(or the path of the directory you have chosen for \texttt{OOopict.pl}).
+Before running the command, you must activate the checkbox `Pass
+selection as input'. If you also activate the third checkbox, the command
+will be stored in the toolbox from where you can run it by double-clicking
+its name.
+
+\section{The filter program \texttt{OOopict.pl}}
+
+The Perl filter program \texttt{OOopict.pl} has got 701 lines not including
+comment lines beginning with `\#' and the lines containing closing
+braces `\}'. The following line numbers don't belong to
+the program itself.
+
+\begin{small}
+\begin{verbatim}
+ 1 #!/usr/bin/perl -w
+ 2 # OOopict.pl
+\end{verbatim}
+\vspace{-4mm}
+\texttt{\mbox{\quad} 3 \# (c) Copyright 2009 H. Moeller
+(mollerh@math.uni-muenster.de).\\
+\mbox{\quad} 4 \# Version 1.3 for OpenOffice.org 3 Draw with Perl 5.8,\\
+\mbox{\hspace{12mm}} and with the LaTeX-package 'pict2e' from 2008\\
+\mbox{\hspace{12mm}} or with 'pict2e' (2003) and 'ebezier'.\\[-1mm]
+\vspace{-3mm}\mbox{\quad} \ldots}
+\begin{verbatim}
+ 14 # If your package pict2e is from 2008 or later (else $pictnew = 0):
+ 15 $pictnew = 1;
+\end{verbatim}
+\end{small}
+
+Since there are two versions of \texttt{pict2e}, the flag
+\verb|$pictnew| of line 15 is used to switch from the environment of
+\texttt{CABpict.pl} to the new one which doesn't need the package
+\texttt{ebezier}, because the 2008 version of \texttt{pict2e} can handle
+dotted quadratic B\'{e}zier curves. Furthermore, the absolute
+value of the bound of the slope components is increased from 1000 to
+16383 which, in \texttt{OOopict.pl}, is also incorporated into the flag
+\verb|$pictnew|.
+
+Usually the file \texttt{pict2e.sty} is located in a subdirectory
+`\texttt{\ldots/tex/latex/}'. If you don't find it in order to look for the
+version date, you can run a test with a \LaTeX\ program containing
+\verb|\usepackage[pdftex]{pict2e}| in the preamble and a line
+\vspace{-1mm}
+\[\verb|\put(0,0){\line(1001,1000){10}}|\]\\[-6mm]
+in the document. If you have the old version you will get an error message.
+
+If you know where the file \texttt{pict2e.sty} is located, you can
+replace it downloading the directory
+\texttt{pict2e} from \cite{GaNi}, running (or opening) the file
+\texttt{pict2e.dtx} (or \texttt{pict2e.ins}) with \LaTeX\ , and moving the
+resulting \texttt{.sty} file to the desired location.\vspace{-1mm}
+
+\begin{small}
+\begin{verbatim}
+ 46 @lines = <>;
+ 47 do {
+ 48 $_ = $lines[$i++];
+ 49 if ((/ l /o) or (/ ct /o) or (/ p[cs ][\se]/o)) {
+ 50 s/\d+ lw \d+ lj //go;
+ 51 s/ m //go;
+ 52 if (/ c /o) {
+ 53 s/(\d\.\d+) (\d\.\d+) (\d\.\d+) c //o;
+ 54 $c=$1.$2.$3." ";
+ 55 }
+ 56 $t="";
+ 57 $l="";
+ 58 $tflag=0;
+ 59 $fflag=0;
+ 60 while ($_ !~ (/p[cs ][\se]/o)) {
+\end{verbatim}
+\vspace{-3mm}
+\texttt{\vspace{-3mm}\mbox{\quad} \ldots}
+\begin{verbatim}
+ 88 if ($tflag and $fflag) {
+ 89 $curve[++$#curve] = $c.$t;
+ 90 }
+ 91 elsif ($fflag) {
+ 92 $polygon[++$#polygon] = $c.$l;
+ 93 }
+ 94 }
+ 95 }
+ 96 until $i == $#lines;
+\end{verbatim}
+\end{small}
+
+There are three difficulties in filtering the text lines for \LaTeX.
+i) If successive elements (lines, polygons, curves) have the same
+colour, only the first one carries the colour data (lines 52 to 54).
+ii) Long data lines are broken by the PostScript translator
+before getting to the characterizing ending (`\texttt{ps}', `\texttt{pc}'
+or `\texttt{ef}'). Therefore, the successive lines have to be
+assembled in the strings `\verb|$l|' and `\verb|$t|' according to the
+data separators, namely `\texttt{l}' (`\texttt{lineto}') for lines
+and `\texttt{ct}' (`\texttt{curveto}') for curves. iii) Whether an
+object is to be filled, can only be recognized by the ending
+`\texttt{ef}'. Here, the flag `\verb|$fflag|' is
+used to decide which strings have to be saved in the arrays
+`\verb|@curve|' or `\verb|@polygon|' (lines 88 to 92).
+
+Since \texttt{OOopict.pl} only needs two arrays for collecting the
+data strings (instead of five in \texttt{CABpict.pl}), there are at
+most 130 lines for calling the appropriate subprocedures (less than
+half as many as in \texttt{CABpict.pl}). About 120 lines and the
+subprocedure `\texttt{arc}' could be eliminated, because the
+PostScript translator of \texttt{OOoDraw} represents all curves as
+cubic B\'{e}zier curves.
+
+Some of the remaining eight subprocedures differ from those in
+\texttt{CABpict.pl}.
+The subprocedure `\texttt{best}' has been corrected, because in the earlier
+version the fact that the greatest integer of Perl is
+given by $2^{31}-1$ was overlooked. Furthermore, an entry for the upper bound of the
+approximating numerator and denominator has been introduced.
+
+In the subprocedure `\texttt{lin}' dotted lines are now generated with
+the `\verb|\multiput|' command of \LaTeX. Depending on the flag
+\verb|$pictnew| there are two ways to produce dotted quadratic
+B\'{e}zier curves with the subprocedure `\texttt{qbez}' and dotted
+cubic B\'{e}zier curves with `\texttt{cbez}'. As mentioned above, the
+latter is done by approximating cubic B\'{e}zier curves with four quadratic
+B\'{e}zier curves, but the result is only satisfying if the cubic
+B\'{e}zier curve doesn't contain points of inflection or
+self-intersection. This can always be achieved by cutting the cubic
+B\'{e}zier curve into suitable segments with \texttt{OOoDraw}.
+
+\begin{thebibliography}{9}
+
+ \setlength{\baselineskip}{18pt}
+ \bibitem{Ba} Bachmaier, Gerhard A.: Using \texttt{ebezier}.
+ Package in CTAN:\texttt{/macros/latex/contrib/ebe-} \texttt{zier}, 2002.
+
+ \bibitem{GaNi} G\"a{\ss}lein, Hubert, Niepraschk, Rolf and
+ Tkadlec, Josef: The \texttt{pict2e}-package. Package in
+ CTAN:\texttt{/macros/latex/contrib/pict2e/pict2e.dtx},
+ 2008.
+
+ \bibitem{GaP} M\"oller, Herbert: How to generate \LaTeX\
+ \texttt{picture} environments using the GaPFilL method.
+ CTAN:\texttt{/graphics/gapfill/GaPDoc1.pdf}, 2006.
+
+ \bibitem{Mo} M\"oller, Herbert: \emph{Mathkompass}
+ (\texttt{http://wwwmath.uni-muenster.de/u/mollerh}).
+
+\end{thebibliography}
+\end{document}
diff --git a/graphics/gapfill/Mac_OS_only/CABebez.pl b/graphics/gapfill/Mac_OS_only/CABebez.pl
new file mode 100755
index 0000000000..d3b7acd68f
--- /dev/null
+++ b/graphics/gapfill/Mac_OS_only/CABebez.pl
@@ -0,0 +1,935 @@
+#!perl -w
+# CABebez.pl
+# (c) Copyright 2006 by H. Mller (mollerh@math.uni-muenster.de).
+# Version 1.2 for Cabri-gˇom¸tre II with MacOS 9.x, Virtual Printer as PostScript driver, MacPerl 5.6, and LATEX-packages 'pict2e' and 'ebezier'.
+# This program may be distributed and/or modified under the conditions of the LaTeX Project Public License, either version 1.3 of this license or (at your option) any later version.
+# The latest version of this license is in http://www.latex-project.org/lppl.txt.
+# This program has the LPPL maintenance status "maintained". The Current Maintainer of this program is H. Mller.
+#
+use POSIX('ceil','floor');
+#________________________________________________________
+# Definable by user:
+# Unitlength in pt:
+$ul = 1.0;
+# Fill factor (for filling with magnification up to 500%):
+$fillf = 5;
+# Bˇzier factor:
+$bezf = 2.0;
+# Point factor:
+$pointf = 0.3;
+#________________________________________________________
+# Constants:
+# Color names:
+$yellow = "0.9843900.9511410.020249";
+$orange = "1.0000000.3927370.009949";
+$red = "0.8649270.0342110.025910";
+$purple = "0.9486080.0325630.519234";
+$violet = "0.2769050.0000000.645487";
+$navy = "0.0000000.0000000.828138";
+$blue = "0.0088040.6692610.917967";
+$green = "0.1215990.7170980.078874";
+$darkgreen = "0.0000000.3933010.069093";
+$darkbrown = "0.3359430.1742730.020081";
+$brown = "0.5657890.4428780.227359";
+#________________________________________________________
+# Further Constants:
+# Pi:
+$Pi = "3.14159265358979";
+# Constant in cubic Bˇzier curves for quarters of a circle:
+$l90 = "0.552284749830794";
+# Constants in dotted figures:
+$uli = sp(4 / $ul);
+$ule = sp(0.8 / $ul);
+#________________________________________________________
+@lines = <>;
+do {
+ $_ = $lines[$i++];
+ if (/ setrgbcolor \s/o) {
+ s/ //go;
+ s/setrgbcolor\s/ /o;
+ $c = $_;
+ $_ = $lines[$i++];
+ s/ moveto//o;
+ s/lineto stroke/stroke/o;
+ s/curveto stroke/curveto/o;
+ s/ setlinewidth stroke//o;
+ s/ lineto//go;
+ if (/stroke/o) {
+ $line[++$#line] = $c.$_;
+ }
+ elsif (/closepath fill/o) {
+ $vector[++$#vector] = $_;
+ }
+ elsif (/arc /o) {
+ $circle[++$#circle] = $c.$_;
+ }
+ elsif (/arcn/o) {
+ $arc[++$#arc] = $c.$_;
+ }
+ elsif (/curveto/o) {
+ do {
+ $conic[++$#conic] = $c.$_;
+ $_ = $lines[$i++];
+ s/ moveto//o;
+ s/curveto stroke/curveto/o;
+ }
+ until $_ !~ /curveto/o;
+ }
+ }
+}
+until $i == $#lines;
+#
+$pflag = 1;
+$sflag = 1;
+$thicknessflag = 1;
+$coun = 0;
+$bmax = 500;
+$xtex = "";
+$mtex = "";
+$btex = "\\documentclass{article}\n\\usepackage{ebezier}\n\n";
+#________________________________________________________
+# Lines and polygons
+$cflag = 1;
+foreach (@line) {
+ @coo = split;
+ $co0 = $coo[0];
+ $co2 = (-1) * $coo[2];
+ $co4 = (-1) * $coo[4];
+ if ($co0 ne $yellow) {
+ if ($cflag) {
+ $xtex .= "%Lines, arrows, polygons and Bˇzier curves\n";
+ $cflag = 0;
+ }
+ if ($co0 ne $blue) {
+ bound($coo[1],$co2);
+ bound($coo[3],$co4);
+ }
+ if (($co0 ne $red) and ($co0 ne $blue) and ($co0 ne $brown)
+ and ($co0 ne $darkbrown) and ($co0 ne $navy)) {
+ lin($co0,$coo[1] * $ul,$co2 * $ul,$coo[3] * $ul,$co4 * $ul);
+ }
+ if (($co0 ne $green) and ($co0 ne $darkgreen) and ($co0 ne $violet)) {
+ if ($pflag) {
+ $cb1 = $coo[1];
+ $cb2 = $co2;
+ $pol = $co0." ".$cb1." ".$cb2;
+ $pflag = 0;
+ }
+ else {
+ $pol .= " ".$coo[1]." ".$co2;
+ if (abs($coo[3] - $cb1) + abs($co4 - $cb2) < 2.0E-6) {
+ $poly[++$#poly] = $pol;
+ $pflag = 1;
+ }
+ }
+ }
+ }
+}
+#
+foreach (@poly) {
+ @po = split;
+ $p0 = $po[0];
+ $pon = $#po;
+ if (($p0 eq $red) or ($p0 eq $purple) or ($p0 eq $darkbrown)
+ or ($p0 eq $orange) or ($p0 eq $brown)) {
+ if ($pon == 6) {
+ tri($p0,$po[1],$po[2],$po[3],$po[4],$po[5],$po[6]);
+ }
+ elsif ($pon == 8) {
+ ($p0,$u1,$v1,$u2,$v2,$u3,$v3,$u4,$v4) = @po;
+ $s1 = abs($u1 - $u4) + abs($u2 - $u3) + abs($v1 - $v2) + abs($v3 -$v4);
+ $s2 = abs($u1 - $u2) + abs($u3 - $u4) + abs($v1 - $v4) + abs($v2 -$v3);
+ if (($s1 < 4.0E-6) or ($s2 < 4.0E-6)) {
+ bound($u1,$v1);
+ bound($u3,$v3);
+ rect($p0,$u1,$v1,$u2,$v2,$u3,$v3,$u4,$v4);
+ }
+ else {
+ bound($u1,$v1);
+ bound($u2,$v2);
+ bound($u3,$v3);
+ bound($u4,$v4);
+ tri($p0,$u1,$v1,$u2,$v2,$u3,$v3);
+ tri($p0,$u1,$v1,$u3,$v3,$u4,$v4);
+ }
+ }
+ elsif ($pon > 8) {
+ bound($po[1],$po[2]);
+ for (my $j = 3; $j <= $pon - 3; $j += 2) {
+ bound($po[$j],$po[$j + 1]);
+ tri($p0,$po[1],$po[2],$po[$j],$po[$j + 1],$po[$j + 2],$po[$j + 3]);
+ }
+ bound($po[$pon - 1],$po[$pon]);
+ }
+ }
+ elsif ($p0 eq $navy) {
+ for (my $j = 1; $j <= $pon - 3; $j +=2) {
+ lin($p0,$po[$j] * $ul,$po[$j + 1] * $ul,$po[$j + 2] * $ul,$po[$j + 3] * $ul);
+ }
+ }
+ elsif ($p0 eq $blue) {
+ if ($pon == 4) {
+#Text marker and Bˇzier curves
+ $coun++;
+ $bo3 = $po[1] + ($po[3] - $po[1]) / $ul;
+ $bo4 = $po[2] + ($po[4] - $po[2]) / $ul;
+ bound($po[1],$po[2]);
+ bound($bo3,$bo4);
+ $po1 = sp($po[1]);
+ $po2 = sp($po[2]);
+ $mtex .= "\\put(".$po1.",".$po2."){".$coun."}\n";
+ }
+ elsif ($pon == 6) {
+ $xtex .= "%Quadratic Bˇzier curve\n";
+ qbez($po[1],$po[2],$po[3],$po[4],$po[5],$po[6]);
+ }
+ elsif ($pon == 8) {
+ $xtex .= "%Cubic Bˇzier curve\n";
+ cbez($po[1],$po[2],$po[3],$po[4],$po[5],$po[6],$po[7],$po[8]);
+ }
+ }
+}
+#________________________________________________________
+# Arrows
+foreach (@vector) {
+ @ve = split;
+ if ($cflag) {
+ $xtex .= "%Arrows\n";
+ $cflag = 0;
+ }
+ $ve[1] = (-1) * $ve[1];
+ $ve[3] = (-1) * $ve[3];
+ $ve[5] = (-1) * $ve[5];
+ $ve[7] = (-1) * $ve[7];
+ bound($ve[0],$ve[1]);
+ bound($ve[2],$ve[3]);
+ bound($ve[6],$ve[7]);
+ $vu0 = $ve[4] + ($ve[0] - $ve[4]) / $ul;
+ $vu1 = $ve[5] + ($ve[1] - $ve[5]) / $ul;
+ $vu2 = $ve[4] + ($ve[2] - $ve[4]) / $ul;
+ $vu3 = $ve[5] + ($ve[3] - $ve[5]) / $ul;
+ $vu6 = $ve[4] + ($ve[6] - $ve[4]) / $ul;
+ $vu7 = $ve[5] + ($ve[7] - $ve[5]) / $ul;
+ tri($red,$vu0,$vu1,$vu2,$vu3,$ve[4],$ve[5]);
+ tri($red,$vu0,$vu1,$vu6,$vu7,$ve[4],$ve[5]);
+}
+#________________________________________________________
+# Conics
+$cflag = 1;
+foreach (@conic) {
+ @po = split;
+ $p0 = $po[0];
+ if ($p0 ne $yellow) {
+ if ($cflag) {
+ $xtex .= "%Conics\n";
+ $cflag = 0;
+ }
+ $po[2] = (-1) * $po[2];
+ $po[4] = (-1) * $po[4];
+ $po[6] = (-1) * $po[6];
+ $po[8] = (-1) * $po[8];
+ cbez($po[1],$po[2],$po[3],$po[4],$po[5],$po[6],$po[7],$po[8]);
+ }
+}
+#________________________________________________________
+# Circles, halves and quarters of circles
+$cflag = 1;
+$aflag = 1;
+foreach (@circle) {
+ @po = split;
+ $p0 = $po[0];
+ if ($p0 ne $yellow) {
+ $po[2] = (-1) * $po[2];
+ if ($po[4] > 1.0E-3 or abs($po[5] - 360) > 1.0E-3) {
+ if ($aflag) {
+ $xtex .= "%Arcs\n";
+ $aflag = 0;
+ }
+ $arce = ($po[4] > 0) ? 360 - $po[4] : 0;
+ $arcb = ($po[5] > 0) ? 360 - $po[5] : 0;
+ $darc = $arce - $arcb;
+ if ($darc < 0) {$darc += 360}
+ $quar = int($darc / 90);
+ $lq = ($p0 eq $darkgreen) ? $pointf : $bezf;
+ if ($quar > 0) {
+ for (my $k = 1; $k <= $quar; $k++) {
+ quart($po[1],$po[2],$po[3],$arcb,$lq);
+ $arcb += 90;
+ if ($arcb > 360) {$arcb -= 360}
+ }
+ }
+ if ($darc > $quar * 90) {
+ arc($po[1],$po[2],$po[3],$arcb,$arce,$lq);
+ }
+ }
+ else {
+ if ($cflag) {
+ $xtex .= "%Circles, halves and quarters of circles\n";
+ $cflag = 0
+ }
+ if ($p0 eq $navy) {
+ quart($po[1],$po[2],$po[3],0,$bezf);
+ quart($po[1],$po[2],$po[3],90,$bezf);
+ quart($po[1],$po[2],$po[3],180,$bezf);
+ quart($po[1],$po[2],$po[3],270,$bezf);
+ }
+ elsif ($p0 eq $purple) {
+ quart($po[1],$po[2],$po[3],90,$bezf);
+ quart($po[1],$po[2],$po[3],180,$bezf);
+ }
+ elsif ($p0 eq $red) {
+ quart($po[1],$po[2],$po[3],0,$bezf);
+ quart($po[1],$po[2],$po[3],270,$bezf);
+ }
+ elsif ($p0 eq $orange) {
+ quart($po[1],$po[2],$po[3],180,$bezf);
+ quart($po[1],$po[2],$po[3],270,$bezf);
+ }
+ elsif ($p0 eq $darkbrown) {
+ quart($po[1],$po[2],$po[3],0,$bezf);
+ quart($po[1],$po[2],$po[3],90,$bezf);
+ }
+ elsif ($p0 eq $blue) {
+ quart($po[1],$po[2],$po[3],180,$bezf);
+ }
+ elsif ($p0 eq $green) {
+ quart($po[1],$po[2],$po[3],90,$bezf);
+ }
+ elsif ($p0 eq $brown) {
+ quart($po[1],$po[2],$po[3],270,$bezf);
+ }
+ elsif ($p0 eq $violet) {
+ quart($po[1],$po[2],$po[3],0,$bezf);
+ }
+ elsif ($p0 eq $darkgreen) {
+ quart($po[1],$po[2],$po[3],0,$pointf);
+ quart($po[1],$po[2],$po[3],90,$pointf);
+ quart($po[1],$po[2],$po[3],180,$pointf);
+ quart($po[1],$po[2],$po[3],270,$pointf);
+ }
+ }
+ }
+}
+#________________________________________________________
+# Arcs
+$aflag = 1;
+foreach (@arc) {
+ @po = split;
+ if ($aflag) {
+ $xtex .= "%Arcs\n";
+ $aflag = 0;
+ }
+ $po[2] = (-1) * $po[2];
+ $arcb = ($po[4] > 0) ? 360 - $po[4] : 0;
+ $arce = ($po[5] > 0) ? 360 - $po[5] : 0;
+ $darc = $arce - $arcb;
+ if ($darc < 0) {$darc += 360}
+ $quar = int($darc / 90);
+ $lq = ($po[0] eq $darkgreen) ? $pointf : $bezf;
+ if ($quar > 0) {
+ for (my $k = 1; $k <= $quar; $k++) {
+ quart($po[1],$po[2],$po[3],$arcb,$lq);
+ $arcb += 90;
+ if ($arcb > 360) {$arcb -= 360}
+ }
+ }
+ if ($darc > $quar * 90) {
+ arc($po[1],$po[2],$po[3],$arcb,$arce,$lq);
+ }
+}
+#________________________________________________________
+# Frame
+if ($bmax > 500) {
+ $bmax = 100 * ceil($bmax / 100);
+ $btex .= "\\renewcommand{\\qbeziermax}{".$bmax."}\n";
+}
+if ($xtex . $mtex ne "") {
+$xtex = $btex."\\begin{document}\n\n\\setlength{\\unitlength}{".
+$ul."pt}\n"."\\begin{picture}(".ceil(($xmax - $xmin)).",".
+ceil(($ymax - $ymin)).")(".floor($xmin).",".floor($ymin).")\n".
+"\\linethickness{0.8pt}\n"."\\thicklines\n".$xtex;
+$xtex .= $mtex."\\end{picture}\n\n\\end{document}";
+}
+print $xtex."\n";
+#
+#________________________________________________________
+# Lines
+sub lin {
+ my ($c,$xb,$yb,$xe,$ye) = @_;
+ if (($c eq $green) or ($c eq $violet) or ($c eq $orange) or
+ ($c eq $purple) or ($c eq $navy)) {
+ $dx = $xe - $xb;
+ $dy = $ye - $yb;
+ $xbu = sp($xb / $ul);
+ $ybu = sp($yb / $ul);
+ if (abs($dx) < 1.0E-6) {
+ $sy = $dy <=> 0;
+ $leu = sp(abs($dy / $ul));
+ $xtex .= "\\put(".$xbu.",".$ybu."){\\line(0,".$sy."){".$leu."}}\n";
+ }
+ elsif (abs($dy) < 1.0E-6) {
+ $sx = $dx <=> 0;
+ $leu = sp(abs($dx / $ul));
+ $xtex .= "\\put(".$xbu.",".$ybu."){\\line(".$sx.",0){".$leu."}}\n";
+ }
+ else {
+ $flag1 = 1;
+ foreach $j (0,1,2,3,4,5,6,8,10,12,13,15,16,18,20,22,24,25,26,27,29,30,34) {
+ $num = int($j / 6) + 1;
+ $den = ($j % 6) + 1;
+ if ($den < $num) {
+ $lem = (int(10 * $den / $num) + 1) / $ul;
+ }
+ else {
+ $lem = 10 / $ul;
+ }
+ if (abs((abs($dy / $dx)) - $num / $den) < 5.0E-4) {
+ if ($dy < 0) {
+ $num = -$num;
+ }
+ if ($dx < 0) {
+ $den = -$den;
+ }
+ $le = abs($dx);
+ $leu = sp(abs($dx) / $ul - 0.1);
+ if ($leu > $lem) {
+ $xtex .= "\\put(".$xbu.",".$ybu."){\\line(".$den.",".$num."){".$leu."}}\n";
+ $flag1 = 0;
+ last;
+ }
+ else {
+ last;
+ }
+ }
+ }
+ if ($flag1) {
+ if (not $thicknessflag) {
+ $xtex .= "\\linethickness{0.8pt}\n";
+ $thicknessflag = 1;
+ }
+ $len = floor($bezf * (sqrt(($xe - $xb)**2 + ($ye - $yb)**2)));
+ if ($len > 0) {
+ if ($len > $bmax) {$bmax = $len}
+ $xeu = sp($xe / $ul);
+ $yeu = sp($ye / $ul);
+ $xtex .= "\\Lbezier[".$len."](".$xbu.",".$ybu.")(".$xeu.",".$yeu.")\n";
+ }
+ }
+ }
+ }
+ elsif ($c eq $darkgreen) {
+ # Dotted line
+ if ($thicknessflag) {
+ $xtex .= "%Dotted line\n\\linethickness{1.2pt}\n";
+ $thicknessflag = 0;
+ }
+ $len = floor($pointf * (sqrt(($xe - $xb)**2 + ($ye - $yb)**2)));
+ if ($len > 0) {
+ if ($len > $bmax) {$bmax = $len}
+ $xbu = sp($xb / $ul);
+ $ybu = sp($yb / $ul);
+ $xeu = sp($xe / $ul);
+ $yeu = sp($ye / $ul);
+ $xtex .= "\\Lbezier[".$len."](".$xbu.",".$ybu.")(".$xeu.",".$yeu.")\n";
+ }
+ }
+}
+#________________________________________________________
+# Triangles
+sub tri {
+my ($q0,$qx1,$qy1,$qx2,$qy2,$qx3,$qy3) = @_;
+ $qx1 = $qx1 * $ul;
+ $qy1 = $qy1 * $ul;
+ $qx2 = $qx2 * $ul;
+ $qy2 = $qy2 * $ul;
+ $qx3 = $qx3 * $ul;
+ $qy3 = $qy3 * $ul;
+ if ($q0 eq $red) {
+# Filled triangle
+ %ha = ($qx1,$qy1,$qx2+1e-07,$qy2+1e-07,$qx3+2e-07,$qy3+2e-07);
+ @hb = ();
+ @hc = ();
+ foreach (sort { $ha{$a} <=> $ha{$b} } keys %ha) {
+ $hb[++$#hb] = $_;
+ $hc[++$#hc] = $ha{$_};
+ }
+ ($qx1,$qx2,$qx3) = @hb;
+ ($qy1,$qy2,$qy3) = @hc;
+ $lin = int(($qy3 - $qy1) * $fillf);
+ $xtex .= "%Filled triangle\n\\linethickness{0.1pt}\n";
+ $si = ($qy3 - $qy1) * $qx2 - ($qx3 - $qx1) * $qy2 - $qx1 * $qy3 + $qx3 * $qy1 <=> 0;
+ $dex = ($qx3 - $qx1) / ($qy3 - $qy1) / $fillf;
+ $d1 = $qy2 - $qy1;
+ $d2 = $qy3 - $qy2;
+ if ($d1 >= 1.0E-3) {
+ $fx1 = ($qx2 - $qx1) / $d1;
+ $sx1 = $qx1 - $qy1 * $fx1;
+ }
+ if ($d2 >= 1.0E-3) {
+ $fx2 = ($qx3 - $qx2) / $d2;
+ $sx2 = $qx2 - $qy2 * $fx2;
+ }
+ for ($k = 1; $k <= $lin; $k++) {
+ $xb = $qx1 + $k * $dex;
+ $yb = $qy1 + $k / $fillf;
+ if ($yb <= $qy2) {
+ if ($d1 >= 1.0E-3) {
+ $leu = sp((abs($sx1 + $yb * $fx1 - $xb) + 0.5) / $ul);
+ }
+ else {
+ $leu = sp((abs($qx2 - $qx1) + 0.5)/ $ul);
+ }
+ }
+ else {
+ if ($d2 >= 1.0E-3) {
+ $leu = sp((abs($sx2 + $yb * $fx2 - $xb) + 0.5)/ $ul);
+ }
+ else {
+ $leu = sp((abs($qx3 - $qx2) + 0.5)/ $ul);
+ }
+ }
+ if ($si > 0) {
+ $xbu = sp($xb / $ul);
+ }
+ else {
+ $xbu = sp($xb / $ul);
+ }
+ $ybu = sp($yb / $ul);
+ $xtex .= "\\put(".$xbu.",".$ybu."){\\line(".$si.",0){".$leu."}}\n";
+ }
+ $xtex .= "\\linethickness{0.8pt}\n";
+ }
+ elsif (($q0 eq $purple) or ($q0 eq $darkbrown)) {
+# Dotted triangle
+ %ha = ($qx1,$qy1,$qx2+1e-07,$qy2+1e-07,$qx3+2e-07,$qy3+2e-07);
+ @hb = ();
+ @hc = ();
+ foreach (sort { $ha{$a} <=> $ha{$b} } keys %ha) {
+ $hb[++$#hb] = $_;
+ $hc[++$#hc] = $ha{$_};
+ }
+ ($qx1,$qx2,$qx3) = @hb;
+ ($qy1,$qy2,$qy3) = @hc;
+ $xtex .= "%Dotted triangle\n";
+ $si = ($qy3 - $qy1) * $qx2 - ($qx3 - $qx1) * $qy2 - $qx1 * $qy3 + $qx3 * $qy1 <=> 0;
+ $dy1 = 2 * ceil($qy1 / 2);
+ $dy3 = 2 * floor($qy3 / 2);
+ $lin = $dy3 - $dy1;
+ $dex = ($qx3 - $qx1) / ($qy3 - $qy1);
+ $xbh = $qx1 + ($dy1 - $qy1 - 2.0) * $dex;
+ $dex = 2 * $dex;
+ $d1 = $qy2 - $qy1;
+ $d2 = $qy3 - $qy2;
+ if ($d1 >= 1.0E-3) {
+ $fx1 = ($qx2 - $qx1) / $d1;
+ $sx1 = $qx1 + ($dy1 - $qy1) * $fx1;
+ }
+ if ($d2 >= 1.0E-3) {
+ $fx2 = ($qx3 - $qx2) / $d2;
+ $sx2 = $qx2 + ($dy1 - $qy2) * $fx2;
+ }
+ for ($k = 0; $k <= $lin; $k += 2) {
+ $qy = $dy1 + $k;
+ $xbh = $xbh + $dex;
+ ($si > 0) ? ($xb = $xbh) : ($xe = $xbh);
+ if ($qy <= $qy2) {
+ ($d1 >= 1.0E-3) ? ($xeh = $sx1 + $k * $fx1) : ($xeh = $qx1);
+ }
+ else {
+ ($d2 >= 1.0E-3) ? ($xeh = $sx2 + $k * $fx2) : ($xeh = $qx2);
+ }
+ ($si > 0) ? ($xe = $xeh) : ($xb = $xeh);
+ $xb = 2 * ceil($xb / 2);
+ $xbd = $xb + (($xb + $qy) % 4);
+ ($xe >= $xbd) ? ($num = floor(($xe - $xbd) / 4) + 1) : ($num = 0);
+ if (not $thicknessflag) {
+ $xtex .= "\\linethickness{0.8pt}\n";
+ $thicknessflag = 1;
+ }
+ $xbu = sp($xbd / $ul);
+ $qyu = sp($qy / $ul);
+ $xtex .= "\\multiput(".$xbu.",".$qyu.")(".$uli.",0){".$num;
+ $xtex .= "}{\\line(1,0){".$ule."}}\n";
+ }
+ }
+ elsif (($q0 eq $orange) or ($q0 eq $brown)) {
+#Hatched triangle
+ $xtex .= "%Hatched triangle\n";
+ $d1 = $qx1 - $qy1;
+ $d2 = $qx2 - $qy2;
+ $d3 = $qx3 - $qy3;
+ $qd1 = $d1;
+ $qd2 = $d2;
+ $qd3 = $d3;
+ %ha = ($qx1,$qd1,$qx2+1e-07,$qd2+1e-07,$qx3+2e-07,$qd3+2e-07);
+ @hb = ();
+ foreach (sort { $ha{$a} <=> $ha{$b} } keys %ha) {
+ $hb[++$#hb] = $_;
+ }
+ ($qx1,$qx2,$qx3) = @hb;
+ %ha = ($qy1,$qd1,$qy2+1e-07,$qd2+1e-07,$qy3+2e-07,$qd3+2e-07);
+ @hb = ();
+ @hc = ();
+ foreach (sort { $ha{$a} <=> $ha{$b} } keys %ha) {
+ $hb[++$#hb] = $_;
+ $hc[++$#hc] = $ha{$_};
+ }
+ ($qy1,$qy2,$qy3) = @hb;
+ ($d1,$d2,$d3) = @hc;
+ $si = (-$qy3 + $qy1) * $qx2 + ($qx3 - $qx1) * $qy2 + $qx1 * $qy3 - $qx3 * $qy1 <=> 0;
+ $p1 = 4 * ceil($d1 / 4);
+ $p2 = 4 * floor($d2 / 4);
+ $p3 = 4 * floor($d3 / 4);
+ $fx1 = ($qx1 - $qx3) / ($d3 - $d1);
+ $sx1 = $qx3 + $fx1 * $d3;
+ $fy1 = ($qy1 - $qy3) / ($d3 - $d1);
+ $sy1 = $qy3 + $fy1 * $d3;
+ $d21 = $d2 - $d1;
+ $d32 = $d3 - $d2;
+ if ($d21 >= 1.0E-3) {
+ $fx2 = ($qx1 - $qx2) / $d21;
+ $sx2 = $qx2 + $fx2 * $d2;
+ }
+ if ($d32 >= 1.0E-3) {
+ $fx3 = ($qx2 - $qx3) / $d32;
+ $sx3 = $qx3 + $fx3 * $d3;
+ }
+ for ($k = $p1; $k <= $p3; $k += 4) {
+ $xbk = $sx1 - $k * $fx1;
+ $ybk = $sy1 - $k * $fy1;
+ if ($k <= $p2) {
+ ($d21 < 1.0E-3) ? ($le = abs($qx2 - $qx1)) : ($le = abs($sx2 - $k * $fx2 - $xbk));
+ }
+ else {
+ ($d32 < 1.0E-3) ? ($le = abs($qx3 - $qx2)) : ($le = abs($sx3 - $k * $fx3 - $xbk));
+ }
+ lin($green,$xbk,$ybk,$xbk + $si * $le,$ybk + $si * $le);
+ }
+ }
+}
+#________________________________________________________
+# Rectangles
+sub rect {
+ my ($q0,$x1,$y1,$x2,$y2,$x3,$y3,$x4,$y4) = @_;
+ $dx = abs($x2 - $x1);
+ $dx = ($dx < 1.0E-6) ? abs($x3 -$x2) : $dx;
+ $dx = $dx * $ul;
+ $xb = ($x1 < $x2) ? (($x1 < $x3) ? $x1 : $x3) : (($x2 < $x3) ? $x2 : $x3);
+ $xb = $xb * $ul;
+ $dy = abs($y2 - $y1);
+ $dy = ($dy < 1.0E-6) ? abs($y3 -$y2) : $dy;
+ $dy = $dy * $ul;
+ $yb = ($y1 < $y2) ? (($y1 < $y3) ? $y1 : $y3) : (($y2 < $y3) ? $y2 : $y3);
+ $yb = $yb * $ul;
+ $xe = $xb + $dx;
+ $ye = $yb + $dy;
+# Filled rectangle
+ if ($q0 eq $red) {
+ $xtex .= "%Filled rectangle\n\\linethickness{0.1pt}\n";
+ $lin = 5 * $dx;
+ if ($dy <= $dx) {
+ $ybf = $yb - 0.2;
+ $xbu = sp($xb / $ul);
+ $dxu = sp($dx / $ul);
+ for ($k = 0; $k <= $lin; $k++) {
+ $ybf += 0.2;
+ $ybu = sp($ybf / $ul);
+ $xtex .= "\\put(".$xbu.",".$ybu."){\\line(1,0){".$dxu."}}\n";
+ }
+ }
+ else {
+ $xbf = $xb - 0.2;
+ $ybu = sp($yb / $ul);
+ $dyu = sp($dy / $ul);
+ for ($k = 0; $k <= $lin; $k++) {
+ $xbf += 0.2;
+ $xbu = sp($xbf / $ul);
+ $xtex .= "\\put(".$xbu.",".$ybu."){\\line(0,1){".$dyu."}}\n";
+ }
+ }
+ $xtex .= "\\linethickness{0.8pt}\n";
+ }
+# Dotted rectangle
+ elsif (($q0 eq $purple) or ($q0 eq $darkbrown)) {
+ $xtex .= "%Dotted rectangle\n";
+ $xbb = 2 * ceil($xb / 2);
+ $ybb = 2 * ceil($yb / 2);
+ for ($k = 0; $k <= 2; $k += 2) {
+ $ybd = $ybb + $k;
+ $xbd = $xbb + (($xbb + $ybd) % 4);
+ $numx = floor(($xe - 0.13 - $xbd) / 4) + 1;
+ $numy = floor(($ye - 0.13 - $ybd) / 4) + 1;
+ $xbu = sp($xbd / $ul);
+ $ybu = sp($ybd / $ul);
+ $xtex .= "\\multiput(".$xbu.",".$ybu.")(".$uli.",0){".$numx;
+ $xtex .= "}{\\begin{picture}(0,0)\\multiput(0,0)(0,".$uli."){".$numy;
+ $xtex .= "}{\\line(1,0){".$ule."}}\\end{picture}}\n"
+ }
+ }
+# Hatched rectangle
+ elsif (($q0 eq $orange) or ($q0 eq $brown)) {
+ $xtex .= "%Hatched rectangle\n";
+ $p1 = 4 * ceil(($xb - $ye) / 4);
+ if ($dx >= $dy) {
+ $p2 = 4 * floor(($xb - $yb) / 4) + 4;
+ $p3 = 4 * floor(($xe - $ye) / 4) + 4;
+ $xp = $yb + $p2;
+ $yp = $yb;
+ $lp = $dy;
+ $ip1 = 4;
+ $ip2 = 0;
+ }
+ else {
+ $p3 = 4 * floor(($xb - $yb) / 4) + 4;
+ $p2 = 4 * floor(($xe - $ye) / 4) + 4;
+ $xp = $xb;
+ $yp = $xb - $p2;
+ $lp = $dx;
+ $ip1 = 0;
+ $ip2 = -4;
+ }
+ $p4 = 4 * floor(($xe - $yb) / 4);
+ for ($k = $p1; $k <= $p2 - 4; $k += 4) {
+ lin($green,$xb,$xb - $k,$ye + $k,$ye);
+ }
+ $np = ($p3 - $p2) / 4;
+ if ($p3 > $p2) {
+ if ($lp >= 10 / $ul) {
+ $xpu = sp($xp / $ul);
+ $ypu = sp($yp / $ul);
+ $ip1u = sp($ip1 / $ul);
+ $ip2u = sp($ip2 / $ul);
+ $lpu = sp($lp / $ul - 0.1);
+ $xtex .= "\\multiput(".$xpu.",".$ypu.")(".$ip1u.",".$ip2u;
+ $xtex .= "){".$np."}{\\line(1,1){".$lpu."}}\n";
+ }
+ else {
+ for ($k = 0; $k <=$np -1; $k++) {
+ $u = $xp + $k * $ip1;
+ $v = $yp + $k * $ip2;
+ lin($green,$u,$v,$u + $lp,$v + $lp);
+ }
+ }
+ }
+ for ($k = $p3; $k <= $p4; $k += 4) {
+ lin($green,$yb + $k,$yb,$xe,$xe - $k);
+ }
+ }
+}
+#________________________________________________________
+# Quadratic Bˇzier curve
+sub qbez {
+ my ($x1,$y1,$x2,$y2,$x3,$y3) = @_;
+ $xb = $x1;
+ $yb = $y1;
+ $len = 0.0;
+ for ($t = 0.02; $t <= 1.0; $t += 0.02) {
+ bound($xb,$yb);
+ $s = 1.0 - $t;
+ $xe = $s * ($s * $x1 + $t * $x2) + $t * ($s * $x2 + $t * $x3);
+ $ye = $s * ($s * $y1 + $t * $y2) + $t * ($s * $y2 + $t * $y3);
+ $len += sqrt(($xe - $xb)**2 + ($ye - $yb)**2);
+ $xb = $xe;
+ $yb = $ye;
+ }
+ bound($x3,$y3);
+ $le = int($bezf * $len * $ul);
+ if ($le > $bmax) {$bmax = $le}
+ $x1 = sp($x1);
+ $y1 = sp($y1);
+ $x2 = sp($x2);
+ $y2 = sp($y2);
+ $x3 = sp($x3);
+ $y3 = sp($y3);
+ $xtex .= "\\Qbezier[".$le."](".$x1.",".$y1.")(".$x2.",".$y2;
+ $xtex .= ")(".$x3.",".$y3.")\n";
+}
+#________________________________________________________
+# Cubic Bˇzier curve
+#
+sub cbez {
+ my ($x1,$y1,$x2,$y2,$x3,$y3,$x4,$y4) = @_;
+ $xb = $x1;
+ $yb = $y1;
+ $len = 0.0;
+ for ($t = 0.02; $t <= 1.0; $t += 0.02) {
+ bound($xb,$yb);
+ $s = 1.0 - $t;
+ $u1 = $s * $x1 + $t * $x2;
+ $v1 = $s * $y1 + $t * $y2;
+ $u2 = $s * $x2 + $t * $x3;
+ $v2 = $s * $y2 + $t * $y3;
+ $u3 = $s * $x3 + $t * $x4;
+ $v3 = $s * $y3 + $t * $y4;
+ $xe = $s * ($s * $u1 + $t * $u2) + $t * ($s * $u2 + $t * $u3);
+ $ye = $s * ($s * $v1 + $t * $v2) + $t * ($s * $v2 + $t * $v3);
+ $len += sqrt(($xe - $xb)**2 + ($ye - $yb)**2);
+ $xb = $xe;
+ $yb = $ye;
+ }
+ bound($x4,$y4);
+ $le = int($bezf * $len * $ul);
+ if ($le > 0) {
+ if ($le > $bmax) {$bmax = $le}
+ $x1 = sp($x1);
+ $y1 = sp($y1);
+ $x2 = sp($x2);
+ $y2 = sp($y2);
+ $x3 = sp($x3);
+ $y3 = sp($y3);
+ $x4 = sp($x4);
+ $y4 = sp($y4);
+ $xtex .= "\\cbezier[".$le."](".$x1.",".$y1.")(".$x2.",";
+ $xtex .= $y2.")(".$x3.",".$y3.")(".$x4.",".$y4.")\n";
+ }
+}
+#________________________________________________________
+# Quarters of circles
+#
+sub quart {
+ my ($xm,$ym,$r,$al,$bf) = @_;
+ if ($al == 0) {
+ $dx1 = $r;
+ $dy1 = 0;
+ }
+ elsif ($al == 90) {
+ $dx1 = 0;
+ $dy1 = $r;
+ }
+ elsif ($al == 180) {
+ $dx1 = (-1) * $r;
+ $dy1 = 0;
+ }
+ elsif ($al == 270) {
+ $dx1 = 0;
+ $dy1 = (-1) * $r;
+ }
+ else {
+ $al1 = $al * $Pi / 180;
+ $dx1 = $r * cos($al1);
+ $dy1 = $r * sin($al1);
+ $gal = 90 * ceil($al / 90);
+ if (($gal == 0) and ($al != 0)) {
+ $gx1 = $r;
+ $gy1 = 0;
+ }
+ elsif (($gal == 90) and ($al != 90)) {
+ $gx1 = 0;
+ $gy1 = $r;
+ }
+ elsif (($gal == 180) and ($al != 180)) {
+ $gx1 = (-1) * $r;
+ $gy1 = 0;
+ }
+ elsif (($gal == 270) and ($al != 270)) {
+ $gx1 = 0;
+ $gy1 = (-1) * $r;
+ }
+ bound($xm + $gx1,$ym + $gy1);
+ }
+ $dx4 = (-1) * $dy1;
+ $dy4 = $dx1;
+ $x1 = $xm + $dx1;
+ $y1 = $ym + $dy1;
+ $x4 = $xm + $dx4;
+ $y4 = $ym + $dy4;
+ bound($x1,$y1);
+ bound($x4,$y4);
+ $x2 = $x1 + $l90 * $dx4;
+ $y2 = $y1 + $l90 * $dy4;
+ $x3 = $x4 + $l90 * $dx1;
+ $y3 = $y4 + $l90 * $dy1;
+ $le = int($bf * $Pi * $r * $ul/ 2);
+ if ($le > $bmax) {$bmax = $le}
+ $x1 = sp($x1);
+ $y1 = sp($y1);
+ $x2 = sp($x2);
+ $y2 = sp($y2);
+ $x3 = sp($x3);
+ $y3 = sp($y3);
+ $x4 = sp($x4);
+ $y4 = sp($y4);
+ $xtex .= "\\cbezier[".$le."](".$x1.",".$y1.")(".$x2;
+ $xtex .= ",".$y2.")(".$x3.",".$y3.")(".$x4.",".$y4.")\n";
+}
+#________________________________________________________
+# Short arcs
+sub arc {
+ my ($xm,$ym,$r,$al,$be,$bf) = @_;
+ $al1 = $al * $Pi / 180;
+ $be1 = $be * $Pi / 180;
+ $dx1 = $r * cos($al1);
+ $dy1 = $r * sin($al1);
+ $dx4 = $r * cos($be1);
+ $dy4 = $r * sin($be1);
+ $x1 = $xm + $dx1;
+ $y1 = $ym + $dy1;
+ $x4 = $xm + $dx4;
+ $y4 = $ym + $dy4;
+ bound($x1,$y1);
+ bound($x4,$y4);
+ $gal = 90 * int($al / 90);
+ $gbe = 90 * int($be / 90);
+ if ($gal != $gbe) {
+ if ($gbe == 0) {
+ $gx1 = $r;
+ $gy1 = 0;
+ }
+ elsif ($gbe == 90) {
+ $gx1 = 0;
+ $gy1 = $r;
+ }
+ elsif ($gbe == 180) {
+ $gx1 = (-1) * $r;
+ $gy1 = 0;
+ }
+ elsif ($gbe == 270) {
+ $gx1 = 0;
+ $gy1 = (-1) * $r;
+ }
+ bound($xm + $gx1,$ym + $gy1);
+ }
+ $aux = 4 * (2 * $r - sqrt(($dx1 + $dx4)**2 + ($dy1 + $dy4)**2)) / 3;
+ $lam = $aux / sqrt(($dx1 - $dx4)**2 + ($dy1 - $dy4)**2);
+ $x2 = $x1 - $lam * $dy1;
+ $y2 = $y1 + $lam * $dx1;
+ $x3 = $x4 + $lam * $dy4;
+ $y3 = $y4 - $lam * $dx4;
+ $d1 = abs($al1 - $be1);
+ if ($d1 > $Pi / 2) {$d1 = 2 * $Pi - $d1}
+ $le = int($bf * $d1 * $r * $ul);
+ if ($le > $bmax) {$bmax = $le}
+ $x1 = sp($x1);
+ $y1 = sp($y1);
+ $x2 = sp($x2);
+ $y2 = sp($y2);
+ $x3 = sp($x3);
+ $y3 = sp($y3);
+ $x4 = sp($x4);
+ $y4 = sp($y4);
+ $xtex .= "\\cbezier[".$le."](".$x1.",".$y1.")(".$x2.",";
+ $xtex .= $y2.")(".$x3.",".$y3.")(".$x4.",".$y4.")\n";
+}
+#________________________________________________________
+# Bounding box
+sub bound {
+ my ($xn,$yn) = @_;
+ if ($sflag) {
+ $xmin = $xn;
+ $xmax = $xn;
+ $ymin = $yn;
+ $ymax = $yn;
+ $sflag = 0;
+ }
+ else {
+ if ($xn < $xmin) {$xmin = $xn} elsif ($xmax < $xn) {$xmax = $xn}
+ if ($yn < $ymin) {$ymin = $yn} elsif ($ymax < $yn) {$ymax = $yn}
+ }
+}
+#________________________________________________________
+# Sprintf
+sub sp {
+ my $x = shift;
+ return sprintf("%.3f",$x) + 0;
+}
+#________________________________________________________
diff --git a/graphics/gapfill/Mac_OS_only/CABpict.pl b/graphics/gapfill/Mac_OS_only/CABpict.pl
new file mode 100755
index 0000000000..bf124726b1
--- /dev/null
+++ b/graphics/gapfill/Mac_OS_only/CABpict.pl
@@ -0,0 +1,958 @@
+#!/usr/bin/perl -w
+# CABpict.pl
+# (c) Copyright 2006 by H. Moeller (mollerh@math.uni-muenster.de).
+# Version 1.2 for Cabri-gˇom¸tre II with MacOS 9.x, Virtual Printer as PostScript driver, MacPerl 5.6, and LATEX-packages 'pict2e' and 'ebezier'.
+# This program may be distributed and/or modified under the conditions of the LaTeX Project Public License, either version 1.3 of this license or (at your option) any later version.
+# The latest version of this license is in http://www.latex-project.org/lppl.txt.
+# This program has the LPPL maintenance status "maintained". The Current Maintainer of this program is H. Möller.
+#
+use POSIX('ceil','floor');
+#________________________________________________________
+# Definable by the user:
+# Unitlength in pt:
+$ul = 1.0;
+# Fill factor (for filling with magnification up to 500%)
+$fillf = 5;
+# Point factor:
+$pointf = 0.3;
+# Flag for the dotting of parabolic arcs (1: Dotting)
+$Qbezflag = 0;
+#________________________________________________________
+# Constants:
+# Color names:
+$yellow = "0.9843900.9511410.020249";
+$orange = "1.0000000.3927370.009949";
+$red = "0.8649270.0342110.025910";
+$purple = "0.9486080.0325630.519234";
+$violet = "0.2769050.0000000.645487";
+$navy = "0.0000000.0000000.828138";
+$blue = "0.0088040.6692610.917967";
+$green = "0.1215990.7170980.078874";
+$darkgreen = "0.0000000.3933010.069093";
+$darkbrown = "0.3359430.1742730.020081";
+$brown = "0.5657890.4428780.227359";
+#________________________________________________________
+# Further Constants:
+# Pi:
+$Pi = "3.14159265358979";
+# Floor of the tenth part of the greatest integer of Perl
+$gi = 214748364;
+# Constants in dotted figures:
+$uli = sp(4 / $ul);
+$ule = sp(0.8 / $ul);
+#________________________________________________________
+@lines = <>;
+do {
+ $_ = $lines[$i++];
+ if (/ setrgbcolor \s/o) {
+ s/ //go;
+ s/setrgbcolor\s/ /o;
+ $c = $_;
+ $_ = $lines[$i++];
+ s/ moveto//o;
+ s/lineto stroke/stroke/o;
+ s/curveto stroke/curveto/o;
+ s/ setlinewidth stroke//o;
+ s/ lineto//go;
+ if (/stroke/o) {
+ $line[++$#line] = $c.$_;
+ }
+ elsif (/closepath fill/o) {
+ $vector[++$#vector] = $c.$_;
+ }
+ elsif (/arc /o) {
+ $circle[++$#circle] = $c.$_;
+ }
+ elsif (/arcn/o) {
+ $arc[++$#arc] = $c.$_;
+ }
+ elsif (/curveto/o) {
+ do {
+ $conic[++$#conic] = $c.$_;
+ $_ = $lines[$i++];
+ s/ moveto//o;
+ s/curveto stroke/curveto/o;
+ }
+ until $_ !~ /curveto/o;
+ }
+ }
+}
+until $i == $#lines;
+#
+$pflag = 1;
+$sflag = 1;
+$thicknessflag = 1;
+$coun = 0;
+$xtex = "";
+$mtex = "";
+#________________________________________________________
+# Lines and polygons
+$cflag = 1;
+foreach (@line) {
+ @coo = split;
+ $co0 = $coo[0];
+ $co2 = (-1) * $coo[2];
+ $co4 = (-1) * $coo[4];
+ if (($co0 ne $violet) and ($co0 ne $yellow)) {
+ if ($cflag) {
+ $xtex .= "%Lines, arrows, polygons and Bezier curves\n";
+ $cflag = 0;
+ }
+ if ($co0 ne $blue) {
+ bound($coo[1],$co2);
+ bound($coo[3],$co4);
+ }
+ if (($co0 ne $red) and ($co0 ne $blue) and ($co0 ne $brown)
+ and ($co0 ne $darkbrown) and ($co0 ne $navy)) {
+ lin($co0,$coo[1],$co2,$coo[3],$co4);
+ }
+ if (($co0 ne $green) and ($co0 ne $darkgreen)) {
+ if ($pflag) {
+ $cb1 = $coo[1];
+ $cb2 = $co2;
+ $pol = $co0." ".$cb1." ".$cb2;
+ $pflag = 0;
+ }
+ else {
+ $pol .= " ".$coo[1]." ".$co2;
+ if (abs($coo[3] - $cb1) + abs($co4 - $cb2) < 2.0E-6) {
+ $poly[++$#poly] = $pol;
+ $pflag = 1;
+ }
+ }
+ }
+ }
+ if ($co0 eq $violet) {
+ $xtex .= "%Arrow\n";
+ bound($coo[1],$co2);
+ bound($coo[3],$co4);
+ $dx = $coo[3] - $coo[1];
+ $dy = $co4 - $co2;
+ $len = sp(abs($dx));
+ if ($len > 1.0E-3) {
+ @p = best(abs($dy / $dx));
+ $psx = sp($p[1]) * ($dx <=> 0);
+ $psy = sp($p[0]) * ($dy <=> 0);
+ }
+ else {
+ $psx = 0;
+ $psy = ($dy <=> 0);
+ $len = sp(abs($dy));
+ }
+ $xb = sp($coo[1]);
+ $yb = sp($co2);
+ if (not $thicknessflag) {
+ $xtex .= "\\linethickness{0.8pt}\n";
+ $thicknessflag = 1;
+ }
+ $xtex .= "\\put(".$xb.",".$yb."){\\vector(".$psx.",".$psy."){".$len."}}\n";
+ }
+}
+#
+foreach (@poly) {
+ @po = split;
+ $p0 = $po[0];
+ $pon = $#po;
+ if (($p0 eq $red) or ($p0 eq $purple) or ($p0 eq $darkbrown)
+ or ($p0 eq $orange) or ($p0 eq $brown)) {
+ if ($pon == 6) {
+ tri($p0,$po[1],$po[2],$po[3],$po[4],$po[5],$po[6]);
+ }
+ elsif ($pon == 8) {
+ ($p0,$u1,$v1,$u2,$v2,$u3,$v3,$u4,$v4) = @po;
+ $s1 = abs($u1 - $u4) + abs($u2 - $u3) + abs($v1 - $v2) + abs($v3 -$v4);
+ $s2 = abs($u1 - $u2) + abs($u3 - $u4) + abs($v1 - $v4) + abs($v2 -$v3);
+ if (($s1 < 4.0E-6) or ($s2 < 4.0E-6)) {
+ bound($u1,$v1);
+ bound($u3,$v3);
+ rect($p0,$u1,$v1,$u2,$v2,$u3,$v3,$u4,$v4);
+ }
+ else {
+ bound($u1,$v1);
+ bound($u2,$v2);
+ bound($u3,$v3);
+ bound($u4,$v4);
+ tri($p0,$u1,$v1,$u2,$v2,$u3,$v3);
+ tri($p0,$u1,$v1,$u3,$v3,$u4,$v4);
+ }
+ }
+ elsif ($pon > 8) {
+ bound($po[1],$po[2]);
+ for (my $j = 3; $j <= $pon - 3; $j += 2) {
+ bound($po[$j],$po[$j + 1]);
+ tri($p0,$po[1],$po[2],$po[$j],$po[$j + 1],$po[$j + 2],$po[$j + 3]);
+ }
+ bound($po[$pon - 1],$po[$pon]);
+ }
+ }
+ elsif ($p0 eq $navy) {
+ for (my $j = 1; $j <= $pon - 3; $j +=2) {
+ lin($p0,$po[$j],$po[$j + 1],$po[$j + 2],$po[$j + 3]);
+ }
+ }
+ elsif ($p0 eq $blue) {
+ if ($pon == 4) {
+# Text marker and Bezier curves
+ $coun++;
+ $bo3 = $po[1] + ($po[3] - $po[1]) / $ul;
+ $bo4 = $po[2] + ($po[4] - $po[2]) / $ul;
+ bound($po[1],$po[2]);
+ bound($bo3,$bo4);
+ $po1 = sp($po[1]);
+ $po2 = sp($po[2]);
+ $mtex .= "\\put(".$po1.",".$po2."){".$coun."}\n";
+ }
+ elsif ($pon == 6) {
+ $xtex .= "%Quadratic Bezier curve\n";
+ qbez($po[1],$po[2],$po[3],$po[4],$po[5],$po[6]);
+ }
+ elsif ($pon == 8) {
+ $xtex .= "%Cubic Bezier curve\n";
+ cbez($po[1],$po[2],$po[3],$po[4],$po[5],$po[6],$po[7],$po[8]);
+ }
+ }
+}
+#________________________________________________________
+# Arrows
+foreach (@vector) {
+ @ve = split;
+ if ($ve[0] eq $darkgreen) {
+ if ($cflag) {
+ $xtex .= "%Arrow\n";
+ $cflag = 0;
+ }
+ $ve[2] = (-1) * $ve[2];
+ $ve[4] = (-1) * $ve[4];
+ $ve[6] = (-1) * $ve[6];
+ $ve[8] = (-1) * $ve[8];
+ bound($ve[1],$ve[2]);
+ bound($ve[3],$ve[4]);
+ bound($ve[7],$ve[8]);
+ $vu0 = $ve[5] + ($ve[1] - $ve[5]) / $ul;
+ $vu1 = $ve[6] + ($ve[2] - $ve[6]) / $ul;
+ $vu2 = $ve[5] + ($ve[3] - $ve[5]) / $ul;
+ $vu3 = $ve[6] + ($ve[4] - $ve[6]) / $ul;
+ $vu6 = $ve[5] + ($ve[7] - $ve[5]) / $ul;
+ $vu7 = $ve[6] + ($ve[8] - $ve[6]) / $ul;
+ tri($red,$vu0,$vu1,$vu2,$vu3,$ve[5],$ve[6]);
+ tri($red,$vu0,$vu1,$vu6,$vu7,$ve[5],$ve[6]);
+ }
+}
+#________________________________________________________
+# Conics
+$cflag = 1;
+foreach (@conic) {
+ @po = split;
+ $p0 = $po[0];
+ if ($p0 ne $yellow) {
+ if ($cflag) {
+ $xtex .= "%Conics\n";
+ $cflag = 0;
+ }
+ $po[2] = (-1) * $po[2];
+ $po[4] = (-1) * $po[4];
+ $po[6] = (-1) * $po[6];
+ $po[8] = (-1) * $po[8];
+ cbez($po[1],$po[2],$po[3],$po[4],$po[5],$po[6],$po[7],$po[8]);
+ }
+}
+#________________________________________________________
+# Circles, halves and quarters of circles
+$cflag = 1;
+$aflag = 1;
+foreach (@circle) {
+ @po = split;
+ $p0 = $po[0];
+ if ($p0 ne $yellow) {
+ $po[2] = (-1) * $po[2];
+ $di = 2 * $po[3];
+ if ($po[4] > 1.0E-3 or abs($po[5] - 360) > 1.0E-3) {
+ if ($aflag) {
+ $xtex .= "%Arcs\n";
+ $aflag = 0;
+ }
+ $arce = ($po[4] > 0) ? 360 - $po[4] : 0;
+ $arcb = ($po[5] > 0) ? 360 - $po[5] : 0;
+ $darc = $arce - $arcb;
+ if ($darc < 0) {$darc += 360}
+ $quar = int($darc / 90);
+ if ($quar > 0) {
+ for (my $k = 1; $k <= $quar; $k++) {
+ arc($p0,$po[1],$po[2],$po[3],$arcb,$arcb + 90);
+ $arcb += 90;
+ if ($arcb > 360) {$arcb -= 360}
+ }
+ }
+ if ($darc > $quar * 90) {
+ arc($p0,$po[1],$po[2],$po[3],$arcb,$arce);
+ }
+ }
+ else {
+ if ($cflag) {
+ $xtex .= "%Circles, halves and quarters of circles\n";
+ $cflag = 0;
+ }
+ if ($p0 eq $navy) {
+ $xtex .= "\\put(".$po[1].",".$po[2]."){\\circle{".$di."}}\n";
+ bound($po[1] + $po[3],$po[2] + $po[3]);
+ bound($po[1] + $po[3],$po[2] - $po[3]);
+ bound($po[1] - $po[3],$po[2] + $po[3]);
+ bound($po[1] - $po[3],$po[2] - $po[3]);
+ }
+ elsif ($p0 eq $purple) {
+ $xtex .= "\\put(".$po[1].",".$po[2]."){\\oval[".$di."](".$di.",".$di.")[l]}\n";
+ bound($po[1],$po[2] + $po[3]);
+ bound($po[1] - $po[3],$po[2] - $po[3]);
+ }
+ elsif ($p0 eq $red) {
+ $xtex .= "\\put(".$po[1].",".$po[2]."){\\oval[".$di."](".$di.",".$di.")[r]}\n";
+ bound($po[1],$po[2] - $po[3]);
+ bound($po[1] + $po[3],$po[2] + $po[3]);
+ }
+ elsif ($p0 eq $orange) {
+ $xtex .= "\\put(".$po[1].",".$po[2]."){\\oval[".$di."](".$di.",".$di.")[b]}\n";
+ bound($po[1] - $po[3],$po[2] - $po[3]);
+ bound($po[1] + $po[3],$po[2]);
+ }
+ elsif ($p0 eq $darkbrown) {
+ $xtex .= "\\put(".$po[1].",".$po[2]."){\\oval[".$di."](".$di.",".$di.")[t]}\n";
+ bound($po[1] - $po[3],$po[2]);
+ bound($po[1] + $po[3],$po[2] + $po[3]);
+ }
+ elsif ($p0 eq $blue) {
+ $xtex .= "\\put(".$po[1].",".$po[2]."){\\oval[".$di."](".$di.",".$di.")[bl]}\n";
+ bound($po[1] - $po[3],$po[2]);
+ bound($po[1],$po[2] - $po[3]);
+ }
+ elsif ($p0 eq $green) {
+ $xtex .= "\\put(".$po[1].",".$po[2]."){\\oval[".$di."](".$di.",".$di.")[tl]}\n";
+ bound($po[1] - $po[3],$po[2]);
+ bound($po[1],$po[2] + $po[3]);
+ }
+ elsif ($p0 eq $brown) {
+ $xtex .= "\\put(".$po[1].",".$po[2]."){\\oval[".$di."](".$di.",".$di.")[br]}\n";
+ bound($po[1],$po[2] - $po[3]);
+ bound($po[1] + $po[3],$po[2]);
+ }
+ elsif ($p0 eq $violet) {
+ $xtex .= "\\put(".$po[1].",".$po[2]."){\\oval[".$di."](".$di.",".$di.")[tr]}\n";
+ bound($po[1] + $po[3],$po[2]);
+ bound($po[1],$po[2] + $po[3]);
+ }
+ elsif ($p0 eq $darkgreen) {
+ $r = $po[3];
+ $le = int(2 * $pointf * $ul * $Pi * $r);
+ $xtex .= "\\cCircle[".$le."](".$po[1].",".$po[2]."){".$r."}[f]\n";
+ bound($po[1] + $r,$po[2] + $r);
+ bound($po[1] + $r,$po[2] - $r);
+ bound($po[1] - $r,$po[2] + $r);
+ bound($po[1] - $r,$po[2] - $r);
+ }
+ }
+ }
+}
+#________________________________________________________
+# Arcs
+$aflag = 1;
+foreach (@arc) {
+ @po = split;
+ if ($aflag) {
+ $xtex .= "%Arcs\n";
+ $aflag = 0;
+ }
+ $po[2] = (-1) * $po[2];
+ $arcb = ($po[4] > 0) ? 360 - $po[4] : 0;
+ $arce = ($po[5] > 0) ? 360 - $po[5] : 0;
+ $darc = $arce - $arcb;
+ if ($darc < 0) {$darc += 360}
+ $quar = int($darc / 90);
+ if ($quar > 0) {
+ for (my $k = 1; $k <= $quar; $k++) {
+ arc($po[0],$po[1],$po[2],$po[3],$arcb,$arcb + 90);
+ $arcb += 90;
+ if ($arcb > 360) {$arcb -= 360}
+ }
+ }
+ if ($darc > $quar * 90) {
+ arc($po[0],$po[1],$po[2],$po[3],$arcb,$arce);
+ }
+}
+#________________________________________________________
+# Frame
+if ($xtex . $mtex ne "") {
+$xtex = "\\documentclass{article}\n\\usepackage{ebezier}\n".
+"\\usepackage[pstarrows]{pict2e}\n\n\\begin{document}\n\n".
+"\\setlength{\\unitlength}{".$ul."pt}\n".
+"\\begin{picture}(".ceil(($xmax - $xmin)).",".
+ceil(($ymax - $ymin)).")(".floor($xmin).",".floor($ymin).")\n".
+"\\linethickness{0.8pt}\n"."\\thicklines\n".$xtex;
+$xtex .= $mtex."\\end{picture}\n\n\\end{document}";
+}
+print $xtex."\n";
+#________________________________________________________
+# Best pair for the slope of a line
+sub best {
+ my $x = shift;
+ if ($x > 1000) {
+ return (1,0);
+ }
+ elsif ($x < 1.0E-3) {
+ return (0,1);
+ }
+ else {
+ if ($x =~ (/^\d+$/)) {
+ return ($x,1);
+ }
+ else {
+ $num1 = floor($x);
+ $den1 = 1;
+ $y = $x;
+ while (($y =~ (/\D+/)) and ($num1 <= $gi) and ($den1 <= $gi)) {
+ $y *= 10;
+ $num1 = floor($y);
+ $den1 *= 10;
+ }
+ $r0 = $num1;
+ $r1 = $den1;
+ $q1 = 1;
+ @li = (0);
+ while ($r1 != 0) {
+ $q1 = floor($r0 / $r1);
+ $r2 = ($r0 % $r1);
+ $r0 = $r1;
+ $r1 = $r2;
+ $li[++$#li] = $q1;
+ }
+ $num1 = $num1 / $r0;
+ $den1 = $den1 / $r0;
+ if ($num1 <= 1000 and $den1 <= 1000) {
+ return ($num1,$den1);
+ }
+ else {
+ $n = $#li;
+ @num = (1,$li[1]);
+ @den = (0,1);
+ $bnum = $li[1];
+ $bden = 1;
+ $i = 2;
+ $numh = 0;
+ $denh = 0;
+ while (($numh <= 1000 and $denh <= 1000) and $i <= $n) {
+ $c = ($li[$i] >> 1);
+ if (($li[$i] % 2) == 1) {
+ $c++;
+ }
+ else {
+ $j = 1;
+ while (($i - $j >= 1 and $i + $j <= $n) and $li[$i - $j] == $li[$i + $j]) {
+ $j++;
+ }
+ $dj = $i - $j;
+ $sj = $i + $j;
+ if (($dj >= 1 and $sj <= $n) and $li[$dj] != $li[$sj]) {
+ $c += (($j + (($li[$sj] < $li[$dj]) ? 0 : 1)) % 2);
+ }
+ elsif ($dj == 0 and $sj <= $n) {
+ $c += ($j % 2);
+ }
+ elsif ($dj >= 1 and $sj == $n + 1) {
+ $c += (($j + 1) % 2);
+ }
+ elsif (($dj == 0 and $sj == $n + 1) or ($dj == 2 and
+ $sj == $n and $li[1] == 1 and $li[2] + 1 == $li[$n]) or
+ ($dj == 1 and $sj == $n - 1 and $li[$n] == 1
+ and $li[$n - 1] + 1 == $li[1])) {
+ $c++;
+ }
+ }
+ $k = $c;
+ while ($k <= $li[$i]) {
+ $numh = $k * $num[$i - 1] + $num[$i - 2];
+ $denh = $k * $den[$i - 1] + $den[$i - 2];
+ if ($numh > 1000 or $denh > 1000) {
+ last;
+ }
+ $bnum = $numh;
+ $bden = $denh;
+ if ($k == $li[$i]) {
+ $num[$i] = $numh;
+ $den[$i] = $denh;
+ }
+ $k++;
+ }
+ $i++;
+ }
+ return ($bnum,$bden);
+ }
+ }
+ }
+}
+#________________________________________________________
+# Lines
+sub lin {
+ my ($c,$xb,$yb,$xe,$ye) = @_;
+ if (($c eq $green) or ($c eq $orange) or ($c eq $purple) or ($c eq $navy)) {
+ $dx = $xe - $xb;
+ $dy = $ye - $yb;
+ $le = abs($dx);
+ if ($le > 1.0E-3) {
+ @p = best(abs($dy / $dx));
+ $psx = sp($p[1]) * ($dx <=> 0);
+ $psy = sp($p[0]) * ($dy <=> 0);
+ }
+ else {
+ $psx = 0;
+ $psy = ($dy <=> 0);
+ $le = abs($dy);
+ }
+ $xbu = sp($xb);
+ $ybu = sp($yb);
+ $leu = sp($le);
+ $xtex .= "\\put(".$xbu.",".$ybu."){\\line(".$psx.",".$psy."){".$leu."}}\n";
+ }
+ elsif ($c eq $darkgreen) {
+# Dotted line
+ if ($thicknessflag) {
+ $xtex .= "%Dotted line\n\\linethickness{1.2pt}\n";
+ $thicknessflag = 0;
+ }
+ $le = floor($pointf * $ul * (sqrt(($xe - $xb)**2 + ($ye - $yb)**2)));
+ if ($le > 0) {
+ $xbu = sp($xb);
+ $ybu = sp($yb);
+ $xeu = sp($xe);
+ $yeu = sp($ye);
+ $xtex .= "\\Lbezier[".$le."](".$xbu.",".$ybu.")(".$xeu.",".$yeu.")\n";
+ }
+ }
+}
+#________________________________________________________
+# Triangles
+sub tri {
+my ($q0,$qx1,$qy1,$qx2,$qy2,$qx3,$qy3) = @_;
+ $qx1 = $qx1 * $ul;
+ $qy1 = $qy1 * $ul;
+ $qx2 = $qx2 * $ul;
+ $qy2 = $qy2 * $ul;
+ $qx3 = $qx3 * $ul;
+ $qy3 = $qy3 * $ul;
+ if ($q0 eq $red) {
+# Filled triangle
+ %ha = ($qx1,$qy1,$qx2+1e-07,$qy2+1e-07,$qx3+2e-07,$qy3+2e-07);
+ @hb = ();
+ @hc = ();
+ foreach (sort { $ha{$a} <=> $ha{$b} } keys %ha) {
+ $hb[++$#hb] = $_;
+ $hc[++$#hc] = $ha{$_};
+ }
+ ($qx1,$qx2,$qx3) = @hb;
+ ($qy1,$qy2,$qy3) = @hc;
+ $lin = int(($qy3 - $qy1) * $fillf);
+ $xtex .= "%Filled triangle\n\\linethickness{0.1pt}\n";
+ $si = ($qy3 - $qy1) * $qx2 - ($qx3 - $qx1) * $qy2 - $qx1 * $qy3 + $qx3 * $qy1 <=> 0;
+ $dex = ($qx3 - $qx1) / ($qy3 - $qy1) / $fillf;
+ $d1 = $qy2 - $qy1;
+ $d2 = $qy3 - $qy2;
+ if ($d1 >= 1.0E-3) {
+ $fx1 = ($qx2 - $qx1) / $d1;
+ $sx1 = $qx1 - $qy1 * $fx1;
+ }
+ if ($d2 >= 1.0E-3) {
+ $fx2 = ($qx3 - $qx2) / $d2;
+ $sx2 = $qx2 - $qy2 * $fx2;
+ }
+ for ($k = 1; $k <= $lin; $k++) {
+ $xb = $qx1 + $k * $dex;
+ $yb = $qy1 + $k / $fillf;
+ if ($yb <= $qy2) {
+ if ($d1 >= 1.0E-3) {
+ $leu = sp((abs($sx1 + $yb * $fx1 - $xb) + 0.5)/ $ul);
+ }
+ else {
+ $leu = sp((abs($qx2 - $qx1) + 0.5)/ $ul);
+ }
+ }
+ else {
+ if ($d2 >= 1.0E-3) {
+ $leu = sp((abs($sx2 + $yb * $fx2 - $xb) + 0.5)/ $ul);
+ }
+ else {
+ $leu = sp((abs($qx3 - $qx2) + 0.5)/ $ul);
+ }
+ }
+ if ($si > 0) {
+ $xbu = sp($xb / $ul);
+ }
+ else {
+ $xbu = sp($xb / $ul);
+ }
+ $ybu = sp($yb / $ul);
+ $xtex .= "\\put(".$xbu.",".$ybu."){\\line(".$si.",0){".$leu."}}\n";
+ }
+ $xtex .= "\\linethickness{0.8pt}\n";
+ }
+ elsif (($q0 eq $purple) or ($q0 eq $darkbrown)) {
+# Dotted triangle
+ %ha = ($qx1,$qy1,$qx2+1e-07,$qy2+1e-07,$qx3+2e-07,$qy3+2e-07);
+ @hb = ();
+ @hc = ();
+ foreach (sort { $ha{$a} <=> $ha{$b} } keys %ha) {
+ $hb[++$#hb] = $_;
+ $hc[++$#hc] = $ha{$_};
+ }
+ ($qx1,$qx2,$qx3) = @hb;
+ ($qy1,$qy2,$qy3) = @hc;
+ $xtex .= "%Dotted triangle\n";
+ $si = ($qy3 - $qy1) * $qx2 - ($qx3 - $qx1) * $qy2 - $qx1 * $qy3 + $qx3 * $qy1 <=> 0;
+ $dy1 = 2 * ceil($qy1 / 2);
+ $dy3 = 2 * floor($qy3 / 2);
+ $lin = $dy3 - $dy1;
+ $dex = ($qx3 - $qx1) / ($qy3 - $qy1);
+ $xbh = $qx1 + ($dy1 - $qy1 - 2.0) * $dex;
+ $dex = 2 * $dex;
+ $d1 = $qy2 - $qy1;
+ $d2 = $qy3 - $qy2;
+ if ($d1 >= 1.0E-3) {
+ $fx1 = ($qx2 - $qx1) / $d1;
+ $sx1 = $qx1 + ($dy1 - $qy1) * $fx1;
+ }
+ if ($d2 >= 1.0E-3) {
+ $fx2 = ($qx3 - $qx2) / $d2;
+ $sx2 = $qx2 + ($dy1 - $qy2) * $fx2;
+ }
+ for ($k = 0; $k <= $lin; $k += 2) {
+ $qy = $dy1 + $k;
+ $xbh = $xbh + $dex;
+ ($si > 0) ? ($xb = $xbh) : ($xe = $xbh);
+ if ($qy <= $qy2) {
+ ($d1 >= 1.0E-3) ? ($xeh = $sx1 + $k * $fx1) : ($xeh = $qx1);
+ }
+ else {
+ ($d2 >= 1.0E-3) ? ($xeh = $sx2 + $k * $fx2) : ($xeh = $qx2);
+ }
+ ($si > 0) ? ($xe = $xeh) : ($xb = $xeh);
+ $xb = 2 * ceil($xb / 2);
+ $xbd = $xb + (($xb + $qy) % 4);
+ ($xe >= $xbd) ? ($num = floor(($xe - $xbd) / 4) + 1) : ($num = 0);
+ if (not $thicknessflag) {
+ $xtex .= "\\linethickness{0.8pt}\n";
+ $thicknessflag = 1;
+ }
+ $xbu = sp($xbd / $ul);
+ $qyu = sp($qy / $ul);
+ $xtex .= "\\multiput(".$xbu.",".$qyu.")(".$uli.",0){".$num;
+ $xtex .= "}{\\line(1,0){".$ule."}}\n";
+ }
+ }
+ elsif (($q0 eq $orange) or ($q0 eq $brown)) {
+# Hatched triangle
+ $xtex .= "%Hatched triangle\n";
+ $d1 = $qx1 - $qy1;
+ $d2 = $qx2 - $qy2;
+ $d3 = $qx3 - $qy3;
+ $qd1 = $d1;
+ $qd2 = $d2;
+ $qd3 = $d3;
+ %ha = ($qx1,$qd1,$qx2+1e-07,$qd2+1e-07,$qx3+2e-07,$qd3+2e-07);
+ @hb = ();
+ foreach (sort { $ha{$a} <=> $ha{$b} } keys %ha) {
+ $hb[++$#hb] = $_;
+ }
+ ($qx1,$qx2,$qx3) = @hb;
+ %ha = ($qy1,$qd1,$qy2+1e-07,$qd2+1e-07,$qy3+2e-07,$qd3+2e-07);
+ @hb = ();
+ @hc = ();
+ foreach (sort { $ha{$a} <=> $ha{$b} } keys %ha) {
+ $hb[++$#hb] = $_;
+ $hc[++$#hc] = $ha{$_};
+ }
+ ($qy1,$qy2,$qy3) = @hb;
+ ($d1,$d2,$d3) = @hc;
+ $si = (-$qy3 + $qy1) * $qx2 + ($qx3 - $qx1) * $qy2 + $qx1 * $qy3 - $qx3 * $qy1 <=> 0;
+ $p1 = 4 * ceil($d1 / 4);
+ $p2 = 4 * floor($d2 / 4);
+ $p3 = 4 * floor($d3 / 4);
+ $fx1 = ($qx1 - $qx3) / ($d3 - $d1);
+ $sx1 = $qx3 + $fx1 * $d3;
+ $fy1 = ($qy1 - $qy3) / ($d3 - $d1);
+ $sy1 = $qy3 + $fy1 * $d3;
+ $d21 = $d2 - $d1;
+ $d32 = $d3 - $d2;
+ if ($d21 >= 1.0E-3) {
+ $fx2 = ($qx1 - $qx2) / $d21;
+ $sx2 = $qx2 + $fx2 * $d2;
+ }
+ if ($d32 >= 1.0E-3) {
+ $fx3 = ($qx2 - $qx3) / $d32;
+ $sx3 = $qx3 + $fx3 * $d3;
+ }
+ for ($k = $p1; $k <= $p3; $k += 4) {
+ $xbk = $sx1 - $k * $fx1;
+ $ybk = $sy1 - $k * $fy1;
+ if ($k <= $p2) {
+ ($d21 < 1.0E-3) ? ($le = abs($qx2 - $qx1)) : ($le = abs($sx2 - $k * $fx2 - $xbk));
+ }
+ else {
+ ($d32 < 1.0E-3) ? ($le = abs($qx3 - $qx2)) : ($le = abs($sx3 - $k * $fx3 - $xbk));
+ }
+ $xbk = sp($xbk / $ul);
+ $ybk = sp($ybk / $ul);
+ $le = sp($le / $ul);
+ $xtex .= "\\put(".$xbk.",".$ybk."){\\line(".$si.",".$si."){".$le."}}\n";
+ }
+ }
+}
+#________________________________________________________
+# Rectangles
+sub rect {
+ my ($q0,$x1,$y1,$x2,$y2,$x3,$y3,$x4,$y4) = @_;
+ $dx = abs($x2 - $x1);
+ $dx = ($dx < 1.0E-6) ? abs($x3 -$x2) : $dx;
+ $dx = $dx * $ul;
+ $xb = ($x1 < $x2) ? (($x1 < $x3) ? $x1 : $x3) : (($x2 < $x3) ? $x2 : $x3);
+ $xb = $xb * $ul;
+ $dy = abs($y2 - $y1);
+ $dy = ($dy < 1.0E-6) ? abs($y3 -$y2) : $dy;
+ $dy = $dy * $ul;
+ $yb = ($y1 < $y2) ? (($y1 < $y3) ? $y1 : $y3) : (($y2 < $y3) ? $y2 : $y3);
+ $yb = $yb * $ul;
+ $xe = $xb + $dx;
+ $ye = $yb + $dy;
+# Filled rectangle
+ if ($q0 eq $red) {
+ $xtex .= "%Filled rectangle\n\\linethickness{0.1pt}\n";
+ $lin = 5 * $dx;
+ if ($dy <= $dx) {
+ $ybf = $yb - 0.2;
+ $xbu = sp($xb / $ul);
+ $dxu = sp($dx / $ul);
+ for ($k = 0; $k <= $lin; $k++) {
+ $ybf += 0.2;
+ $ybu = sp($ybf / $ul);
+ $xtex .= "\\put(".$xbu.",".$ybu."){\\line(1,0){".$dxu."}}\n";
+ }
+ }
+ else {
+ $xbf = $xb - 0.2;
+ $ybu = sp($yb / $ul);
+ $dyu = sp($dy / $ul);
+ for ($k = 0; $k <= $lin; $k++) {
+ $xbf += 0.2;
+ $xbu = sp($xbf / $ul);
+ $xtex .= "\\put(".$xbu.",".$ybu."){\\line(0,1){".$dyu."}}\n";
+ }
+ }
+ $xtex .= "\\linethickness{0.8pt}\n";
+ }
+# Dotted rectangle
+ elsif (($q0 eq $purple) or ($q0 eq $darkbrown)) {
+ $xtex .= "%Dotted rectangle\n";
+ $xbb = 2 * ceil($xb / 2);
+ $ybb = 2 * ceil($yb / 2);
+ for ($k = 0; $k <= 2; $k += 2) {
+ $ybd = $ybb + $k;
+ $xbd = $xbb + (($xbb + $ybd) % 4);
+ $numx = floor(($xe - 0.13 - $xbd) / 4) + 1;
+ $numy = floor(($ye - 0.13 - $ybd) / 4) + 1;
+ $xbu = sp($xbd / $ul);
+ $ybu = sp($ybd / $ul);
+ $xtex .= "\\multiput(".$xbu.",".$ybu.")(".$uli.",0){".$numx."}\n";
+ $xtex .= "{\\begin{picture}(0,0)\\multiput(0,0)(0,".$uli."){";
+ $xtex .= $numy."}\n{\\line(1,0){".$ule."}}\\end{picture}}\n";
+ }
+ }
+# Hatched rectangle
+ elsif (($q0 eq $orange) or ($q0 eq $brown)) {
+ $xtex .= "%Hatched rectangle\n";
+ $p1 = 4 * ceil(($xb - $ye) / 4);
+ if ($dx >= $dy) {
+ $p2 = 4 * floor(($xb - $yb) / 4) + 4;
+ $p3 = 4 * floor(($xe - $ye) / 4) + 4;
+ $xp = $yb + $p2;
+ $yp = $yb;
+ $lp = $dy;
+ $ip1 = 4;
+ $ip2 = 0;
+ }
+ else {
+ $p3 = 4 * floor(($xb - $yb) / 4) + 4;
+ $p2 = 4 * floor(($xe - $ye) / 4) + 4;
+ $xp = $xb;
+ $yp = $xb - $p2;
+ $lp = $dx;
+ $ip1 = 0;
+ $ip2 = -4;
+ }
+ $p4 = 4 * floor(($xe - $yb) / 4);
+ for ($k = $p1; $k <= $p2 - 4; $k += 4) {
+ $xbu = sp($xb / $ul);
+ $ybu = sp(($xb - $k) / $ul);
+ $le = sp(($ye - $xb + $k) / $ul);
+ $xtex .= "\\put(".$xbu.",".$ybu."){\\line(1,1){".$le."}}\n";
+ }
+ $np = ($p3 - $p2) / 4;
+ if ($p3 > $p2) {
+ $xpu = sp($xp / $ul);
+ $ypu = sp($yp / $ul);
+ $ip1u = sp($ip1 / $ul);
+ $ip2u = sp($ip2 / $ul);
+ $lpu = sp($lp / $ul - 0.1);
+ $xtex .= "\\multiput(".$xpu.",".$ypu.")(".$ip1u.",".$ip2u;
+ $xtex .= "){".$np."}{\\line(1,1){".$lpu."}}\n";
+ }
+ for ($k = $p3; $k <= $p4; $k += 4) {
+ $xbu = sp(($yb + $k) / $ul);
+ $ybu = sp($yb / $ul);
+ $leu = sp(($xe - $yb - $k) / $ul);
+ $xtex .= "\\put(".$xbu.",".$ybu."){\\line(1,1){".$leu."}}\n";
+ }
+ }
+}
+#________________________________________________________
+# Quadratic Bezier curve
+sub qbez {
+ my ($x1,$y1,$x2,$y2,$x3,$y3) = @_;
+ my $xb = $x1;
+ my $yb = $y1;
+ my $len = 0.0;
+ for ($t = 0.02; $t <= 1.0; $t += 0.02) {
+ bound($xb,$yb);
+ $s = 1.0 - $t;
+ $xe = $s * ($s * $x1 + $t * $x2) + $t * ($s * $x2 + $t * $x3);
+ $ye = $s * ($s * $y1 + $t * $y2) + $t * ($s * $y2 + $t * $y3);
+ $len += sqrt(($xe - $xb)**2 + ($ye - $yb)**2);
+ $xb = $xe;
+ $yb = $ye;
+ }
+ bound($x3,$y3);
+ $x1 = sp($x1);
+ $y1 = sp($y1);
+ $x2 = sp($x2);
+ $y2 = sp($y2);
+ $x3 = sp($x3);
+ $y3 = sp($y3);
+ if ($Qbezflag) {
+ $le = int($pointf * $ul * $len);
+ $xtex .= "\\Qbezier[".$le."](".$x1.",".$y1.")(".$x2.",".$y2;
+ $xtex .= ")(".$x3.",".$y3.")\n";
+ }
+ else {
+ $xtex .= "\\qbezier(".$x1.",".$y1.")(".$x2.",".$y2;
+ $xtex .= ")(".$x3.",".$y3.")\n";
+ }
+}
+#________________________________________________________
+# Cubic Bezier curve
+sub cbez {
+ my ($x1,$y1,$x2,$y2,$x3,$y3,$x4,$y4) = @_;
+ my $xb = $x1;
+ my $yb = $y1;
+ for ($t = 0.02; $t <= 1.0; $t += 0.02) {
+ bound($xb,$yb);
+ $s = 1.0 - $t;
+ $u1 = $s * $x1 + $t * $x2;
+ $v1 = $s * $y1 + $t * $y2;
+ $u2 = $s * $x2 + $t * $x3;
+ $v2 = $s * $y2 + $t * $y3;
+ $u3 = $s * $x3 + $t * $x4;
+ $v3 = $s * $y3 + $t * $y4;
+ $xe = $s * ($s * $u1 + $t * $u2) + $t * ($s * $u2 + $t * $u3);
+ $ye = $s * ($s * $v1 + $t * $v2) + $t * ($s * $v2 + $t * $v3);
+ $xb = $xe;
+ $yb = $ye;
+ }
+ bound($x4,$y4);
+ $x1 = sp($x1);
+ $y1 = sp($y1);
+ $x2 = sp($x2);
+ $y2 = sp($y2);
+ $x3 = sp($x3);
+ $y3 = sp($y3);
+ $x4 = sp($x4);
+ $y4 = sp($y4);
+ $xtex .= "\\cbezier(".$x1.",".$y1.")(".$x2.",".$y2.")(".$x3.",".$y3.")(".$x4.",".$y4.")\n";
+}
+#________________________________________________________
+# Short arcs
+sub arc {
+ my ($col,$xm,$ym,$r,$al,$be) = @_;
+ $al1 = $al * $Pi / 180;
+ $be1 = $be * $Pi / 180;
+ $dx1 = $r * cos($al1);
+ $dy1 = $r * sin($al1);
+ $dx4 = $r * cos($be1);
+ $dy4 = $r * sin($be1);
+ $x1 = $xm + $dx1;
+ $y1 = $ym + $dy1;
+ $x4 = $xm + $dx4;
+ $y4 = $ym + $dy4;
+ bound($x1,$y1);
+ bound($x4,$y4);
+ $gal = 90 * int($al / 90);
+ $gbe = 90 * int($be / 90);
+ if ($gal != $gbe) {
+ if ($gbe == 0) {
+ $gx1 = $r;
+ $gy1 = 0;
+ }
+ elsif ($gbe == 90) {
+ $gx1 = 0;
+ $gy1 = $r;
+ }
+ elsif ($gbe == 180) {
+ $gx1 = (-1) * $r;
+ $gy1 = 0;
+ }
+ elsif ($gbe == 270) {
+ $gx1 = 0;
+ $gy1 = (-1) * $r;
+ }
+ bound($xm + $gx1,$ym + $gy1);
+ }
+ $aux = 4 * (2 * $r - sqrt(($dx1 + $dx4)**2 + ($dy1 + $dy4)**2)) / 3;
+ $lam = $aux / sqrt(($dx1 - $dx4)**2 + ($dy1 - $dy4)**2);
+ $x1u = sp($x1);
+ $y1u = sp($y1);
+ $x4u = sp($x4);
+ $y4u = sp($y4);
+ if ($col eq $darkgreen) {
+ $d1 = abs($al1 - $be1);
+ if ($d1 > $Pi) {$d1 = 2 * $Pi - $d1}
+ $le = int($pointf * $d1 * $r * $ul);
+ $xmu = sp($xm);
+ $ymu = sp($ym);
+ $xtex .= "\\cArcs[".$le."](".$xmu.",".$ymu.")(".$x1u.",".$y1u,
+ $xtex .= ")(".$x4u.",".$y4u.")\n";
+ }
+ else {
+ $x2u = sp($x1 - $lam * $dy1);
+ $y2u = sp($y1 + $lam * $dx1);
+ $x3u = sp($x4 + $lam * $dy4);
+ $y3u = sp($y4 - $lam * $dx4);
+ $xtex .= "\\cbezier(".$x1u.",".$y1u.")(".$x2u.",".$y2u.")(".$x3u.",";
+ $xtex .= $y3u.")(".$x4u.",".$y4u.")\n";
+ }
+}
+#________________________________________________________
+# Bounding box
+sub bound {
+ my ($xn,$yn) = @_;
+ if ($sflag) {
+ $xmin = $xn;
+ $xmax = $xn;
+ $ymin = $yn;
+ $ymax = $yn;
+ $sflag = 0;
+ }
+ else {
+ if ($xn < $xmin) {$xmin = $xn} elsif ($xmax < $xn) {$xmax = $xn}
+ if ($yn < $ymin) {$ymin = $yn} elsif ($ymax < $yn) {$ymax = $yn}
+ }
+}
+#________________________________________________________
+# Sprintf
+sub sp {
+ my $x = shift;
+ return sprintf("%.3f",$x) + 0;
+}
+#________________________________________________________
diff --git a/graphics/gapfill/README b/graphics/gapfill/README
new file mode 100644
index 0000000000..5e54da1d6d
--- /dev/null
+++ b/graphics/gapfill/README
@@ -0,0 +1,105 @@
+% README
+% for the GaPFilL method ("Graphics as PostScript Filtered for LaTeX"),
+% Version 1.1, January 2006; version 1.6, January 2015
+% Changes: April 2006, October 2006, August 2009, April 2011, January 2015
+
+Author: H. Moeller
+E-Mail: mollerh@math.uni-muenster.de
+Homepage: http://www.math.uni-muenster.de/u/mollerh
+Address: Department of Mathematics and Computer Science
+ University of Muenster
+ Einsteinstr. 62
+ D-48149 Muenster
+ Germany
+
+(1) INTRODUCTION
+-----------------
+
+Using geometry software or a drawing program ("geometry program") LaTeX picture environments may be constructed in the following way:
+
+ i) Generating the desired figure with the geometry program;
+ ii) "Printing" (or exporting) the construction as a PostScript file;
+ iii) Applying a Perl filter program to the PostScript text;
+ iv) Copying the resulting code or parts of it into a LaTeX document.
+
+On account of this structure the method is called "GaPFilL" (Graphics as PostScript Filtered for LaTeX).
+
+Since the steps i) and ii) and the packages used in the LaTeX document may vary, it is necessary to apply different filter programs.
+
+Therefore the GaPFilL folder in the CTAN may collect open-source Perl filter programs for many combinations of geometry programs, PostScript versions, and LaTeX packages on different platforms.
+
+The first two Perl filter programs in the folder 'Mac_OS_only' are written for the "dynamic" geometry software 'Cabri-gˇom¸tre II', the PostScript driver 'Virtual Printer', and the LaTeX packages 'ebezier' and 'pict2e'.
+
+Both have been well tested using a Macintosh G4 and Mac OS 9.2. The package pict2e with LaTeX code generated by 'CABpict.pl' could only be used with PDFTeX.
+
+Together with the documentation 'GaPDoc1.pdf' these programs may serve as prototypes for those who will write or modify Perl filter programs for GaPFilL.
+
+Added in 2009: A new Perl filter program 'OOopict.pl' is added for the powerful free drawing software OpenOffice.org 3 Draw which has its own PostScript generator not depending on the operating systems supplied by OpenOffice.org, namely Linux, Mac OS, Unix and Windows.
+
+(2) REQUIRED SYSTEMS
+--------------------
+
+ i) A geometry program,
+ ii) a PostScript driver (http://www.adobe.com/support/downloads/main.html),
+ iii) the Perl interpreter (http://www.Perl.com/CPAN/ports/index.html),
+ iv) a TeX/LaTeX installation.
+
+(3) PACKAGE FILES
+------------------
+
+ README -- this file,
+ GaPDoc1.tex -- tex file of the GaPFilL documentation,
+ GaPDoc1.pdf -- pdf version of the GaPFilL documentation,
+ Mac_OS_only/CABebez.pl -- Perl filter for Cabri-gˇom¸tre II and the LaTeX package 'ebezier',
+ Mac_OS_only/CABpict.pl -- Perl filter for Cabri-gˇom¸tre II and the LaTeX packages 'ebezier' and 'pict2e'.
+
+ Added in 2009:
+ GaPDoc2.tex -- tex file of the GaPFilL documentation for OpenOffice.org 3 Draw,
+ GaPDoc2.pdf -- pdf file of the GaPFilL documentation for OpenOffice.org 3 Draw,
+ Various_OSs/OOopict.pl -- Perl filter for OpenOffice.org 3 Draw and the LaTeX package 'pict2e' (2008) or the packages 'ebezier' and 'pict2e' (2003).
+
+(4) INSTALLATION
+----------------
+
+Each of the four systems in (2) has its own installation mode depending on the platform. In general with the respective software you get an installer or an explanation how to install it.
+
+(5) USAGE
+---------
+
+If you are familiar with your geometry program, you are able to generate even complicated drawings without using any manual. For the assignment of colors you only need the two tables on pages 4 and 5 of the documentation GaPDoc1.pdf.
+
+Added in 2009: With OOopict.pl you have to use the table of colors on page 6 of the documentation GaPDoc2.pdf.
+
+The Perl filter programs need to be placed where your Perl interpreter can find them.
+
+With Mac OS you may select the PostScript text in your text editor and run the desired filter of the Perl filters list.
+
+The use of Perl filter programs in Unix/Linux and with MS-Windows is explained for example in the README.TXT of CTAN/graphics/pictex/mathspic/Perl.
+
+If there are difficulties between 64-bit Windows 7 and the text editor you may use the command line of Windows with the eps-file as parameter.
+
+(6) CHANGES
+-----------
+April 2006: The German documentation has been substituded by an English translation of it.
+
+October 2006: In the Perl filter Mac_OS_only/CABebez.pl on line 111 "and ($co0 ne $violet)) " has been added.
+
+August 2009: In the Perl filter Mac_OS_only/CABpict.pl the subprocedure 'best' is corrected taking into account that Perl has a greatest integer.
+
+April 2011: In the PostScript file of OpenOffice.org 3 Draw rectangles consist of five lines. These are reduced to the ordinary four ones. The length of arrow shafts is corrected. Dotted lines and curves are shifted half a dot to the left. The letter 'D' in the subprocedure 'best' is replaced by 'd'.
+
+June 2011: The subprocedure 'best' of OOopict.pl is simplified on lines 269 to 300.
+
+January 2015: The Perl filter program OOopict.pl can also be used with the free drawing programs Apache OpenOffice Draw and LibreOffice Draw, which belong to the office suits succeeding OpenOffice.org. To get the correct colors, the "standard" color list must be replaced by the "web" color list: From the menue/submenue "Format/Area..." choose "Colors" and load the color list "standard.soc" clicking the left icon on the lower right side of the window. Save it with the other icon as "standard0.soc". Then, load the color list "web.soc" and replace the numbers in the Name field. Using A for 0, B for 128 and C for 255, the color names should be: black for AAA, navy for AAB, green for ABA, teal for ABB, maroon for BAA, purple for BAB, olive for BBA, blue for AAC, lime for ACA, cyan for ACC, red for CAA and magenta for CAC. Save this list as "standard.soc".
+
+(7) LICENSE (LPPL)
+------------------
+
+These programs are free software; you can redistribute them and/or modify them under the conditions of the LaTeX Project Public License.
+
+These programs are distributed in the hope that they will be useful, but WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+-------------
+
+End of README
+=============
+
diff --git a/graphics/gapfill/Various_OSs/OOopict.pl b/graphics/gapfill/Various_OSs/OOopict.pl
new file mode 100755
index 0000000000..d5ca7f8f2e
--- /dev/null
+++ b/graphics/gapfill/Various_OSs/OOopict.pl
@@ -0,0 +1,918 @@
+#!/usr/bin/perl -w
+# OOopict.pl
+# (c) Copyright 2009 by H. Moeller (mollerh@math.uni-muenster.de).
+# Version 1.6 for OpenOffice.org Draw , Apache OpenOffice Draw or LibreOffice Draw
+# with Perl 5.16, and with the LaTeX package 'pict2e' from 2008
+# or with 'pict2e' (2003) and 'ebezier'.
+# This program may be distributed and/or modified under the conditions of the
+# LaTeX Project Public License, either version 1.3 of this license or
+# (at your option) any later version.
+# The latest version of this license is in http://www.latex-project.org/lppl.txt.
+# This program has the LPPL maintenance status "maintained by the author".
+#
+use POSIX('ceil','floor');
+#________________________________________________________
+# Definable by the user:
+# Unitlength in pt:
+$ul = 1.0;
+# If your package pict2e is from 2008 or later (else: $pictnew = 0):
+$pictnew = 1;
+# Fill factor (for laser printer; for filling up to 360% zoom: $fillf=5)
+$fillf = 10;
+# Point factor (for points on dotted lines and curves):
+$pointf = 0.3;
+#________________________________________________________
+# Constants:
+# Constants in dotted figures:
+$uli = sp(4 / $ul);
+$ule = sp(0.8 / $ul);
+$ulb = sp(1.2 / $ul);
+# Color names:
+$black = "0.0030.0030.003";
+$navy = "0.0030.0030.503";
+$green = "0.0030.5030.003";
+$teal = "0.0030.5030.503";
+$maroon = "0.5030.0030.003";
+$purple = "0.5030.0030.503";
+$olive = "0.5030.5030.003";
+$blue = "0.0030.0031.000";
+$lime = "0.0031.0000.003";
+$cyan = "0.0031.0001.000";
+$red = "1.0000.0030.003";
+$magenta = "1.0000.0031.000";
+#________________________________________________________
+# Further Constants:
+#Conversion factor to pt:
+$cpt = 0.02845276;
+# Greatest integer of Perl
+$gi = 2147483647;
+#________________________________________________________
+@lines = <>;
+do {
+ $_ = $lines[$i++];
+ if ((/ l /o) or (/ ct /o) or (/ p[cs ][\se]/o)) {
+ s/\d+ lw \d+ lj //go;
+ s/ m //go;
+ if (/ c /o) {
+ s/(\d\.\d+) (\d\.\d+) (\d\.\d+) c //o;
+ $c=$1.$2.$3." ";
+ }
+ $t="";
+ $l="";
+ $tflag=0;
+ $fflag=0;
+ while ($_ !~ (/p[cs ][\se]/o)) {
+ if (/ ct /o) {
+ $tflag=1;
+ s/ ct / /go;
+ /(.*)/o;
+ $t.=$1;
+ }
+ elsif (/ l /o) {
+ s/ l / /go;
+ s/ l / /o;
+ /(.*)/o;
+ $l.=$1;
+ }
+ $_ = $lines[$i++];
+ }
+ $fflag=($_ !~ (/p /o));
+ if (/ ct /o) {
+ $tflag=1;
+ s/ ct / /go;
+ /(.*\d)/o;
+ $t.=$1;
+ }
+ elsif (/ l /o) {
+ s/ l / /go;
+ s/ l / /o;
+ /(.*\d)/o;
+ $l.=$1;
+ }
+ if ($tflag and $fflag) {
+ $curve[++$#curve] = $c.$t;
+ }
+ elsif ($fflag) {
+ $polygon[++$#polygon] = $c.$l;
+ }
+ }
+}
+until $i == $#lines;
+#
+$sflag = 1;
+$lt = 8;
+$coun = 0;
+$xtex = "";
+$mtex = "";
+$btex = "\\documentclass{article}\n";
+if (not $pictnew) {
+ $btex .= "\\usepackage{ebezier}\n";
+}
+#________________________________________________________
+# Lines and polygons
+$cflag = 1;
+foreach (@polygon) {
+ @po = split;
+ $p0 = $po[0];
+ $pon = $#po;
+ if ($pon == 12) {$rec = abs($po[2] - $po[4]) + abs($po[3] - $po[5]) +
+ abs($po[6] - $po[8]) + abs($po[7] -$po[9]) + abs($po[10]- $po[12]) < 1.0E-4;
+ }
+ for (my $j = 1; $j <= $pon; $j++) {
+ $po[$j] *= (-1)**($j+1)*$cpt;
+ }
+ if ($cflag) {
+ $xtex .= "%Lines, arrows, polygons and quadratic B".chr(142)."zier curves\n";
+ $cflag = 0;
+ }
+ if (($p0 ne $blue) and ($p0 ne $green)) {
+ for (my $i = 1; $i <= $pon - 1; $i += 2) {
+ bound($po[$i],$po[$i + 1]);
+ }
+ }
+ if (($p0 eq $black) or ($p0 eq $lime) or ($p0 eq $maroon)
+ or ($p0 eq $purple)) {
+ if ($pon == 12 and $rec) {
+ for (my $h = 3; $h <= 7; $h += 2) {
+ lin($p0,$po[$h],$po[$h+1],$po[$h+2],$po[$h+3]);
+ }
+ lin($p0,$po[9],$po[10],$po[3],$po[4]);
+ }
+ else {
+ for (my $i = 1; $i <= $pon - 3; $i += 2) {
+ lin($p0,$po[$i],$po[$i+1],$po[$i+2],$po[$i+3]);
+ }
+ }
+ }
+ if (($p0 eq $teal) or ($p0 eq $navy)) {
+ $xtex .= "%Arrow\n";
+ $dx = $po[3] - $po[1];
+ $dy = $po[4] - $po[2];
+ $roo = sqrt($dx**2+$dy**2);
+ $co = $dx / $roo;
+ $si = $dy / $roo;
+ $pxh = $po[3] - 4.8 * $co / $ul;
+ $pyh = $po[4] - 4.8 * $si / $ul;
+ $px2 = $pxh - 2.4 * $si / $ul;
+ $py2 = $pyh + 2.4 * $co / $ul;
+ $px3 = $pxh + 2.4 * $si / $ul;
+ $py3 = $pyh - 2.4 * $co / $ul;
+ bound($px2,$py2);
+ bound($px3,$py3);
+ $len = abs($dx);
+ if ($len > 1.0E-3) {
+ @p = best(abs($dy / $dx), 1000);
+ $psx = $p[1] * ($dx <=> 0);
+ $psy = $p[0] * ($dy <=> 0);
+ $len = sp(abs($len - 4 * $len / ($roo * $ul)));
+ }
+ else {
+ $psx = 0;
+ $psy = ($dy <=> 0);
+ $len = sp(abs(abs($dy) - 4 / $ul));
+ }
+ if ($p0 eq $teal) {
+ $xb = sp($po[1]);
+ $yb = sp($po[2]);
+ if ($lt != 8) {
+ $xtex .= "\\linethickness{0.8pt}\n";
+ $lt = 8;
+ }
+ $xtex .= "\\put(".$xb.",".$yb."){\\line(".$psx.",".$psy."){".$len."}}\n";
+ }
+ else {
+ $xe = $po[3] - $uli * $dx / $roo;
+ $ye = $po[4] - $uli * $dy / $roo;
+ lin($p0,$po[1],$po[2],$xe,$ye);
+ }
+ if ($lt != 12) {
+ $xtex .= "\\linethickness{1.2pt}\n";
+ $lt = 12;
+ }
+ $xtex .= "\\put(".sp($po[3]).",".sp($po[4])."){\\vector(".$psx.",".$psy."){0}}\n";
+ }
+ if (($p0 eq $red) or ($p0 eq $maroon) or ($p0 eq $olive)
+ or ($p0 eq $purple) or ($p0 eq $magenta)) {
+ if ($pon == 8) {
+ tri($p0,$po[1],$po[2],$po[3],$po[4],$po[5],$po[6]);
+ }
+ elsif ($pon == 10) {
+ ($p0,$u1,$v1,$u2,$v2,$u3,$v3,$u4,$v4,$u5,$v5) = @po;
+ tri($p0,$u1,$v1,$u2,$v2,$u3,$v3);
+ tri($p0,$u1,$v1,$u3,$v3,$u4,$v4);
+ }
+ elsif ($pon == 12) {
+ ($p0,$u0,$v0,$u1,$v1,$u2,$v2,$u3,$v3,$u4,$v4,$u5,$v5) = @po;
+ if ($rec) {
+ rect($p0,$u1,$v1,$u2,$v2,$u3,$v3,$u4,$v4);
+ }
+ else {
+ tri($p0,$u0,$v0,$u1,$v1,$u2,$v2);
+ tri($p0,$u0,$v0,$u2,$v2,$u3,$v3);
+ tri($p0,$u0,$v0,$u3,$v3,$u4,$v4);
+ }
+ }
+ elsif ($pon > 12) {
+ for (my $j = 3; $j <= $pon - 5; $j += 2) {
+ tri($p0,$po[1],$po[2],$po[$j],$po[$j + 1],$po[$j + 2],$po[$j + 3]);
+ }
+ }
+ }
+ elsif ($p0 eq $cyan) {
+# Text marker
+ $coun++;
+ $bo3 = $po[1] + ($po[3] - $po[1]) / $ul;
+ $bo4 = $po[2] + ($po[4] - $po[2]) / $ul;
+ bound($po[1],$po[2]);
+ bound($bo3,$bo4);
+ $po1 = sp($po[1]);
+ $po2 = sp($po[2]);
+ $mtex .= "\\put(".$po1.",".$po2."){".$coun."}\n";
+ }
+ elsif (($p0 eq $blue) or ($p0 eq $green)) {
+ $xtex .= "%Quadratic B".chr(142)."zier curve\n";
+ qbez($p0,$po[1],$po[2],$po[3],$po[4],$po[5],$po[6]);
+ }
+}
+# Curves
+$cflag = 1;
+foreach (@curve) {
+ @co = split;
+ $c0 = $co[0];
+ $con = $#co;
+ if (($c0 eq $black) or ($c0 eq $lime)) {
+ for (my $j = 1; $j <= $con; $j++) {
+ $co[$j] *= (-1)**($j+1)*$cpt;
+ }
+ if ($cflag) {
+ $xtex .= "%Cubic B".chr(142)."zier curves\n";
+ $cflag = 0;
+ }
+ for (my $j = 3; $j <= $con - 5; $j += 6) {
+ cbez($c0,$co[$j-2],$co[$j-1],$co[$j],$co[$j+1],$co[$j+2],$co[$j+3],
+ $co[$j+4],$co[$j+5]);
+ }
+ }
+}
+#________________________________________________________
+# Frame
+if ($xtex . $mtex ne "") {
+ $xtex = $btex."\\usepackage[pdftex,pstarrows]{pict2e}\n\n".
+ "\\begin{document}\n\n".
+ "\\setlength{\\unitlength}{".$ul."pt}\n".
+ "\\begin{picture}(".ceil(($xmax - $xmin)).",".
+ ceil(($ymax - $ymin)).")(".floor($xmin).",".floor($ymin).")\n".
+ "\\linethickness{0.8pt}\n".$xtex;
+ $xtex .= $mtex."\\end{picture}\n\n\\end{document}";
+}
+print $xtex."\n";
+#________________________________________________________
+# Best pair for the slope of a line or an arrow
+sub best {
+ my ($x,$lsc) = @_;
+ if ($x > 1000) {
+ return (1,0);
+ }
+ elsif ($x < 0.001) {
+ return (0,1);
+ }
+ else {
+ if ($x =~ (/^\d+$/)) {
+ return ($x,1);
+ }
+ else {
+ if ($x < 1.0) {
+ $num1 = floor($x * $gi);
+ $den1 = $gi;
+ }
+ else {
+ $num1 = $gi;
+ $den1 = floor($gi / $x);
+ }
+ $r0 = $num1;
+ $r1 = $den1;
+ $q1 = 1;
+ @li = (0);
+ while ($r1 != 0) {
+ $q1 = floor($r0 / $r1);
+ $r2 = ($r0 % $r1);
+ $r0 = $r1;
+ $r1 = $r2;
+ $li[++$#li] = $q1;
+ }
+ $num1 /= $r0;
+ $den1 /= $r0;
+ if ($num1 <= $lsc and $den1 <= $lsc) {
+ return ($num1,$den1);
+ }
+ else {
+ $n = $#li;
+ @num = (1,$li[1]);
+ @den = (0,1);
+ $bnum = $li[1];
+ $bden = 1;
+ $i = 2;
+ $numh = 0;
+ $denh = 0;
+ while (($numh <= $lsc and $denh <= $lsc) and $i <= $n) {
+ $c = ($li[$i] >> 1);
+ if (($li[$i] % 2) == 1) {
+ $c++;
+ }
+ else {
+ $j = 1;
+ while (($i - $j >= 1 and $i + $j <= $n) and $li[$i - $j] == $li[$i + $j]) {
+ $j++;
+ }
+ $dj = $i - $j;
+ $sj = $i + $j;
+ if (($dj >= 1 and $sj <= $n) and $li[$dj] != $li[$sj]) {
+ $c += (($j + (($li[$sj] < $li[$dj]) ? 0 : 1)) % 2);
+ }
+ elsif ($dj == 0 and $sj <= $n) {
+ $c += ($j % 2);
+ }
+ elsif ($dj >= 1 and $sj == $n + 1) {
+ $c += (($j + 1) % 2);
+ }
+ elsif (($dj == 0 and $sj == $n + 1) or ($dj == 2 and
+ $sj == $n and $li[1] == 1 and $li[2] + 1 == $li[$n]) or
+ ($dj == 1 and $sj == $n - 1 and $li[$n] == 1
+ and $li[$n - 1] + 1 == $li[1])) {
+ $c++;
+ }
+ }
+ $k = $c;
+ while ($k <= $li[$i]) {
+ $numh = $k * $num[$i - 1] + $num[$i - 2];
+ $denh = $k * $den[$i - 1] + $den[$i - 2];
+ if ($numh > $lsc or $denh > $lsc) {
+ last;
+ }
+ $bnum = $numh;
+ $bden = $denh;
+ if ($k == $li[$i]) {
+ $num[$i] = $numh;
+ $den[$i] = $denh;
+ }
+ $k++;
+ }
+ $i++;
+ }
+ return ($bnum,$bden);
+ }
+ }
+ }
+}
+#________________________________________________________
+# Lines
+sub lin {
+ my ($c,$xb,$yb,$xe,$ye) = @_;
+ if (($c eq $black) or ($c eq $maroon) or ($c eq $purple)) {
+ $dx = $xe - $xb;
+ $dy = $ye - $yb;
+ $le = abs($dx);
+ if ($le > 1.0E-3) {
+ if ($pictnew) {
+ @p = best(abs($dy / $dx), 16383);
+ }
+ else {
+ @p = best(abs($dy / $dx), 1000);
+ }
+ $psx = $p[1] * ($dx <=> 0);
+ $psy = $p[0] * ($dy <=> 0);
+ }
+ else {
+ $psx = 0;
+ $psy = ($dy <=> 0);
+ $le = abs($dy);
+ }
+ $xbu = sp($xb);
+ $ybu = sp($yb);
+ $leu = sp($le);
+ if ($lt != 8) {
+ $xtex .= "\\linethickness{0.8pt}\n";
+ $lt = 8;
+ }
+ $xtex .= "\\put(".$xbu.",".$ybu."){\\line(".$psx.",".$psy."){".$leu."}}\n";
+ }
+ elsif (($c eq $lime) or ($c eq $navy)) {
+# Dotted line
+ $dx = $xe - $xb;
+ $dy = $ye - $yb;
+ $le = floor($pointf * $ul * (sqrt($dx**2 + $dy**2))) + 1;
+ if ($le > 1) {
+ $xbu = sp($xb - $ulb / 2);
+ $ybu = sp($yb);
+ $xiu = sp($dx / ($le - 1));
+ $yiu = sp($dy / ($le - 1));
+ if ($lt != 12) {
+ $xtex .= "\\linethickness{1.2pt}\n";
+ $lt = 12;
+ }
+ $xtex .= "\\multiput(".$xbu.",".$ybu.")(".$xiu.",".$yiu;
+ $xtex .= "){".$le."}{\\line(1,0){".$ulb."}}\n";
+ }
+ }
+}
+#________________________________________________________
+# Triangles
+sub tri {
+my ($q0,$qx1,$qy1,$qx2,$qy2,$qx3,$qy3) = @_;
+ $qx1 *= $ul;
+ $qy1 *= $ul;
+ $qx2 *= $ul;
+ $qy2 *= $ul;
+ $qx3 *= $ul;
+ $qy3 *= $ul;
+ if ($q0 eq $red) {
+# Filled triangle
+ %ha = ($qx1,$qy1,$qx2+1e-07,$qy2+1e-07,$qx3+2e-07,$qy3+2e-07);
+ @hb = ();
+ @hc = ();
+ foreach (sort { $ha{$a} <=> $ha{$b} } keys %ha) {
+ $hb[++$#hb] = $_;
+ $hc[++$#hc] = $ha{$_};
+ }
+ ($qx1,$qx2,$qx3) = @hb;
+ ($qy1,$qy2,$qy3) = @hc;
+ $lin = floor(($qy3 - $qy1) * $fillf);
+ $xtex .= "%Filled triangle\n";
+ if ($lt != 1) {
+ $xtex .= "\\linethickness{0.1pt}\n";
+ $lt = 1;
+ }
+ $si = ($qy3 - $qy1) * $qx2 - ($qx3 - $qx1) * $qy2 - $qx1 * $qy3 + $qx3 * $qy1 <=> 0;
+ $dex = ($qx3 - $qx1) / ($qy3 - $qy1) / $fillf;
+ $d1 = $qy2 - $qy1;
+ $d2 = $qy3 - $qy2;
+ if ($d1 >= 1.0E-3) {
+ $fx1 = ($qx2 - $qx1) / $d1;
+ $sx1 = $qx1 - $qy1 * $fx1;
+ }
+ if ($d2 >= 1.0E-3) {
+ $fx2 = ($qx3 - $qx2) / $d2;
+ $sx2 = $qx2 - $qy2 * $fx2;
+ }
+ for ($k = 1; $k <= $lin; $k++) {
+ $xb = $qx1 + $k * $dex;
+ $yb = $qy1 + $k / $fillf;
+ if ($yb <= $qy2) {
+ if ($d1 >= 1.0E-3) {
+ $leu = sp((abs($sx1 + $yb * $fx1 - $xb) + 0.5)/ $ul);
+ }
+ else {
+ $leu = sp((abs($qx2 - $qx1) + 0.5)/ $ul);
+ }
+ }
+ else {
+ if ($d2 >= 1.0E-3) {
+ $leu = sp((abs($sx2 + $yb * $fx2 - $xb) + 0.5)/ $ul);
+ }
+ else {
+ $leu = sp((abs($qx3 - $qx2) + 0.5)/ $ul);
+ }
+ }
+ if ($si > 0) {
+ $xbu = sp($xb / $ul);
+ }
+ else {
+ $xbu = sp($xb / $ul);
+ }
+ $ybu = sp($yb / $ul);
+ $xtex .= "\\put(".$xbu.",".$ybu."){\\line(".$si.",0){".$leu."}}\n";
+ }
+ }
+ elsif (($q0 eq $purple) or ($q0 eq $magenta)) {
+# Dotted triangle
+ %ha = ($qx1,$qy1,$qx2+1e-07,$qy2+1e-07,$qx3+2e-07,$qy3+2e-07);
+ @hb = ();
+ @hc = ();
+ foreach (sort { $ha{$a} <=> $ha{$b} } keys %ha) {
+ $hb[++$#hb] = $_;
+ $hc[++$#hc] = $ha{$_};
+ }
+ ($qx1,$qx2,$qx3) = @hb;
+ ($qy1,$qy2,$qy3) = @hc;
+ $xtex .= "%Dotted triangle\n";
+ if ($lt != 8) {
+ $xtex .= "\\linethickness{0.8pt}\n";
+ $lt = 8;
+ }
+ $si = ($qy3 - $qy1) * $qx2 - ($qx3 - $qx1) * $qy2 - $qx1 * $qy3 + $qx3 * $qy1 <=> 0;
+ $dy1 = 2 * ceil($qy1 / 2);
+ $dy3 = 2 * floor($qy3 / 2);
+ $lin = $dy3 - $dy1;
+ $dex = ($qx3 - $qx1) / ($qy3 - $qy1);
+ $xbh = $qx1 + ($dy1 - $qy1 - 2.0) * $dex;
+ $dex = 2 * $dex;
+ $d1 = $qy2 - $qy1;
+ $d2 = $qy3 - $qy2;
+ if ($d1 >= 1.0E-3) {
+ $fx1 = ($qx2 - $qx1) / $d1;
+ $sx1 = $qx1 + ($dy1 - $qy1) * $fx1;
+ }
+ if ($d2 >= 1.0E-3) {
+ $fx2 = ($qx3 - $qx2) / $d2;
+ $sx2 = $qx2 + ($dy1 - $qy2) * $fx2;
+ }
+ for ($k = 0; $k <= $lin; $k += 2) {
+ $qy = $dy1 + $k;
+ $xbh = $xbh + $dex;
+ ($si > 0) ? ($xb = $xbh) : ($xe = $xbh);
+ if ($qy <= $qy2) {
+ ($d1 >= 1.0E-3) ? ($xeh = $sx1 + $k * $fx1) : ($xeh = $qx1);
+ }
+ else {
+ ($d2 >= 1.0E-3) ? ($xeh = $sx2 + $k * $fx2) : ($xeh = $qx2);
+ }
+ ($si > 0) ? ($xe = $xeh) : ($xb = $xeh);
+ $xb = 2 * ceil($xb / 2);
+ $xbd = $xb + (($xb + $qy) % 4);
+ ($xe >= $xbd) ? ($num = floor(($xe - $xbd) / 4) + 1) : ($num = 0);
+ $xbu = sp($xbd / $ul - $ule / 2);
+ $qyu = sp($qy / $ul);
+ $xtex .= "\\multiput(".$xbu.",".$qyu.")(".$uli.",0){".$num;
+ $xtex .= "}{\\line(1,0){".$ule."}}\n";
+ }
+ }
+ elsif (($q0 eq $maroon) or ($q0 eq $olive)) {
+# Hatched triangle
+ $xtex .= "%Hatched triangle\n";
+ if ($lt != 8) {
+ $xtex .= "\\linethickness{0.8pt}\n";
+ $lt = 8;
+ }
+ $d1 = $qx1 - $qy1;
+ $d2 = $qx2 - $qy2;
+ $d3 = $qx3 - $qy3;
+ $qd1 = $d1;
+ $qd2 = $d2;
+ $qd3 = $d3;
+ %ha = ($qx1,$qd1,$qx2+1e-07,$qd2+1e-07,$qx3+2e-07,$qd3+2e-07);
+ @hb = ();
+ foreach (sort { $ha{$a} <=> $ha{$b} } keys %ha) {
+ $hb[++$#hb] = $_;
+ }
+ ($qx1,$qx2,$qx3) = @hb;
+ %ha = ($qy1,$qd1,$qy2+1e-07,$qd2+1e-07,$qy3+2e-07,$qd3+2e-07);
+ @hb = ();
+ @hc = ();
+ foreach (sort { $ha{$a} <=> $ha{$b} } keys %ha) {
+ $hb[++$#hb] = $_;
+ $hc[++$#hc] = $ha{$_};
+ }
+ ($qy1,$qy2,$qy3) = @hb;
+ ($d1,$d2,$d3) = @hc;
+ $si = (-$qy3 + $qy1) * $qx2 + ($qx3 - $qx1) * $qy2 + $qx1 * $qy3 - $qx3 * $qy1 <=> 0;
+ $p1 = 4 * ceil($d1 / 4);
+ $p2 = 4 * floor($d2 / 4);
+ $p3 = 4 * floor($d3 / 4);
+ $fx1 = ($qx1 - $qx3) / ($d3 - $d1);
+ $sx1 = $qx3 + $fx1 * $d3;
+ $fy1 = ($qy1 - $qy3) / ($d3 - $d1);
+ $sy1 = $qy3 + $fy1 * $d3;
+ $d21 = $d2 - $d1;
+ $d32 = $d3 - $d2;
+ if ($d21 >= 1.0E-3) {
+ $fx2 = ($qx1 - $qx2) / $d21;
+ $sx2 = $qx2 + $fx2 * $d2;
+ }
+ if ($d32 >= 1.0E-3) {
+ $fx3 = ($qx2 - $qx3) / $d32;
+ $sx3 = $qx3 + $fx3 * $d3;
+ }
+ for ($k = $p1; $k <= $p3; $k += 4) {
+ $xbk = $sx1 - $k * $fx1;
+ $ybk = $sy1 - $k * $fy1;
+ if ($k <= $p2) {
+ ($d21 < 1.0E-3) ? ($le = abs($qx2 - $qx1)) : ($le = abs($sx2 - $k * $fx2 - $xbk));
+ }
+ else {
+ ($d32 < 1.0E-3) ? ($le = abs($qx3 - $qx2)) : ($le = abs($sx3 - $k * $fx3 - $xbk));
+ }
+ $xbk = sp($xbk / $ul);
+ $ybk = sp($ybk / $ul);
+ $le = sp($le / $ul);
+ $xtex .= "\\put(".$xbk.",".$ybk."){\\line(".$si.",".$si."){".$le."}}\n";
+ }
+ }
+}
+#________________________________________________________
+# Rectangles
+sub rect {
+ my ($q0,$x1,$y1,$x2,$y2,$x3,$y3,$x4,$y4) = @_;
+ $dx = abs($x2 - $x1);
+ $dx = ($dx < 1.0E-6) ? abs($x3 -$x2) : $dx;
+ $dx = $dx * $ul;
+ $xb = ($x1 < $x2) ? (($x1 < $x3) ? $x1 : $x3) : (($x2 < $x3) ? $x2 : $x3);
+ $xb = $xb * $ul;
+ $dy = abs($y2 - $y1);
+ $dy = ($dy < 1.0E-6) ? abs($y3 -$y2) : $dy;
+ $dy = $dy * $ul;
+ $yb = ($y1 < $y2) ? (($y1 < $y3) ? $y1 : $y3) : (($y2 < $y3) ? $y2 : $y3);
+ $yb = $yb * $ul;
+ $xe = $xb + $dx;
+ $ye = $yb + $dy;
+# Filled rectangle
+ if ($q0 eq $red) {
+ $xtex .= "%Filled rectangle\n";
+ if ($lt != 1) {
+ $xtex .= "\\linethickness{0.1pt}\n";
+ $lt = 1;
+ }
+ $xbu = sp($xb / $ul);
+ $ybu = sp($yb / $ul);
+ if ($dy <= $dx) {
+ $lin = floor($fillf * $dy);
+ $dxu = sp($dx / $ul);
+ $ybi = sp(1.0 / ($fillf * $ul));
+ $xtex .= "\\multiput(".$xbu.",".$ybu.")(0,".$ybi."){".$lin;
+ $xtex .= "}{\\line(1,0){".$dxu."}}\n";
+ }
+ else {
+ $lin = floor($fillf * $dx);
+ $dyu = sp($dy / $ul);
+ $xbi = sp(1.0 / ($fillf * $ul));
+ $xtex .= "\\multiput(".$xbu.",".$ybu.")(".$xbi.",0){".$lin;
+ $xtex .= "}{\\line(0,1){".$dyu."}}\n";
+ }
+ }
+# Dotted rectangle
+ elsif (($q0 eq $purple) or ($q0 eq $magenta)) {
+ $xtex .= "%Dotted rectangle\n";
+ if ($lt != 8) {
+ $xtex .= "\\linethickness{0.8pt}\n";
+ $lt = 8;
+ }
+ $xbb = 2 * ceil($xb / 2);
+ $ybb = 2 * ceil($yb / 2);
+ for ($k = 0; $k <= 2; $k += 2) {
+ $ybd = $ybb + $k;
+ $xbd = $xbb + (($xbb + $ybd) % 4);
+ $numx = floor(($xe - 0.13 - $xbd) / 4) + 1;
+ $numy = floor(($ye - 0.13 - $ybd) / 4) + 1;
+ $xbu = sp($xbd / $ul - $ule / 2);
+ $ybu = sp($ybd / $ul);
+ $xtex .= "\\multiput(".$xbu.",".$ybu.")(".$uli.",0){".$numx."}\n";
+ $xtex .= "{\\begin{picture}(0,0)\\multiput(0,0)(0,".$uli."){";
+ $xtex .= $numy."}\n{\\line(1,0){".$ule."}}\\end{picture}}\n";
+ }
+ }
+# Hatched rectangle
+ elsif (($q0 eq $maroon) or ($q0 eq $olive)) {
+ $xtex .= "%Hatched rectangle\n";
+ if ($lt != 8) {
+ $xtex .= "\\linethickness{0.8pt}\n";
+ $lt = 8;
+ }
+ $p1 = 4 * ceil(($xb - $ye) / 4);
+ if ($dx >= $dy) {
+ $p2 = 4 * floor(($xb - $yb) / 4) + 4;
+ $p3 = 4 * floor(($xe - $ye) / 4) + 4;
+ $xp = $yb + $p2;
+ $yp = $yb;
+ $lp = $dy;
+ $ip1 = 4;
+ $ip2 = 0;
+ }
+ else {
+ $p3 = 4 * floor(($xb - $yb) / 4) + 4;
+ $p2 = 4 * floor(($xe - $ye) / 4) + 4;
+ $xp = $xb;
+ $yp = $xb - $p2;
+ $lp = $dx;
+ $ip1 = 0;
+ $ip2 = -4;
+ }
+ $p4 = 4 * floor(($xe - $yb) / 4);
+ for ($k = $p1; $k <= $p2 - 4; $k += 4) {
+ $xbu = sp($xb / $ul);
+ $ybu = sp(($xb - $k) / $ul);
+ $le = sp(($ye - $xb + $k) / $ul);
+ $xtex .= "\\put(".$xbu.",".$ybu."){\\line(1,1){".$le."}}\n";
+ }
+ $np = ($p3 - $p2) / 4;
+ if ($p3 > $p2) {
+ $xpu = sp($xp / $ul);
+ $ypu = sp($yp / $ul);
+ $ip1u = sp($ip1 / $ul);
+ $ip2u = sp($ip2 / $ul);
+ $lpu = sp($lp / $ul - 0.1);
+ $xtex .= "\\multiput(".$xpu.",".$ypu.")(".$ip1u.",".$ip2u;
+ $xtex .= "){".$np."}{\\line(1,1){".$lpu."}}\n";
+ }
+ for ($k = $p3; $k <= $p4; $k += 4) {
+ $xbu = sp(($yb + $k) / $ul);
+ $ybu = sp($yb / $ul);
+ $leu = sp(($xe - $yb - $k) / $ul);
+ $xtex .= "\\put(".$xbu.",".$ybu."){\\line(1,1){".$leu."}}\n";
+ }
+ }
+}
+#________________________________________________________
+# Quadratic Bézier curves
+sub qbez {
+ my ($q0,$x1,$y1,$x2,$y2,$x3,$y3) = @_;
+ my $xb = $x1;
+ my $yb = $y1;
+ my $len = 0.0;
+ for ($t = 0.02; $t <= 1.0; $t += 0.02) {
+ bound($xb,$yb);
+ $s = 1.0 - $t;
+ $xe = $s * ($s * $x1 + $t * $x2) + $t * ($s * $x2 + $t * $x3);
+ $ye = $s * ($s * $y1 + $t * $y2) + $t * ($s * $y2 + $t * $y3);
+ $len += sqrt(($xe - $xb)**2 + ($ye - $yb)**2);
+ $xb = $xe;
+ $yb = $ye;
+ }
+ bound($x3,$y3);
+ $x1 = sp($x1);
+ $y1 = sp($y1);
+ $x2 = sp($x2);
+ $y2 = sp($y2);
+ $x3 = sp($x3);
+ $y3 = sp($y3);
+ if ($q0 eq $green) {
+ $le = floor($pointf * $ul * $len);
+ if ($lt != 12) {
+ $xtex .= "\\linethickness{1.2pt}\n";
+ $lt = 12;
+ }
+ if ($pictnew) {
+ $xtex .= "\\qbezier[";
+ }
+ else {
+ $xtex .= "\\Qbezier[";
+ }
+ $xtex .= $le."](".$x1.",".$y1.")(".$x2.",".$y2.")(".$x3.",".$y3.")\n";
+ }
+ elsif ($q0 eq $blue) {
+ if ($lt != 8) {
+ $xtex .= "\\linethickness{0.8pt}\n";
+ $lt = 8;
+ }
+ $xtex .= "\\qbezier(".$x1.",".$y1.")(".$x2.",".$y2;
+ $xtex .= ")(".$x3.",".$y3.")\n";
+ }
+}
+#________________________________________________________
+# Cubic Bézier curves
+sub cbez {
+ my ($q0,$x1,$y1,$x2,$y2,$x3,$y3,$x4,$y4) = @_;
+ my $xb = $x1;
+ my $yb = $y1;
+ if ($q0 eq $black) {
+ for ($t = 0.02; $t <= 1.0; $t += 0.02) {
+ bound($xb,$yb);
+ $s = 1.0 - $t;
+ $u1 = $s * $x1 + $t * $x2;
+ $v1 = $s * $y1 + $t * $y2;
+ $u2 = $s * $x2 + $t * $x3;
+ $v2 = $s * $y2 + $t * $y3;
+ $u3 = $s * $x3 + $t * $x4;
+ $v3 = $s * $y3 + $t * $y4;
+ $xe = $s * ($s * $u1 + $t * $u2) + $t * ($s * $u2 + $t * $u3);
+ $ye = $s * ($s * $v1 + $t * $v2) + $t * ($s * $v2 + $t * $v3);
+ $xb = $xe;
+ $yb = $ye;
+ }
+ bound($x4,$y4);
+ $x1 = sp($x1);
+ $y1 = sp($y1);
+ $x2 = sp($x2);
+ $y2 = sp($y2);
+ $x3 = sp($x3);
+ $y3 = sp($y3);
+ $x4 = sp($x4);
+ $y4 = sp($y4);
+ if ($lt != 8) {
+ $xtex .= "\\linethickness{0.8pt}\n";
+ $lt = 8;
+ }
+ $xtex .= "\\cbezier(".$x1.",".$y1.")(".$x2.",".$y2.")(".$x3.",".$y3.")(".$x4.",".$y4.")\n";
+ }
+ elsif ($q0 eq $lime) {
+ if ($lt != 12) {
+ $xtex .= "\\linethickness{1.2pt}\n";
+ $lt = 12;
+ }
+ my $len = 0.0;
+ for ($t1 = 0.02; $t1 <= 1.0; $t1 += 0.02) {
+ bound($xb,$yb);
+ $s1 = 1.0 - $t1;
+ $u1 = $s1 * $x1 + $t1 * $x2;
+ $v1 = $s1 * $y1 + $t1 * $y2;
+ $u2 = $s1 * $x2 + $t1 * $x3;
+ $v2 = $s1 * $y2 + $t1 * $y3;
+ $u3 = $s1 * $x3 + $t1 * $x4;
+ $v3 = $s1 * $y3 + $t1 * $y4;
+ $xe = $s1 * ($s1 * $u1 + $t1 * $u2) + $t1 * ($s1 * $u2 + $t1 * $u3);
+ $ye = $s1 * ($s1 * $v1 + $t1 * $v2) + $t1 * ($s1 * $v2 + $t1 * $v3);
+ $len += sqrt(($xe - $xb)**2 + ($ye - $yb)**2);
+ $xb = $xe;
+ $yb = $ye;
+ }
+ bound($x4,$y4);
+ $le = floor($pointf * $ul * $len);
+ $dflag = 0;
+ if ($le >= 4) {
+ @px = ();
+ @py = ();
+ @qx = ();
+ @qy = ();
+ @r = ();
+ @de = ();
+ @xh = ();
+ @yh = ();
+ for (my $k = 0; $k <= 4; $k++) {
+ $tk = $k / 4;
+ $sk = 1.0 - $tk;
+ $px[++$#px]=$sk**3*$x1+3*$sk**2*$tk*$x2+3*$sk*$tk**2*$x3+$tk**3*$x4;
+ $py[++$#py]=$sk**3*$y1+3*$sk**2*$tk*$y2+3*$sk*$tk**2*$y3+$tk**3*$y4;
+ $qx[++$#qx]=3.0*(-$sk**2*$x1+$sk*(1-3*$tk)*$x2+$tk*(2-3*$tk)*$x3+
+ $tk**2*$x4);
+ $qy[++$#qy]=3.0*(-$sk**2*$y1+$sk*(1-3*$tk)*$y2+$tk*(2-3*$tk)*$y3+
+ $tk**2*$y4);
+ $r[++$#r] = $px[$k] * $qy[$k] - $py[$k] * $qx[$k];
+ }
+ for (my $i = 0; $i <=3; $i++) {
+ $det = $qx[$i] * $qy[$i+1] - $qy[$i]*$qx[$i+1];
+ if (abs($det) < 1.0E-10) {
+ last;
+ }
+ $de[++$#de] = $det;
+ $xh[++$#xh] = ($qx[$i] * $r[$i+1] - $r[$i]*$qx[$i+1]) / $det;
+ $yh[++$#yh] = ($qy[$i] * $r[$i+1] - $r[$i]*$qy[$i+1]) / $det;
+ }
+ if ($#de == 3) {
+ $le = ceil($le / 4);
+ for (my $i = 0; $i <=3; $i++) {
+ $x1 = sp($px[$i]);
+ $y1 = sp($py[$i]);
+ $x2 = sp($xh[$i]);
+ $y2 = sp($yh[$i]);
+ $x3 = sp($px[$i+1]);
+ $y3 = sp($py[$i+1]);
+ if ($pictnew) {
+ $xtex .= "\\qbezier[";
+ }
+ else {
+ $xtex .= "\\Qbezier[";
+ }
+ $xtex .= $le."](".$x1.",".$y1.")(".$x2.",".$y2.")(".$x3.",".$y3.")\n";
+ }
+ $dflag = 1;
+ }
+ }
+ if (not $dflag) {
+ $xb = $x1;
+ $yb = $y1;
+ $le = 1/ceil($pointf * $ul * $len);
+ $xc = sp($xb - $ulb / 2);
+ $yc = sp($yb);
+ for ($t = $le; $t <= 1.0 + $le; $t += $le) {
+ $xtex .= "\\put(".$xc.",".$yc."){\\line(1,0){".$ulb."}}\n";
+ $s = 1.0 - $t;
+ $u1 = $s * $x1 + $t * $x2;
+ $v1 = $s * $y1 + $t * $y2;
+ $u2 = $s * $x2 + $t * $x3;
+ $v2 = $s * $y2 + $t * $y3;
+ $u3 = $s * $x3 + $t * $x4;
+ $v3 = $s * $y3 + $t * $y4;
+ $xe = $s * ($s * $u1 + $t * $u2) + $t * ($s * $u2 + $t * $u3);
+ $ye = $s * ($s * $v1 + $t * $v2) + $t * ($s * $v2 + $t * $v3);
+ $xb = $xe;
+ $yb = $ye;
+ $xc = sp($xb - $ulb / 2);
+ $yc = sp($yb);
+ }
+ $xc = sp($x4 - $ulb / 2);
+ $yc = sp($y4);
+ $xtex .= "\\put(".$xc.",".$yc."){\\line(1,0){".$ulb."}}\n";
+ }
+ }
+}
+#________________________________________________________
+# Bounding box
+sub bound {
+ my ($xn,$yn) = @_;
+ if ($sflag) {
+ $xmin = $xn;
+ $xmax = $xn;
+ $ymin = $yn;
+ $ymax = $yn;
+ $sflag = 0;
+ }
+ else {
+ if ($xn < $xmin) {$xmin = $xn} elsif ($xmax < $xn) {$xmax = $xn}
+ if ($yn < $ymin) {$ymin = $yn} elsif ($ymax < $yn) {$ymax = $yn}
+ }
+}
+#________________________________________________________
+# Sprintf
+sub sp {
+ my $x = shift;
+ return sprintf("%.3f",$x) + 0;
+}
+#________________________________________________________