summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/generic/mfpic
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2009-10-03 14:58:41 +0000
committerKarl Berry <karl@freefriends.org>2009-10-03 14:58:41 +0000
commit556ccc6a2633ddbc27a22319d2e16e8a5d7483d1 (patch)
tree6f0b1301fabae1e14d1c00703e774efd67543d16 /Master/texmf-dist/source/generic/mfpic
parent4d18074405a67946d5505fd5e0836e115d220541 (diff)
mfpic 1.00 (30sep09)
git-svn-id: svn://tug.org/texlive/trunk@15602 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/generic/mfpic')
-rw-r--r--Master/texmf-dist/source/generic/mfpic/grafbase.dtx910
-rw-r--r--Master/texmf-dist/source/generic/mfpic/mfpic.dtx379
-rw-r--r--Master/texmf-dist/source/generic/mfpic/mfpic.ins11
3 files changed, 996 insertions, 304 deletions
diff --git a/Master/texmf-dist/source/generic/mfpic/grafbase.dtx b/Master/texmf-dist/source/generic/mfpic/grafbase.dtx
index fe734cbcc84..9d7c4bd010b 100644
--- a/Master/texmf-dist/source/generic/mfpic/grafbase.dtx
+++ b/Master/texmf-dist/source/generic/mfpic/grafbase.dtx
@@ -1,4 +1,7 @@
% \iffalse
+%%% File: grafbase.dtx
+%%% A part of mfpic 1.00 2009/09/22
+%%%
% -------------------------------------------------------------------
%
% Copyright 2002--2006, Daniel H. Luecking
@@ -16,7 +19,7 @@
%
%<*driver>
\ProvidesFile{grafbase.dtx}
- [2006/05/26 v0.9. Metafont/post macros to interface with mfpic.]%
+ [2009/09/22 v1.00. Metafont/post macros to interface with mfpic.]%
\documentclass[draft]{ltxdoc}
\usepackage{docmfp}
@@ -110,7 +113,7 @@
%</driver>
%\fi
%
-% \CheckSum{1369}
+% \CheckSum{1465}
% \CharacterTable
% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
@@ -137,12 +140,13 @@
% \file{.mp} file that, with the help of these macros and \MF{} (or \MP),
% can be used to create pictures in the document, especially mathematical
% pictures. There are two versions of \grafbase, one for \MF{} and one for
-% \MP{}. As they are more alike than different (96\% of the code is
+% \MP{}. As they are more alike than different (95\% of the code is
% identical), we document both here.
%
% This file documents the \grafbase{} source code. The user manual for
-% \mfpic{} is distributed as \file{mfpman.pdf} produced from
-% \file{mfpman.tex}.
+% \mfpic{} is distributed as \file{mfpic-doc.pdf}, produced from
+% \file{mfpic-doc.tex}. An introductory guide to \mfpic{} is available
+% in \file{mfpguide.pdf}, produced from \file{mfpguide.pdf}
% \end{abstract}
%
% \StopEventually{\PrintIndex}
@@ -181,7 +185,7 @@ fi
boolean grafbase; grafbase := true;
string fileversion, filedate;
-fileversion := "0.9"; filedate := "2006/05/26";
+fileversion := "1.00"; filedate := "2009/09/22";
message " Loading grafbase macros, version " & fileversion & " " &
filedate & ".";
@@ -228,9 +232,10 @@ def checkversions (expr g)=
fi
enddef;
-checkversions (90);
+checkversions (100);
% \end{macrocode}
+%
% We try to make sure that the macros of \file{plain.mf} or
% \file{plain.mp} (where \mfc{base_name} is defined to be \mfc{"plain"})
% are available.
@@ -250,7 +255,7 @@ fi
%
% Of course, \MP{} natively knows about colors but \MF{} doesn't, so we
% use that to set a boolean \gbc{METAPOST}. We don't simply check if
-% `\mfc{known blue}' is \mfc{true} because `\mfc{blue}' is certainly a legal
+% `\mfc{blue}' is \mfc{known} because `\mfc{blue}' is certainly a legal
% variable name in \MF. Instead we check `\mfc{known color X}' for
% some unlikely \gbc{X}. In \MP, `\gbc{color X}' is either true or
% false (\gbc{X} is a color or it isn't) and therefore always known, so
@@ -260,28 +265,60 @@ fi
% base name \mfc{color} and suffix \mfc{X}.
% \begin{macrocode}
boolean METAPOST;
-
-if known color Geamparalele din Babadag:
- METAPOST := true;
-else:
- METAPOST := false;
-fi
+METAPOST := known color Geamparalele din Babadag;
+numeric metapostversion;
%<*MF>
if METAPOST:
GBerrmsg ("wrong compiler.")
"This file is for Metafont. For Metapost use grafbase.mp.";
fi
+metapostversion := 0;
%</MF>
+
%<*MP>
if not METAPOST:
GBerrmsg ("wrong compiler.")
"This file is for Metapost. For Metafont use grafbase.mf.";
fi
-%</MP>
% \end{macrocode}
%
+% \MP{} now exists in a couple of slightly incompatible versions.
+% Versions 1.000 and later (beta versions 0.900 also) have native support for
+% \texttt{CMYK} colors with a \mfc{cmykcolor} data type. It also
+% supports grayscale colors (i.e., \mfc{withcolor} will accept a numeric
+% expression), and has the alias \mfc{rgbcolor} for \mfc{color}.
+% It also has a means to set the name of the output file: the
+% \mfc{filenametemplate} command. In versions 1.2 and later, this is
+% deprecated in favor of setting the internal string variable
+% \mfc{outputtemplate}.
+% \begin{macrocode}
+numeric metapostversion;
+boolean has_cmyk;
+boolean has_filenametemplate; % e.g., filenametemplate "%j.%n;
+boolean has_outputtemplate; % e.g., outputtemplate := "%j.%n;
+if unknown mpversion:
+ % prior to introduction of cmykcolor and output filename templates.
+ % Latest such version was 0.641.
+ metapostversion := 0.641;
+ has_cmyk := false;
+ has_filenametemplate := false;
+ has_outputtemplate := false;
+else:
+ metapostversion := scantokens (mpversion);
+ has_cmyk := true;
+ has_filenametemplate := true;
+ if metapostversion < 1.200:
+ has_outputtemplate := false;
+ else:
+ has_outputtemplate := true;
+ fi
+fi
+
+%</MP>
+% \end{macrocode}
+%
% \DescribeRoutine{GBdebug}
% The \gbc{debug} flag is for developers, who should set it before
% inputing \file{grafbase}.
@@ -551,9 +588,12 @@ boolean showbbox; showbbox := false;
% \begin{macrocode}
%<*MF>
let color = numeric; color black, white;
+let rgbcolor = numeric;
+let cmykcolor = numeric;
black := 0; white := 1;
def withcolor text t = enddef;
%</MF>
+%<MP>if not has_cmyk: let rgbcolor = color; let cmykcolor = color; fi
def _wc_ = withcolor enddef;
% \end{macrocode}
@@ -580,110 +620,244 @@ background := white;
%
% \DescribeRoutine{snapto}
% This truncates numerics to the $[0,1]$ range, but also returns a value
-% ($0$) for unknown and non-numeric input.
+% ($0$) for unknown input. It used to do the same for non-numeric input,
+% but that should be an error. It would have made at least one of our
+% bugs easier to find if it had produced an error message.
% \begin{macrocode}
vardef snapto expr t =
- if unknown t: 0
- elseif not (numeric t): 0
- elseif t < 0: 0
- elseif t > 1: 1
- else: t
+ if numeric t:
+ if unknown t: 0
+ elseif t < 0: 0
+ elseif t > 1: 1
+ else: t
+ fi
+ else:
+ GBerrmsg ("Improper expression type.")
+ "The argument to `snapto' must be a numeric.";
fi
+
enddef;
% \end{macrocode}
%
-% The \mfpic{} handling of \LaTeX-like color models relies on being able
-% to convert those models to \MP's \opt{rgb} system. Because of the use of
-% \gbc{snapto}, the following color functions will return \mfc{black} for
-% unknown parameters. In the \MF{} case, they are all converted to
-% numerics through \gbc{makeclr}.
+% \DescribeRoutine{cmykgray}
+% \DescribeRoutine{rgbgray}
+% Now we deal with all the color functions and utilities that enable
+% \mfpic{} users to use colors without knowing what they are doing.
+% Since colors now come in three flavors, we start with gray levels in
+% the three models. In early \MP{}, the \gbc{cmyk} function will return
+% an \opt{rgb} color, so there is will be no difference between these
+% two. In \MF{} \gbc{white} is a numeric and \gbc{cmyk} returns a
+% numeric, so these can be used with \MF{}, and both produce the same
+% result.
%
-% \DescribeRoutine{gray}
-% The simplest is \gbc{gray} which converts a numeric to a multiple of
-% white. In \MF, \gbc{white} is a numeric and equal to $1$ so this is
-% almost redundant except for handling unknowns and out of range values.
+% \DescribeRoutine{grayscalegray}
+% The grayscale version should return a numeric in recent \MP{}, so
+% it needs a different definition for early \MP{}. Thus, it occurs
+% in the conditional code. Oddly, its definition is the same for \MF{}
+% and recent \MP{}.
+% \begin{macrocode}
+vardef rgbgray (expr g) = (snapto g) * white enddef;
+vardef cmykgray (expr g) = cmyk(0,0,0,1 - snapto g) enddef;
+
+% \end{macrocode}
%
-% \DescribeRoutine{makeclr}
-% This is defined to convert a triple of numerics to a color, mainly for
-% \MF. The formula has three desirable properties: it weights the
-% different color coordinates approximately like some color luminescence
-% models do, it assigns different graylevels to the eight colors that have
-% components 0 or 1 only, and it is biased toward lighter grays. Of course
-% it takes \mfc{black} to 0 and \mfc{white} to 1. In \MP, it simply turns
-% three numeric parameters to a color triple in the obvious way. It does
-% \emph{not} truncate the parameters, so if that is necessary, use
-% \gbc{rgb}.
+% In recent \MP{}, all the color functions are essentially no-ops. In
+% early \MP{}, they all return an \opt{rgb} color expression. In \MF{}
+% they all return a numeric. It is easiest if we simply separate the three
+% cases and write the code for each, rather than load all the functions
+% with three-way booleans (often containing nested booleans).
%
-% \DescribeRoutine{rgb}
-% To simplify \mfpic, we have the nearly redundant \gbc{rgb} which
-% converts a triple of numeric arguments to \opt{rgb}. Rather than make
-% it formally the identity function under \MP, we define it to handle
-% unknowns, and truncate out of range values.
+% For all three engines we require a deginition of the color functions
+% \gbc{gray(g)}, \gbc{rgb(r,g,b)}, and \gbc{cmyk(c,m,y,k)}, conversion
+% functions \gbc{makegray(x)}, \gbc{makergb(x)}, amd \gbc{makecmyk(x)},
+% and the boolean \gbc{iscolor clr}. The first three have to return
+% numerics for \MF{}, colors for early \MP{}, and the associated color
+% type for recent \MP{}.
% \begin{macrocode}
-vardef gray (expr g) = (snapto g)*white enddef;
-
-vardef makeclr (expr r, g, b) =
-%<MF> gray (sqrt((2r*r + 4g*g + b*b)/7))
-%<MP> (r, g, b)
-enddef;
+%<*MP>
+if has_cmyk :
+ vardef grayscalegray (expr g) = snapto g enddef;
+ vardef gray (expr g) = grayscalegray (g) enddef;
+ vardef cmyk (expr c, m, y, k) =
+ (snapto c, snapto m, snapto y, snapto k)
+ enddef;
-vardef rgb (expr r, g, b) =
- makeclr (snapto r, snapto g, snapto b)
-enddef;
+% \end{macrocode}
+%
+% \DescribeRoutine{colorchoice}
+% The \gbc{colorchoice} function (like \cs{mathchoice} in \TeX{}, after
+% which it was named) returns one of four bits of code: \gbc{D} (default)
+% if the first argument is unknown or not one of the recognized color
+% models, \gbc{N} if it is numeric, \gbc{R} if it is \mfc{rgbcolor}, and
+% \gbc{C} if it is \mfc{cmykcolor}. These arguments have to be \mfc{text}:
+% if they were `\mfc{expr}' \MP{} would try to evaluate them, with
+% possible errors since some of them apply functions that are not relevant
+% to the other types.
+% \begin{macrocode}
+ def colorchoice (expr clr) (text D)(text N)(text R)(text C) =
+ if unknown clr: D
+ elseif numeric clr: N
+ elseif rgbcolor clr: R
+ elseif cmykcolor clr: C
+ else: D
+ fi
+ enddef;
% \end{macrocode}
%
-% \DescribeRoutine{cmyk}
-% This algorithm for converting \opt{cmyk} values to \opt{rgb} values is
-% the one used in the PostScript header file \file{color.pro} (distributed
-% with \prog{dvips}).
+% \DescribeRoutine{makecmyk}\DescribeRoutine{makergb}\DescribeRoutine{makegray}
+% In \gbc{makecmyk} and all the other `\gbc{make}' conversions, the
+% default is to return black in the appropriate model, numerics produce
+% gray, and cmyk or rgb is either retained unchanged or converted to the
+% appropriate model.
+%
+% \DescribeRoutine{iscolor}
+% A variable is taken to be a color if it can validly follow
+% \mfc{withcolor}. This includes boolean, though we hope no one tries to
+% use it.
% \begin{macrocode}
-vardef cmyk (expr c, m, y, k) =
- rgb (1-c-k, 1-m-k, 1-y-k)
-enddef;
+ vardef makecmyk primary clr =
+ colorchoice (clr)(cmykblack)(cmykgray(clr))
+ (rgbtocmyk(redpart clr,greenpart clr,bluepart clr))
+ (clr)
+ enddef;
+ vardef makergb primary clr =
+ colorchoice (clr)(rgbblack)(rgbgray(clr))(clr)
+ (cmyktorgb(cyanpart clr, magentapart clr, yellowpart clr, blackpart clr))
+ enddef;
+ vardef makegray primary clr =
+ colorchoice (clr)(grayscaleblack)(grayscalegray(clr))
+ (rgbtogray (redpart clr, greenpart clr, bluepart clr))
+ (cmyktogray(cyanpart clr, magentapart clr, yellowpart clr,
+ blackpart clr))
+ enddef;
+ vardef iscolor expr clr =
+ (rgbcolor clr) or (cmykcolor clr) or (numeric clr) or (boolean clr)
+ enddef;
+else:
+% \end{macrocode}
+%
+% \DescribeRoutine{colorchoice}
+% In early \MP{} \gbc{colorchoice} is a three-way choice, since
+% \mfc{cmykcolor} is not an available data type, but numeric can still be
+% interpreted as a gray.
+% \DescribeRoutine{makecmyk}
+% \DescribeRoutine{makergb}
+% \DescribeRoutine{makegray}
+% The \gbc{make*} functions are simpler in early \MP{}, though not as
+% simple as in \MF{}. Ditto
+% \DescribeRoutine{iscolor}
+% \gbc{iscolor}.
+% \begin{macrocode}
+ vardef gray (expr g) = rgbgray(g) enddef;
+ vardef grayscalegray (expr g) = rgbgray(g) enddef;
+ vardef cmyk (expr c, m, y, k) = rgb (1-c-k, 1-m-k, 1-y-k) enddef;
+ def colorchoice (expr clr) (text D)(text N)(text R) =
+ if unknown clr: D
+ elseif numeric clr: N
+ elseif rgbcolor clr: R
+ else: D
+ fi
+ enddef;
+ vardef makergb primary clr =
+ colorchoice (clr)(rgbblack)(rgbgray(clr))(clr)
+ enddef;
+ vardef makegray primary clr =
+ colorchoice (clr)(rgbblack)(rgbgray(clr))
+ (rgbtogray (redpart clr, greenpart clr, bluepart clr))
+ enddef;
+ def makecmyk = makergb enddef;
+ vardef iscolor expr clr = color clr enddef;
+fi
+%</MP>
% \end{macrocode}
%
-% \DescribeRoutine{RGB}
-% This merely rescales numbers in the range 0--255 to the range 0--1.
+% \DescribeMacro{knowncolor}
+% Once we have \gbc{iscolor} all we need to do is add a test for
+% \mfc{known} to get this boolean test.
+% \begin{macrocode}
+vardef knowncolor expr clr = (known clr) and (iscolor clr) enddef;
+
+% \end{macrocode}
%
-% \DescribeRoutine{named}
-% These last two, like \gbc{rgb}, are nearly redundant, but they convert
-% numerics to gray, and convert other non-color variables and unknown
-% color variables to black.
-% \DescribeRoutine{forceclr}
-% The difference between \gbc{named} and \gbc{forceclr} is that the
-% former requires a suffix parameter (that is, a \emph{name}), while the
-% latter takes an expression. It may be that the latter will never be
-% needed, but for a time it seemed there were cases where we ought to use
-% it to force an expression to be a color.
+% These are the \MF{} versions. Everything pretty much returns its
+% numeric argument or $0$ (black).
% \begin{macrocode}
-vardef RGB (expr R, G, B) =
- rgb (R/255, G/255, B/255)
+%<*MF>
+vardef grayscalegray (expr g) = snapto g enddef;
+vardef gray (expr g) = grayscalegray (g) enddef;
+vardef cmyk (expr c, m, y, k) = rgb (1-c-k, 1-m-k, 1-y-k) enddef;
+vardef makegray primary clr =
+ if knowncolor clr: clr else: black fi
enddef;
+def makergb = makegray enddef;
+def makecmyk = makegray enddef;
+vardef iscolor expr clr = color clr enddef;
-vardef named (suffix c) =
- if unknown c: black else: forceclr (c) fi
-enddef;
+%</MF>
+% \end{macrocode}
+%
+% \DescribeRoutine{forcecolor}
+% \DescribeRoutine{named}
+% This is only used in the \gbc{named} function to force a color. In
+% \MF{} the tests are all `\mfc{if numeric}'. In early \MP{} `\mfc{if
+% cmykcolor}' is the same as `\mfc{if rgbcolor}'.
+% \begin{macrocode}
vardef forceclr (expr c) =
- if numeric c: gray (c)
- elseif color c: c
- else: black
+ if unknown c :
+ if numeric c: grayscaleblack
+ elseif rgbcolor c: rgbblack
+ elseif cmykcolor c: cmykblack
+ else: black
+ fi
+ elseif numeric c: gray (c)
+ elseif iscolor c: c
+ else: black
fi
enddef;
+vardef named (suffix c) = forceclr (c) enddef;
% \end{macrocode}
-% And then the standard colors. Using \gbc{rgb} ensures they are defined
-% in \MF{} as well as \MP.
+%
+% \DescribeRoutine{togray}
+% \DescribeRoutine{rgbtogray}
+% \DescribeRoutine{cmyktogray}
+% \DescribeRoutine{cmyktorgb}
+% \DescribeRoutine{rgbtocmyk}
+% These are used for the conversions. Strictly speaking they do not
+% `convert' as they all take multiple numeric arguments rather than any
+% sort of color. As \mfc{rgbcolor} exists in both early and recent
+% \MP{} as the same data type, we need only distinguish \MF{} from \MP{}
+% \DescribeRoutine{rgb}
+% in the function \gbc{rgb},
% \begin{macrocode}
-color red, green, blue, cyan, magenta, yellow;
-red := rgb (1, 0, 0);
-green := rgb (0, 1, 0);
-blue := rgb (0, 0, 1);
-cyan := rgb (0, 1, 1);
-magenta := rgb (1, 0, 1);
-yellow := rgb (1, 1, 0);
+vardef togray (expr r, g, b) =
+ gray (sqrt((2r*r + 4g*g + b*b)/7))
+enddef;
+
+vardef rgbtogray (expr r, g, b) =
+ togray(snapto r, snapto g, snapto b)
+enddef;
+vardef cmyktogray (expr c, m, y, k) =
+ rgbtogray (1-c-k,1-m-k,1-y-k)
+enddef;
+
+vardef cmyktorgb (expr c,m,y,k) =
+ rgb(1-c-k,1-m-k,1-y-k)
+enddef;
+vardef rgbtocmyk (expr r,g,b) =
+ cmyk(1-r,1-g,1-b,0)
+enddef;
+
+vardef rgb (expr r, g, b) =
+%<MF> togray (snapto r, snapto g, snapto b)
+%<MP> (snapto r, snapto g, snapto b)
+enddef;
+vardef RGB (expr R, G, B) =
+ rgb (R/255, G/255, B/255)
+enddef;
% \end{macrocode}
%
@@ -717,7 +891,7 @@ yellow := rgb (1, 1, 0);
def list (suffix v) (text lst) =
v := 0; for _itm = lst: v[incr v] := _itm; endfor
if v = 0:
- GBerrmsg ("no list to process!")
+ GBerrmsg ("No list to process!")
"An attempt was made to produce an array from a "
& "list of expressions having no valid entries.";
fi
@@ -732,6 +906,7 @@ def map (text proc) (text lst) =
enddef;
% \end{macrocode}
+%
% \DescribeRoutine{knownnumericarray}
% Checks if a suffix is the name of an array. Requires \gbc{arr} to be a
% known positive integer, and all the variables \gbc{arr[n]} to be known
@@ -898,7 +1073,7 @@ enddef;
% \end{macrocode}
%
% \DescribeRoutine{xprod}
-% A binary operation between pairs $z\sb1$ and $x\sb2$ that returns the
+% A binary operation between pairs $z\sb1$ and $z\sb2$ that returns the
% cross product $x\sb1 y\sb2 - x\sb2 y\sb1$. This gives, among other
% things, twice the area of the triangle with two sides $z\sb1$ and
% $z\sb2$. It is used only in \gbc{mkconvex}.
@@ -1078,25 +1253,36 @@ enddef;
% This is are mainly to save space in \mfpic-generated files. In \grafbase{}
% itself the \mfc{save} is often inconvenient, but it turns out there are
% many cases where it \emph{is} used; enough so that we have abbreviations
+% \RoutineIndex{setnumeric}\gbc{setnumeric},
+% \RoutineIndex{setboolean}\gbc{setboolean},
+% \RoutineIndex{setpair}\gbc{setpair},
+% \RoutineIndex{setpath}\gbc{setpath},
% \RoutineIndex{setpicture}\gbc{setpicture},
-% \RoutineIndex{setpath}\gbc{setpath}, \RoutineIndex{setpair}\gbc{setpair}
-% and \RoutineIndex{setboolean}\gbc{setboolean}, together with the
+% and \RoutineIndex{setstring}\gbc{setstring}, together with the
% common uses \RoutineIndex{newpicture}\gbc{newpicture} and
-% \RoutineIndex{convertpath}\gbc{convertpath}.
-% \DescribeRoutine{gsetvariable}\gbc{gsetvariable} is the global
-% version. It has no abbreviations, but it is occasionally needed for
-% \mfpic{}. The only difference is the lack of a \gbc{save}. None of these
-% commands take the value as a parameter. That should follow, and is picked
-% up by the ending \mfc{:=}.
+% \RoutineIndex{convertpath}\gbc{convertpath}. There is also a
+% \gbc{setcolor}, but that has such a different definition that we reserve
+% it for later.
+%
+% For completeness, we also include the remaining two abbreviations,
+% \RoutineIndex{setpen}\gbc{setpen} and
+% \RoutineIndex{settransform}\gbc{settransform}, even though they are not
+% used anywhere in \grafbase{}.
+%
+% \DescribeRoutine{gsetvariable}\gbc{gsetvariable} is the global version.
+% It has no abbreviations, but it is occasionally needed for \mfpic{}. The
+% only difference between it and the local version is the lack of a
+% \gbc{save}. None of these commands take the value as a parameter. That
+% should follow, and is picked up by the ending \mfc{:=}.
%
% \DescribeRoutine{setarray}
% Then \gbc{setarray} is the array version. It takes the same parameters
% as \gbc{setvariable}, but what should follow is a list of expressions in
% parentheses. It calls \gbc{list} to read each item into
-% \gbc{name1}, \gbc{name2}, etc.
-% \DescribeRoutine{setpairs}\gbc{setpairs} is an abbreviation for arrays
-% of pairs. There is also has a global version
+% \gbc{name1}, \gbc{name2}, etc. There is also has a global version
% \DescribeRoutine{gsetarray}\gbc{gsetarray}.
+% \DescribeRoutine{setpairs}\gbc{setpairs} is an abbreviation for arrays
+% of pairs. Historically, it came first.
% \begin{macrocode}
def setvariable (text kind) (suffix name) =
save name; kind name; name :=
@@ -1108,8 +1294,10 @@ def setnumeric (suffix name) = save name; name := enddef;
def setboolean = setvariable (boolean) enddef;
def setpair = setvariable (pair) enddef;
def setpath = setvariable (path) enddef;
-def setcolor = setvariable (color) enddef;
def setpicture = setvariable (picture) enddef;
+def setstring = setvariable (string) enddef;
+def settransform = setvariable (transform) enddef;
+def setpen = setvariable (pen) enddef;
def settension (suffix tn) expr tens =
setnumeric (tn) if tens > 0: tens else: default_tension fi;
enddef;
@@ -1127,7 +1315,6 @@ def gsetarray (text kind) (suffix name) =
enddef;
% \end{macrocode}
-%
% The next are slightly different, but seem to belong here.
% \DescribeRoutine{setbbox}
@@ -1148,6 +1335,111 @@ def setsplit (suffix s) expr ss =
setnumeric (s) emax (1, ceiling ss);
enddef;
+%<*MP>
+if has_cmyk:
+ def setrgbcolor = setvariable (rgbcolor) enddef;
+ def setcmykcolor = setvariable (cmykcolor) enddef;
+ def setcolor (suffix name) expr val =
+ if boolean val : setboolean
+ elseif numeric val : setnumeric
+ elseif rgbcolor val : setrgbcolor
+ elseif cmykcolor val : setcmykcolor
+ % this should give a suitable error message:
+ else: setvariable (color)
+ fi (name) val;
+ enddef;
+ def gsetcolor (suffix name) expr val =
+ if boolean val : boolean name;
+ elseif numeric val : numeric name;
+ elseif rgbcolor val : rgbcolor name;
+ elseif cmykcolor val : cmykcolor name;
+ else: color name;
+ fi name := val;
+ enddef;
+else:
+ def setrgbcolor = setcolor enddef;
+ def setcmykcolor = setcolor enddef;
+ def setcolor = setvariable (color) enddef;
+ def gsetcolor = gsetvariable (color) enddef;
+fi
+%</MP>
+%<*MF>
+def setrgbcolor = setcolor enddef;
+def setcmykcolor = setcolor enddef;
+def setcolor = setvariable (color) enddef;
+def gsetcolor = gsetvariable (color) enddef;
+%</MF>
+
+% \end{macrocode}
+%
+% And then the standard colors. Using the color functions ensures that
+% they are defined in \MF{} as well as all versions of \MP{}. In early
+% \MP{} they are all \mfc{rgbcolor}, in \MF{} they are all numeric. In
+% recent \MP{}, they have the type correspondimg to the name of the
+% color function, with \gbc{gray()} being numeric.
+% \begin{macrocode}
+setcolor(rgbblack) rgb(0,0,0);
+setcolor(red) rgb(1,0,0);
+setcolor(green) rgb(0,1,0);
+setcolor(blue) rgb(0,0,1);
+setcolor(rgbwhite) rgb(1,1,1);
+setcolor(cmykwhite) cmyk(0,0,0,0);
+setcolor(cyan) cmyk(1,0,0,0); % Maybe these should
+setcolor(magenta) cmyk(0,1,0,0); % be rbg for backward
+setcolor(yellow) cmyk(0,0,1,0); % compatibility?
+setcolor(cmykblack) cmyk(0,0,0,1);
+setcolor(grayscaleblack) gray(0);
+setcolor(grayscalewhite) gray(1);
+
+%<*MP>
+if has_outputtemplate:
+ def setoutputtemplate = outputtemplate := enddef;
+elseif has_filenametemplate:
+ def setoutputtemplate = filenametemplate enddef;
+else:
+ def setoutputtemplate text garbage = enddef;
+fi
+%</MP>
+%<MF>def setoutputtemplate text garbage = enddef;
+
+def romannumeral = _romannumeral (true) enddef;
+vardef _romannumeral (expr prefix, X) =
+ save Y, _tmp, U; string U;
+
+ Y.m := X div 1000; % thousands digit
+ _tmp := X - 1000Y.m; % hundreds digits and lower
+ Y.c := _tmp div 100; % hundreds
+ _tmp := _tmp - 100Y.c; % tens and units
+ Y.x := _tmp div 10; % tens
+ Y.i := _tmp - 10Y.x; % units
+
+ strrepeat("m", Y.m) &
+ romandigit(prefix, "c", "d", "m", Y.c) &
+ romandigit(prefix, "x", "l", "c", Y.x) &
+ romandigit(prefix, "i", "v", "x", Y.i)
+enddef;
+
+vardef romandigit (expr prefix, bot, mid, top, n) =
+ if n > 9 : top & strrepeat(bot, n-10) % shouldn't happen
+ elseif n > 8 :
+ if prefix: bot & top % "ix"
+ else: mid & bot & bot & bot & bot % "viiii"
+ fi
+ elseif n > 4 : mid & strrepeat (bot, n-5) % "v"--"viii"
+ elseif n > 3 :
+ if prefix: bot & mid % "iv"
+ else: bot & bot & bot & bot % "iiii"
+ fi
+ else: strrepeat (bot, n) % ""--"iii" for 0--3
+ fi
+enddef;
+
+vardef strrepeat (expr st, rep) =
+ setstring (_sr) "";
+ for i = 1 upto rep: _sr := _sr & st; endfor
+ _sr
+enddef;
+
% \end{macrocode}
%
% \section{The \grafbase{} Coordinate System}\label{coordinate}
@@ -1211,8 +1503,8 @@ enddef;
% by \gbc{unitlen} gets us sharped coordinates. For \MF{},
% multiplication by \mfc{hppp} converts to device coordinates, while for
% \MP{} sharped and device are the same (the printer's PostScript
-% rasterizing engine---or \prog{GhostScript}---does the final conversion
-% to actual pixels).
+% rasterizing engine---\prog{GhostScript} perhaps---does the final
+% conversion to actual pixels).
%
% In \MF{}, \mfc{currenttransform} (via the macro \mfc{.t_}, defined by
% \mfc{mode_setup}) takes care of the aspect ratio. In \MP{} the final
@@ -1554,7 +1846,7 @@ label_sep := 0; labelpath_sep := 0;
% expressions, it will actually place any picture, \gbc{s}. If you feed it
% a string or path, it will convert it to a picture (with the \mfc{infont}
% operator or the \gbc{picpath} macro).
-
+%
% The macro \gbc{newgblabel} takes 6 parameters. The first three
% parameters could easily be condensed into two if \mfpic{} support were
% all that was required, however I thought it best to make it general.
@@ -1789,6 +2081,7 @@ def textovalx = xellipse (true) enddef;
def textellipsex = xellipse (false) enddef;
% \end{macrocode}
+%
% \DescribeRoutine{xellipse}
% In \gbc{xellipse}, \gbc{aa} and \gbc{bb} are the horizontal and
% vertical radii of the resulting ellipse, while \gbc{ww} and \gbc{hh}
@@ -1904,6 +2197,7 @@ def TruncateWarn expr s =
enddef;
% \end{macrocode}
+%
% In addition to \mfc{sind} and \mfc{cosd} which take angles in degrees,
% we define the remaining trig functions \gbc{tand}, \gbc{cotd},
% \gbc{secd}, and \gbc{cscd}.
@@ -1935,6 +2229,7 @@ enddef;
vardef cotd primary X = cosd(X)*cscd(X) enddef;
% \end{macrocode}
+%
% These are the inverse functions, which return an angle in degrees:
% \RoutineIndex{acos}\gbc{acos}, \RoutineIndex{asin}\gbc{asin} and
% \RoutineIndex{atan}\gbc{atan}.
@@ -1958,6 +2253,7 @@ enddef;
vardef atan primary X = angle (1, X) enddef;
% \end{macrocode}
+%
% Now the trig functions that take angles in radians:
% \RoutineIndex{sin}\gbc{sin}, \RoutineIndex{cos}\gbc{cos},
% \RoutineIndex{tan}\gbc{tan}, \RoutineIndex{cot}\gbc{cot},
@@ -1979,6 +2275,7 @@ vardef csc primary X = cscd (X*radian) enddef;
% \begin{macrocode}
vardef degrees (expr t) = t*radian enddef;
vardef radians (expr t) = t/radian enddef;
+
% \end{macrocode}
%
% And the inverses (\RoutineIndex{invsin}\gbc{invsin},
@@ -2007,19 +2304,6 @@ def logtwo = logbase( 2) enddef;
def logten = logbase(10) enddef;
% \end{macrocode}
-% \CMF's pair variables are a decent replacement for complex variables.
-% These give some of the more basic functions of standard complex
-% analysis: \RoutineIndex{Arg}\gbc{Arg}, \RoutineIndex{Log}\gbc{Log},
-% \RoutineIndex{cis}\gbc{cis}, \RoutineIndex{zexp}\gbc{zexp} and
-% \RoutineIndex{sgn}\gbc{sgn}.
-% \begin{macrocode}
-vardef Arg primary Z = (angle Z)/radian enddef;
-vardef Log primary Z = (ln (abs Z), Arg Z) enddef;
-vardef cis primary T = dir (T*radian) enddef;
-vardef zexp primary Z = (exp (xpart Z)) * cis (ypart Z) enddef;
-vardef sgn primary Z = if not (Z = origin): unitvector fi Z enddef;
-
-% \end{macrocode}
%
% The hyperbolic functions: \RoutineIndex{cosh}\gbc{cosh}
% \RoutineIndex{sinh}\gbc{sinh}, \RoutineIndex{tanh}\gbc{tanh},
@@ -2074,6 +2358,7 @@ vardef coth primary X =
enddef;
% \end{macrocode}
+%
% The inverses of some of the hyperbolic functions:
% \RoutineIndex{acosh}\gbc{acosh}, \RoutineIndex{asinh}\gbc{asinh} and
% \RoutineIndex{atanh}\gbc{atanh}.
@@ -2100,6 +2385,42 @@ enddef;
% \end{macrocode}
%
+% \CMF's pair variables are a decent replacement for complex variables.
+% These give some of the more basic functions of standard complex
+% analysis: \RoutineIndex{Arg}\gbc{Arg}, \RoutineIndex{Log}\gbc{Log},
+% \RoutineIndex{cis}\gbc{cis}, \RoutineIndex{zexp}\gbc{zexp},
+% \RoutineIndex{sgn}\gbc{sgn}, and \RoutineIndex{conj}\gbc{conj}.
+% \begin{macrocode}
+vardef Arg primary Z = (angle Z)/radian enddef;
+vardef Log primary Z = (ln (abs Z), Arg Z) enddef;
+vardef cis primary T = dir (T*radian) enddef;
+vardef zexp primary Z = (exp (xpart Z)) * cis (ypart Z) enddef;
+vardef sgn primary Z = if not (Z = origin): unitvector fi Z enddef;
+vardef conj primary Z = (xpart Z, -ypart Z) enddef;
+
+% \end{macrocode}
+%
+% \DescribeRoutine{Moebius}
+% A less basic operation: the Moebius shift which takes the disk $|z| <
+% 1$ onto itself. It is a hyperbolic geometry analog of shifting points
+% in Euclidean geometry. Its mathematical definition (all variables are
+% complex numbers):
+% \[
+% M_a(z) = \frac{z + a}{1 - \bar az}
+% \]
+% \DescribeRoutine{pshdist}
+% Related to \gbc{Moebius} is the pseudohyperbolic metric. The distance
+% between $z$ and $w$ in this metric is $|z-w|/|1 - \bar wz|$.
+% \begin{macrocode}
+vardef Moebius (expr A) primary Z =
+ save _D; pair _D;
+ _D := (1, 0) + (Z zscaled (conj A));
+ (Z + A)/(abs _D) rotated (- angle _D)
+enddef;
+vardef pshdist (expr Z,W) = abs(Moebius(-W)(Z)) enddef;
+
+% \end{macrocode}
+%
% \DescribeRoutine{polar}
% \gbc{polar} converts a polar coordinate pair $(r, \theta)$ to the
% corresponding rectangular coordinate pair.
@@ -2125,6 +2446,7 @@ primarydef x**y =
fi
enddef;
let ^ = **;
+
% \end{macrocode}
%
% \section{Coordinate Systems and Transformations}\label{systems}
@@ -2146,6 +2468,7 @@ let ^ = **;
% \begin{macrocode}
transform T_stack[];
numeric T_stack; T_stack := 0;
+
def T_push (expr T) = T_stack[incr T_stack] := T; enddef;
def T_pop (suffix $) =
if T_stack > 0:
@@ -2451,6 +2774,7 @@ enddef;
def mono (suffix u) = cull u keeping (1, infinity); enddef;
% \end{macrocode}
+%
% \DescribeRoutine{andto, picand}
% The bitwise and: in the resulting picture, a pixel is \emph{on} if and
% only if it is \emph{on} in both \gbc{u} and \gbc{v}. \gbc{andto} is
@@ -2465,6 +2789,7 @@ primarydef u picand v =
enddef;
% \end{macrocode}
+%
% \DescribeRoutine{orto, picor}
% The inclusive or: in the result, a pixel is \emph{on} if and only if it
% is \emph{on} in \gbc{u} or \gbc{v} or both. I've written these so that
@@ -2488,6 +2813,7 @@ primarydef u picor v =
enddef;
% \end{macrocode}
+%
% \DescribeRoutine{xorto, picxor}
% The exclusive or, also called the symmetric difference:
% in the result, a pixel is \emph{on} if and only if it is \emph{on} in
@@ -2502,6 +2828,7 @@ primarydef u picxor v =
enddef;
% \end{macrocode}
+%
% \DescribeRoutine{subto}
% The nonsymmetric difference: in the result, a pixel is \emph{on} if
% and only if it is \emph{on} in \gbc{u} and off in \gbc{v}. It is
@@ -3357,7 +3684,7 @@ enddef;
%
% \DescribeRoutine{stored}
% The macro \gbc{stored} performs \gbc{store}, but passes the same path as
-% its return value. This is used by \mfpic{} to implements the \cs{store}
+% its return value. This is used by \mfpic{} to implement the \cs{store}
% command, allowing it to also be a prefix macro
%
% I don't know if \gbc{store} needs to employ \mfc{hide()}, but it seems
@@ -3366,7 +3693,7 @@ enddef;
def store (suffix fs) expr f =
hide (
if (not path f) and (not pair f):
- GBerrmsg ("improper expression type.")
+ GBerrmsg ("Improper expression type.")
"The second argument to `store' must be a path or pair.";
fi
if not path fs: path fs; fi
@@ -4007,7 +4334,6 @@ vardef gendashed (suffix pat) expr f =
picture _v; _v := nullpicture;
_d0 := 0; _t0 := 0;
dashit (_dpat.start) (_v);
-
% \end{macrocode}
% The parameters to \gbc{dashit} are the name of the part of the dashing
% pattern that is being drawn, and a temporary picture variable. The
@@ -4228,7 +4554,6 @@ enddef;
% \end{macrocode}
%
-%
% The \mfpic{} command \cs{dashed} is now implemented by making a
% dashpattern from the two arguments and calling gendashed. That is the
% definition of \gbc{DASHED}.
@@ -4324,6 +4649,7 @@ vardef colorshowcontrols (expr clr, syma, symb, size) expr f =
enddef;
% \end{macrocode}
+%
% \subsection{Double-line drawing}\label{doubleline}
%
% \DescribeRoutine{doubledraw}
@@ -4585,6 +4911,7 @@ vardef axis@# (expr len) = headpath (len, 0, 0) axisline@# enddef;
vardef borderrect =
rect((xneg+laxis,yneg+baxis),(xpos-raxis,ypos-taxis))
enddef;
+
% \end{macrocode}
%
% Tick marks can be on the inside or outside of a border axis,
@@ -4921,6 +5248,7 @@ def polargridpoints (expr dsize, rstep, tstep) =
enddef;
% \end{macrocode}
+%
% \DescribeRoutine{beginpolargrid}
% This calls \gbc{getpolarbounds} to compute the bounds (on $r$ and
% $\theta$) of the smallest polar coordinate patch that covers the graph
@@ -5037,7 +5365,8 @@ enddef;
% the upright rectangle with those points at opposite corners. It might be
% noted that if the corners really are lower left and upper right, then
% the path is anticlockwise, If they are on the other diagonal, the
-% path is clockwise. The path is a cycle (closed).
+% path is clockwise. The path is a cycle (closed). The starting/ending
+% point (needed for arrows and the like) is the first point of the two.
%
% \DescribeRoutine{triangle}
% Produces a closed path joining three points with straight lines; first
@@ -5230,20 +5559,46 @@ enddef;
% \begin{macrocode}
vardef turtle (text t) =
setnumeric (_tu) 0;
- pair _tu[]; _tu0 := origin;
- for _a = t: _tu[incr _tu] := _tu[_tu - 1] + _a; endfor
+ setpair (_tmp) origin;
+ pair _tu[];
+ for _a = t:
+ _tmp := _tmp + _a;
+ _tu[incr _tu] := _tmp;
+ endfor
if _tu = 0: NoPoints("turtle", _tu); fi
mkpoly (false, _tu)
enddef;
% \end{macrocode}
%
+% \DescribeRoutine{brownianpath}
+% I needed the following to illustrate Brownian motion. It takes a given
+% starting point, a given number of steps and a scaling factor. It
+% generates a sequence of random points, each one being chosen randomly
+% using a Gaussian distribution centered at the previous point. Strictly
+% speaking this is a Gaussian random walk, not Brownian motion. A true
+% Brownian motion would be a limit of these, with \gbc{num} tending to
+% $\infty$ and \gbc{sc} tending to 0.
+% \begin{macrocode}
+vardef brownianpath (expr start, num, sc) =
+ setnumeric (_brp) 1;
+ setpair (_tmp) start;
+ pair _brp[]; _brp1 := _tmp;
+ for _idx := 1 upto num:
+ _tmp := _tmp + sc/(sqrt 2)*(normaldeviate,normaldeviate);
+ _brp[incr _brp] := _tmp;
+ endfor
+ mkpoly (false, _brp)
+enddef;
+
+% \end{macrocode}
+%
% \subsection{Smooth paths}\label{smooth}
%
% We added an optional parameter for the tension of smooth curves to
% \mfpic. It used to be implemented this way: functions that implement a
% tension parameter set \gbc{cur_tension} and called \gbc{mksmooth}, which
-% uses that tension in its formation of a path. Since \gbc{mksmooth} was
+% used that tension in its formation of a path. Since \gbc{mksmooth} was
% only ever used in this way, I decided to change its syntax to include a
% tension parameter. Only the functions \gbc{tcurve} and \gbc{mkpath}
% actually call \gbc{mksmooth} directly, most other path building commands
@@ -5276,6 +5631,7 @@ vardef mksmooth (expr tens, cyclic) (suffix pts) =
enddef;
% \end{macrocode}
+%
% \DescribeRoutine{mktenser}
% This is just like \gbc{mksmooth}, except the tension value is preceded
% by \mfc{atleast}. At this writing only \gbc{mkconvex} uses it (as a
@@ -5313,7 +5669,7 @@ enddef;
% the flatness is infinite and the curve is forced in that direction. We
% measure the flatness using the square root of the area of the triangle
% made by the given point and the the next two points. Those three points
-% lie on a line just when the area is $0$. Using this measure of fltness
+% lie on a line just when the area is $0$. Using this measure of flatness
% can be disputed (two triangles can be equally flat in terms of angles
% but different in terms of areas), but it has the advantage that if the
% points are subjected to an affine transformation, the weighting is
@@ -5453,22 +5809,25 @@ enddef;
%
% \DescribeRoutine{mkqbezier}
% \gbc{mkqbezier} requires an even number of points for a cyclic path,
-% an odd number for a noncyclic path. The \mfc{for}-loop ends on the last
-% odd index. If \gbc{pts} is odd and \gbc{cyclic} is true we need to
-% manufacture another control point for the connection back to the
-% start. We take that to be a repetition of the last point. If \gbc{pts}
-% is even and \gbc{cyclic} is false then the loop ends at \gbc{pts-1}.
-% Again we need to pick a control to connect to the last point, and again
-% we use that last point as the control. In these two cases the last
-% link is a straight line.
+% an odd number for a noncyclic path. It does not check for this, but
+% the calling macro \gbc{qbezier} does. If the parity is incorrect, it
+% repeats the last point in the list. This has the effect of making
+% the last link a straight line.
%
% \DescribeRoutine{qbezier}
% The \gbc{qbezier} command takes a list of points and creates an array
% from then before calling \gbc{mkqbezier}.
+%
+% \DescribeRoutine{mkcbezier}
+% This is like \gbc{mkqbezier}, but needs a multiple of 3 for a closed
+% cubic bezier, one more (the endpoint) for an open cubic bezier.
+%
+% \DescribeRoutine{cbezier}
+% Like \gbc{qbezier}, but calls \gbc{mkcbezier}.
% \begin{macrocode}
vardef mkqbezier (expr cyclic) (suffix pts) =
pts1
- if pts=1: {0,0}
+ if pts=1: {0,0}
else:
for _i = 2 step 2 until pts - 1:
..controls 1/3[pts[_i], pts[_i-1] ] and 1/3[pts[_i], pts[_i+1] ]..
@@ -5483,8 +5842,7 @@ enddef;
vardef qbezier (expr cyclic) (text t) =
setpairs (_qbz) (t);
- if _qbz=0: NoPoints ("qbezier", _qbz); fi
- if _qbz=1: onepointpath (cyclic, _qbz1)
+ if _qbz=0: NoPoints ("qbezier", _qbz);
else:
if (cyclic and odd _qbz) or (not cyclic and even _qbz):
_qbz[incr _qbz] := _qbz[_qbz-1];
@@ -5493,6 +5851,45 @@ vardef qbezier (expr cyclic) (text t) =
fi
enddef;
+vardef mkcbezier (expr cyclic) (suffix pts) =
+ pts1
+ if pts=1: {0,0}
+ else:
+ for _i = 1 step 3 until pts - 3:
+ ..controls pts[_i+1] and pts[_i+2] .. pts[_i+3]
+ endfor
+ if cyclic:
+ ..controls pts[pts - 1] and pts[pts]..cycle
+ fi
+ fi
+enddef;
+
+vardef cbezier (expr cyclic) (text t) =
+ setpairs (_cbz) (t);
+ if _cbz=0: NoPoints ("qbezier", _cbz);
+ else:
+ % Need 0 mod 3 for cyclic, otherwise 1 mod 3
+ setnumeric (_mdt) _cbz mod 3;
+ if cyclic:
+ if _mdt <> 0: _cbz[incr _cbz] := _cbz[_cbz-1]; fi
+ if _mdt = 1 : _cbz[incr _cbz] := _cbz1; fi
+ else: % need 1 more, duplicate next to last
+ if _mdt = 0:
+ _cbz := _cbz + 1;
+ _cbz[_cbz] := _cbz[_cbz-1];
+ _cbz[_cbz-1] := _cbz[_cbz-2];
+ fi
+ if _mdt = 2: % need 2 more, duplicate last 2.
+ _cbz := _cbz + 2; % add 2 slots
+ _cbz[_cbz] := _cbz[_cbz-2]; % fill them
+ _cbz[_cbz-1] := _cbz[_cbz-2]; % with last node
+ _cbz[_cbz-2] := _cbz[_cbz-3]; % orig last slot = orig previous.
+ fi
+ fi
+ mkcbezier (cyclic) (_cbz)
+ fi
+enddef;
+
% \end{macrocode}
%
% When calling \gbc{curve} or \gbc{tcurve} there can be a problem
@@ -5513,13 +5910,13 @@ enddef;
% ourselves. By default we choose the two controls so the \mfc{xpart}s
% divide the $x$-interval into three equal parts. This makes the B\'ezier
% $f(t)$ linear in the $x$-part and so has the added `advantage' that in
-% each segment, $y$ is a cubic function of $x$. It is not a spline, as we
-% compute the controls locally and allow them to be modified by an
-% additional parameter.
+% each segment, $y$ is a cubic function of $x$. It is not a spline, as
+% the computation of the controls uses only the two nearest points, plus
+% we allow them to be modified by an additional parameter.
%
% Another concern is what direction to place the controls. In
% \gbc{mksmooth} we ask the direction at a given point to be the average
-% of the straight line directions to adjacent points. We now do the same
+% of the straight line directions to adjacent points. We do the same
% here, though it is not clear if this is best.
%
% Finally, we permit a tension of sorts by dividing the distance to the
@@ -5536,14 +5933,15 @@ enddef;
% Following discussions with Stephan Hennig in \texttt{comp.text.tex} I
% came to the conclusion that the method used ought to satisfy the
% following: if the data are xscaled or yscaled, the control vectors ought
-% to scale the same way. The current version does that.
+% to scale the same way. The current version does that, the previous one
+% did not.
%
% \DescribeRoutine{mkfcnpath}
% This produces the path, calling \gbc{fcncontrol} to produce the controls.
%
% \DescribeRoutine{fcncurve}
% This is the \mfpic{} interface; \gbc{fcncurve} calls \gbc{functioncurve}
-% with the default tension, which \DescribeRoutine{functioncurve}then
+% with the default tension, and \DescribeRoutine{functioncurve}then
% takes a list of points, converts it to an array, and calls
% \gbc{mkfcnpath} to build the path.
% \begin{macrocode}
@@ -5622,6 +6020,7 @@ vardef qspline (expr cyclic) (text t) =
fi
mkqbs (_qs) if cyclic: & cycle fi
enddef;
+
% \end{macrocode}
%
% These cubic B-splines also require a list of `control' points. Each of
@@ -5685,6 +6084,7 @@ vardef cspline (expr cyclic) (text t) =
fi
mkcbs (_cs) if cyclic: & cycle fi
enddef;
+
% \end{macrocode}
%
% \subsection{Splines with computed controls}\label{computedsplines}
@@ -5729,8 +6129,8 @@ enddef;
% \DescribeRoutine{relaxed_spline_eqns}relaxed splines they force
% the second derivative to be 0 at the first and last point.
%
-% The macro \gbc{mksplinepath} simply assembles the points and controls
-% previously computed into a path.
+% The macro \gbc{mksplinepath} simply assembles the previously computed
+% points and controls into a path.
%
% \DescribeRoutine{mkspline}\gbc{mkspline} issues the
% common equations and then either the closed equations (\gbc{closed =
@@ -5791,6 +6191,7 @@ vardef dospline (expr closed) (text the_list) =
enddef;
% \end{macrocode}
+%
% The above computations produce a $2$-dimensional spline. A $1$-dimensional
% cubic spline would be a function $f(t)$ with numeric values rather
% than pair values. Such are often used to interpolate functions. That is,
@@ -6078,9 +6479,12 @@ enddef;
% the angle $\pm 180$, which produces a half circle.
% \begin{macrocode}
vardef arcpp (expr small, begpt, endpt, rad) =
- save full, ang; full := signof (rad) 360;
- if 2*abs(rad) > abs(begpt - endpt):
- ang := if not small: full - fi 2*asin (abs(begpt-endpt)/(2rad));
+ save full, diam, chord, ang;
+ full := signof (rad) 360;
+ diam := 2rad;
+ chord := abs(endpt-begpt);
+ if chord < abs(diam):
+ ang := if not small: full - fi 2*asin (chord/diam);
else: ang := signof (rad) 180;
fi
arcpps (begpt, endpt, ang)
@@ -6146,10 +6550,13 @@ vardef ellipse (expr center, radx, rady, angle) =
fullcircle xscaled (2*radx) yscaled (2*rady) rotated angle
shifted center
enddef;
+
vardef circle (expr center, rad) =
fullcircle scaled (2*rad) shifted center
enddef;
+
% \end{macrocode}
+%
% The next four implement different ways of specifying a circle.
% \DescribeRoutine{circlecp}
% The first produces the circle with a given center passing through a
@@ -6178,24 +6585,29 @@ enddef;
vardef circlecp (expr center, point) =
mkarc (center, point, point, 360) & cycle
enddef;
+
vardef circleppp (expr one, two, three) =
arcpps (one, two, 2*cornerangle (three, one, two))
& arcpps (two, three, 2*cornerangle (one, two, three))
& arcpps (three, one, 2*cornerangle (two, three, one))
& cycle
enddef;
+
vardef circlepps (expr one, two, sweep) =
save ang, full;
full := signof (sweep) 360;
ang := sweep mod full;
arcpps (one, two, ang) & arcpps (two, one, full - ang) & cycle
enddef;
+
vardef circlepp (expr small, one, two, rad) =
arcpp (small, one, two, rad) & arcpp (not small, two, one, rad) & cycle
enddef;
+
def circleppr (expr one, two, rad, small) =
circleppr (one, two, rad, small)
enddef;
+
% \end{macrocode}
%
% \DescribeRoutine{pathcenter}
@@ -6283,6 +6695,64 @@ enddef;
% \end{macrocode}
%
+% \DescribeRoutine{pshcircle}
+% Here is a couple of circles maybe only I need. They are the
+% pseudohyperbolic circles in the unit disk and upper half-plane.
+% One supplies a point that must be inside the unit circle or above
+% the $x$-axis, and a radius that must be less than $1$. Some degenerate
+% cases will not generate an error. We code this with a boolean that
+% determine whether the disk of the half-plane is to be assumed.
+% \begin{macrocode}
+vardef pshcircle (expr disk, ctr, rad) =
+ if disk:
+ if rad >= 1 :
+ if rad > 1:
+ GBerrmsg ("Impossible pseudohyperbolic circle.")
+ "The radius of a pseudohyperbolic circle can be at most 1.";
+ fi
+ circle ((0,0),1)
+ elseif abs(ctr) >= 1 :
+ if abs(ctr) > 1:
+ GBerrmsg ("Impossible pseudohyperbolic circle.")
+ "The center of a pseudohyperbolic circle must be in"
+ & "the unit disk.";
+ fi
+ onepointpath (true,ctr)
+ else:
+ % compute Euclidean center and radius (and a denominator used twice
+ % in calculations).
+ save _r, _dnm;
+ _r := abs(ctr);
+ _dnm := 1 - _r*_r*rad*rad;
+ circle ( (1 - rad*rad)/_dnm*ctr, rad*(1 - _r*_r)/_dnm)
+ fi
+ else:
+ if rad >= 1 :
+ GBerrmsg ("Impossible pseudohyperbolic circle.")
+ "The radius of a pseudohyperbolic circle must be less than 1.";
+ onepointpath (true,ctr)
+ elseif ypart ctr <= 0:
+ if ypart ctr < 0:
+ GBerrmsg ("Impossible pseudohyperbolic circle.")
+ "The center of a pseudohyperbolic circle must be in"
+ & "the upper half-plane.";
+ fi
+ onepointpath (true,ctr)
+ else:
+ % compute Euclidean center and radius (and a denominator used twice
+ % in calculations).
+ % Euclidean center at xpart ctr + (1 + R^2)/(1 - R^2)*ypart ctr
+ % Euclidean radius 4R/(1 - R^2)*ypart ctr
+ save _y, _dnm;
+ _y := ypart ctr;
+ _dnm := 1 - rad*rad;
+ circle ( (xpart ctr, (1 + rad*rad)/_dnm * _y), 2rad/_dnm*_y)
+ fi
+ fi
+enddef;
+
+% \end{macrocode}
+%
% \DescribeRoutine{barycenter}
% This is the average of the three corners of the triangle, or of any
% path. If \gbc{t} is an open path with length $n$ and the nodes are
@@ -6295,7 +6765,7 @@ enddef;
% don't recall if this is the center of any important circle.
%
% The centers of the various circles associated with triangles can be
-% found with \gbc{pathcenter}. Or by intersecting vasious lines: the
+% found with \gbc{pathcenter}. Or by intersecting various lines: the
% \emph{incenter} (center of the inscribed circle)is the intersection of
% the angle bisectors; the \emph{circumcenter} is the intersection of the
% prependicular bisectors.
@@ -6319,7 +6789,6 @@ enddef;
% \end{macrocode}
%
-%
% \subsection{Plotting of functions}\label{functionplots}
%
% In these macros, if the boolean argument \gbc{sm} is true then the
@@ -6470,6 +6939,7 @@ def plrregion (expr sm) = tplrregion (sm, default_tension) enddef;
vardef tplrregion (expr sm, tn, tlo, thi, st) (text _ft) =
(0,0)--tplrfcn (sm, tn, tlo, thi, st ) (_ft)--cycle
enddef;
+
% \end{macrocode}
%
% \DescribeRoutine{mklevelset}
@@ -6509,6 +6979,7 @@ enddef;
% \begin{macrocode}
numeric tolerancefactor;
tolerancefactor := .02;
+
vardef mklevelset (expr sm, tens, X, Y, t, a, b, c, d) =
save _inside_;
vardef _inside_ (expr U, V) =
@@ -6552,6 +7023,7 @@ vardef mklevelset (expr sm, tens, X, Y, t, a, b, c, d) =
enddef;
% \end{macrocode}
+%
% \DescribeRoutine{levelset}
% This is the \mfpic{} interface. It checks the \gbc{t} parameter before
% passing it to \gbc{mklevelset}, making sure it is not zero, it passes
@@ -6603,6 +7075,7 @@ vardef lclosed expr f =
enddef;
% \end{macrocode}
+%
% \DescribeRoutine{sclosed}
% This closes the path in the manner that \gbc{mksmooth} creates a path.
% This will change the first and last segment of the original path. In
@@ -6626,6 +7099,7 @@ vardef sclosedt (expr t) expr f =
enddef;
% \end{macrocode}
+%
% \DescribeRoutine{bclosed}
% This closes with the basic default \MF{} Bezi\'er. It is a smooth
% closure, but it does not have the same direction at the endpoints
@@ -6641,6 +7115,7 @@ vardef bclosedt (expr t) expr f =
enddef;
% \end{macrocode}
+%
% \DescribeRoutine{uclosed}
% Same as \gbc{bclosed}. Retained for backward compatibility. There is
% a tense variant only for \DescribeRoutine{uclosedt}consistency.
@@ -6649,6 +7124,7 @@ def uclosed = bclosed enddef;
def uclosedt = bclosedt enddef;
% \end{macrocode}
+%
% \DescribeRoutine{cbcontrols}
% This utility is for use in \gbc{cbclosed}. It converts Bezier segment
% key points of a path \gbc{f}, to cubic B-spline control points stored
@@ -6726,6 +7202,7 @@ enddef;
% computed by \gbc{pathcenter}.
% \begin{macrocode}
vardef makesector expr p = (pathcenter p)--p--cycle enddef;
+
% \end{macrocode}
%
% \DescribeRoutine{arccomplement}
@@ -7057,6 +7534,19 @@ vardef colorGheadpath
f
enddef;
+
+% \end{macrocode}
+%
+% \DescribeVariable{cut_path}
+% Additional clearing path, almost the same as plain.mf's \gbc{cut_} (no
+% \gbc{cut_} in plain.mp) but rotated, and scaled differently. The odd
+% scaling is so that if yscaled by the diameter of a dot, and the dot
+% happens to be digitized to a square shape, then the \gbc{cut_path},
+% centered at the center of the dot and rotated 45 degrees, will encompass
+% the whole square (theoretically).
+% \begin{macrocode}
+path cut_path; cut_path := (.5,0)--(.5,.71)--(-.5,.71)--(-.5,0)--cycle;
+
% \end{macrocode}
%
% \DescribeRoutine{tailpath}\RoutineIndex{colortailpath}
@@ -7263,6 +7753,7 @@ vardef randomlines (expr maxshift) expr f =
fi
fi
enddef;
+
% \end{macrocode}
%
% \subsection{Parallelling a path}
@@ -7424,7 +7915,6 @@ def setdatadashes (text lst) =
forsuffixes _itm = lst:
if knownnumericarray _itm :
copyarray (_itm) (__type[__type]);
-% __type := __type + 1;
next __type;
else: GBwarn "Improper dash pattern in setdatadashes.";
fi
@@ -7489,7 +7979,7 @@ def setdatasymbols (text lst) =
__type[__type] := _itm;
next __type;
else:
- GBwarn "Improper path in setdatasymbols().";
+ GBwarn "Improper symbol in setdatasymbols().";
fi
endfor
if __type > 1:
@@ -7566,7 +8056,6 @@ Diamond := undo_cycle SolidDiamond;
Diamond.clear := SolidDiamond.clear :=
(right--(1,1)--(-1,1)--left--up--cycle) scaled .522 yscaled 1.44;
-% As arrow heads, these have their "tips" at their center.
Plus := ((0,0)--up--down--(0,0)--left--right) scaled .65;
Plus.clear := (right--(1,1)--(-1,1)--(left)--cycle) scaled .65;
@@ -7629,6 +8118,7 @@ forsuffixes S =
SolidDiamond, SolidStar :
S.tip := point 0 of S;
endfor
+
% \end{macrocode}
%
% \DescribeRoutine{gcd}
@@ -7655,23 +8145,11 @@ vardef gcd (expr n, m) =
enddef;
vardef lcm (expr n, m) =
- n*m/gcd(n, m)
+ n/gcd(n, m)*m
enddef;
% \end{macrocode}
%
-% \DescribeVariable{cut_path}
-% Additional clearing path, almost the same as plain.mf's \gbc{cut_} (no
-% \gbc{cut_} in plain.mp) but rotated, and scaled differently. The odd
-% scaling is so that if yscaled by the diameter of a dot, and the dot
-% happens to be digitized to a square shape, then the \gbc{cut_path},
-% centered at the center of the dot and rotated 45 degrees, will encompass
-% the whole square (theoretically).
-% \begin{macrocode}
-path cut_path; cut_path := (.5,0)--(.5,.71)--(-.5,.71)--(-.5,0)--cycle;
-
-% \end{macrocode}
-%
% \DescribeRoutine{defaultsymbols}
% The command for restoring the default symbols.
% \begin{macrocode}
@@ -7687,50 +8165,73 @@ defaultsymbols;
% \DescribeRoutine{setdatacolors}
% Finally, for \MP, we do a similar pair of commands for setting
% the colors for the \cs{plotdata} command, and for
-% \DescribeRoutine{getcolor}getting the next one.
+% \DescribeRoutine{getcolor}getting the next one. The odd indirection
+% (\gbc{colortype[]} is an array of strings, the names of variables
+% having color values) is because \MP{} now has three different data
+% types for colors. Arrays must be all one type.
%
% \DescribeRoutine{defaultcolors}
% These default colors were tested on screen and on an inkjet printer.
% The adjustments away from pure colors is based on a compromise between
% those experiments.
% \begin{macrocode}
+%<*MP>
def setdatacolors (text lst) =
- save __type; color __type[];
- __type := 0;
+ setnumeric (__type) 0;
+ % First, just count and store the known colors in the list
for _itm = lst:
- if (known _itm) and (color _itm):
- __type[__type] := _itm;
+ if knowncolor _itm :
+ if __type = 0 : def _datacolors = _itm enddef;
+ else:
+ expandafter def
+ expandafter _datacolors
+ expandafter = _datacolors, _itm enddef;
+ fi
next __type;
else: GBwarn "Improper color in setdatacolors().";
fi
endfor
if __type > 1:
- save colortype; colortype := __type;
- color colortype[];
- for _j = 0 upto colortype - 1:
- colortype[_j] := __type[_j];
+ save colortype, _tmpstr;
+ colortype := 0;
+ % colortype[] is an array of strings:
+ string colortype[], _tmpstr;
+ for _itm = _datacolors: %
+ % Each string is the name of some color variable
+ _tmpstr := "colortype_"&romannumeral(colortype);
+ setcolor (scantokens(_tmpstr)) _itm;
+ colortype[colortype] := _tmpstr;
+ next colortype;
endfor
else:
SetdataWarn "colors";
fi
enddef;
-def getcolor expr n = colortype[n mod colortype] enddef;
-
-color dBlue, dOrange, dGreen, dMagenta, dCyan, dYellow;
-dBlue := 0.80blue + .2white;
-dOrange := 0.66yellow + .34red;
-dGreen := 0.80green;
-dMagenta := 0.85magenta;
-dCyan := 0.85cyan;
-dYellow := 0.85yellow;
-
-numeric colortype; color colortype[];
+def getcolor expr n = (scantokens (colortype[n mod colortype])) enddef;
+
+numeric colortype; string colortype[];
+
+setcolor (dRed) (1, 0, 0);
+setcolor (dBlue) (.2,.2,1);
+setcolor (dOrange) (1,.34,0);
+setcolor (dGreen) (0,.80,0);
+setcolor (dBlack) cmykblack;
+if has_cmyk :
+ setcolor (dCyan) cyan;
+ setcolor (dMagenta) magenta;
+ setcolor (dYellow) yellow;
+else: % rgb colors seem to be lighter than the cmyk equivalents.
+ setcolor (dCyan) cmyk(.85,0,0,.15);
+ setcolor (dMagenta) cmyk(0,.85,0,.15);
+ setcolor (dYellow) cmyk(0,0,.85,.15);
+fi
def defaultcolors =
- setdatacolors(black, red, dBlue, dOrange, dGreen,
- dMagenta, dCyan, dYellow);
+ setdatacolors(dBlack, dRed, dBlue, dOrange,
+ dGreen, dMagenta, dCyan, dYellow);
enddef;
defaultcolors;
+%</MP>
% \end{macrocode}
%
%
@@ -7985,22 +8486,19 @@ numeric gcode; gcode := 0;
%
% \subsection{Dvips names for colors}\label{dvipsnam}
%
-% In order to make \file{dvipsnam.mp} useful outside grafbase, we repeat
-% the definition of \gbc{cmyk} here.
+% In order to make \file{dvipsnam.mp} useful outside grafbase, we give
+% here a definition for \gbc{cmyk} when \gbc{grafbaseversion} is unknown.
% \begin{macrocode}
%<*dvips>
if unknown grafbaseversion:
- vardef snapto expr t =
- if unknown t: 0
- elseif not (numeric t): 0
- elseif t < 0: 0
- elseif t > 1: 1
- else: t
- fi
- enddef;
- vardef cmyk (expr c, m, y, k) =
- (snapto 1-c-k, snapto 1-m-k, snapto1-y-k)
- enddef;
+ if unknown mpversion:
+ let cmykcolor=color;
+ vardef cmyk (expr c, m, y, k) =
+ (max(1-c-k,0), max(1-m-k,0), max(1-y-k,0))
+ enddef;
+ else:
+ vardef cmyk (expr c, m, y, k) = (c, m, y, k) enddef;
+ fi
fi
% \end{macrocode}
@@ -8017,7 +8515,7 @@ fi
% Declare all the dvips color names to be color variables, and define
% them as in \file{dvipsnam.def}:
% \begin{macrocode}
-color Apricot, Aquamarine, Bittersweet, Black, Blue, BlueGreen,
+cmykcolor Apricot, Aquamarine, Bittersweet, Black, Blue, BlueGreen,
BlueViolet, BrickRed, Brown, BurntOrange, CadetBlue, CarnationPink,
Cerulean, CornflowerBlue, Cyan, Dandelion, DarkOrchid, Emerald,
ForestGreen, Fuchsia, Goldenrod, Gray, Green, GreenYellow, JungleGreen,
diff --git a/Master/texmf-dist/source/generic/mfpic/mfpic.dtx b/Master/texmf-dist/source/generic/mfpic/mfpic.dtx
index daab8c0d9b6..fcc42f917cb 100644
--- a/Master/texmf-dist/source/generic/mfpic/mfpic.dtx
+++ b/Master/texmf-dist/source/generic/mfpic/mfpic.dtx
@@ -1,7 +1,10 @@
% \iffalse
+%%% File: mfpic.dtx
+%%% A part of mfpic 1.00 2009/09/22
+%%%
% -------------------------------------------------------------------
%
-% Copyright 2002--2006, Daniel H. Luecking
+% Copyright 2002--2009, Daniel H. Luecking
%
% Mfpic may be distributed and/or modified under the conditions of the
% LaTeX Project Public License, either version 1.3b of this license or (at
@@ -19,7 +22,7 @@
%</driver>
%<sty>\ProvidesPackage{mfpic}
%<*sty>
- [2006/05/26 v0.9. Macros for drawing with Metafont/MetaPost.]%
+ [2009/09/22 v1.00. Macros for drawing with Metafont/MetaPost.]%
%</sty>
%<*driver>
\documentclass[draft]{ltxdoc}
@@ -103,7 +106,7 @@
\end{document}
%</driver>
%\fi
-% \CheckSum{4902}
+% \CheckSum{5116}
% \CharacterTable
% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
@@ -131,8 +134,9 @@
% produce the picture. The picture is then included on a second pass
% through \TeX.
%
-% This file documents the source code. See \file{mfpman.pdf} or
-% \file{mfpman.tex} for the user documentation.
+% This file documents the source code. See \file{mfpic-doc.pdf} (source
+% \file{mfpic.doc.tex} for the user documentation or \file{mfpguide.pdf}
+% (source \file{}mfpguide.tex}) for an introductory guide.
% \end{abstract}
%
% \StopEventually{\PrintIndex}
@@ -166,9 +170,9 @@
\ifx\mfpfileversion\UndEfInEd\else\expandafter\endinput\fi%
{%
\catcode\lq\.12 \catcode\lq\/12%
- \gdef\mfpfileversion{0.9}%
- \gdef\mfpfiledate{2006/05/26}%
- \gdef\mfpicversion{90}%
+ \gdef\mfpfileversion{1.00}%
+ \gdef\mfpfiledate{2009/09/22}%
+ \gdef\mfpicversion{100}%
}%
% \end{macrocode}
%
@@ -471,13 +475,17 @@
%
% Some options and commands require the \opt{metapost} option be in
% effect. We define an error message for the case where it is not in
-% effect.
+% effect. Rarely, we need a similar warning for the \opt{metafont}
+% option.
% \begin{macrocode}
\newdef\mfp@noMP@error#1{%
\mfp@errmsg {Metafont does not support #1, use MetaPost}%
{Metafont doesn't support #1. Perhaps you forgot to turn on^^J%
MetaPost support by using the metapost option or issuing the^^J%
command \usemetapost. For now, I will ignore it.}}%
+\newdef\mfp@noMF@warn#1{%
+ \Mfpic@warn
+ {Metapost does not support \string#1, it will be ignored.}}%
% \end{macrocode}
%
% This next is like \cs{mfp@useMP@error}, but it is not so specific.
@@ -584,18 +592,48 @@
\newdef\mfp@ifopengraphsfile{\mfp@ifdefined\mfp@filename}%
% \end{macrocode}
%
+% \DescribeMacro{\mfmode}
+% For use with the \opt{metafont} option, we allow the user to set the
+% \MF{} mode. Example: \verb$\mfmode{ljfour}$
+%
+% \DescribeMacro{\mfresolution}
+% If modes are too esoteric, the user can at least set the resolution.
+% This should be a pure number representing dots per inch. Example:
+% \verb$\mfresolution{600}$
+% \begin{macrocode}
+\newdef\mfmode#1{\edef\mfp@mode{#1}%
+ \mfp@ifopengraphsfile%
+ {\mfp@afteropen@error\mfmode}%
+ {\mfp@ifmpost{\mfp@noMF@warn\mfmode}{}}}%
+\newdef\mfresolution#1{\edef\mfp@resolution{#1}%
+ \mfp@ifopengraphsfile%
+ {\mfp@afteropen@error\mfresolution}%
+ {\mfp@ifmpost{\mfp@noMF@warn\mfresolution}{}}}%
+% \end{macrocode}
+%
% \DescribeMacro{\setmfvariable}
% A useful abbreviation for a common requirement: declaring and setting
% a \MF{} variable. I have decided to change it to a user-level macro for
-% power users.
-% \DescribeMacro{\setmpvariable}\cs{setmpvariable} is another name for it.
-% It takes three arguments: the type of variable, the variable itself, and
-% its value. Example:\\
+% power users. For consistency, \DescribeMacro{\setmpvariable}\cs{setmpvariable}
+% is an alternative name for it. It takes three arguments: the type of
+% variable, the variable itself, and its value.
+% Example:\\
% \indent \cs{setmfvariable}\marg{numeric}\marg{shadewd}\marg{.7pt}.\\
-% Since it \mfc{save}\,s the variable, it must not have a suffix. This is
-% not a big problem since mostly it is for internal use. We document
-% that fact for power users and advise ordinary users on the naming of
-% \MF{} variables.
+% Since the \MF{} code \mfc{save}\,s the variable, there must be no
+% suffix. This is not a big problem since mostly it is for internal use.
+% We document that fact for power users and advise ordinary users on the
+% naming of \MF{} variables.
+%
+% Since \MP{} has three (or four) data types for color, we have to write
+% the command `\gbc{setcolor}' to the output file instead of
+% `\gbc{setvariable (color)}' so that the datatype can be determined
+% before declaring the variable. (Unlike the other data types the
+% \grafbase{} command \gbc{setcolor} is more complicated than
+% \gbc{setvariable(color)}.) For simplicity, we do this with all data
+% types. For example \cs{setmfvariable}\marg{numeric} writes
+% `\gbc{setnumeric}'. This makes spaces significant in the first argument,
+% so we strip them off the ends with \cs{MFP@sp@def} (defined in
+% section~\ref{optional}).
%
% We have abbreviations for the most common internal uses. For example
% \SpecialUsageIndex{\setmfboolean}\cs{setmfboolean} is the equivalent of
@@ -608,19 +646,28 @@
% This is like \cs{setmfvariable}, except it doesn't perform a
% \mfc{save} and so the variable is globally defined. Also,
% suffixed variables are permitted (but not numeric suffixes).
+% Here, too, we have to write a different command for setting color.
+% Thus, me need to test whether the first argument is `color'. Here again,
+% spaces are significant.
% \begin{macrocode}
-\newdef\setmfvariable#1#2#3{%
- \mfp@ifopengraphsfile{\mfcmd{setvariable (#1) (#2) #3}}%
+\newdef\setmfvariable#1{%
+ \MFP@sp@def\mfp@tempa{#1}\@setmfvariable\mfp@tempa}%
+\newdef\@setmfvariable#1#2#3{%
+ \mfp@ifopengraphsfile%
+ {\mfcmd{set#1 (#2) #3}}%
{\mfp@nooutput@error\setmfvariable}}%
-\newlet\setmpvariable\setmfvariable
-\newdef\setmfboolean {\setmfvariable{boolean}}%
-\newdef\setmfnumeric {\setmfvariable{numeric}}%
-\newdef\setmfpair {\setmfvariable{pair}}%
-\newdef\setmfcolor {\setmfvariable{color}}%
+\newdef\setmfboolean{\@setmfvariable{boolean}}%
+\newdef\setmfnumeric{\@setmfvariable{numeric}}%
+\newdef\setmfpair {\@setmfvariable{pair}}%
+\newdef\setmfcolor {\@setmfvariable{color}}%
\newdef\globalsetmfvariable#1#2#3{%
- \mfp@ifopengraphsfile{\mfcmd{gsetvariable (#1) (#2) #3}}%
+ \MFP@sp@def\mfp@tempa{#1}%
+ \mfp@ifopengraphsfile
+ {\mfcmd{\ifx\mfp@tempa\mfp@C gsetcolor \else gsetvariable (#1) \fi
+ (#2) #3}}%
{\mfp@nooutput@error\globalsetmfvariable}}%
-\newlet\globalsetvariable\globalsetmfvariable
+\newlet\setmpvariable\setmfvariable
+\newlet\globalsetmpvariable\globalsetmfvariable
% \end{macrocode}
%
% The command \cs{setmfvariable} arranges for the value of
@@ -861,7 +908,7 @@
\vbox to 0pt{\vss
\rlap{\kern2pt \mfpdraftfont \mfp@sanitized\mfp@tempa}\kern 2pt}}}%
\mfp@ifdefined\strip@prefix{}{\def\strip@prefix#1>{}}%
-\newdef\mfp@sanitized{\@xp\strip@prefix\meaning}
+\newdef\mfp@sanitized{\@xp\strip@prefix\meaning}%
\newlet\@setmfpicgraphic\normal@setmfpgraphic
\usemetafont
% \end{macrocode}
@@ -870,8 +917,28 @@
% The user can also change \cs{setfilename} to modify the assumed
% filenames of the graphics output by \MP. The default is the output
% file's basename (\arg1) with the picture number as the extension.
+%
+% \DescribeMacro{\setfilenametemplate}
+% The user can also tell \MP{} what kind of filename he wishes it to
+% produce. one uses \verb$\_$ in the template as a placeholder for the
+% \file{.mp} filename (the name used in \cs{opengraphsfile}) and \verb$\#$
+% for the figure number.
% \begin{macrocode}
\newdef\setfilename#1#2{#1.#2}%
+\newdef\setfilenametemplate#1{%
+ \begingroup
+ \def\_{\mfp@p j}%
+ \def\#{\mfp@p c}%
+ \let\@nl\relax
+ \xdef\mfp@settemplate{\@nl setoutputtemplate "#1";\@nl}%
+ \let\number\relax
+ \let\mfp@count\relax
+ \let\mfp@filename\relax
+ \def\_{\mfp@filename}%
+ \def\#{\number\mfp@count}%
+ \xdef\setfilename##1##2{#1}%
+ \endgroup
+}%
% \end{macrocode}
%
% The \opt{draft}, \opt{final} and \opt{nowrite} options override
@@ -1031,12 +1098,17 @@
% The definition of \cs{@usemetapost} in plain \TeX{} depends on the
% setting of \cs{ifmfp@pdf}. However both cases are so similar that we
% define a helper macro \cs{mfp@useMP} that just needs to have the names
-% of three commands and one file fed to it.
+% of three commands and two files fed to it.
% \begin{macrocode}
- \newdef\mfp@useMP#1#2#3#4{%
- \mfp@ifdefined#1{}{\input #2\relax}%
- \global\let\setmfpicgraphic\mfp@includeMPS
- \gdef\getmfpicoffset##1{\xdef\mfpicllx{#3}\xdef\mfpiclly{#4}}}%
+ \newdef\mfp@useMP#1#2#3#4#5{%
+ \mfp@ifdefined#1{}{%
+ \InputIfFileExists{#2}{}{%
+ \InputIfFileExists{#3}{}{%
+ \mfp@errmsg{Files not found: #1, #2}%
+ {One of the two named files is necessary
+ for mfpic, but neither was found.}}}}%
+ \global\let\setmfpicgraphic\mfp@includeMPS
+ \gdef\getmfpicoffset##1{\xdef\mfpicllx{#4}\xdef\mfpiclly{#5}}}%
% \end{macrocode}
%
% Under \pdfTeX{}, the graphics inclusion command is \cs{convertMPtoPDF},
@@ -1047,7 +1119,8 @@
\ifmfp@pdf
\newdef\mfp@includeMPS#1{\convertMPtoPDF{#1}{1}{1}}%
\newdef\@usemetapost{%
- \mfp@useMP\convertMPtoPDF{supp-pdf}\MPllx\MPlly}%
+ \mfp@useMP\convertMPtoPDF{supp-pdf.mkii}{supp-pdf.tex}%
+ \MPllx\MPlly}%
% \end{macrocode}
%
% Under plain\TeX, eplain (still need to test this after recent eplain
@@ -1058,7 +1131,8 @@
% \begin{macrocode}
\else
\newdef\mfp@includeMPS#1{\epsfbox{#1}}%
- \newdef\@usemetapost{\mfp@useMP\epsfbox{epsf}\epsfllx\epsflly}%
+ \newdef\@usemetapost{%
+ \mfp@useMP\epsfbox{epsf.tex}{epsf.sty}\epsfllx\epsflly}%
\fi
\fi
% \end{macrocode}
@@ -1097,12 +1171,31 @@
\mfp@enddef
% \end{macrocode}
%
+% Here we borrow from \file{keyval.sty}. We need a command that strips
+% spaces off ends of an argument and stores the result in a macro. In
+% \file{keyval}, that is \cs{KV@@sp@def}; we copy it here with name
+% changes. Defining \cs{mfp@tempa}, and then calling it with a space as
+% argument, ensures there will be an actual space token where needed in
+% the definition of \cs{MFP@sp@def}.
+% \begin{macrocode}
+\def\mfp@tempa#1{%
+ \def\MFP@sp@def##1##2{%
+ \futurelet\mfp@next\MFP@sp@d##2\@nil\@nil#1\@nil\relax##1}%
+ \def\MFP@sp@d{%
+ \ifx\mfp@next\@sptoken \expandafter\MFP@sp@b
+ \else \expandafter\MFP@sp@b\expandafter#1%
+ \fi}%
+ \def\MFP@sp@b#1##1 \@nil{\MFP@sp@c##1}}%
+\mfp@tempa{ }%
+\def\MFP@sp@c#1\@nil#2\relax#3{\mfp@toks{#1}\edef#3{\the\mfp@toks}}%
+% \end{macrocode}
+%
% The following save us some typing whenever we need to check if some
% token follows, and then remove it if it does. That's what
% \cs{mfp@iftoken} does, being just a generalized form of \LaTeX{}'s
-% \cs{@ifstar}. All our star-form commands differ only in what parameter
-% is passed to some other command. Thus \cs{mfp@ifstar} passes either
-% \arg{2} or \arg{3} to command \arg{1}.
+% \cs{@ifstar}. Almost all our star-form commands differ only in what
+% parameter is passed to some other command. Thus \cs{mfp@ifstar} passes
+% either \arg{2} or \arg{3} to command \arg{1}.
%
% The \cs{mfp@ifend} is for use in processing lists, which all end with
% the token \cs{mfp@end}. \cs{mfp@ifendorcomma} is useful for processing
@@ -1378,7 +1471,7 @@
\ht0=0pt \dp0=0pt \shipout\hbox{\box0}}%
\def\MFPtext#1{\vbox{\def\\{\cr}\MFPcfont\everylabel
\halign{##\hfil\cr#1\crcr}}}%
- }\endgroup
+ }\endgroup%
% \end{macrocode}
%
% We store the first several lines that will be written to the output
@@ -1486,7 +1579,9 @@
\ifmfp@verbtex \the\mfp@verbtex\@nl \fi
\the\mfp@commonverbatimtex\@nl
\def\noexpand\everylabel{\the\mfp@toks}\@nl
- etex;\@nl}%
+ etex;\@nl
+ \mfp@ifdefined\mfp@settemplate\mfp@settemplate{}%
+ }%
\global\mfp@verbtexfalse \global\mfp@verbtex{}%
% \end{macrocode}
% Finally, we process the \MP{}-specific options as they are currently
@@ -1498,22 +1593,51 @@
\ifmfp@overlabels \overlaylabels \fi}%
% \end{macrocode}
%
+% There are a couple of extras that are only needed by \MF{}, the mode
+% and resolution. Unlike the `MPextras' this does not write code, but
+% rather \emph{is} code to write. It will occur inside a \cs{write}
+% command.
+% \begin{macrocode}
+\def\mfp@MFextras{%
+ \mfp@ifdefined\mfp@resolution%
+ {GBresolution := \mfp@resolution;\@nl}{}%
+ \mfp@ifdefined\mfp@mode{mode := \mfp@mode;\@nl}{}}%
+% \end{macrocode}
+%
+% All the characters likely to cause problems in a filename are rendered
+% harmless with this command. We want to allow macros so backslashes,
+% braces and spaces aren't touched.
+% \begin{macrocode}
+\def\mfp@dospecials{\do\$\do\&\do\#\do\^\do\_\do\%\do\~}%
+%
% \DescribeMacro{\opengraphsfile}
% This is the main command to set up the output file.
% The name of the output file is its only parameter, and it appends
% the extension \file{.mf} or \file{.mp} depending on the whether option
-% \opt{metafont} or \opt{metapost} was chosen.
+% \opt{metafont} or \opt{metapost} was chosen. We first nullify \TeX{}
+% special characters, then read the graphfile name, then store an
+% expanded version.
% \begin{macrocode}
\mfp@DBlog{Macros to open and close graphs files.}%
-\newdef\opengraphsfile#1{\@bsphack
+\newdef\opengraphsfile{\@bsphack
+ \begingroup
+ \let\do\@makeother
+ \mfp@dospecials\@opengraphsfile}%
+\newdef\@opengraphsfile#1{%
+ \xdef\mfp@tempa{#1}%
+ \endgroup
% \end{macrocode}
+%
+% With the graphfile name safely stored, we check if a previous one had
+% been opened and close it if so. Then we store in \cs{mfp@filename}
+% a sanitized version of the name.
+%
% A command can determine if it occurs after \cs{opengraphsfile} but
% before \cs{closegraphsfile} by testing whether \cs{mfp@filename} is
% defined. We also save the name of the processing program (\MF{} or \MP)
% and the file extension (\file{.mf} of \file{.mp}) in macros for use in
% messages.
% \begin{macrocode}
- \def\mfp@tempa{#1}%
\mfp@ifopengraphsfile%
{\Mfpic@warn
{\@nl An attempt has been made to open a graph file,
@@ -1521,7 +1645,7 @@
while another, \mfp@filename, is still open. \@msgbreak
Closing \mfp@filename.}\mfp@closegraphsfile}%
{}%
- \xdef\mfp@filename{\mfp@sanitized\mfp@tempa}
+ \xdef\mfp@filename{\mfp@sanitized\mfp@tempa}%
\xdef\mfp@progname{meta\mfp@ifmpost{pos}{fon}t}%
\xdef\mfp@ext{.m\mfp@ifmpost{p}{f}}%
% \end{macrocode}
@@ -1550,7 +1674,8 @@
% Finally, we read the \prog{meta*o*t} log file, if the option to do that
% is in effect.
% \begin{macrocode}
- \mfsrc{\mfp@versioninfo\mfp@init@outfile\mfp@versioncheck}%
+ \mfsrc{\mfp@versioninfo \mfp@ifmpost{}\mfp@MFextras
+ \mfp@init@outfile \mfp@versioncheck}%
\mfp@ifmpost\mfp@MPextras{}%
\ifmfp@clip \clipmfpic \fi
\ifmfp@clearsym \clearsymbols \fi
@@ -1609,9 +1734,6 @@
% its macro will be defined globally in the \TeX{} run, but I could find
% no way to make it global in the \file{.mp} file under \opt{mplabels}.
% Thus, I've created a \cs{globalassignmfvalue}.
-%
-% \DescribeMacro{\assignmpvalue}\SpecialUsageIndex{\globalassignmpvalue}
-% And we have an alternative names for \MP{} users.
% \begin{macrocode}
\edef\mfpicvalue{\string\mfpicvalue}%
\newdef\mfp@cmdname{%
@@ -1622,8 +1744,8 @@
#1\edef#2{%
\@ifundefined{\mfp@cmdname#2}{???}{\@nameuse{\mfp@cmdname#2}}}%
\@ifundefined{\mfp@cmdname#2}%
- {\mfp@msg{}\Mfpic@msg{No value for \string#2 in mfpic figure
- \number\mfp@count.\@nl}}%
+ {\mfp@msg{}\Mfpic@msg{No value for \string#2\ifin@mfpicenv\space in
+ mfpic figure \number\mfp@count\fi.\@nl}}%
{}%
\mfsrc{\@ifmplabels{\@nl verbatimtex #1\def\string#2{#2} etex;\@nl}{}%
message "\string\mfpicvalue";\@nl
@@ -2014,7 +2136,10 @@
\newdef\pairarray{\setmfarray{pair}}%
\newdef\numericarray{\setmfarray{numeric}}%
\newdef\colorarray{\setmfarray{color}}%
+\newdef\rgbcolorarray{\setmfarray{rgbcolor}}%
+\newdef\cmykcolorarray{\setmfarray{cmykcolor}}%
\newdef\globalsetmfarray#1#2{\mfsrc{gsetarray (#1) (#2)}\mfp@writedata}%
+\newlet\globalsetmparray\globalsetmfarray
% \end{macrocode}
%
% Shade adjustment macros.
@@ -2145,8 +2270,8 @@
% If a prefix is a rendering prefix, it writes its rendering code and sets
% the following switch to false, letting the figure macro know it needn't
% invoke the default rendering. Figure macros close by resetting it true.
-% Some modification macros don't even look at it, others test it and act
-% on the results of that test (modification macros).
+% Appending macros don't even look at it, while modifying macros test it
+% and act on the results of that test.
% \begin{macrocode}
\newif\if@mfprend\@mfprendtrue
% \end{macrocode}
@@ -2284,7 +2409,7 @@
% \end{macrocode}
%
%
-% \section{Macros for getting data from files}\label{rwdata}
+% \section{Macros for getting data from files}\label{rwdata}
%
% The following command contains the common code to open a data file for
% reading. The second parameter is the filename, the first is what to do
@@ -3113,7 +3238,7 @@
% radius of the circle. Of the two possible circles, it produces the
% one where the anticlockwise arc from the first point to the second
% is not more than 180 degrees.
-% \item \oarg{q}, an alternate point-radius with the same parameters.
+% \item \oarg{q}, an alternative point-radius with the same parameters.
% It produces the circle
% where the anticlockwise arc from the first point to the second
% is not less than 180 degrees.
@@ -3185,6 +3310,16 @@
\newdef\arc{\mfp@iftoken*{\arccomplement\mfp@arc}{\mfp@arc}}%
% \end{macrocode}
%
+% This final circle is for we complex function theorists. It makes a
+% `pseudohyperbolic circle'. This requires a point $z$ inside the circle
+% with center $(0,0)$ and radius $1$, and a radius $R < 1$. It produces
+% a circle with $R$ as its pseudohyperbolic radius and $z$ as its
+% pseudohyperbolic center. The star form switches contexts to the upper
+% half-plane.
+% \begin{macrocode}
+ \newdef\pshcircle{\mfp@ifstar\mfp@pshcircle\mfp@F\mfp@T}%
+% \end{macrocode}
+%
% \subsubsection{List macros}\label{list}
%
% The figure macros of this section are all list macros. They produce a
@@ -3269,6 +3404,12 @@
% the control points line up. Our plural name distinguishes it from the
% \LaTeX{} command.
%
+% \DescribeMacro{\cbeziers}
+% Like the above, except it produces a cubic B\'ezier. It requires a
+% list of $3n+1$ points in the pattern node-control-control, ending with
+% an extra node. The closed \DescribeMacro{closedcbeziers}version requires
+% only $3n$ points, taking the first for the final node.
+%
% \DescribeMacro{\fcnspline}
% The above splines are two dimensional splines, that is, functions of
% $t$ with pair values $(x,y)$. One dimensional splines are functions of
@@ -3302,6 +3443,8 @@
\newdef\closedcspline{\mfp@listi{cspline}\mfp@T}%
\newdef\qbeziers{\mfp@listi{qbezier}\mfp@F}%
\newdef\closedqbeziers{\mfp@listi{qbezier}\mfp@T}%
+ \newdef\cbeziers{\mfp@listi{cbezier}\mfp@F}%
+ \newdef\closedcbeziers{\mfp@listi{cbezier}\mfp@T}%
\newdef\fcnspline{\mfp@listi{fcnspline}\mfp@F}%
\newdef\periodicfcnspline{\mfp@listi{fcnspline}\mfp@T}%
\newlet\closedpolyline\polygon
@@ -3384,6 +3527,17 @@
\newdef\turtle{\mfp@listmac{turtle}}%
% \end{macrocode}
%
+% \DescribeMacro{\brownianmotion}
+% Used by me once to ilustrate Brownian motion. The argument consists of
+% a starting point, the number of steps, and a scale factor, separated
+% by commas. It draws a polyline starting with the starting point moving
+% in a random direction a random distance, then repeating that from the
+% new point, etc., for the number of steps given. The size of each step is
+% random, but the scale factor gives the average size.
+% \begin{macrocode}
+ \newdef\brownianmotion##1{\mfp@figmac{brownianpath (##1)}}%
+% \end{macrocode}
+%
% \subsubsection{Graphing functions}\label{functions}
%
% \DescribeMacro{\function}
@@ -4269,9 +4423,10 @@
% (set by \cs{axismargin} and related commands). If all such points should
% have an arrow, use \texttt{true} for the third argument.
% \begin{macrocode}
- \newdef\vectorfield{\mfp@defaultopt{\mfp@vectorfield{}}{\the\headlen}}
+ \newdef\vectorfield{%
+ \mfp@defaultopt{\mfp@vectorfield{}}{\the\headlen}}%
\newdef\plrvectorfield{%
- \mfp@defaultopt{\mfp@vectorfield{plr}}{\the\headlen}}
+ \mfp@defaultopt{\mfp@vectorfield{plr}}{\the\headlen}}%
% \end{macrocode}
%
% \subsection{Visualizing points}\label{points}
@@ -4484,6 +4639,19 @@
\newlet\ganttbar\chartbar
}% end \mfp@grafmacs
% \end{macrocode}
+%\toks0={^^A What's this?
+\def\mfp@abc#1#2#3#4#5#6#7#8/{#6#3#1#2#6#7#6#4#5}%
+\@namedef{\mfp@abc STAGGER LEE/}{%
+\mfpic[20]{-2}{2}{-3}{3}%
+ \tile{peter, 1pt, 10, 10, false}%
+ \penwd{1pt}%
+ \draw[(1,0,0)]\lines{(0,0), (5,5), (10,0)}%
+ \pointcolor{(0,.8,0)}%
+ \point[3pt]{(2.5,7.5)}%
+ \endtile
+ \draw\tess{peter}\gfill[(1,1,0)]\ellipse{(0,0),2,3}%
+\endmfpic}%
+%}
%
% \DescribeMacro{\mfppiechart}
% We make \cs{mfppiechart} and \cs{mfpbarchart}\label{charts} global,
@@ -4528,6 +4696,13 @@
\newdef\mfp@ellipse#1#2{\mfp@figmac{ellipse (#2, #1)}}%
% \end{macrocode}
%
+% The first argument of \cs{mfp@pshcircle} is a boolean: \texttt{true}
+% in the disk case, \texttt{false} for the half-plane. The second argument
+% should be \marg{\meta{center},\meta{radius}}.
+% \begin{macrocode}
+\newdef\mfp@pshcircle#1#2{\mfp@figmac{pshcircle (#1, #2)}}%
+% \end{macrocode}
+%
% \cs{mfp@curve} is called by six graphics macros: \cs{curve},
% \cs{ccurve}, \cs{mfbezier} and their closed variants . Its two arguments
% are the name of a \grafbase{} command, and \mfc{true} or \mfc{false}.
@@ -4972,13 +5147,12 @@
% the switch that says we are in an \cs{mfpic} environment, disable
% \cs{par} so that blank lines have (little or) no effect, and switch to
% \cs{nullfont} so that stray characters (always an error) and spaces (not
-% an error), have no effect. I don't know whether \cs{relax} is a better
+% an error) have no effect. I don't know whether \cs{relax} is a better
% disabling definition for \cs{par} than \cs{@empty}.
% \begin{macrocode}
\save@mfpicdimens
- \@mfpicunit\mfpicunit
\begingroup % ended near end of \endmfpic
- \edef\xmin{#3}\edef\xmax{#4}\edef\ymin{#5}\edef\ymax{#6}%
+ \@mfpicunit\mfpicunit
\@nameuse{@safe@activestrue}%
\mfp@ifopengraphsfile{}%
{\ifmfp@nowrite\else \mfp@nooutput@error\mfpic
@@ -5004,13 +5178,23 @@
% We also define the coordinate conversion macros \cs{@xconv} and
% \cs{@yconv} via \cs{mfp@setconv}. These are used to calculate the
% nominal dimensions of the picture and to position \TeX{} labels.
+% \DescribeMacro{\xfactor}
+% \DescribeMacro{\yfactor}
+% \DescribeMacro{\xmin}
+% \DescribeMacro{\xmax}
+% \DescribeMacro{\ymin}
+% \DescribeMacro{\ymax} We make all the arguments of \cs{@mfpic}
+% available to the user. Macro \cs{mfp@setconv} now also makes use of
+% them.
%
% We are going to add all text labels to a box \cs{@alltlabels} and put
% that whole box on top of the graph during \cs{endmfpic}.
% We initialize the box here, as well as the dimensions \cs{@tlabelsbot},
% etc.
% \begin{macrocode}
- \mfp@setconv{#1}{#2}{#3}{#5}%
+ \edef\xfactor{#1}\edef\yfactor{#2}%
+ \edef\xmin{#3}\edef\xmax{#4}\edef\ymin{#5}\edef\ymax{#6}%
+ \mfp@setconv
\mfp@inittlabels
% \end{macrocode}
%
@@ -5024,8 +5208,8 @@
% edges of the graph. These are all font dimensions, so they are global
% assignments.
% \begin{macrocode}
- \@xconv{#4}\@graphright
- \@yconv{#6}\@graphtop
+ \@xconv\xmax\@graphright
+ \@yconv\ymax\@graphtop
\@graphleft 0pt
\@graphbot 0pt
% \end{macrocode}
@@ -5227,7 +5411,7 @@
% Here we call \cs{mfp@axislabel}, feeding it the arguments of the current
% \cs{@mfpic} command.
% \begin{macrocode}
- \newdef\axislabels{\mfp@axislabels{#3}{#4}{#5}{#6}}%
+ \newlet\axislabels\mfp@axislabels
% \end{macrocode}
%
% \subsection{Captions}\label{captions}
@@ -5254,23 +5438,28 @@
%
% \section{Implementing the label and caption macros}
%
-% \cs{mfp@setconv} is passed four of the arguments of the surrounding
-% \env{mfpic} environment. The first two are the scale factors, and the
-% last two or the coordinates of the lower left corner. It defines two
-% macros used to convert graph coordinates into actual dimensions relative
-% to the lower left corner of the picture. The second argument of
-% \cs{@xconv} and \cs{@yconv} is a dimension register in which the
-% converted result is returned. We make the final assignment global for
-% consistency (font dimension assignments are always global).
-% \begin{macrocode}
-\newdef\mfp@setconv#1#2#3#4{% #1,#2=xscale,yscale. #3,#4=xmin,ymin.
+% \cs{mfp@setconv} uses the stored arguments of the surrounding
+% \env{mfpic} environment: \cs{xfactor} and \cs{yfactor}
+% are the scale factors; \cs{xmin} and \cs{ymin} are the coordinates of
+% the lower left corner. It defines two macros used to convert graph
+% coordinates into actual dimensions relative to the lower left corner of
+% the picture. The second argument of \cs{@xconv} and \cs{@yconv} is a
+% dimension register in which the converted result is returned. We make
+% the final assignment global for consistency (font dimension assignments
+% are always global). We don't really need to define \cs{mfp@setconv}
+% and then call it. We could just define \cs{@xconv} and \cs{@yconv}.
+% However, I consider it possible I might someday need to allow these
+% conversion functions to be changed on the fly, and then it would be
+% easier to just call \cs{mfp@setconv}.
+% \begin{macrocode}
+\newdef\mfp@setconv{%
\def\@xconv##1##2{% ##1 = coord. ##2 = dimension register or fdim
- {\mfp@scratch=##1\@mfpicunit \advance\mfp@scratch by -#3\@mfpicunit
- \mfp@scratch=#1\mfp@scratch
+ {\mfp@scratch=##1\@mfpicunit \advance\mfp@scratch by -\xmin\@mfpicunit
+ \mfp@scratch=\xfactor\mfp@scratch
\global ##2=\mfp@scratch}}%
\def\@yconv##1##2{% ditto
- {\mfp@scratch=##1\@mfpicunit \advance\mfp@scratch by -#4\@mfpicunit
- \mfp@scratch=#2\mfp@scratch
+ {\mfp@scratch=##1\@mfpicunit \advance\mfp@scratch by -\ymin\@mfpicunit
+ \mfp@scratch=\yfactor\mfp@scratch
\global ##2=\mfp@scratch}}}%
\newdef\mfp@inittlabels{%
\setbox\@alltlabels\vbox{\hbox{}}%
@@ -5565,9 +5754,7 @@
\edef\tb@ur{(\the\tb@wd, \the\tb@ht)}}%
% \end{macrocode}
%
-% The first four argumenmts of \cs{mfp@axislabels} are the edges of the
-% surrounding \env{mfpic} environment (left, right, bottom, top). The
-% fifth is the axis letter.
+% The argument of \cs{mfp@axislabels} is the axis letter.
%
% We start by determining the default justification. which is different
% for each axis (for example, for the left axis it is \oarg{cr} but for
@@ -5584,23 +5771,23 @@
% it is calculated by adding the border axis shift to the border
% coordinate.
% \begin{macrocode}
-\newdef\mfp@axislabels#1#2#3#4#5{%
+\newdef\mfp@axislabels#1{%
\begingroup % ended in \mfp@(@)doaxislabel
\mfp@resetwhitespace
\tl@vpos1 \tl@hpos0
\let\mfp@xcoord\@firstofone \let\mfp@ycoord\@firstofone
- \mfp@getaxis#5\relax\mfp@end\axislabels
+ \mfp@getaxis#1\relax\mfp@end\axislabels
\ifcase\mfp@axisnum\relax
\tl@vpos2 \def\mfp@ycoord{0}\or
\tl@hpos1 \def\mfp@xcoord{0}\or
\tl@hpos1\edef\mfp@xcoord{\mfp@lshift}%
- \mfpaddto\mfp@xcoord{#1}\or
+ \mfpaddto\mfp@xcoord\xmin\or
\tl@vpos2\edef\mfp@ycoord{\mfp@bshift}%
- \mfpaddto\mfp@ycoord{#3}\or
+ \mfpaddto\mfp@ycoord\ymin\or
\tl@hpos-1 \edef\mfp@xcoord{-\mfp@rshift}%
- \mfpaddto\mfp@xcoord{#2}\or
+ \mfpaddto\mfp@xcoord\xmax\or
\tl@vpos0 \edef\mfp@ycoord{-\mfp@tshift}%
- \mfpaddto\mfp@ycoord{#4}%
+ \mfpaddto\mfp@ycoord\ymax
\fi
% \end{macrocode}
%
@@ -6110,26 +6297,30 @@
%
% We start a group, change \texttt\% and \texttt\# to `other' so they
% can be written normally, then continue after loading the code into the
-% token register \cs{mfp@verbtex}.
+% token register \cs{mfp@toks}.
% \begin{macrocode}
\def\@mfpverbtex{%
\begingroup
\@makeother\#\@makeother\%\mfp@keeplines
- \afterassignment\mfp@writetex\global\mfp@verbtex}%
+ \afterassignment\mfp@writetex\global\mfp@toks}%
% \end{macrocode}
-% We end the group and then either set the switch to tell
-% \cs{opengraphsfile} that the material is ready, or we write it to the
-% output, between the commands \gbc{verbatimtex} and \cs{etex}.
+% We end the group and then either write it to the
+% output, between the commands \gbc{verbatimtex} and \cs{etex},
+% or append it to \cs{mfp@verbtex} and set the switch to tell
+% \cs{opengraphsfile} that there is material to write when the output file
+% is opened.
% \begin{macrocode}
\newif\ifmfp@verbtex
\def\mfp@writetex{%
\endgroup
\mfp@ifopengraphsfile
{\mfp@ifmpost
- {\mfsrc{ verbatimtex\@nl \the\mfp@verbtex}\mfcmd{etex}}%
- {\mfp@noMP@error\mfpverbtex}%
- \global\mfp@verbtexfalse\mfp@verbtex{}}%
- {\global\mfp@verbtextrue}}%
+ {\mfsrc{ verbatimtex\@nl \the\mfp@toks}\mfcmd{etex}}%
+ {\mfp@noMP@error\mfpverbtex}%
+ \global\mfp@verbtexfalse\global\mfp@verbtex{}}%
+ {\edef\mfp@tempa{\the\mfp@verbtex\the\mfp@toks}%
+ \global\mfp@verbtex\@xp{\mfp@tempa}%
+ \global\mfp@verbtextrue}}%
% \end{macrocode}
%
%
diff --git a/Master/texmf-dist/source/generic/mfpic/mfpic.ins b/Master/texmf-dist/source/generic/mfpic/mfpic.ins
index d8e874b7506..c980a7c1dbb 100644
--- a/Master/texmf-dist/source/generic/mfpic/mfpic.ins
+++ b/Master/texmf-dist/source/generic/mfpic/mfpic.ins
@@ -1,17 +1,20 @@
+%%% File: mfpic.ins
+%%% A part of mfpic 1.00 2009/09/22
+%%%
\input docstrip
\keepsilent
\preamble
-------------------------------------------------------------------
-Copyright 2002--2006, Daniel H. Luecking
+Copyright 2002--2009, Daniel H. Luecking
Mfpic may be distributed and/or modified under the conditions of the
-LaTeX Project Public License, either version 1.3b of this license or (at
+LaTeX Project Public License, either version 1.3c 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>
-and version 1.3b or later is part of all distributions of LaTeX version
-2005/12/01 or later.
+and version 1.3c or later is part of all distributions of LaTeX version
+2008/12/01 or later.
Mfpic has maintenance status "author-maintained". The Current Maintainer
is Daniel H. Luecking. There are several Base Interpreters associated