% \CheckSum{3947} % \iffalse meta-comment % % Copyright 1993, 1994, 1995, 1996 Alan Jeffrey, % hacked and maintained 1997, 1998 Sebastian Rahtz, % copyright 1998, 1999, 2000 the fontinst maintenance team and any % individual authors listed elsewhere in this file. All rights reserved. % % This file is part of the fontinst system version 1.9. % ----------------------------------------------------- % % It may be distributed under the terms of the LaTeX Project Public % License, as described in lppl.txt in the base LaTeX distribution. % Either version 1.1 or, at your option, any later version. % %%% From file: fimain.dtx % %<*driver> \documentclass{ltxdoc} \usepackage{fisource} \title{The \package{fontinst} utility} \author{Alan Jeffrey, Sebastian Rahtz, Ulrik Vieth, Lars Hellstr\"om} \begin{document} \maketitle \tableofcontents \DocInput{fimain.dtx} \end{document} % % \fi % % \StopEventually{} % % % \section{General commands} % % \subsection{Setting variables} % % \meta{int}, \meta{str}, and \meta{dim} below can be any strings. % \meta{command} can be any control sequence. % % \DescribeMacro{\setint} % \DescribeMacro{\setstr} % \DescribeMacro{\setdim} % \DescribeMacro{\setcommand} % The macros: % \begin{quote} % |\setint|\marg{int}\marg{integer expression}\\ % |\setstr|\marg{str}\marg{string}\\ % |\setdim|\marg{dim}\marg{dimension}\\ % |\setcommand|\meta{command}\meta{definition} % \end{quote} % define new macros |\i-|\meta{int}, |\s-|\meta{str}, |\d-|\meta{dim} or % \meta{command}. % % \DescribeMacro{\resetint} % \DescribeMacro{\resetstr} % \DescribeMacro{\resetdim} % \DescribeMacro{\resetcommand} % The macros: % \begin{quote} % |\resetint|\marg{int}\marg{integer expression}\\ % |\resetstr|\marg{str}\marg{string}\\ % |\resetdim|\marg{dim}\marg{dimension}\\ % |\resetcommand|\meta{command}\meta{definition} % \end{quote} % redefine the macros |\i-|\meta{int}, |\s-|\meta{str}, |\d-|\meta{dim} or % \meta{command}. % % \DescribeMacro{\int} % \DescribeMacro{\str} % \DescribeMacro{\dim} % The macros: % \begin{quote} % |\int|\marg{int}\\ % |\str|\marg{str}\\ % |\dim|\marg{dim}\\ % \meta{command} % \end{quote} % return the values of |\i-|\meta{int}, |\s-|\meta{str}, |\d-|\meta{dim}, % or \meta{command}. % % \DescribeMacro{\strint} % The macro % \begin{quote} % |\strint|\marg{int} % \end{quote} % returns the value of |\i-|\meta{int} as a string. % % \DescribeMacro{\ifisint} % \DescribeMacro{\ifisstr} % \DescribeMacro{\ifisdim} % \DescribeMacro{\ifiscommand} % The macros: % \begin{quote} % |\ifisint|\marg{int}|\then|\\ % |\ifisstr|\marg{str}|\then|\\ % |\ifisdim|\marg{dim}|\then|\\ % |\ifiscommand|\meta{command}|\then| % \end{quote} % return |\if_true| if |\i-|\meta{int}, |\s-|\meta{str}, % |\d-|\meta{dim}, or \meta{command} have been defined, and |\if_false| % otherwise. % % \DescribeMacro{\unsetint} % \DescribeMacro{\unsetstr} % \DescribeMacro{\unsetdim} % \DescribeMacro{\unsetcommand} % The macros: % \begin{quote} % |\unsetint|\marg{int}\\ % |\unsetstr|\marg{str}\\ % |\unsetdim|\marg{dim}\\ % |\unsetcommand|\meta{command} % \end{quote} % undefine |\i-|\meta{int}, |\s-|\meta{str}, |\d-|\meta{dim}, or % \meta{command}. % % \DescribeMacro{\x_setint} % \DescribeMacro{\x_resetint} % \DescribeMacro{\x_setstr} % The macros |\x_setint|, |\x_resetint|, and |\x_setstr| are ``private'' % versions of |\setint|, |\resetint|, and |\setstr| respectively. They % have been included to reduce the problems in case a user turns off one % of these commands and forgets to turn it on again. % % \changes{1.900}{1999/02/07}{Replaced \cs{setint} by \cs{x_setint}. (LH)} % \changes{1.900}{1999/02/07}{Replaced \cs{resetint} by \cs{x_resetint}. % (LH)} % \changes{1.900}{1999/02/07}{Replaced \cs{setstr} by \cs{x_setstr}. % (LH)} % % Integers are kept as |\mathchardef|s if possible; a comparision of % doing this versus not doing this appears in % Subsection~\ref{Ssec: ASAJ tests}. % % \begin{macro}{\setsomething_global} % The |\setsomething_global| control sequence should be either % |\relax| or |\global|. It appears before the central assignments in % all the |\set|\textellipsis, |\reset|\textellipsis, and % |\unset|\textellipsis\ commands. The normal value is |\relax|, so % that these assignments are local. % % When there is counter-intuitive grouping, and it could seem that % \TeX\ should not be inside a group at all---i.e., between % |\installfonts| and |\endinstallfonts|---one can make the basic % assignment commands act more logical by setting % |\setsomething_global| to |\global|. % % \changes{1.912}{2000/01/15}{Control sequence introduced and added % to all \cs{set}\dots, \cs{reset}\dots, and \cs{unset}\dots\ % commands, as well as \cs{offcommand} and \cs{oncommand}. (LH)} % \begin{macrocode} %<*pkg|misc> \let\setsomething_global=\x_relax % \end{macrocode} % \end{macro} % % \begin{macro}{\x_setint} % \begin{macro}{\setint} % \begin{macro}{\x_setstr} % \begin{macro}{\setstr} % \begin{macro}{\setdim} % \begin{macro}{\setcommand} % \changes{1.909}{1999/10/17}{Since \package{fontdoc} adds some % grouping, \cs{setcommand} must set its argument globally there. % (LH)} % \changes{1.912}{2000/01/15}{Settings of a command already defined % is diverted to \cs{a_macro}; it used to be \cs{a_command}. Saves % one hash table position. (LH)} % % \begin{macrocode} \def\x_setint#1#2{ \x_cs\ifx{i-#1}\x_relax \x_resetint{#1}{#2} \fi } \let\setint=\x_setint \def\x_setstr#1#2{ \x_cs\ifx{s-#1}\x_relax \setsomething_global\x_cs\edef{s-#1}{#2} \fi } \let\setstr=\x_setstr \def\setdim#1#2{ \x_cs\ifx{d-#1}\x_relax \a_dimen=#2\x_relax \setsomething_global\x_cs\edef{d-#1}{\the\a_dimen} \fi } \def\setcommand#1{ \ifx#1\undefined_command \setsomething_global \expandafter\def \expandafter#1 \else \expandafter\def \expandafter\a_macro \fi } % % \end{macrocode} % % In \package{fontdoc}, |\setint|, |\setstr|, and |\setdim| print % headings. There is no need for the private forms |\x_setint| and % |\x_setstr|. |\setcommand|, finally, does the same thing as in % \package{fontinst}; the assignment is global because of grouping % not present in \package{fontinst}. % \begin{macrocode} %<*doc> \def\setint#1#2{\Bheading{Default} #1 = $\expression0{#2}$} \def\setstr#1#2{\Bheading{Default} #1 = #2} \def\setdim#1#2{\a@dimen=#2\relax\Bheading{Default} #1 = \the\a@dimen} \def\setcommand#1{\ifx#1\undefined@command \expandafter\gdef\expandafter#1\else \expandafter\gdef\expandafter\a@command\fi} % % \end{macrocode} % \end{macro} \end{macro} \end{macro} \end{macro} \end{macro} % \end{macro} % % \begin{macro}{\x_resetint} % \begin{macro}{\resetint} % \begin{macro}{\resetstr} % \begin{macro}{\resetdim} % \begin{macro}{\resetcommand} % \changes{1.909}{1999/10/17}{Since \package{fontdoc} adds some % grouping, \cs{resetcommand} must set its argument globally there. % (LH)} % \begin{macrocode} %<*pkg|misc> \def\x_resetint#1#2{ \eval_expr{#2} \setsomething_global \ifnum\result<\max_mathchardef \ifnum 0>\result \x_cs\edef{i-#1}{\the\result} \else \x_cs\mathchardef{i-#1}=\result \fi \else \x_cs\edef{i-#1}{\the\result} \fi } \let\resetint=\x_resetint \def\resetstr#1#2{\setsomething_global\x_cs\edef{s-#1}{#2}} \def\resetdim#1#2{ \a_dimen=#2 \setsomething_global\x_cs\edef{d-#1}{\the\a_dimen} } \def\resetcommand#1{\setsomething_global\def#1} % % \end{macrocode} % % In \package{fontdoc}, |\resetint|, |\resetstr|, and |\resetdim| % print headings. There is no need for the private form |\x_resetint|. % |\resetcommand|, finally, does the same thing as in % \package{fontinst}. % % \begin{macrocode} %<*doc> \def\resetint#1#2{\Bheading{Value} #1 = $\expression0{#2}$} \def\resetstr#1#2{\Bheading{Value} #1 = #2} \def\resetdim#1#2{\a@dimen=#2\relax\Bheading{Value} #1 = \the\a@dimen} \def\resetcommand#1{\gdef#1} % % \end{macrocode} % \end{macro} \end{macro} \end{macro} \end{macro} \end{macro} % % % \begin{macro}{\int} % \changes{1.909}{1999/10/19}{doc implementation changed to using % \cs{typeset@integer}. (LH)} % \begin{macro}{\str} % \begin{macro}{\dim} % \begin{macro}{\strint} % \changes{1.909}{1999/10/19}{Change to stop it from gobbling a % following space if the integer is stored in a macro. (LH)} % \begin{macrocode} %<*pkg|misc> \def\int#1{\csname~i-#1\endcsname} \def\str#1{\csname~s-#1\endcsname} \def\dim#1{\csname~d-#1\endcsname} \def\strint#1{\expandafter\identity_one\expandafter{\number\int{#1}}} % % \end{macrocode} % % \missing{doc}{\str} % \missing{doc}{\dim} % \missing{doc}{\strint} % \begin{macrocode} %<*doc> \def\int#1{\typeset@integer{#1}} % \end{macrocode} % \end{macro} \end{macro} \end{macro} \end{macro} % % \begin{macro}{\typeset@integer} % \begin{macro}{\typeset@string} % \begin{macro}{\typeset@dimen} % These macros take the name of an integer\slash string\slash dimen % as argument and typesets that name with the correct formating. They % should work equally well in horizontal, math, and vertical mode. % \begin{macrocode} \def\typeset@integer#1{\x@relax \ifmmode {\fam0 #1}\else $\fam0 #1$\fi} \def\typeset@string#1{\x@relax \ifmmode \hbox{\normalfont#1}\else \textnormal{#1}\fi } \let\typeset@dimen=\typeset@string % % \end{macrocode} % \end{macro}\end{macro}\end{macro} % % \begin{macro}{\ifisint} % \begin{macro}{\ifisstr} % \begin{macro}{\ifisdim} % \multchanges{\cs{ifisint}\cs{ifisstr}\cs{ifisdim}}{1.912} % {2000/02/10}{Reimplemented using \cs{if_defined}. (LH)} % \begin{macro}{\ifiscommand} % \begin{macrocode} %<*pkg|misc> \def\ifisint#1\then{\if_defined i-#1\then} \def\ifisstr#1\then{\if_defined s-#1\then} \def\ifisdim#1\then{\if_defined d-#1\then} \def\ifiscommand#1\then{ \ifx#1\undefined_command \expandafter\if_false \else \expandafter\if_true \fi } % % \end{macrocode} % % In \package{fontdoc}, all conditionals are handled through % |\generic@if|, which by default expands to |\iftrue|. % \changes{1.909}{1999/10/17}{Changed one fontdoc definition of % \cs{ifisglyph} to a definition of \cs{ifiscommand}, which was % missing from fontdoc.} % \begin{macrocode} %<*doc> \def\ifisint#1\then{\generic@if{integer \typeset@integer{#1} set}} \def\ifisstr#1\then{\generic@if{string \typeset@string{#1} set}} \def\ifisdim#1\then{\generic@if{dimension \typeset@dimen{#1} set}} \def\ifiscommand#1\then{% \generic@if{command \normalfont{\ttfamily\string#1} set}% } % % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\unsetint} % \begin{macro}{\unsetstr} % \begin{macro}{\unsetdim} % \begin{macro}{\unsetcommand} % \begin{macrocode} %<*pkg|misc> \def\unsetint#1{\setsomething_global\x_cs\let{i-#1}\x_relax} \def\unsetstr#1{\setsomething_global\x_cs\let{s-#1}\x_relax} \def\unsetdim#1{\setsomething_global\x_cs\let{d-#1}\x_relax} \def\unsetcommand#1{\setsomething_global\let#1=\undefined_command} % % \end{macrocode} % \missing{doc}{\unsetint} % \missing{doc}{\unsetstr} % \missing{doc}{\unsetdim} % \missing{doc}{\unsetcommand} % \begin{macrocode} %<*doc> % % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\offcommand} % \begin{macro}{\oncommand} % LH 1999/02: The calls % \begin{quote} % |\offcommand|\meta{command}\\ % |\oncommand|\meta{command} % \end{quote} % can be used to turn a command off (make it simply absorb its % arguments but expand to nothing) or on (return it to normal) % respectively. Their primary use is for ignoring some of the % commands in \texttt{.mtx} files that \package{fontinst} generates % from \texttt{.afm}, \texttt{.pl}, or other \texttt{.mtx} files. % % \DescribeMacro{\saved-COMMAND} % The normal definition of a command that have been turned off is saved % as the control sequence |\saved-|\meta{command}. If the syntax of a % command is tricky---not all arguments are read by the base command or % its parameter text contains tokens that are not parameters---or if % simply making it do nothing is not the expected `off' behaviour, % then the automatic off-turning may not work. In such cases a % handtooled off definition of the command \meta{command} may be % provided as the control sequence |\off-|\meta{command}.^^A % \DescribeMacro{\off-COMMAND} % % Nothing happens if |\offcommand| is called for a command that is % not on. Nothing happens if |\oncommand| is called for a command % that is not off. % \begin{macrocode} %<*pkg|misc> \def\offcommand#1{ \x_cs\ifx{saved-\string#1}\x_relax \setsomething_global\x_cs\let{saved-\string#1}#1 \x_cs\ifx{off-\string#1}\x_relax \generate_off_command{#1} \else \setsomething_global \expandafter\let \expandafter#1 \csname off-\string#1\endcsname \fi \fi } % \end{macrocode} % \begin{macrocode} \def\oncommand#1{ \x_cs\ifx{saved-\string#1}\x_relax \else \setsomething_global \expandafter\let \expandafter#1 \csname saved-\string#1\endcsname \setsomething_global\x_cs\let{saved-\string#1}\x_relax \fi } % % \end{macrocode} % \multchanges{\cs{offcommand}\cs{oncommand}}{1.914}{2000/05/28} % {\package{fontdoc} definitions added. (LH)} % \begin{macrocode} %<*doc> \def\offcommand#1{\Bheading{Turn off} \texttt{\string#1}} \def\oncommand#1{\Bheading{Turn on} \texttt{\string#1}} % % \end{macrocode} % \end{macro}\end{macro} % % \begin{macro}{\generate_off_command} % \begin{macro}{\count_hashes} % \begin{macro}{\gobble_to_xrelax} % |\generate_off_command|\meta{command} converts \meta{command} to % an ``off'' version of itself by counting the number of arguments % and defining it to gobble that many arguments. It cannot cope with % commands whose parameter texts are not simply of the type % \begin{quote} % |#1#2|\textellipsis|#|$n$ % \end{quote} % \begin{macrocode} %<*pkg|misc> \def\generate_off_command#1{ \a_count=0 \let\next=\count_hashes \expandafter\next\meaning#1~->\x_relax \b_count=0 \a_toks={} \loop \ifnum \b_count<\a_count \advance \b_count 1 \a_toks=\expandafter{\the\expandafter\a_toks \expandafter#### \the\b_count} \repeat \setsomething_global \expandafter\def \expandafter#1 \the\a_toks {} } % \end{macrocode} % \begin{macrocode} \def\count_hashes#1#2{ \if \hash_char#1 \advance \a_count 1 \else \if -#1 \if >#2 \let\next=\gobble_to_xrelax \fi\fi \fi \next#2 } \def\gobble_to_xrelax#1\x_relax{} % % \end{macrocode} % \end{macro}\end{macro}\end{macro} % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % \subsection{For loops} % % % \begin{macro}{\for} % \begin{macro}{\endfor} % LH 1999/02: The command sequence % \begin{quote} % |\for|\parg{name}\marg{start}\marg{stop}\marg{step}\\ % \vadjust{}\quad\meta{body code}\\ % |\endfor|\parg{name} % \end{quote} % will cause the \meta{body code} to be repeated some number of times. % How many depends on the values of \meta{start}, \meta{stop}, and % \meta{step}, which are integer expressions. % % As a precaution, the \meta{body code} is not allowed to contain any % empty lines (|\par| tokens). If you want to have the visual % separation (for sakes of legibility or otherwise), put a |%| % somewhere on the line---that makes it nonempty. % % \meta{name} is used as the name of an integer variable. This % variable gets reset to the value of \meta{start} before the first % repetition of \meta{body code}. After each repetition but the last, % it is incremented by \meta{step}. \meta{body code} gets repeated if % the value of \meta{name} has not gotten past that of \meta{stop}. To % get past means to be bigger if \meta{step} is positive and to be % smaller if \meta{step} is negative. In the case that \meta{step} is % zero, the entire construction above will be equivalent to % \begin{quote} % |\resetint|\marg{name}\marg{start}\\ % \meta{body code} % \end{quote} % % |\for| \textellipsis\ |\endfor| constructions can be nested. % \meta{name} is used by |\for| to identify its matching |\endfor|, so % they need to be identical in |\for| and |\endfor|. % % \multchanges{\cs{for}\cs{for_i}\cs{foreach}}{1.914}{2000/05/21} % {\cs{setsomething_global} added to assignments of the % \cs{for-\meta{name}} and \cs{body-\meta{name}} control % sequences. (LH)} % \begin{macrocode} %<*pkg|misc> \def\for(#1)#2#3#4{ \eval_expr_to\a_count{#2} \x_resetint{#1}{\a_count} \eval_expr{#4} \ifnum 0=\result \else \c_count=\result \eval_expr_to\b_count{#3} \setsomething_global\x_cs\edef{for-#1}{ \the\c_count \x_relax \noexpand\ifnum \gobble_one\fi \the\b_count \ifnum 0>\c_count > \else < \fi } \def\next##1##2##3\endfor(#1){##2\for_i{##1}{##3}} \next{#1} \fi } % \end{macrocode} % % \DescribeMacro{\for-NAME}The macro |\for-|\meta{name} will contain % \begin{quote} % \meta{step}|\x_relax\ifnum|\meta{stop}\meta{rel} % \end{quote} % \meta{step} is the value of the \meta{step} parameter of |\for|, % computed when the loop was entered and now expressed in digits. % \meta{stop} is likewise for the \meta{stop} parameter. \meta{rel} % is |>| or |<|, depending on whether \meta{step} is positive or % negative respectively. The reason for this curious definition will % be appearent in the light of the definition of |\for_ii|. % % |\for_i| is expanded in the context % \begin{quote} % |\for_i|\marg{name}\marg{body code} % \end{quote} % Also remember, when reading the definition below, that |\ifnum| % keeps on expanding tokens until it has found a % \begin{quote} % \meta{number}\meta{relation}\meta{number} % \end{quote} % structure. It is therefore possible to nest |\ifnum|s like this! % % \begin{macrocode} \def\for_i#1#2{ \setsomething_global\x_cs\def{body-#1}{#2} \ifnum \b_count \ifnum0>\c_count >\else<\fi \a_count \expandafter\gobble_two \else \csname body-#1 \expandafter\endcsname \fi \for_ii{#1} } % \end{macrocode} % % \DescribeMacro{\body-NAME}The macro |\body-|\meta{name} expands to % the \meta{body code}. % % |\for_ii| executes the following code: % \begin{quote} % |\a_count=\int|\marg{name}\\ % |\advance \a_count |\meta{step}|\x_relax|\\ % |\ifnum |\meta{stop}\meta{rel}|\a_count|\\ % | \expandafter\gobble_two|\\ % |\else|\\ % | \resetint|\marg{name}|\a_count|\\ % | \csname body-|\meta{name}| \expandafter\endcsname|\\ % |\fi|\\ % |\for_ii|\marg{name} % \end{quote} % \meta{step}, \meta{stop}, and \meta{rel} are in |\for-|\meta{name}, % and since there only are two other tokens between \meta{step} and % \meta{rel} in the above, one might as well include them in % |\for-|\meta{name} as well. Doing that requires that a matching % hole---that will be filled in by |\for-|\meta{name}---is made in the % definition of |\for_ii| and that is the reason for its somewhat % curious definition. % % \begin{macrocode} \def\for_ii#1{ \a_count=\int{#1} \advance \a_count \csname for-#1\endcsname \a_count \expandafter\gobble_two \else \x_resetint{#1}\a_count \csname body-#1 \expandafter\endcsname \fi \for_ii{#1} } % \end{macrocode} % % |\endfor| just gobbles its argument, so that the \meta{step}${}=0$ % case will work right. % % \begin{macrocode} \def\endfor(#1){} % % \end{macrocode} % \missing{doc}{\for} % \missing{doc}{\endfor} % \begin{macrocode} %<*doc> % % \end{macrocode} % \end{macro}\end{macro} % % % \begin{macro}{\foreach} % \changes{1.901}{1999/03/07}{Command added. (LH)} % \begin{macro}{\foreach_i} % The command sequence % \begin{quote} % |\foreach|\parg{name}\marg{csep-list}\\ % \vadjust{}\quad\meta{body code}\\ % |\endfor|\parg{name} % \end{quote} % will cause the \meta{body code} to be repeated one time for each item % in the \meta{csep-list}. \meta{csep-list} is a comma-separated list % of strings. % % As a precaution, the \meta{body code} is not allowed to contain any % empty lines (|\par| tokens). If you want to have the visual % separation (for sakes of legibility or otherwise), put a |%| % somewhere on the line---that makes it nonempty. % % \meta{name} is used as the name of a string variable. Before each % repetition of the \meta{body code}, this variable will get reset to % the next item in the \meta{csep-list}. % % |\for|\textellipsis\ |\endfor| constructions can be nested. % \meta{name} is used by |\foreach| to identify its matching |\endfor|, % so they need to be identical in |\foreach| and |\endfor|. % % \missing{doc}{\foreach} % \begin{macrocode} %<*pkg|misc> \def\foreach(#1)#2{ \def\next##1\endfor(#1){ \setsomething_global\x_cs\def{body-#1}{##1} \process_csep_list{\foreach_i{#1}}#2,\process_csep_list, } \next } \def\foreach_i#1#2{ \resetstr{#1}{#2} \csname body-#1\endcsname } % % \end{macrocode} % \end{macro} \end{macro} % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % \subsection{Integer expressions} % % \begin{macro}{\eval_expr} % \begin{macro}{\eval_expr_to} % \begin{macro}{\g_eval_expr_to} % The macro % \begin{quote} % |\eval_expr|\marg{integer expression} % \end{quote} % globally assigns |\result| to the value of % \meta{integer expression}, and changes the value of no other % counters. % % The macro % \begin{quote} % |\eval_expr_to|\marg{integer variable}\marg{integer expression} % \end{quote} % locally assigns the value of \meta{integer expression} to % \meta{integer variable} (which is an integer variable as defined % in~\cite{TeXbook}). % |\g_eval_expr_to| does the same globally. % % \begin{macrocode} %<*pkg|misc> \newcount\result \def\eval_expr#1{\global\result=#1\x_relax} \def\eval_expr_to#1#2{\eval_expr{#2}#1=\result} \def\g_eval_expr_to#1#2{\eval_expr{#2}\global#1=\result} % \end{macrocode} % \end{macro}\end{macro}\end{macro} % % \begin{macro}{\rounded_thousandths} % \changes{1.901}{1999/03/06}{Macro added. \cs{scale} changed to % use it. (LH)} % \begin{macro}{\l_rounded_thousandths} % The |\rounded_thousandths| macro divides |\result| % by 1000 and rounds the result to the nearest integer. This is % different from % \begin{quote} % |\global\divide \result \one_thousand| % \end{quote} % since the latter always rounds positive numbers downwards and % negative numbers upwards. % % |\l_rounded_thousandths| does the same thing, but to the register % passed as parameter \#1 and is assigned locally. % \changes{1.913}{2000/03/04}{Macro added. (LH)} % \begin{macrocode} \def\rounded_thousandths{ \global\divide \result \five_hundred \ifodd \result \global\advance \result by \ifnum 0>\result - \fi 1 \fi \global\divide \result \tw@ } % \end{macrocode} % \begin{macrocode} \def\l_rounded_thousandths#1{ \divide #1 \five_hundred \ifodd #1 \advance #1 by \ifnum 0>#1 - \fi\@ne \fi \divide #1 \tw@ } % \end{macrocode} % \end{macro}\end{macro} % % \begin{macro}{\l_inv_scale} % \changes{1.913}{2000/03/11}{Macro added. (LH)} % The |\l_inv_scale| takes two arguments: as \#1 a count register, % and as \#2 a \TeX\ number. |\l_inv_scale| scales \#1 by the inverse % of \#2, if the value in \#1 is $n$ and the value in \#2 is $m$ then % |\l_inv_scale| computes % $$ % \left[ \frac{1000n}{m} \right] \mbox{,} % $$ % where the brackets denote rounding to the nearest integer, and % assigns this number to \#1 locally. % \begin{macrocode} \def\l_inv_scale#1#2{ \multiply #1 \two_thousand \divide #1 #2\x_relax \ifodd#1 \advance #1 \ifnum 0>#1 - \fi\@ne \fi \divide #1 \tw@ } % \end{macrocode} % \end{macro} % % % \begin{macro}{\neg} % \begin{macro}{\add} % \begin{macro}{\sub} % \changes{1.909}{1999/10/20}{Changed priority of first term, so that % unnecessary bracketing is reduced. (LH)} % \begin{macro}{\mul} % \begin{macro}{\div} % \changes{1.909}{1999/10/20}{Changed priority of numerator, so that % unnecessary bracketing is reduced. (LH)} % \begin{macro}{\max} % \begin{macro}{\min} % These macros return an integer expression: % \begin{quote} % |\neg|\marg{integer expression}\\ % |\add|\marg{integer expression}\marg{integer expression}\\ % |\sub|\marg{integer expression}\marg{integer expression}\\ % |\mul|\marg{integer expression}\marg{integer expression}\\ % |\div|\marg{integer expression}\marg{integer expression}\\ % |\max|\marg{integer expression}\marg{integer expression}\\ % |\min|\marg{integer expression}\marg{integer expression}\\ % |\scale|\marg{integer expression}\marg{integer expression} % \end{quote} % % \begin{macrocode} \def\neg#1{#1\global\result=-\result} \def\add#1#2{#1{\a_count=\result\eval_expr{#2} \global\advance\result by \a_count}} \def\sub#1#2{#1{\a_count=\result\eval_expr{#2} \advance\a_count by -\result \global\result=\a_count}} \def\mul#1#2{#1{\a_count=\result\eval_expr{#2} \global\multiply\result by \a_count}} \def\div#1#2{#1{\a_count=\result\eval_expr{#2} \divide\a_count by \result \global\result=\a_count}} \def\max#1#2{#1{\a_count=\result\eval_expr{#2} \ifnum\a_count>\result \global\result=\a_count \fi}} \def\min#1#2{#1{\a_count=\result\eval_expr{#2} \ifnum\a_count<\result \global\result=\a_count \fi}} % % \end{macrocode} % \begin{macrocode} %<*doc> \def\neg#1{\priority8{-\expression6{#1}}} \def\add#1#2{\priority2{\expression2{#1}+\expression2{#2}}} \def\sub#1#2{\priority2{\expression2{#1}-\expression3{#2}}} \def\mul#1#2{\priority4{\expression4{#1}\times\expression4{#2}}} \def\div#1#2{\priority4{\expression4{#1}/\expression5{#2}}} \def\max#1#2{\priority6{\expression6{#1}\sqcup\expression6{#2}}} \def\min#1#2{\priority7{\expression7{#1}\sqcap\expression7{#2}}} % % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\scale} % \begin{macro}{\grabchars@} % \begin{macro}{\grabchars@i} % \begin{macro}{\grabchars@ii} % \begin{macro}{\grabchars@iii} % \begin{macro}{\scale-500X} % The |\scale| macro performs the operation of multiplying the % operands and dividing that result by one thousand. % \begin{macrocode} %<*pkg|misc> \def\scale#1#2{#1{\a_count=\result\eval_expr{#2} \global\multiply\result by \a_count \rounded_thousandths}} % % \end{macrocode} % % |\scale| is often used with a fixed scaling factor, such as for % example 500, as the second argument. In those cases it often makes % more sense to typeset the expression as for example a fraction times % the first argument than to typeset it as |\div{\mul{#1}{#2}}{1000}| % would. Such special cases can be specified by defining a control % sequence \DescribeMacro{\scale-FACTOR}|\scale-|\meta{factor}, where % \meta{factor} is the first four characters of the |#2| integer % expression (all control sequences are |\string|ed), with |X|s added % at the end if the expression is shorter than four characters. % % For the moment, the only scaling factor with such a special % definition is 500. This scaling factor gets typeset as % $\frac{1}{2}$. % \begin{macrocode} %<*doc> \def\scale#1#2{% \x@cs\ifx{scale-\grabchars@#2XXXX\@nil}\x@relax \div{\mul{#1}{#2}}{1000}% \else \csname scale-\grabchars@#2XXXX\@nil\endcsname{#1}{#2}% \fi } \def\grabchars@{\expandafter\grabchars@i\string} \def\grabchars@i#1{#1\expandafter\grabchars@ii\string} \def\grabchars@ii#1{#1\expandafter\grabchars@iii\string} \def\grabchars@iii#1{#1\expandafter\@car\string} \x@cs\def{scale-500X}#1#2{\priority4{\frac{1}{2}\expression4{#1}}} % % \end{macrocode} % \end{macro}\end{macro}\end{macro}\end{macro}\end{macro}\end{macro} % % \begin{macro}{\expression} % \begin{macro}{\priority} % \changes{1.909}{1999/10/20}{Changed condition for \cs{ifnum}, so % that expressions with equal priority will not get bracketed when % nested. (LH)} % \begin{macro}{\identity} % \begin{macro}{\bracket} % \package{fontdoc} uses |\expression| and |\priority| for typsetting % nested arithmetic expressions. |\expression| is called as % \begin{quote} % |\expression|\marg{priority}\marg{expression} % \end{quote} % where \meta{priority} is the minimum priority the outermost % operation in \meta{expression} must have if \meta{expression} is to % be read correctly without bracketing. |\priority| is called as % \begin{quote} % |\priority|\marg{priority}\marg{expression} % \end{quote} % where \meta{priority} is the priority the outermost operation in % \meta{expression}. Its object is to bracket \meta{expression} if % that is necessary. % % \begin{macrocode} %<*doc> \def\expression#1#2{\a@count=#1\relax#2} % \end{macrocode} % \begin{macrocode} \def\priority#1#2{% \ifnum #1<\a@count \let\next=\bracket \else \let\next=\identity \fi \next{#2}} \def\identity#1{#1} \def\bracket#1{(#1)} % % \end{macrocode} % \end{macro} \end{macro} \end{macro} \end{macro} % % \begin{macro}{\ifnumber} % LH 1999/02: The call % \begin{quote} % |\ifnumber|\marg{integer expression}\meta{rel}^^A % \marg{integer expression}|\then| % \end{quote} % can be used to compare the two integer expressions. \meta{rel} may % be |<|, |=|, or |>|. % \begin{macrocode} %<*pkg|misc> \def\ifnumber#1#2#3\then{ \eval_expr_to\a_count{#1} \eval_expr{#3} \ifnum \a_count#2\result \expandafter\if_true \else \expandafter\if_false \fi } % % \end{macrocode} % % Like the other conditionals, |\ifnumber| is treated as being true by % \package{fontdoc}. % \begin{macrocode} %<*doc> \def\ifnumber#1#2#3\then{% \generic@if{$ \expression0{#1} #2 \expression0{#3} $}% } % % \end{macrocode} % \end{macro} % % % \subsection{Comments} % % \changes{1.911}{1999/11/30}{Comment commands included in % \protect\protect\protect\Module{misc} module. (LH)} % % \begin{macro}{\comment} % In \package{fontinst}, |\comment| simply gobbles its argument. % \begin{macrocode} %<*pkg|misc> \let\comment=\gobble_one % % \end{macrocode} % % In \package{fontdoc}, |\comment| starts a new text paragraph and % leaves the argument to be typeset. % \begin{macrocode} %<*doc> \def\comment{\par\noindent} % % \end{macrocode} % \end{macro} % % % \begin{macro}{\begincomment} % \changes{1.900}{1999/02/07}{Command added. (LH)} % \begin{macro}{\endcomment} % \changes{1.900}{1999/02/07}{Command added. (LH)} % Since |\comment| cannot be used for a comment longer than one % paragraph, we also provide the means of introducing longer comments, % by writing % \begin{quote} % |\begincomment| \meta{any amount of text} |\endcomment| % \end{quote} % The names are admittedly not nice from a \LaTeX\ point of view, but % it is hardly worth the cost to implement some kind of environment % processing in \package{fontinst}, just for the sake of this command. % \begin{macrocode} %\let\begincomment=\iffalse %\let\begincomment=\iftrue %\let\endcomment=\fi % \end{macrocode} % \end{macro} \end{macro} % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % \section{Encoding files} % % \changes{1.911}{1999/11/21}{Definitions of encoding file commands % added to \protect\protect\protect\Module{misc}. (LH)} % % \DescribeMacro{\inputetx} % The macro % \begin{quote} % |\inputetx|\marg{filename} % \end{quote} % inputs \meta{filename}|.etx|, ignoring anything between |\relax| % and |\encoding|, and anything after |\endencoding|. % % The file name is transformed to lowercase before opening. % % \begin{macro}{\inputetx} % \begin{macro}{\encoding} % \changes{1.900}{1999/02/07} % {Changed group in fontdoc to \cs{begingroup} type. (LH)} % \begin{macro}{\endencoding} % \changes{1.900}{1999/02/07}{Made it outer. (LH)} % \begin{macrocode} %<*pkg|misc> \def\inputetx#1{ \edef\lowercase_file{\lowercase{ \edef\noexpand\lowercase_file{#1}}} \lowercase_file \slot_number=0 \def\relax{\let\relax=\x_relax\iffalse} \let\encoding=\fi \primitiveinput \lowercase_file.etx\x_relax \let\relax=\x_relax } \let\encoding=\relax \outer\def\endencoding{\endinput} % % \end{macrocode} % % Things are a bit more complicated in \package{fontdoc}, since the % |\relax| \textellipsis\ |\encoding| \textellipsis\ |\endencoding| % markup must be able to work in two different ways. In the main file % only |\encoding| actually does anything---it sets |\slot@number| to % zero. In a file that is being |\inputetx|ed, they must work as with % \package{fontinst}: Everything between |\relax| and |\encoding|, % and everything after |\endencoding| must be ignored. % \multchanges{\cs{inputetx}\cs{inputmtx}}{1.914}{2000/05/27} % {New \package{fontdoc} definition, using \cs{IfFileExists}. (LH)} % \begin{macrocode} %<*doc> \def\inputetx#1{% \begingroup \edef\lowercase@file{\lowercase{% \edef\noexpand\lowercase@file{#1}% }}% \lowercase@file \global\slot@number=0% \IfFileExists{\lowercase@file.etx}{% \def\relax{\let\relax=\x@relax\iffalse}% \let\encoding=\fi \outer\x@cs\def{endencoding}{\endinput}% \@@input \@filef@und \let\relax=\x@relax }{% \PackageError{fontdoc}{File #1.etx not found}% {\@eha\MessageBreak You can \protect\inputetx\space some other file now, if you want.}% } \endgroup } \def\encoding{\begingroup\global\slot@number=0} \outer\def\endencoding{\endgroup} % % \end{macrocode} % \end{macro} \end{macro} \end{macro} % % % \begin{macro}{\setslot} % \begin{macro}{\endsetslot} % \begin{macro}{\slot_name} % \begin{macro}{\slot@name} % |\setslot|\marg{name} \meta{slot commands} |\endsetslot| % % In \package{fontinst}, this sets |\slot_name| to \meta{name} and % calls |\do_slot| at the beginning of the slot and it calls % |\end_do_slot| and increments |\slot_number| by one at the end. % By default, |\do_slot| and |\end_do_slot| do nothing, but this is % over-ridden later. % % \begin{macrocode} %<*pkg|misc> \def\setslot#1{\edef\slot_name{#1}\do_slot} \def\endsetslot{\end_do_slot\advance\slot_number by 1\x_relax} % % \end{macrocode} % % In \package{fontdoc}, the same code sets |\slot@name| to \meta{name}, % prints an |\Aheading| heading for the slot which show the name and % number of the slot, and prints the current automatic slot comment % (if one has been set) at the beginning of the slot. At the end of % the slot, it simply increments |\slot@number| by one. % % \begin{macrocode} %<*doc> \def\setslot#1{\def\slot@name{#1}% \Aheading{Slot \the\slot@number\space `#1'}% \ifslot@comment@ \comment{\slot@comment}\fi} \def\endsetslot{\global\advance\slot@number by 1\relax} % % \end{macrocode} % \end{macro} \end{macro} \end{macro} \end{macro} % % \begin{macro}{\do_slot} % \begin{macro}{\end_do_slot} % \begin{macrocode} %<*pkg|misc> \let\do_slot\empty_command \let\end_do_slot\empty_command % \end{macrocode} % \expandafter\edef \csname saved@macroname\endcsname % {\string\do_new_slot} % \changes{1.910}{1999/11/01}{Macro removed. (LH)} % \end{macro} \end{macro} % % \begin{macro}{\nextslot} % \begin{macro}{\skipslots} % \begin{macro}{\slot_number} % \begin{macro}{\slot@number} % |\nextslot|\marg{integer expression}\\ % |\skipslots|\marg{integer expression} % % In \package{fontinst}, |\nextslot| sets the |\slot_number| and % |\skipslots| addvances the |\slot_number|. % % \begin{macrocode} \newcount\slot_number \def\nextslot#1{\eval_expr_to\slot_number{#1}} \def\skipslots#1{\eval_expr{#1} \advance\slot_number by \result} % % \end{macrocode} % % The commands do the same in \package{fontdoc} as in % \package{fontinst}, although they do it to |\slot@number| instead of % |\slot_number|. % % \begin{macrocode} %<*doc> \newcount\slot@number \def\nextslot#1{\global\slot@number=#1\relax} \def\skipslots#1{\global\advance\slot@number by #1\relax} % % \end{macrocode} % % \ambiguity{What should the arguments to \cs{nextslot} and % \cs{skipslots} be?} At least since v\,1.335 the comments in the % source has said it was an integer expression, but the implementation % was for a \TeX\ number. Alan's v\,1.5 manual and Rowland's v\,1.8 % manual both say the arguments must be numbers. Allowing arbitrary % integer expressions with \package{fontinst} is trivial, the above % implementation copes with that, but \package{fontdoc} gets in % trouble, so what should we do about it? /LH % % AFAIK, all instances of |\nextslot| or |\skipslots| appearing in % present |*.etx| files are explicit numbers, no fancy constructs. /UV % % \changes{1.900}{1999/02/07}{Made changes of \cs{slot@number} % global. (LH)} % \end{macro} \end{macro} \end{macro} \end{macro} % % \begin{macro}{\setleftboundary} % \changes{1.909}{1999/10/19}{doc definition added. (LH)} % \begin{macro}{\endsetleftboundary} % \changes{1.909}{1999/10/19}{doc definition added. (LH)} % \begin{macro}{\do_boundary} % |\setleftboundary|\marg{glyph} \meta{slot commands} % |\endsetleftboundary| % % These macros are like |\setslot| and |\endsetslot|, but they merely % set the left boundary ligkern program, they do not cause any % |CHARACTER| property list to be written. Thus the only metric % information connected to the \meta{glyph} argument that is ever used % is the kerns with this glyph on the left. % % |\do_boundary| and |\endsetleftboundary| are initally |\relax|, but % are later redefined. % % \begin{macrocode} %<*pkg> \def\setleftboundary#1{\edef\slot_name{#1}\do_boundary} \let\endsetleftboundary\x_relax \let\do_boundary\x_relax % %<*doc> \def\setleftboundary#1{\def\slot@name{#1}% \Aheading{Left boundary `#1'}% } \let\endsetleftboundary=\x@relax % %<*misc> \let\setleftboundary=\gobble_one \let\endsetleftboundary=\x_relax % % \end{macrocode} % \end{macro}\end{macro}\end{macro} % % % \begin{macro}{\setrightboundary} % |\setrightboundary|\marg{glyph} % % The |\setrightboundary| macro should be used to set which slot in % the font is used as right boundary marker if that slot is empty. It % advances |\slot_number| just like a |\setslot| \textellipsis\ % |\endsetslot| pair, but since the slot will be left empty, there is % no need for any \meta{slot commands}, and hence there is no need for % a closing |\endset|\textellipsis\ command either. % % If the right boundary marker slot is not to be left empty (often % unavoidable), then one should use the slot command % |\makerightboundary| instead. % % \changes{1.909}{1999/10/19}{doc definition added. (LH)} % \begin{macrocode} %<*pkg|misc> \def\setrightboundary#1{ \makerightboundary{#1} \advance \slot_number 1\x_relax } % %<*doc> \def\setrightboundary#1{% \Aheading{Right boundary slot \the\slot@number\space `#1'}% \global\advance\slot@number by 1\relax } % % \end{macrocode} % \end{macro} % % % \DescribeMacro{\ligature} % \DescribeMacro{\nextlarger} % \DescribeMacro{\varchar} % \DescribeMacro{\endvarchar} % \DescribeMacro{\usedas} % \DescribeMacro{\makerightboundary} % The \meta{slot commands} are: % \begin{quote} % |\ligature|\marg{lig}\marg{glyph}\marg{glyph}\\ % |\nextlarger|\marg{glyph}\\ % |\varchar| \meta{varchar commands} |\endvarchar|\\ % |\usedas|\marg{command}\marg{type}\\ % |\makerightboundary|\marg{glyph} % \end{quote} % By default, these do nothing in \package{fontinst}, but those % defaults are overridden later.\footnote{With the exception of % \cs{usedas}, which is never used at all AFAIK. It was intended to be % used for math font encodings, but that is still on the \texttt{TODO} % list. /LH} In \package{fontdoc}, they generate descriptive headings. % % \begin{macro}{\ligature} % \begin{macrocode} %\let\ligature=\gobble_three %<*doc> \def\ligature#1{\Bheading{Ligature} \csname doc-#1\endcsname} % \end{macrocode} % Symbolic typesetting of |\ligature| programs requires % special processing. % % \begin{macrocode} \x@cs\def{doc-LIG}#1#2{% $\typeset@glyph{\slot@name} * \typeset@glyph{#1} \rightarrow \typeset@glyph{#2}$} \x@cs\def{doc-/LIG}#1#2{% $\typeset@glyph{\slot@name} * \typeset@glyph{#1} \rightarrow \typeset@glyph{\slot@name} * \typeset@glyph{#2}$} \x@cs\def{doc-LIG/}#1#2{% $\typeset@glyph{\slot@name} * \typeset@glyph{#1} \rightarrow \typeset@glyph{#2} * \typeset@glyph{#1}$} \x@cs\def{doc-/LIG/}#1#2{% $\typeset@glyph{\slot@name} * \typeset@glyph{#1} \rightarrow \typeset@glyph{\slot@name} * \typeset@glyph{#2} * \typeset@glyph{#1}$} \x@cs\def{doc-/LIG>}#1#2{% $\typeset@glyph{\slot@name} * \typeset@glyph{#1} \rightarrow \typeset@glyph{\slot@name} + \typeset@glyph{#2}$} \x@cs\def{doc-LIG/>}#1#2{% $\typeset@glyph{\slot@name} * \typeset@glyph{#1} \rightarrow \typeset@glyph{#2} + \typeset@glyph{#1}$} \x@cs\def{doc-/LIG/>}#1#2{% $\typeset@glyph{\slot@name} * \typeset@glyph{#1} \rightarrow \typeset@glyph{\slot@name} + \typeset@glyph{#2} * \typeset@glyph{#1}$} \x@cs\def{doc-/LIG/>>}#1#2{% $\typeset@glyph{\slot@name} * \typeset@glyph{#1} \rightarrow \typeset@glyph{\slot@name} + \typeset@glyph{#2} + \typeset@glyph{#1}$} % % \end{macrocode} % \end{macro} % % % \begin{macro}{\nextlarger} % \begin{macro}{\usedas} % \begin{macro}{\makerightboundary} % \begin{macrocode} %<*pkg|misc> \let\nextlarger=\gobble_one \let\usedas=\gobble_two \let\makerightboundary=\gobble_one % % \end{macrocode} % \begin{macrocode} %<*doc> \def\nextlarger#1{\Bheading{Next larger} \typeset@glyph{#1}} \def\makerightboundary#1{% \Bheading{Right boundary marker slot} designation \typeset@glyph{#1}% } % % \end{macrocode} % \missing{doc}{\usedas} % \end{macro} \end{macro} \end{macro} % % % \DescribeMacro{\vartop} % \DescribeMacro{\varmid} % \DescribeMacro{\varbot} % \DescribeMacro{\varrep} % The \meta{varchar commands} are: % \begin{quote} % |\vartop|\marg{glyph}\\ % |\varmid|\marg{glyph}\\ % |\varbot|\marg{glyph}\\ % |\varrep|\marg{glyph} % \end{quote} % These too do by default, which is overridden later, nothing in % \package{fontinst} but typeset descriptive headings in \package{fontdoc}. % % \begin{macro}{\varchar} % \begin{macro}{\vartop} % \begin{macro}{\varmid} % \begin{macro}{\varbot} % \begin{macro}{\varrep} % \begin{macro}{\endvarchar} % \begin{macrocode} %<*pkg|misc> \let\varchar=\empty_command \let\vartop=\gobble_one \let\varmid=\gobble_one \let\varbot=\gobble_one \let\varrep=\gobble_one \let\endvarchar=\empty_command % % \end{macrocode} % \begin{macrocode} %<*doc> \def\varchar{\Bheading{Extensible glyph:}} \def\vartop#1{\Bheading{Top} \typeset@glyph{#1}} \def\varmid#1{\Bheading{Middle} \typeset@glyph{#1}} \def\varbot#1{\Bheading{Bottom} \typeset@glyph{#1}} \def\varrep#1{\Bheading{Repeated} \typeset@glyph{#1}} \let\endvarchar\relax % % \end{macrocode} % \end{macro} \end{macro} \end{macro} \end{macro} \end{macro} \end{macro} % % % \begin{macro}{\useexamplefont} % \begin{macro}{\slotexample} % \begin{macro}{\setslotcomment} % \begin{macro}{\resetslotcomment} % \begin{macro}{\unsetslotcomment} % \begin{macro}{\slot@comment} % \begin{macro}{\slot@font} % As of v\,1.8 of \package{fontinst}, we have added an interface % for automatic documentation of encoding files, which has been % developed by Matthias Clasen as part of his work on math fonts. % The implementation was slightly modified and integrated into % this version by Ulrik Vieth. % % |\setslotcomment| defines a default slot comment, stored in the % variable |\slot@comment|, which is subsequently used to annotate % all |\setslot| commands. The slot comment can be changed by % |\resetslotcomment| or turned off by |\unsetslotcomment|. % % |\useexamplefont| defines a default font, |\slot@font|, which % may be referenced by calling |\slotexample| in slot comments to % display the character or symbol allocated to the current slot. % % Taking advantage of this mechanism, it is possible to write: % \begin{quote} % |\useexamplefont{FONT}|\\[0.5\baselineskip] % |\setslotcomment{The symbol `\slotexample'.}|\\ % |\setslot{FOO}\endsetslot|\\ % |\setslot{BAR}\endsetslot|\\ % |\resetslotcomment{The character `\slotexample'.}|\\ % |\setslot{BAZ}\endsetslot| % \end{quote} % instead of having to write: % \begin{quote} % |\usepackage{PACKAGE-to-use-symbols-from-FONT}|\\[0.5\baselineskip] % |\setslot{FOO}\comment{The symbol `\foo'.}\endsetslot|\\ % |\setslot{BAR}\comment{The symbol `\bar'.}\endsetslot|\\ % |\setslot{BAZ}\comment{The character `\baz'.}\endsetslot| % \end{quote} % % These macros never do anything in \package{fontinst}, they just % gobble their arguments. % \begin{macrocode} %<*pkg|misc> \let\useexamplefont=\gobble_one \let\slotexample=\empty_command \let\setslotcomment=\gobble_one \let\resetslotcomment=\gobble_one \let\unsetslotcomment=\empty_command % % \end{macrocode} % \begin{macrocode} %<*doc> \newif\ifslot@comment@ \slot@comment@false \def\slot@comment{} \def\setslotcomment#1{% \slot@comment@true \gdef\slot@comment{#1}} \def\resetslotcomment#1{% \gdef\slot@comment{#1}} \def\unsetslotcomment{% \slot@comment@false \gdef\slot@comment{}} % \end{macrocode} % % \begin{macrocode} \let\slot@font=\nullfont \def\useexamplefont#1{\font\slot@font=#1 } \def\slotexample{{\slot@font\char\the\slot@number}} % % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % \section{Metric files} % \label{Sec:Metric files} % % \changes{1.911}{1999/11/17}{Definitions of metric file commands % added to \protect\protect\protect\Module{misc}. (LH)} % % \DescribeMacro{\inputmtx} % The macro % \begin{quote} % |\inputmtx|\marg{filename} % \end{quote} % inputs \meta{filename}|.mtx|, ignoring anything between |\relax| and % |\metrics|, and anything after |\endmetrics|. % % \begin{macro}{\inputmtx} % \begin{macro}{\metrics} % \changes{1.914}{2000/05/26}{Fixed typo: \cs{x@relax} instead of % \cs{x_relax}. (LH)} % \begin{macro}{\endmetrics} % \changes{1.900}{1999/02/08}{Made it outer. (LH)} % \begin{macro}{\endmetrics_text} % \begin{macro}{\endmetrics@hook} % The |\endmetrics_text| macro expands to |\endmetrics| (eleven % `other' tokens, not one control sequence token). It is used instead % of |\string\endmetrics|, which does not work since |\endmetrics| is % outer. % \begin{macrocode} %<*pkg|misc> \def\inputmtx#1{ \def\relax{\let\relax=\x_relax\iffalse} \let\metrics=\fi \primitiveinput #1.mtx\x_relax \let\relax=\x_relax } \let\metrics=\x_relax \edef\endmetrics_text{\string\endmetrics} \outer\def\endmetrics{\endinput} % % \end{macrocode} % |\inputmtx| used to set |\a_count|, but we haven't been able to % find a reason for this, so it was removed. % % In \package{fontdoc}, the |\metrics| and |\endmetrics| macros % initially just define a group, but |\inputmtx| redefines them to % work as they do in \package{fontinst}. |\endmetrics@hook| is a % macro that gets executed just before the |\endgroup| in % |\endmetrics|; it is normally |\@empty|, and it is set to this value % at each |\metrics|, but the metric package system redefines it. % \multchanges{\cs{endmetrics_hook}}{1.914}{2000/05/27}{Macro added. % (LH)} % \multchanges{\cs{inputetx}\cs{inputmtx}}{1.914}{2000/05/27} % {New \package{fontdoc} definition, using \cs{IfFileExists}. (LH)} % \begin{macrocode} %<*doc> \def\inputmtx#1{% \begingroup \edef\lowercase@file{\lowercase{% \edef\noexpand\lowercase@file{#1}% }}% \lowercase@file \let\endmetrics@hook=\@empty \IfFileExists{\lowercase@file.mtx}{% \skip@mtx@preamble \@@input \@filef@und \let\relax=\x@relax }{% \PackageError{fontdoc}{File #1.mtx not found}% {\@eha\MessageBreak You can \protect\inputmtx\space some other file now, if you want.}% } \endmetrics@hook \endgroup } \def\skip@mtx@preamble{% \def\relax{\let\relax=\x@relax\iffalse}% \let\metrics=\fi \outer\x@cs\def{endmetrics}{\endinput}% } \def\metrics{\begingroup\let\endmetrics@hook=\@empty} \outer\def\endmetrics{\endmetrics@hook\endgroup} % % \end{macrocode} % \end{macro}\end{macro}\end{macro}\end{macro}\end{macro} % % % \begin{macro}{\ProvidesMtxPackage} % \begin{switch}{@mtxpackage@headed@} % \begin{macro}{\announce@package} % \begin{macro}{\finish@package} % \multchanges{\cs{ProvidesMtxPackage}\cs{usemtxpackage}}{1.914} % {2000/05/27}{New \package{fontdoc} implementation---the packages % are actually loaded (they have to, since they can define % commands). Multiple loading is prevented as in % \package{fontinst}. (LH)} % The call % \begin{quote} % |\ProvidesMtxPackage|\marg{package~name} % \end{quote} % signals to the package managing system that there is no need to load % this package again. % \begin{macrocode} %\def\ProvidesMtxPackage#1{\x_cs\let{pack-#1}P} %<*doc> \def\ProvidesMtxPackage#1{% \endmetrics@hook \@mtxpackage@headed@false \everypar={\announce@package{#1}}% \def\endmetrics@hook{\finish@package{#1}} \global\x@cs\let{FD@pack-#1}\@empty } % \end{macrocode} % \begin{macrocode} \newif\if@mtxpackage@headed@ % \end{macrocode} % \begin{macrocode} \def\announce@package#1{% \everypar={}% \@mtxpackage@headed@true \Aheading{Metric package \textsf{#1}:}% } % \end{macrocode} % \begin{macrocode} \def\finish@package#1{% \if@mtxpackage@headed@ \Aheading{End of metric package \textsf{#1}.}% \else \everypar={}% \Aheading{(Metric package \textsf{#1}.)}% \fi \par\addvspace\medskipamount } % % \end{macrocode} % \end{macro}\end{macro}\end{switch}\end{macro} % % % \begin{macro}{\usemtxpackage} % The call % \begin{quote} % |\usemtxpackage|\marg{package~list} % \end{quote} % inputs those of the packages in the list that have not been loaded % yet (i.e., those for which no |\ProvidesMtxPackage| has been made). % Each package is assumed to reside in the metric file that % |\inputmtx| loads when given the name of the package as argument. % % The call % \begin{quote} % |\usemtxpackage|\oarg{filename}\marg{package~list} % \end{quote} % inputs the packages in the list if at least one of them has not been % loaded yet. In this case, all the packages are assumed to reside in % the single metric file that |\inputmtx| loads when given % \meta{filename} as argument. % % \begin{macrocode} %<*pkg> \def\usemtxpackage{\futurelet\next_token\test_UseMtxPkg_arguments} \def\test_UseMtxPkg_arguments{\ifx\next_token[ \expandafter\mtx_package_given_file \else \expandafter\mtx_package_separate_files \fi } % \end{macrocode} % \begin{macrocode} \def\mtx_package_given_file[#1]#2{ \_a_false \process_csep_list\load_true_unless_loaded #2,\process_csep_list, \if_a_ \inputmtx{#1} \fi } \def\load_true_unless_loaded#1{ \x_cs\ifx{pack-#1}P\else\_a_true\fi } % \end{macrocode} % \begin{macrocode} \def\mtx_package_separate_files#1{ \process_csep_list\load_file_unless_loaded #1,\process_csep_list, } \def\load_file_unless_loaded#1{ \x_cs\ifx{pack-#1}P\else \inputmtx{#1} \fi } % % \end{macrocode} % \begin{macrocode} %<*doc> \newcommand\usemtxpackage[2][\x@relax]{% \ifx \x@relax#1% \@for\@tempa:=#2\do{% \x@cs\ifx{FD@pack-\@tempa}\@empty \else \inputmtx{\@tempa}% \fi }% \else \@tempswafalse \@for\@tempa:=#1\do{% \x@cs\ifx{FD@pack-\@tempa}\@empty \else \@tempswatrue \fi }% \if@tempswa \inputmtx{#2}% \fi \fi } % % \end{macrocode} % \end{macro} % % % \subsection{Kerning information} % % \DescribeMacro{\l-NAME} % \DescribeMacro{\r-NAME} % \DescribeMacro{\k} % \DescribeMacro{\AMOUNT} % The kerning information is kept in the macros |\l-|\meta{name} and % |\r-|\meta{name}, containing information about how \meta{name} kerns on % the left and on the right, respectively. The |\l-|\meta{name} macro % should expand out to a series of % \begin{quote} % |\k|\,|\r-|\meta{name}\,|\|\meta{amount} % \end{quote} % control sequences, and vice versa. Examples of |\|\meta{amount} % control sequences are: |\0|, |\1|, |\1000|, |\-50|, |\33|; these % corresponds to the kern amounts $0$, $1$, $1000$ (which would be % grotesquely large), $-50$, and $33$ respectively. % % % \begin{macro}{\setkern} % |\setkern|\marg{glyph1}\marg{glyph2}\marg{integer expression} % % Sets a kern pair between \meta{glyph1} and \meta{glyph2} to the % specified value, which is typically a value returned by % |\kerning|\marg{glyph3}\marg{glyph4}. If there already is a kern % set between \meta{glyph1} and \meta{glyph2} then this will not affect % the output, but it will use up another 3 units of token memory. % % \begin{macrocode} %<*pkg> \def\setkern#1#2#3{ \x_cs\ifx{i-rawscale}\x_relax \expandafter\set_kern \csname~r-#1\expandafter\endcsname \csname~l-#2\endcsname{#3} \else \expandafter\set_kern \csname~r-#1\expandafter\endcsname \csname~l-#2\endcsname{\scale{#3}{\int{rawscale}}} \fi } \def\set_kern#1#2#3{ \eval_expr{#3} \expandafter\set_kern_cs\csname\the\result\endcsname#1#2 } \def\set_kern_cs#1#2#3{ \add_to#2{\k#3#1} \add_to#3{\k#2#1} } % % \end{macrocode} % \begin{macrocode} %<*doc> \def\setkern#1#2#3{% \Bheading{Kern} ${\typeset@glyph{#1} + \typeset@glyph{#2}} \rightarrow \expression0{#3}$} % %\let\setkern=\gobble_three % \end{macrocode} % \end{macro} % % \begin{macro}{\resetkern} % |\resetkern|\marg{glyph1}\marg{glyph2}\marg{integer expression} % % Resets the kern pair between \meta{glyph1} and \meta{glyph2} to % the specified value. Note however that this does not relieve \TeX\ % of the burden to remember the previous kerning pair between these % two glyphs (if there was one). % % \begin{macrocode} %<*pkg> \def\resetkern#1#2#3{ \x_cs\ifx{i-rawscale}\x_relax \expandafter\reset_kern \csname~r-#1\expandafter\endcsname \csname~l-#2\endcsname{#3} \else \expandafter\reset_kern \csname~r-#1\expandafter\endcsname \csname~l-#2\endcsname{\scale{#3}{\int{rawscale}}} \fi } \def\reset_kern#1#2#3{ \eval_expr{#3} \expandafter\reset_kern_cs\csname\the\result\endcsname#1#2 } \def\reset_kern_cs#1#2#3{ \prep_to#2{\k\expandafter#3\expandafter#1} \prep_to#3{\k\expandafter#2\expandafter#1} } % % \end{macrocode} % \begin{macrocode} %<*doc> \def\resetkern#1#2#3{% \Bheading{Override kern} ${\typeset@glyph{#1} + \typeset@glyph{#2}} \rightarrow \expression0{#3}$} % % \end{macrocode} % \end{macro} % % \begin{macro}{\setleftkerning} % \begin{macro}{\setrightkerning} % \begin{macro}{\setleftrightkerning} % |\setleftkerning|\marg{glyph1}\marg{glyph2}\marg{scaled}\\ % |\setrightkerning|\marg{glyph1}\marg{glyph2}\marg{scaled}\\ % |\setleftrightkerning|\marg{glyph1}\marg{glyph2}\marg{scaled} % % Sets left or right kerning of \meta{glyph1} to that of \meta{glyph2} % scaled by \meta{scaled} (which is an integer expression). % |\setleftrightkerning| does both. % % \begin{macrocode} %<*pkg> \def\setleftkerning#1#2#3{ \eval_expr_to\b_count{#3} \expandafter\set_kerning \csname~l-#1\expandafter\endcsname \csname~l-#2\endcsname } \def\setrightkerning#1#2#3{ \eval_expr_to\b_count{#3} \expandafter\set_kerning \csname~r-#1\expandafter\endcsname \csname~r-#2\endcsname } \def\setleftrightkerning#1#2#3{ \eval_expr_to\b_count{#3} \expandafter\set_kerning \csname~l-#1\expandafter\endcsname \csname~l-#2\endcsname \expandafter\set_kerning \csname~r-#1\expandafter\endcsname \csname~r-#2\endcsname } \def\set_kerning#1#2{ \if\b_count=\one_thousand \def\k##1##2{ \set_kern_cs##2##1#1 } \else \def\k##1##2{ \set_kern##1#1{ \scale\b_count{\expandafter\gobble_one\string##2} } } \fi #2 } % % \end{macrocode} % \begin{macrocode} %<*doc> \def\setleftkerning#1#2#3{% \Bheading{Kern} \typeset@glyph{#1} on the left like \typeset@glyph{#2} scaled $\expression0{#3}$} \def\setrightkerning#1#2#3{% \Bheading{Kern} \typeset@glyph{#1} on the right like \typeset@glyph{#2} scaled $\expression0{#3}$} \def\setleftrightkerning#1#2#3{% \Bheading{Kern} \typeset@glyph{#1} on the left and right like \typeset@glyph{#2} scaled $\expression0{#3}$} % % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\kerning} % |\kerning|\marg{glyph1}\marg{glyph2} % % Returns the value of kern pair between \meta{glyph1} and % \meta{glyph2} as an integer. Returns a value of zero if such a kern % pair doesn't exist. % % \begin{macrocode} %<*pkg> \def\kerning#1#2{0\x_relax \def\k##1{\csname~set-\string##1\endcsname\gobble_one} \bgroup \x_cs\def{set-\string\l-#2}##1##2{ \global\result=\expandafter\gobble_one\string##2\egroup } \csname~r-#1\endcsname \csname~set-\string\l-#2\endcsname\gobble_one{00} } % % \end{macrocode} % \changes{1.909}{1999/10/19}{A use of \#1 where it should have % been \#2 was corrected. (LH)} % \begin{macrocode} %\def\kerning#1#2{k(\typeset@glyph{#1})(\typeset@glyph{#2})} % \end{macrocode} % \end{macro} % % \begin{macro}{\ifiskern} % |\ifiskern|\marg{glyph1}\marg{glyph2}|\then| % % This command tests if there is a kern pair between \meta{glyph1} and % \meta{glyph2}. It's hard to say if there is a use for it, but it is % included for symmetry. % % \begin{macrocode} %<*pkg> \def\ifiskern#1#2\then{ \def\k##1##2{\ifx T##1 \let\k\gobble_two \fi} \bgroup \x_cs\let{l-#2}T \csname r-#1\endcsname \expandafter\egroup \ifx\k\gobble_two } % % \end{macrocode} % \begin{macrocode} %<*doc> \def\ifiskern#1#2\then{% \generic@if{kern \typeset@glyph{#1}${}+{}$\typeset@glyph{#2} set}} % % \end{macrocode} % \end{macro} % % % \begin{macro}{\unsetkerns} % |\unsetkerns|\marg{left~glyph~list}\marg{right~glyph~list} % % This command unsets all kerns with a glyph in the \meta{left~glyph~list} % on the left and a glyph in the \meta{right~glyph~list} on the right. % The lists themselves are ordinary comma-separated lists. Unlike % |\setkern| and |\resetkern|, |\unsetkerns| actually removes the % kerning pairs from \TeX's memory. % % The implementation itself simply goes through |\r-|\meta{left~glyph} % for each element \meta{left~glyph} in \meta{left~glyph~list} and % |\l-|\meta{right~glyph} for each element \meta{right~glyph} in % \meta{right~glyph~list}, removing each |\k|\meta{token}\meta{token} % tripple that refers to a glyph from the opposite list as it goes % along. To make this test reasonably fast, the routine first ``marks'' % the glyphs in the other list by setting the control sequences % |\slots-|\meta{glyph} to |U| (the letter token U). This mark is % later removed when the |\r-|\meta{glyph} or |\l-|\meta{glyph} % respectively control sequences have been gone through; the % |\slots-|\meta{glyph} control sequences are then set to |\relax|. % % \begin{macrocode} %<*pkg> \def\unsetkerns#1#2{ \let\k\k_unless_to_U \process_csep_list\make_slots_U#1,\process_csep_list, \def\do##1{\x_cs\main_remove_Us{l-##1}} \process_csep_list\do#2,\process_csep_list, \process_csep_list\make_slots_relax#1,\process_csep_list, \process_csep_list\make_slots_U#2,\process_csep_list, \def\do##1{\x_cs\main_remove_Us{r-##1}} \process_csep_list\do#1,\process_csep_list, \process_csep_list\make_slots_relax#2,\process_csep_list, } \def\make_slots_U#1{\x_cs\let{slots-#1}U} \def\make_slots_relax#1{\x_cs\let{slots-#1}\x_relax} \def\k_unless_to_U#1#2{ \x_cs\ifx{slots-\expandafter\gobble_three\string#1}U \else \noexpand\k\noexpand#1\noexpand#2 \fi } \def\main_remove_Us#1{ \ifx#1\x_relax \else \edef#1{#1} \ifx#1\empty_command \let#1\x_relax \fi \fi } % % \end{macrocode} % \begin{macrocode} %<*doc> \def\unsetkerns#1#2{% \Bheading{Remove} all kerning pairs in \print@csep@list{\fam0}{\{#1\}\times\{#2\}}.% } % % \end{macrocode} % \end{macro} % % % \begin{macro}{\noleftkerning} % \changes{1.906}{1999/07/30}{Macro added. (LH)} % \begin{macro}{\norightkerning} % \changes{1.906}{1999/07/30}{Macro added. (LH)} % \begin{macro}{\noleftrightkerning} % \changes{1.906}{1999/07/30}{Macro added. (LH)} % The argument of these commands is the name of a glyph. The commands % removes all kerns on the left, on the right, and on both sides % respectively, of this glyph. % % \begin{macrocode} %<*pkg> \def\noleftkerning#1{\no_kerning{l}{#1}} \def\norightkerning#1{\no_kerning{r}{#1}} \def\noleftrightkerning#1{\no_kerning{l}{#1}\no_kerning{r}{#1}} % % \end{macrocode} % \begin{macrocode} %<*doc> \def\noleftkerning#1{% \Bheading{Remove kerns} on the left of glyphs in \print@csep@list{\fam0}{\{#1\}}.} \def\norightkerning#1{% \Bheading{Remove kerns} on the right of glyphs in \print@csep@list{\fam0}{\{#1\}}.} \def\noleftrightkerning#1{% \Bheading{Remove kerns} on any side of glyphs in \print@csep@list{\fam0}{\{#1\}}.} % % \end{macrocode} % \end{macro}\end{macro}\end{macro} % % \begin{macro}{\no_kerning} % \changes{1.906}{1999/07/30}{Macro added. (LH)}^^A % \changes{1.906}{1999/08/01}{Macro thoroughly rewritten. (LH)}^^A % This macro is called as % \begin{quote} % |\no_kerning|\marg{side}\marg{glyph list} % \end{quote} % where \meta{side} is |l| or |r|, and \meta{glyph list} is a % comma-separated list of glyph names. The macro unsets all kerns on % the \meta{side} side of the glyphs in the \meta{glyph list}. % % \begin{macrocode} %<*pkg> \def\no_kerning#1#2{ \let\k\no_kerning_i \def\do##1{\csname #1-##1\endcsname} \bgroup \aftergroup\def \aftergroup\a_macro \aftergroup{ \process_csep_list\do #2,\process_csep_list, \aftergroup} \egroup \def\do##1{\expandafter\let \csname #1-##1\endcsname \x_relax} \process_csep_list\do #2,\process_csep_list, \let\k\no_kerning_ii \def\do##1{\edef##1{##1}} \a_macro } % \end{macrocode} % \begin{macro}{\no_kerning_i} % The |\no_kerning_i| macro is used by |\no_kerning| in constructing % a list of all glyphs that a glyph in the \meta{glyph list} has a % \meta{side} kern to, while avoiding repetitions. % \begin{macrocode} \def\no_kerning_i#1#2{ \ifx #1\x_relax \else \aftergroup\do \aftergroup#1 \let #1\x_relax \fi } % \end{macrocode} % \end{macro} % \begin{macro}{\no_kerning_ii} % The |\no_kerning_ii| macro is similar to the |\k_unless_to_U| % macro. % \begin{macrocode} \def\no_kerning_ii#1#2{ \ifx #1\x_relax \else \noexpand\k \noexpand#1 \noexpand#2 \fi } % % \end{macrocode} % \end{macro} % \end{macro} % % % % \subsection{Glyph information} % \label{Ssec:Glyph-info} % % The glyph information is kept in the macros % \DescribeMacro{\g-NAME}|\g-|\meta{name}, which expands out to: % \begin{quote} % \marg{width}\marg{height}\marg{depth}\marg{italic}^^A % \marg{mapcommands}\marg{mapfonts} % \end{quote} % where the \meta{mapcommands} will write out VPL |MAP| fragments to a % |.vpl| file, and the \meta{mapfonts} will produce any |MAPFONT| % instructions that are needed. % % % \begin{macro}{\typeset@glyph} % \changes{1.909}{1999/10/20}{Macro added, and most commands that % print a glyph name changed to use this macro. (LH)} % The |\typeset@glyph| macro is analogous to |\typeset@string| and % friends. % \begin{macrocode} %\let\typeset@glyph=\typeset@string % \end{macrocode} % \end{macro} % % % \begin{macro}{\width} % \begin{macro}{\height} % \begin{macro}{\depth} % \begin{macro}{\italic} % |\width|\marg{glyph}\\ % |\height|\marg{glyph}\\ % |\depth|\marg{glyph}\\ % |\italic|\marg{glyph} % % In \package{fontinst}, these macros return the width, height, % depth, and italic correction of \meta{glyph} as an integer. % \begin{macrocode} %<*pkg> \def\width{\glyph_parameter\first_of_six} \def\height{\glyph_parameter\second_of_six} \def\depth{\glyph_parameter\third_of_six} \def\italic{\glyph_parameter\fourth_of_six} % % \end{macrocode} % % In \package{fontdoc}, they print symbolic representations for the % corresponding integer expressions. % \begin{macrocode} %<*doc> \def\width#1{w(\typeset@glyph{#1})} \def\height#1{h(\typeset@glyph{#1})} \def\depth#1{d(\typeset@glyph{#1})} \def\italic#1{i(\typeset@glyph{#1})} % % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % % \begin{macro}{\mapcommands} % \begin{macro}{\mapfonts} % These are similar to |\width| and its companions, but they are not % user level commands. % \begin{macrocode} %<*pkg> \def\mapcommands{\glyph_parameter\fifth_of_six} \def\mapfonts{\glyph_parameter\sixth_of_six} % % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\glyph_parameter} % \begin{macro}{\first_of_six} % \begin{macro}{\second_of_six} % \begin{macro}{\third_of_six} % \begin{macro}{\fourth_of_six} % \begin{macro}{\fifth_of_six} % \begin{macro}{\sixth_of_six} % \begin{macro}{\glyph_metrics} % These macros are used to define |\width| and its friends. % |\glyph_parameter| takes one of the other seven for its first % argument and a glyph name for its second argument. The % |\glyph_metrics| macro can be used if one wants to get all the % metric variables at once. % \begin{macrocode} %<*pkg> \def\glyph_parameter#1#2{ \expandafter\expandafter\expandafter #1\csname g-#2\endcsname } % \end{macrocode} % \begin{macrocode} \def\first_of_six#1#2#3#4#5#6{#1} \def\second_of_six#1#2#3#4#5#6{#2} \def\third_of_six#1#2#3#4#5#6{#3} \def\fourth_of_six#1#2#3#4#5#6{#4} \def\fifth_of_six#1#2#3#4#5#6{#5} \def\sixth_of_six#1#2#3#4#5#6{#6} % \end{macrocode} % \begin{macrocode} \def\glyph_metrics#1#2#3#4#5#6{ \a_count=#1 \b_count=#2 \c_count=#3 \d_count=#4~ } % \end{macrocode} % \end{macro} \end{macro} \end{macro} \end{macro} \end{macro} % \end{macro} \end{macro} \end{macro} % % % \begin{macro}{\saved_scale} % \begin{macro}{\saved_mapfont} % \begin{macro}{\saved_raw} % \begin{macro}{\saved_rule} % \begin{macro}{\saved_special} % \begin{macro}{\saved_warning} % \begin{macro}{\saved_movert} % \begin{macro}{\saved_moveup} % \begin{macro}{\saved_push} % \begin{macro}{\saved_pop} % These are the commands allowed inside a glyph. They are initally % set to |\relax|, so we can |\edef| with them safely. % \begin{macrocode} \let\saved_scale\x_relax \let\saved_mapfont\x_relax \let\saved_raw\x_relax \let\saved_rule\x_relax \let\saved_special\x_relax \let\saved_warning\x_relax \let\saved_movert\x_relax \let\saved_moveup\x_relax \let\saved_push\x_relax \let\saved_pop\x_relax % \end{macrocode} % \end{macro} \end{macro} \end{macro} \end{macro} \end{macro} % \end{macro} \end{macro} \end{macro} \end{macro} \end{macro} % % When the glyph is being constructed by % \begin{quote} % |\setglyph|\marg{glyph} \meta{glyph commands} |\endsetglyph| % \end{quote} % the values of each of these parameters are kept in the following % variables. Except for |\glyph_width|, these are kept globally, % so they survive through |\push| \textellipsis\ |\pop| pairs. In % addition, the current vertical offset is kept locally in % |\glyph_voffset|. The |\glyph_maxhpos| variable globally keeps track % of the largest horizontal offset position reached so far (with the % possible exception of the current position, i.e.\ width, which may % well be larger). % % % \begin{macro}{\glyph_width} % \begin{macro}{\glyph_height} % \begin{macro}{\glyph_depth} % \begin{macro}{\glyph_italic} % \begin{macro}{\glyph_map_commands} % \begin{macro}{\glyph_map_fonts} % \begin{macro}{\glyph_voffset} % \begin{macro}{\glyph_maxhpos} % \changes{1.903}{1999/05/20}{Variable added. (LH)} % \begin{macrocode} \newcount\glyph_width \newcount\glyph_height \newcount\glyph_depth \newcount\glyph_italic \newtoks\glyph_map_commands \newtoks\glyph_map_fonts \newcount\glyph_voffset \newcount\glyph_maxhpos % \end{macrocode} % \end{macro} \end{macro} \end{macro} \end{macro} \end{macro} % \end{macro} \end{macro} \end{macro} % % \begin{macro}{\setglyph} % \begin{macro}{\gobble_glyph} % The |\setglyph|\marg{name} command defines |\g-|\meta{name}, % unless |\g-|\meta{name} has already been defined. % % The reason |\g-|\meta{name} is defined before calling |\resetglyph| % is to make it possible to refer to ``the glyph constructed so far'' % using |\width|\marg{name}, |\height|\marg{name}, etc. % \begin{macrocode} \def\setglyph#1{ \ifisglyph{#1}\then \expandafter\gobble_glyph \else \x_cs\def{g-#1}{{\the\glyph_width}{\the \glyph_height}{\the\glyph_depth}{\the\glyph_italic}{\the \glyph_map_commands}{\the\glyph_map_fonts}} \resetglyph{#1} \fi } \long\def\gobble_glyph#1\endsetglyph{} % % \end{macrocode} % \begin{macrocode} %\def\setglyph#1{\Aheading{Glyph `#1'}} %\long\def\setglyph#1\endsetglyph{} % \end{macrocode} % \end{macro} \end{macro} % % \begin{macro}{\resetglyph} % The |\resetglyph|\marg{name} command redefines |\g-|\meta{name}, % regardless of whether |\g-|\meta{name} has already been defined. % % \begin{macrocode} %<*pkg> \def\resetglyph#1{ \def\glyphname{#1} \glyph_width=0 \global\glyph_height=0 \global\glyph_depth=0 \global\glyph_italic=0 \glyph_voffset=0 \global\glyph_maxhpos=0 \global\glyph_map_commands={} \global\glyph_map_fonts={} } % % \end{macrocode} % \begin{macrocode} %\def\resetglyph#1{\Aheading{Reset glyph `#1'}} % \end{macrocode} % \end{macro} % % \begin{macro}{\endsetglyph} % \begin{macro}{\endresetglyph} % \begin{macrocode} %<*pkg> \def\endsetglyph{ \x_cs\edef{g-\glyphname} {{\the\glyph_width}{\the\glyph_height} {\the\glyph_depth}{\the\glyph_italic} {\the\glyph_map_commands}{\the\glyph_map_fonts}} } \let\endresetglyph=\endsetglyph % % \end{macrocode} % \begin{macrocode} %<*doc> \def\endsetglyph{} \def\endresetglyph{} % % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\setscaledrawglyph} % \begin{macro}{\setrawglyph} % The |\setscaledrawglyph| has the syntax % \begin{isyntax} % |\setscaledrawglyph|\marg{glyph}\marg{font}\marg{design size}^^A % \marg{scale}\penalty0\marg{slot}\penalty0\marg{width}\penalty0 % \marg{height}\penalty0\marg{depth}\penalty0\marg{italic} % \end{isyntax} % It is a generalized form of the old |\setrawglyph| command, which % has the syntax % \begin{isyntax} % |\setrawglyph|\marg{glyph}\marg{font}\marg{design size}^^A % \marg{slot}\penalty0\marg{width}\penalty0 % \marg{height}\penalty0\marg{depth}\penalty0\marg{italic} % \end{isyntax} % |\setrawglyph| is now syntactic sugar for the equivalent call of % |\set|\-|scaled|\-|raw|\-|glyph|. % \begin{macrocode} %<*pkg> \def\setrawglyph#1#2#3{ \setscaledrawglyph{#1}{#2}{#3}\one_thousand } % \end{macrocode} % % These commands are generated automatically, when an |.mtx| file is % written out by |\afmtomtx|, |\pltomtx|, or |\mtxtomtx|. % % To illustrate the difference between |\setrawglyph| and the new % |\set|\-|scaled|\-|raw|\-|glyph|, note that % \begin{quote} % |\setscaledrawglyph{fscaled}{xfont}{10pt}{800}{102}%|\\ % | {300}{600}{300}{40}| % \end{quote} % produces the same \texttt{fscaled} glyph as % \begin{quote} % |\setrawglyph{f}{xfont}{10pt}{102}{375}{750}{375}{50}|\\ % |\setglyph{fscaled} \glyph{f}{800} \endsetglyph| % \end{quote} % % \begin{macrocode} \def\setscaledrawglyph#1#2#3#4#5#6#7#8#9{ \if_undefined{g-#1}\then \eval_expr{#4} \ifnum \result=\one_thousand \let\a_macro\identity_one \else \edef\a_macro##1{\saved_scale{\the\result}{##1}} \fi \eval_expr_to\a_count{#6} \eval_expr_to\b_count{#7} \eval_expr_to\c_count{#8} \eval_expr_to\d_count{#9} \ifisint{i-rawscale}\then \e_count=\int{rawscale} \multiply \a_count \e_count \l_rounded_thousandths\a_count \multiply \b_count \e_count \l_rounded_thousandths\b_count \multiply \c_count \e_count \l_rounded_thousandths\c_count \multiply \d_count \e_count \l_rounded_thousandths\d_count \edef\a_macro##1{\saved_scale{\the\e_count}{\a_macro{##1}}} \fi \x_cs\edef{g-#1}{ {\the\a_count} {\the\b_count} {\the\c_count} {\the\d_count} {\a_macro{\saved_raw{#2}{#5}{#1}}} {\a_macro{\saved_mapfont{#2}{#3}}} } \fi } % % \end{macrocode} % \begin{macrocode} %<*doc> \def\setrawglyph#1#2#3#4#5#6#7#8{\Aheading{Glyph `#1'} \Bheading{Taken from} slot #4 in font #2} \def\setscaledrawglyph#1#2#3#4#5#6#7#8{\Aheading{Glyph `#1'} \Bheading{Taken from} slot #5 in font #2 scaled by #4} % %\def\setrawglyph#1#2#3#4#5#6#7#8{} %\def\setscaledrawglyph#1#2#3#4#5#6#7#8#9{} % \end{macrocode} % \end{macro}\end{macro} % % \begin{macro}{\setscalednotglyph} % \begin{macro}{\setnotglyph} % The |\setscalednotglyph| command has the same syntax as the % |\set|\-|scaled|\-|raw|\-|glyph| command, i.e., % \begin{isyntax} % |\setscalednotglyph|\marg{glyph}\marg{font}\marg{design size}^^A % \marg{scale}\penalty0\marg{slot}\penalty0\marg{width}\penalty0 % \marg{height}\penalty0\marg{depth}\penalty0\marg{italic} % \end{isyntax} % It is a generalized form of the old |\setnotglyph| command, which % has the syntax % \begin{isyntax} % |\setnotglyph|\marg{glyph}\marg{font}\marg{design size}^^A % \marg{slot}\penalty0\marg{width}\penalty0\marg{height}\penalty0 % \marg{depth}\penalty0\marg{italic} % \end{isyntax} % |\setnotglyph| is now syntactic sugar for the equivalent call of % |\set|\-|scaled|\-|not|\-|glyph|. % \begin{macrocode} %<*pkg> \def\setnotglyph#1#2#3{ \setscalednotglyph{#1}{#2}{#3}\one_thousand } % \end{macrocode} % % Note that only the \meta{glyph}, \meta{width}, \meta{height}, % \meta{depth}, and \meta{italic} parameters are used. The reason for % having the other parameters is that |\set|\-|scaled|\-|not|\-^^A % |glyph| commands can be converted to |\set|\-|scaled|\-|raw|\-^^A % |glyph| commands when a font is reencoded. Therefore all the % information must be present, even if it is not used by the main % definition. % % To think about (LH 2000/03/02): Perhaps the \meta{mapcommands} field % of a \texttt{-not}-glyph should contain a |\glyphwarning|, just in % case anyone tries to use one? % \begin{macrocode} \def\setscalednotglyph#1#2#3#4#5#6#7#8#9{ \if_undefined{g-#1-not}\then \eval_expr_to\a_count{#6} \eval_expr_to\b_count{#7} \eval_expr_to\c_count{#8} \eval_expr_to\d_count{#9} \ifisint{i-rawscale}\then \e_count=\int{rawscale} \multiply \a_count \e_count \l_rounded_thousandths\a_count \multiply \b_count \e_count \l_rounded_thousandths\b_count \multiply \c_count \e_count \l_rounded_thousandths\c_count \multiply \d_count \e_count \l_rounded_thousandths\d_count \fi \x_cs\edef{g-#1}{ {\the\a_count} {\the\b_count} {\the\c_count} {\the\d_count} {}{} } \fi } % % \end{macrocode} % \begin{macrocode} %\def\setnotglyph#1#2#3#4#5#6#7#8{\Aheading{Pseudoglyph `#1-not'}} %\def\setscalednotglyph#1{\setnotglyph} %\let\setnotglyph=\setrawglyph %\let\setscalednotglyph=\setscaledrawglyph % \end{macrocode} % \end{macro}\end{macro} % % \begin{macro}{\unsetglyph} % The |\unsetglyph|\marg{name} command makes |\g-|\meta{name} % undefined. % % \begin{macrocode} %\def\unsetglyph#1{\x_cs\let{g-#1}\x_relax} % \end{macrocode} % \missing{doc}{\unsetglyph} % \end{macro} % % % \subsection{Glyph commands} % % The \meta{glyph commands} are: % \changes{1.908}{1999/08/22}{Glyph commands avoid \cs{edef}ing old % contents of \cs{glyph_map_commands} and \cs{glyph_map_fonts}. (LH)} % \begin{macro}{\glyph} % |\glyph|\marg{glyph}\marg{scale} % \changes{1.900}{1999/02/08}{Avoids scaling by 1000. (LH)} % % \begin{macrocode} %<*pkg> \def\glyph#1#2{ \glyph_parameter\glyph_metrics{#1} \eval_expr_to\e_count{#2} \ifnum \e_count=\one_thousand \edef\a_macro{\mapcommands{#1}} \global\glyph_map_commands\expandafter{ \the\expandafter\glyph_map_commands \a_macro } \edef\a_macro{\mapfonts{#1}} \else \multiply \a_count \e_count \l_rounded_thousandths\a_count \multiply \b_count \e_count \l_rounded_thousandths\b_count \multiply \c_count \e_count \l_rounded_thousandths\c_count \multiply \d_count \e_count \l_rounded_thousandths\d_count \edef\a_macro{\saved_scale{\the\e_count}{\mapcommands{#1}}} \global\glyph_map_commands\expandafter{ \the\expandafter\glyph_map_commands \a_macro } \edef\a_macro{\saved_scale{\the\e_count}{\mapfonts{#1}}} \fi \advance \glyph_width \a_count \advance \b_count \glyph_voffset \ifnum \glyph_height<\b_count \global\glyph_height=\b_count \fi \advance \c_count -\glyph_voffset \ifnum \glyph_depth<\c_count \global\glyph_depth=\c_count \fi \global\glyph_italic=\d_count \global\glyph_map_fonts\expandafter{ \the\expandafter\glyph_map_fonts \a_macro } } % % \end{macrocode} % \begin{macrocode} %\def\glyph#1#2{\Bheading{Glyph} `#1' scaled $\expression0{#2}$} % \end{macrocode} % \end{macro} % % \begin{macro}{\glyphrule} % |\glyphrule|\marg{width}\marg{height} % % \begin{macrocode} %<*pkg> \def\glyphrule#1#2{ \eval_expr_to\b_count{#1} \eval_expr_to\c_count{#2} \advance\glyph_width by \b_count \g_eval_expr_to\glyph_depth{\max\glyph_depth{-\glyph_voffset}} \g_eval_expr_to\glyph_height{ \max\glyph_height{\add\glyph_voffset\c_count} } \global\glyph_italic=0 \edef\a_macro{\saved_rule{\the\b_count}{\the\c_count}} \global\glyph_map_commands\expandafter{ \the\expandafter\glyph_map_commands \a_macro } } % % \end{macrocode} % \begin{macrocode} %<*doc> \def\glyphrule#1#2{% \Bheading{Rule} $\expression0{#1}$ by $\expression0{#2}$} % % \end{macrocode} % \end{macro} % % \begin{macro}{\glyphspecial} % \begin{macro}{\glyphwarning} % |\glyphspecial|\marg{string}\\ % |\glyphwarning|\marg{string} % % \begin{macrocode} %<*pkg> \def\glyphspecial#1{ \edef\a_macro{\saved_special{#1}} \global\glyph_map_commands\expandafter{ \the\expandafter\glyph_map_commands \a_macro } } \def\glyphwarning#1{ \edef\a_macro{\saved_warning{#1}} \global\glyph_map_commands\expandafter{ \the\expandafter\glyph_map_commands \a_macro } } % % \end{macrocode} % \begin{macrocode} %<*doc> \def\glyphspecial#1{\Bheading{Special} `#1'} \def\glyphwarning#1{\Bheading{Warning} `#1'} % % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\movert} % \changes{1.903}{1999/05/20}{Added update of \cs{glyph_maxhpos}. (LH)} % \begin{macro}{\moveup} % |\movert|\marg{xoffset}\\ % |\moveup|\marg{yoffset} % % \begin{macrocode} %<*pkg> \def\movert#1{ \eval_expr{#1} \ifnum \glyph_maxhpos<\glyph_width \global\glyph_maxhpos\glyph_width \fi \ifnum 0=\result \else \advance\glyph_width by \result \edef\a_macro{\saved_movert{\the\result}} \global\glyph_map_commands\expandafter{ \the\expandafter\glyph_map_commands \a_macro } \fi } % \end{macrocode} % \begin{macrocode} \def\moveup#1{ \eval_expr{#1} \ifnum\result=0\else \advance\glyph_voffset by \result \edef\a_macro{\saved_moveup{\the\result}} \global\glyph_map_commands\expandafter{ \the\expandafter\glyph_map_commands \a_macro } \fi } % % \end{macrocode} % \begin{macrocode} %<*doc> \def\movert#1{\Bheading{Rt}~$\expression0{#1}$} \def\moveup#1{\Bheading{Up}~$\expression0{#1}$} % % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\push} % \changes{1.907}{1999/08/02}{Removed the \cs{edef}. (LH)} % \begin{macro}{\pop} % \changes{1.903}{1999/05/20}{Added update of \cs{glyph_maxhpos}. (LH)} % \changes{1.907}{1999/08/02}{Removed the \cs{edef}. (LH)} % \begin{macrocode} %<*pkg> \def\push{ \bgroup \global\glyph_map_commands\expandafter{ \the\glyph_map_commands \saved_push } } % \end{macrocode} % \begin{macrocode} \def\pop{ \ifnum \glyph_maxhpos<\glyph_width \global\glyph_maxhpos\glyph_width \fi \egroup \global\glyph_map_commands\expandafter{ \the\glyph_map_commands \saved_pop } } % % \end{macrocode} % \begin{macrocode} %<*doc> \def\push{\Bheading{Push}} \def\pop{\Bheading{Pop}} % % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\resetwidth} % \begin{macro}{\resetheight} % \begin{macro}{\resetdepth} % \begin{macro}{\resetitalic} % |\resetwidth|\marg{width}\\ % |\resetheight|\marg{height}\\ % |\resetdepth|\marg{depth}\\ % |\resetitalic|\marg{italic} % % \begin{macrocode} %<*pkg> \def\resetwidth#1{\movert{\sub{#1}\glyph_width}} \def\resetheight{\g_eval_expr_to\glyph_height} \def\resetdepth{\g_eval_expr_to\glyph_depth} \def\resetitalic{\g_eval_expr_to\glyph_italic} % % \end{macrocode} % \begin{macrocode} %<*doc> \def\resetwidth#1{\Bheading{Reset width to $\expression0{#1}$}} \def\resetheight#1{\Bheading{Reset height to $\expression0{#1}$}} \def\resetdepth#1{\Bheading{Reset depth to $\expression0{#1}$}} \def\resetitalic#1{\Bheading{Reset italic to $\expression0{#1}$}} % % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\glyphpcc} % Some syntactic sugar: |\glyphpcc| could do with optimization. % % |\glyphpcc|\marg{glyph}\marg{xoffset}\marg{yoffset} % % \begin{macrocode} %<*pkg> \def\glyphpcc#1#2#3{ \push \movert{#2} \moveup{#3} \glyph{#1}{\one_thousand} \pop } % % \end{macrocode} % \begin{macrocode} %<*doc> \def\glyphpcc#1#2#3{ \push \movert{#2} \moveup{#3} \glyph{#1}{1000} \pop } % % \end{macrocode} % \end{macro} % % \begin{macro}{\glyphbboxright} % \changes{1.903}{1999/05/20}{Macro added. (LH)} % The |\glyphbboxright| command is a valid integer expression, but % its value is only meaningful inside a |\setglyph| \textellipsis\ % |\endsetglyph| or |\resetglyph| \textellipsis\ |\endresetglyph| % structure. There its value is almost the horizontal position of % the right edge of the bounding box for the glyph constructed so % far---in reality it is the greatest horizontal offset reached so % far. % % \begin{macrocode} %\def\glyphbboxright{\max\glyph_width\glyph_maxhpos} %\def\glyphbboxright{\hbox{glyphbboxright}} % \end{macrocode} % \end{macro} % % \begin{macro}{\samesize} % \changes{1.903}{1999/05/20}{Added behaviour for nonexistent glyph % (based on a suggestion from Hilmar Schlegel) and fixed typo in % \package{fontdoc}. (LH)} % |\samesize|\marg{glyph} % % \begin{macrocode} %<*pkg> \def\samesize#1{ \x_cs\ifx{g-#1}\x_relax \resetwidth{\glyphbboxright} \else \expandafter\expandafter\expandafter \same_size\csname g-#1\endcsname \fi } \def\same_size#1#2#3#4#5#6{ \movert{\sub{#1}\glyph_width} \global\glyph_height=#2 \global\glyph_depth=#3 \global\glyph_italic=#4 } % % \end{macrocode} % \begin{macrocode} %\def\samesize#1{\Bheading{Reset dimensions to those of `#1'.}} % \end{macrocode} % \end{macro} % % \begin{macro}{\ifisglyph} % The control flow command: % % \begin{macrocode} %<*pkg> \def\ifisglyph#1\then{ \x_cs\ifx{g-#1}\x_relax \expandafter\if_false \else \expandafter\if_true \fi } % % \end{macrocode} % \changes{1.911}{1999/11/30}{\protect\protect\protect\Module{misc} % definition added. (LH)} % |\ifisglyph| evaluates to false in \Module{misc}, since this avoids % uses of various metric integer expressions (such as |\width|, % |\height|, etc.) that are not defined there. % \begin{macrocode} %\def\ifisglyph#1\then{\generic@if{glyph \typeset@glyph{#1} set}} %\def\ifisglyph#1\then{\iffalse} % \end{macrocode} % \end{macro} % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % \section{Converting an ETX file to a (V)PL file} % % \subsection{Lowest-level user interface} % % \DescribeMacro{\etxtovpl} % The macro: % \begin{quote} % |\etxtovpl|\marg{encoding}\marg{vplfile} % \end{quote} % writes a virtual font (as a virtual property list) with the encoding % \meta{encoding}. (This macro is called by |\installfont|.) % % \DescribeMacro{\etxtopl} % The macro: % \begin{quote} % |\etxtopl|\marg{encoding}\marg{plfile} % \end{quote} % writes a font (as a property list) with the encoding \meta{encoding}. % (This macro is called by |\installrawfont|.) % % \begin{macro}{\etxtovpl} % \begin{macro}{\etxtopl} % \begin{macrocode} %<*pkg> \def\etxtovpl#1#2{{ \def\vpl_extension{vpl} \def\vpl_title{COMMENT} \def\vpl_font{virtual~font} \def\vpl_Font{Virtual~font} \def\vpl_caller{\string\etxtovpl} \def\vpl_to_vf##1{vpltovf~##1.vpl~##1.vf~##1.tfm} \etx_to_font{#1}{#2} }} \def\etxtopl#1#2{{ \def\vpl_extension{pl} \def\vpl_title{COMMENT} \def\vpl_font{font} \def\vpl_Font{Font} \def\vpl_caller{\string\etxtopl} \def\vpl_to_vf##1{pltotfm~##1.pl~##1.tfm} \_including_map_false \global\rawfont_scaling=-\p@ \etx_to_font{#1}{#2} }} % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\if_including_map_} % \changes{1.900}{1998/10/02}{New switch that can inhibit writing of % VPL-specific properties. (LH)} % The v\,1.5 method of controlling whether \texttt{MAP} and % \texttt{MAPFONT} properties should be written requires that some % code is put in an awkward place (in |\make_mapfonts| rather than % |\make_characters|). As the code was being reorganised anyway, it % seemed best to let a switch control this instead. If % |\if_including_map_| is true, \texttt{MAP} and \texttt{MAPFONT} % properties are written to the file (which should be a VPL), if it is % false then they are not written to the file (which is then a normal % PL). % \begin{macrocode} \newif\if_including_map_ \_including_map_true % \end{macrocode} % \end{macro} % % % \begin{macro}{\etx_to_font} % |\etx_to_font|\marg{encoding}\marg{fontfile} makes a (V)PL file. % % \begin{macrocode} \def\etx_to_font#1#2{ \make_assignments{#1} \open_out{#2.\vpl_extension} \top_of_pl_hook \out_line{(\vpl_title\space\vpl_font\space #2~created~by~fontinst~v\fontinstversion)} \out_line{} \out_line{(COMMENT~Filename:~#2.\vpl_extension)} \out_line{(COMMENT~Created~by:~tex~\jobname)} \out_line{(COMMENT~Created~using:~\vpl_caller{#1}{#2})} \out_line{} \out_line{(COMMENT~This~file~can~be~turned~into~a~\vpl_font\space with)} \out_line{(COMMENT~\vpl_to_vf{#2})} \out_line{} \out_line{(COMMENT~THIS~FILE~CAN~THEN~BE~DELETED.)} \out_line{} \make_header{#1} \if_including_map_ \make_mapfonts{#1} \fi \make_fontdimens{#1} \make_ligtable{#1} \make_characters{#1} \make_tidy{#1} \out_line{} \out_line{(COMMENT~END~OF~FILE~#2.\vpl_extension)} \close_out{\vpl_Font} } % \end{macrocode} % \end{macro} % % % \begin{macro}{\pre_first_etx_pass_hook} % \begin{macro}{\pre_second_etx_pass_hook} % \begin{macro}{\pre_third_etx_pass_hook} % \begin{macro}{\pre_fourth_etx_pass_hook} % \begin{macro}{\post_first_etx_pass_hook} % \begin{macro}{\post_second_etx_pass_hook} % \begin{macro}{\post_third_etx_pass_hook} % \begin{macro}{\post_fourth_etx_pass_hook} % \begin{macro}{\tidying_up_hook} % \multchanges{\cs{pre_first_etx_pass_hook}^^A % \cs{pre_second_etx_pass_hook}\cs{pre_third_etx_pass_hook}^^A % \cs{pre_fourth_etx_pass_hook}\cs{post_first_etx_pass_hook}^^A % \cs{post_second_etx_pass_hook}\cs{post_third_etx_pass_hook}^^A % \cs{post_fourth_etx_pass_hook}\cs{tidying_up_hook}}{1.900}^^A % {1998/09/30}{ETX-to-VPL hooks added. (LH)} % \begin{macro}{\top_of_pl_hook} % \changes{1.912}{2000/01/29}{Property list hook added. (LH)} % As the |\etxtovpl| and |\etxtopl| macros are the % lowest-level interfaces to what they do that are available in % \package{fontinst} and as the amount of code they execute is really % quite large, I suspect that users may occationally have need of % some robust mechanism for inserting extra code at well specified % positions. Such a mechanism is provided by the following hooks: % \begin{macrocode} \let\pre_first_etx_pass_hook\x_relax \let\pre_second_etx_pass_hook\x_relax \let\pre_third_etx_pass_hook\x_relax \let\pre_fourth_etx_pass_hook\x_relax \let\post_first_etx_pass_hook\x_relax \let\post_second_etx_pass_hook\x_relax \let\post_third_etx_pass_hook\x_relax \let\post_fourth_etx_pass_hook\x_relax \let\tidying_up_hook\x_relax \let\top_of_pl_hook\x_relax % \end{macrocode} % The first nine are executed at the positions of the ETX-to-VPL % file generation that their name indicate. |\top_of_pl_hook| is % slightly different---it is executed right after a PL or VPL file % is opened for writing. Thus it is also used by the MTX-to-PL system. % % To include code in one of them, one should write things like % \begin{quote} % |\add_to\pre_first_etx_pass_hook|\marg{extra code} % \end{quote} % I (LH) have the following in my \texttt{fontinst.rc} file % \begin{quote} % |\add_to\top_of_pl_hook{\out_line{(COMMENT~-*-Text-*-)}}| % \end{quote} % Without it, my text editor annoys me by assuming that \texttt{.pl} % stands for Perl. % \end{macro} \end{macro} \end{macro} \end{macro} \end{macro} % \end{macro} \end{macro} \end{macro} \end{macro} \end{macro} % % % \subsection{Glyph to slot assignments} % % \changes{1.900}{1998/12/06}{New method of storing slot assignments. % (LH)} % The way \package{fontinst} has traditionally kept track % of which glyph goes to which slot---information which is needed when % writing the |LIGTABLE| in a (V)PL, for |\nextlarger|, and for the % varchar commands---is by storing the slot number in the integer % whose name is the name of the glyph. There are two main problems with % this implementation: (i)~If a user sets an integer which happens to % have the same name as a glyph that is not assigned to any slot, then % kerns for that unused glyph might be written to the file, accidentally % creating a kerning pair where there should be none. (ii)~It is only % possible to store one slot number per glyph, so if one uses the same % glyph for several slots then \package{fontinst} can only write kerns % (and ligatures) for one of the occurences, despite the fact that all % occurences have the same typographical need for them. These problems % do only occur for glyphs on the right side of a ligature/kerning % pair, but they are still serious enough. This part of % \package{fontinst} has therefore been reimplemented. % % \changes{1.910}{1999/11/04}{Changed the way slot numbers are stored % in \cs{slots-}\meta{glyph} control sequences. (LH)} % The new implementation does not use integers, instead it uses a new % family of macros with names on the form |\slots-|\meta{glyph}^^A % \DescribeMacro{\slots-GLYPH}. These macros expand to sequences of % |\do|\thinspace\meta{character}, where \meta{character} is a category % 12 (other) token whose character code equals the slot number. % % In the entire space of such names, each slot sould be mensioned % at most once, with one exception, namely the slot which serves as % right boundary marker, which may occur twice (once for the glyph % which actually is assigned to the slot and once for the right boundary % marker glyph). To detect whether there is a collision between these two % uses of the slot, the right boundary marker glyph uses |\rboundary_do| % instead of |\do| and the glyph whose slot serves as boundarychar uses % |\rbserver_do| instead of |\do|. By redefining these two control % sequences to generate a warning message when appropriate, the occurence % of such a collision can be brought to the user's attention. % % \changes{1.900}{1998/12/11}{Added compability code for the old % interface for boundary ligatures and kerns. (LH)} % As it turned out to not be such a big deal, some extra code (protected % by a \package{docstrip} switch called \Module{boundaryCompability}) % that makes \package{fontinst} compatible with the previous syntax for % boundary handling has been included. I don't recommend using % it though, since it makes \package{fontinst} store almost all slot % numbers in two places. % % % \begin{macro}{\make_assignments} % \begin{macrocode} \def\make_assignments#1{ \let\do_slot=\assign_slot \let\end_do_slot=\end_assign_slot \def\do_boundary{\bgroup \let\makerightboundary=\bad_makerightboundary } \let\endsetleftboundary=\egroup \let\makerightboundary=\assign_rboundary \pre_first_etx_pass_hook \inputetx{#1} \post_first_etx_pass_hook \let\end_do_slot=\empty_command \let\do_boundary=\x_relax \let\endsetleftboundary=\x_relax \let\makerightboundary=\gobble_one } % \end{macrocode} % \end{macro} % % % \begin{macro}{\assign_slot} % \begin{macro}{\end_assign_slot} % \changes{1.907}{1999/08/20}{Slots are not assigned to glyphs that % do not exist. (LH)} % |\assign_slot| begins the assignment of a slot to a glyph. % |\end_assign_slot| completes it. In the time between these two, % some information is stored in |\a_toks|, so that it can be % modified by an intervening |\makerightboundary| (which is then % |\assign_rboundary|). % % Note that the code below will not reset |\lccode0|. The value of % this register should be considered uncertain while a ligful PL % or VPL file is written, i.e., in ETX files. % \SortIndex{lccode0}{\cs{lccode} 0 register\encapchar usage} % \begin{macrocode} \def\assign_slot{\a_toks={\do}} \begingroup \catcode0=12 \gdef\end_assign_slot{ \ifisglyph\slot_name\then \lccode0=\slot_number \lowercase{ \expandafter\add_to \csname slots-\slot_name\expandafter\endcsname \expandafter{\the\a_toks^^@} } % \x_resetint\slot_name\slot_number \fi } % \end{macrocode} % \end{macro}\end{macro} % % % \begin{macro}{\assign_rboundary} % \begin{macro}{\bad_makerightboundary} % |\assign_rboundary| is what |\makerightboundary| is when it is % assigning a slot to act as right boundary marker. % % |\bad_makerightboundary| is what |\makerightboundary| temporarily % gets set to between |\setleftboundary| and |\endsetleftboundary|. % \begin{macrocode} \gdef\assign_rboundary#1{ \lccode0=\slot_number \lowercase{\x_cs\add_to{slots-#1}{\rboundary_do^^@}} \x_setint{\percent_char boundarychar}\slot_number \a_toks={\rbserver_do} } \endgroup \def\bad_makerightboundary#1{ \errhelp={The~left~boundary~is~not~a~slot,~so~it~cannot~serve~ as~right~boundary.} \errmessage{Incorrect~use~of~\string\makerightboundary} } % \end{macrocode} % \end{macro} \end{macro} % % \begin{macro}{\get_slot_num} % \changes{1.910}{1999/11/04}{Removed redefinition of \cs{do} to % \cs{gobble_one} from temporary definition of \cs{do}, since a % \cs{slots-} list usually contains only one or two elements % anyway. (LH)} % It is sometimes necessary to get the number of an arbitrary slot % given only the name of the glyph which has been assigned to the % slot. In such situations, the call % \begin{quote} % |\get_slot_num{|\meta{glyph}|}| % \end{quote} % will set |\result| to the number of one such slot if the glyph has % been assigned to some slot, or set |\result| to minus one if the glyph % has not been assigned to a slot. % \begin{macrocode} \def\get_slot_num#1{ %<*!boundaryCompability> \global\result=-1 \bgroup \def\do{\global\result=`} \let\rbserver_do=\do \let\rboundary_do=\gobble_one \csname slots-#1\endcsname \egroup % %<*boundaryCompability> \ifisint{#1}\then \global\result=\int{#1} \else \global\result=-1 \fi \x_relax % } % \end{macrocode} % \end{macro} % % % \begin{macro}{\ifisinslot} % The call |\ifisinslot|\marg{glyph}\marg{slot}|\then| can be used to % test whether glyph \meta{glyph} has been assigned to slot \meta{slot}. % Both then-part and else-part of the conditional will however be % ignored when the ETX file is read the first time, since the % assignment of glyph to slots need not have been completed yet. % \begin{macrocode} \def\ifisinslot#1#2\then{ \ifx \makerightboundary\gobble_one % \end{macrocode} % This is used to test if the ETX file is being read in for the first % time. It is a bit hacky, but it is efficient. % \begin{macrocode} \eval_expr{#2} \begingroup \def\do##1{\ifnum `##1=\result \let\do=\gobble_one \fi} \def\rbserver_do{\do} \let\rboundary_do=\gobble_one \csname slots-#1\endcsname \expandafter\endgroup \ifx \do\gobble_one \expandafter\expandafter \expandafter\if_true \else \expandafter\expandafter \expandafter\if_false \fi \else \expandafter\gobble_if \fi } % % \end{macrocode} % \begin{macrocode} %<*doc> \def\ifisinslot#1#2\then{% \generic@if{glyph \typeset@glyph{#1} assigned to slot $\expression0{#2}$}% } % % \end{macrocode} % \end{macro} % % % \subsection{The header, mapfonts, and fontdimens} % % \changes{1.913}{2000/02/26}{Using \cs{make_factor} for making PL % reals, rather than \cs{afm_convert}+\cs{vpl_real}. % \cs{scaled_design_size} replaced by new dimen \cs{mapfont_scaling} for % determining mapfont atsize. (LH)} % % \begin{macro}{\mapfont_scaling} % The |\mapfont_scaling| dimen is used for calculating how much a mapfont % has been scaled, for use in \texttt{FONTAT} properties, and for % selecting the correct mapfont. It is initialized to $1$. % \begin{macrocode} %<*pkg> \newdimen\mapfont_scaling \mapfont_scaling=1pt % \end{macrocode} % \end{macro} % % \begin{macro}{\rawfont_scaling} % The |\rawfont_scaling| dimen is used for communicating the scaling % that has been applied to a raw font---a font being installed using % |\install|\-|rawfont|\penalty0---out to that macro. |\rawfont_|\-^^A % |scaling| should always be globally assigned. % \changes{1.913}{2000/03/21}{Dimen added. (LH)} % \begin{macrocode} \newdimen\rawfont_scaling % \end{macrocode} % \end{macro} % % \begin{macro}{\scaled_design_size} % \begin{macro}{\afmconvert} % The call % \begin{quote} % |\afmconvert|\meta{dimen}|=|\meta{integer expression}|;| % \end{quote} % converts a count into a dimen, assuming the count is a number % of AFM units. I'll assume that the largest dimension I'll have % to deal with is 131\,pt, to try to minimize rounding errors. % % \begin{macrocode} % \newdimen\scaled_design_size % \end{macrocode} % \begin{macrocode} % \def\afm_convert#1=#2;{ % \eval_expr{#2} % #1=\scaled_design_size % \divide#1 by 8 % \multiply #1 by \result % \divide #1 by \one_thousand % \multiply#1 by 8 % } % \end{macrocode} % \end{macro} \end{macro} % % \begin{macro}{\vpl_real} % \begin{macro}{\vpl_int} % The commands |\vpl_real|\meta{dimen} and |\vpl_int|\meta{count} print % a dimension and integer respectively in (V)PL syntax. % % \begin{macrocode} \def\vpl_real#1{R~\expandafter\lose_measure\the#1} \def\vpl_int#1{D~\the#1} % \end{macrocode} % \end{macro} \end{macro} % % % The count register |\boundary_char| has been removed, since % the reimplementation of the left and right boundaries have drastically % decreased the need to check which slot serves as the right boundary. % Instead the integer |%boundarychar| (whose name cannot normally be typed) % is used to store the number of this slot, but the user need never (and % should not) access this integer directly. If the integer is not set % then no slot serves as boundarychar. % \changes{1.900}{1998/12/04}{\cs{boundary_char} count register % removed. Right boundary slot number is now stored in the % \texttt{\%boundarychar} integer instead. (LH)} % % \begin{macro}{\side_bearings} % \begin{macro}{\curr_bearings} % These two dimens are used by the letterspacing mechanism. % \begin{macrocode} \newdimen\side_bearings \newdimen\curr_bearings % \end{macrocode} % \end{macro} \end{macro} % % \begin{macro}{\make_header} % \begin{macrocode} \def\make_header#1{ \global\font_count=0 \setdim{designsize}{10pt} \a_dimen=\dim{designsize} \out_line{(DESIGNSIZE~\vpl_real\a_dimen)} \x_setstr{codingscheme}{UNKNOWN} \out_line{(CODINGSCHEME~\str{codingscheme})} %<*boundaryCompability> \ifisint{boundarychar}\then \x_setint{\percent_char boundarychar}{\int{boundarychar}} \immediate\write16{Please~use~\string\setleftboundary\space and/or~\string\makerightboundary^^J instead~of~setting~the~boundarychar~integer.} \fi % \ifisint{\percent_char boundarychar}\then \a_count=\int{\percent_char boundarychar} \out_line{(BOUNDARYCHAR~\vpl_int\a_count)} \fi \x_setint{letterspacing}{0} \side_bearings=\make_factor{\int{letterspacing}}\half_point \x_setint{minimumkern}{0} \minimum_kern=\int{minimumkern} \out_line{} } % \end{macrocode} % \changes{1.900}{1999/01/20}{Removed test for no letterspacing. (LH)} % \changes{1.900}{1999/01/20}{Made integer expression \cs{div} a % dimen \cs{divide}. (LH)} % \end{macro} % % % \begin{macro}{\make_mapfonts} % \begin{macrocode} \def\make_mapfonts#1{ \let\saved_scale\vpl_scale \let\saved_mapfont\vpl_mapfont \let\do_slot=\do_mapfont \pre_second_etx_pass_hook \inputetx{#1} \post_second_etx_pass_hook \out_line{} } % \end{macrocode} % \end{macro} % % \begin{macro}{\do_mapfont} % |\do_mapfont| produces a |MAPFONT| entry for each font used by % glyph |\slot_name|. % \begin{macrocode} \def\do_mapfont{ \ifisglyph\slot_name\then \mapfonts\slot_name \fi } % \end{macrocode} % \end{macro} % % The following commands can be used in the \meta{mapfonts} glyph % parameter. % % \begin{macro}{\vpl_scale} % \begin{macrocode} \def\vpl_scale#1#2{{ \mapfont_scaling=\make_factor{#1}\mapfont_scaling #2 }} % \end{macrocode} % \end{macro} % % \begin{macro}{\vpl_mapfont} % \changes{1.904}{1999/06/16}{Added \cs{record_usage}. (LH)} % \changes{1.913}{2000/02/26}{Mapfont number control sequences are % named \cs{\meta{scaling factor}pt-\meta{font}} instead of % \cs{\meta{font}-\meta{scaling factor}pt}. They are also made % \cs{mathchardef}s. (LH)} % \begin{macrocode} \def\vpl_mapfont#1#2{ \a_dimen=#2 \if_undefined{\the\mapfont_scaling-#1}\then \global\x_cs\mathchardef{\the\mapfont_scaling-#1}=\font_count \x_cs\xdef{f-\the\font_count}{\the\mapfont_scaling-#1} \out_line{(MAPFONT~\vpl_int\font_count\space (FONTNAME~#1)~ (FONTDSIZE~\vpl_real\a_dimen)~ (FONTAT~\vpl_real\mapfont_scaling))} \record_usage{#1} \global\advance\font_count by 1 \fi } % \end{macrocode} % \end{macro} % % \begin{macro}{\pl_mapfont} % As PL files have no \texttt{MAPFONT} properties, the |\pl_mapfont| % macro only needs to do one thing: copy the current value of % |\mapfont_|\-|scaling| to |\rawfont_|\-|scaling|. This is necessary % since if the raw font for which a ligful PL is being written has % been scaled, then that scaling factor must be put in the appropriate % place in the FD file entry, and the simplest way to determine this % scaling factor is to execute the |\mapfonts| of some glyph in the % font. % % Due to the fact that the second ETX file pass (that during which the % \texttt{MAPFONT} properties are written) is skipped when a PL file % is being written, the |\mapfonts| get executed during the fourth ETX % file pass instead of the second. This works fine since the % |\mapcommands| that are executed at that time when a VPL file is % being written aren't needed for PL files. % \changes{1.913}{2000/03/21}{Macro added. (LH)} % \begin{macrocode} \def\pl_mapfont#1#2{\global\rawfont_scaling=\mapfont_scaling} % \end{macrocode} % \end{macro} % % \begin{macro}{\font_count} % \begin{macro}{\next_mapfont} % \begin{macro}{\prev_mapfont} % \begin{macrocode} \newcount\font_count \newcount\next_mapfont \newcount\prev_mapfont % \end{macrocode} % \end{macro} \end{macro} \end{macro} % % % \begin{macro}{\make_fontdimens} % This macro writes the \texttt{FONTDIMEN} property list. Note that % there is a difference between fontdimen 1 and the others, in that % fontdimen 1 is always in \texttt{pt}, not in the atsize-relative % \texttt{FONTUNITS} unit that the others are. Nonetheless, they can % both be treated the same here. This relies on (i) that 1000 denotes % the factor 1, and (ii) that 1000 AFM units equals 1 fontunit. % \begin{macrocode} \def\make_fontdimens#1{ \out_line{(FONTDIMEN} \a_count=1 \loop\ifnum 256>\a_count \ifisint{fontdimen(\the\a_count)}\then \out_lline{(PARAMETER~\vpl_int\a_count\space R~\make_factor{\int{fontdimen(\the\a_count)}})} \fi \advance \a_count \@ne \repeat \out_lline{)} \out_line{} } % \end{macrocode} % \end{macro} % % % \subsection{The ligtable} % % \begin{macro}{\make_ligtable} % \begin{macrocode} \def\make_ligtable#1{ \bgroup \out_line{(LIGTABLE} % \let\do_slot=\bgroup %<*boundaryCompability> \def\do_slot{\bgroup \ifisint{boundarychar}\then \ifnum \int{boundarychar}=\slot_number \def\vpl_liglabel{\out_liglabel\boundary_liglabel} \fi \fi } % \let\end_do_slot=\vpl_kerning \def\do_boundary{\bgroup \let\vpl_liglabel=\boundary_liglabel} \let\endsetleftboundary=\vpl_kerning \let\ligature=\vpl_ligature \let\k=\vpl_kern \let\rbserver_do=\vpl_rbserver_do \let\rboundary_do=\vpl_rboundary_do \pre_third_etx_pass_hook \inputetx{#1} \post_third_etx_pass_hook \out_lline{)} \egroup \out_line{} } % \end{macrocode} % \end{macro} % % \begin{macro}{\vpl_rbserver_do} % \begin{macro}{\vpl_rboundary_do} % \begin{macro}{\wrn_rboundary_do} % |\vpl_rbserver_do| and |\vpl_rboundary_do| are what |\rbserver_do| % and |\rboundary_do| respectively are when a ligkern program is being % written and no entry has yet been written for the boundarychar % slot. |\wrn_rboundary_do| is what one of them will get set to % afterwards, so that warnings are written when collisions between % using the slot as a right boundary marker and using the slot for % the actual glyph occur. % \begin{macrocode} \def\vpl_rbserver_do#1{ \do{#1} \let\rboundary_do=\wrn_rboundary_do } \def\vpl_rboundary_do#1{ \do{#1} \let\rbserver_do=\wrn_rboundary_do } \def\wrn_rboundary_do#1{ \do{#1} \immediate\write16{Boundarychar~slot~usage~collision~in~ `\slot_name'~ligkern~program.} } % \end{macrocode} % \end{macro}\end{macro}\end{macro} % % % \begin{macro}{\vpl_ligature} % |\vpl_ligature{|\meta{type}|}{|\meta{glyph}|}{|\meta{glyph}|}| % produces a ligtable entry for glyph |\slot_name|. % % The double spaces in the |\out_lline| statement below might look % strange, but |\number| will always gobble the first one. % \begin{macrocode} \def\vpl_ligature#1#2#3{ \get_slot_num{#3} \ifnum -1=\result \immediate\write16{Warning:~\string\ligature\space for~unknown~slot~`#3'.} \else \x_cs\ifx{slots-#2}\x_relax \immediate\write16{Warning:~\string\ligature\space for~unknown~slot~`#2'.} \else \def\do##1{ \vpl_liglabel \out_lline{(#1~D~\number`##1~\space\vpl_int\result)~ (COMMENT~#2~#3)} } \csname slots-#2\endcsname \fi \fi } % \end{macrocode} % \end{macro} % % % % \begin{macro}{\vpl_kerning} % |\vpl_kerning| writes out kerning instructions. % \begin{macrocode} \def\vpl_kerning{ \let\do=\vpl_kern_do \csname~r-\slot_name\endcsname \vpl_ligstop \egroup } % \end{macrocode} % \end{macro} % % \begin{macro}{\vpl_kern} % |\vpl_kern|\,|\l-|\meta{name}\,|\|\meta{amount} writes out a |KRN| % instruction. % % \changes{1.900}{1998/10/02}{Macro modified to avoid duplicate kerns. % (LH)} % |\vpl_kern| has been modified so that at most one % \texttt{KRN} instruction is written for each (ordered) pair of % characters. The idea is basically to make \package{fontinst} forget, % until the end of |\vpl_kerning|, that the glyph for which |\vpl_kern| % is being called has been assigned a slot, as this stops any more % \texttt{KRN} instructions for that particular glyph from being % written. |\vpl_kern| has also been modified so that it will not write % out any \texttt{KRN} instructions for kerns whose absolute value is % less than or equal to |\minimum_kern|. |\minimum_kern| gets set to % the value of the integer \texttt{minimumkern} in |\make_header|. If % the user has not set \texttt{minimumkern}, a default value of 0 will % be supplied by \package{fontinst}. % % \changes{1.900}{1998/12/07}{Much of the code from \cs{vpl_kern} has % been moved to \cs{vpl_kern_do}. (LH)} % \changes{1.913}{2000/02/26}{Using a nested \cs{ifnum} construct to % test the condition $\left\protect\vert % \protect\mbox{\cs{a_count}}\right\protect\vert \quotechar > % \protect\mbox{\cs{minimum_kern}}$. (LH)} % \begin{macrocode} \def\vpl_kern#1#2{ \edef\a_macro{\expandafter\gobble_three\string#1} \a_count=\expandafter\gobble_one\string#2\x_relax \ifnum \ifnum -\a_count>\a_count - \fi\a_count>\minimum_kern \edef\b_macro{~R~\make_factor\a_count} \csname slots-\a_macro\endcsname \fi \x_cs\let{slots-\a_macro}=\x_relax } % \end{macrocode} % Observation (LH 1999/03/16): The above construction has the % side-effect that a direct contradiction between a right boundary % glyph and a glyph in the |%boundarychar| slot won't be detected if % one of the items in contradiction is a kern less than or equal to % |\minimum_kern|. Perhaps this should be changed (letting |\do| equal % to |\gobble_one| would let the dectection mechanism work, but |\do| % would have to be restored afterwards and it is doubtful if it is % worth it). % \end{macro} % % % \begin{macro}{\vpl_kern_do} % |\vpl_kern_do| is what |\do| is defined to be when kerns are written. % \begin{macrocode} \def\vpl_kern_do#1{ \vpl_liglabel \out_lline{ (KRN~D~\number`#1~\b_macro)~ (COMMENT~\a_macro) } } % \end{macrocode} % \end{macro} % % % \begin{macro}{\out_liglabel} % \begin{macro}{\boundary_liglabel} % \begin{macro}{\vpl_liglabel} % |\out_liglabel| writes out a |LIGLABEL| instruction for a slot. % |\boundary_liglabel| writes out a |LIGLABEL| instruction for the % |BOUNDARYCHAR| ligkern program. |\vpl_liglabel| writes out the % correct |LIGLABEL| instruction for the current ligkern program, if it % is approriate. % % \begin{macrocode} \def\out_liglabel{ \out_lline{(LABEL~\vpl_int\slot_number)~(COMMENT~\slot_name)} \let\vpl_liglabel=\x_relax \let\vpl_ligstop=\out_ligstop } \def\boundary_liglabel{ \out_lline{(LABEL~BOUNDARYCHAR)~(COMMENT~\slot_name)} \let\vpl_liglabel=\x_relax \let\vpl_ligstop=\out_ligstop } \let\vpl_liglabel=\out_liglabel % \end{macrocode} % \end{macro}\end{macro}\end{macro} % % \begin{macro}{\out_ligstop} % \begin{macro}{\vpl_ligstop} % |\vpl_ligstop| writes out a |LIGSTOP| instruction if appropriate. % \begin{macrocode} \def\out_ligstop{\out_lline{(STOP)} \let\vpl_liglabel=\out_liglabel \let\vpl_ligstop=\x_relax} \let\vpl_ligstop=\x_relax % \end{macrocode} % \end{macro} \end{macro} % % % \subsection{The characters} % % \begin{macro}{\make_characters} % \begin{macrocode} \def\make_characters#1{ \bgroup \let\do_slot=\do_character \let\end_do_slot=\end_do_character \let\nextlarger=\vpl_nextlarger \let\varchar=\vpl_varchar \let\endvarchar=\end_vpl_varchar \let\vartop=\vpl_vartop \let\varmid=\vpl_varmid \let\varbot=\vpl_varbot \let\varrep=\vpl_varrep \if_including_map_ \let\saved_raw\vpl_raw \let\saved_rule\vpl_rule \let\saved_special\vpl_special \let\saved_warning\vpl_warning \let\saved_movert\vpl_movert \let\saved_moveup\vpl_moveup \let\saved_push\vpl_push \let\saved_pop\vpl_pop \else \def\do_character_map{ \ifdim \rawfont_scaling=-\p@ \mapfonts\slot_name \else \let\do_character_map=\x_relax \fi } \let\saved_mapfont\pl_mapfont \let\saved_scale\vpl_scale \fi \pre_fourth_etx_pass_hook \inputetx{#1} \post_fourth_etx_pass_hook \egroup } % \end{macrocode} % \end{macro} % % \begin{macro}{\do_character} % \changes{1.913}{2000/03/10}{Negative italic corrections \emph{are} % written to the (V)PL being generated. (LH)} % |\do_character| produces a character entry for glyph |\slot_name| in % slot |\slot_number|. % % \begin{macrocode} \def\do_character{ \if_undefined{g-\slot_name}\then \expandafter\gobble_setslot \else \ifx\slot_name\notdef_name\else \out_line{(CHARACTER~\vpl_int\slot_number\space (COMMENT~\slot_name)} \glyph_parameter\glyph_metrics\slot_name \a_dimen=\make_factor\a_count \p@ \do_character_sidebearings \out_lline{(CHARWD~\vpl_real\a_dimen)} \ifnum \z@=\b_count \else \out_lline{(CHARHT~R~\make_factor\b_count)} \fi \ifnum \z@=\c_count \else \out_lline{(CHARDP~R~\make_factor\c_count)} \fi \ifnum \z@=\d_count \else \out_lline{(CHARIC~R~\make_factor\d_count)} \fi \do_character_map \fi \fi } % \end{macrocode} % \end{macro} % % \begin{macro}{\do_character_sidebearings} % \begin{macrocode} \def\do_character_sidebearings{ \ifisint{\slot_name-spacing}\then \curr_bearings=\make_factor{\int{\slot_name-spacing}}\half_point \else \curr_bearings=\side_bearings \fi \advance\a_dimen by 2\curr_bearings } % \end{macrocode} % \end{macro} % % \begin{macro}{\do_character_map} % \begin{macrocode} \def\do_character_map{ \global\prev_mapfont=0 \out_lline{(MAP} \ifdim 0pt=\curr_bearings \mapcommands\slot_name \else \out_llline{(MOVERIGHT~\vpl_real\curr_bearings)} \mapcommands\slot_name \out_llline{(MOVERIGHT~\vpl_real\curr_bearings)} \fi \out_llline{)} } % \end{macrocode} % \end{macro} % % \begin{macro}{\do_character_no_letterspacing} % LH 1999/03/27: This is an alternative version of |\do_character| % which I think is now antiquated. It used to have an advantage over % |\do_character| in that it did not do any letterspacing (in v\,1.5, % that was good since |\do_character| used to write code for % letterspacing to the VPL regardless of whether is was needed or % not), but that advantage is gone since |\do_character_map| is now % a bit less stupid than it used to be. % % For the record, I don't think there ever was a user interface for % using this macro instead of |\do_character|, but I suspect there % are plenty of people around who have hacked it into being used. % % With v\,1.913 I commented it out completely, since I didn't feel % like updating the calls to |\afm_convert|. % \begin{macrocode} %<*obsolete> % \def\do_character_no_letterspacing{ % \x_cs\ifx{g-\slot_name}\x_relax % \expandafter\gobble_setslot % \else % \ifx\slot_name\notdef_name\else % \out_line{(CHARACTER~\vpl_int\slot_number\space % (COMMENT~\slot_name)} % \afm_convert\a_dimen=\width\slot_name; % \out_lline{(CHARWD~\vpl_real\a_dimen)} % \afm_convert\a_dimen=\height\slot_name; % \out_lline{(CHARHT~\vpl_real\a_dimen)} % \afm_convert\a_dimen=\depth\slot_name; % \out_lline{(CHARDP~\vpl_real\a_dimen)} % \afm_convert\a_dimen=\italic\slot_name; % \ifnum\a_dimen>0 \out_lline{(CHARIC~\vpl_real\a_dimen)} \fi % \global\prev_mapfont=0 \out_lline{(MAP} % \mapcommands\slot_name % \out_llline{)} % \fi % \fi % } % % \end{macrocode} % \end{macro} % % \begin{macro}{\gobble_setslot} % \begin{macrocode} \long\def\gobble_setslot#1\endsetslot{\endsetslot} % \end{macrocode} % \changes{1.901}{1999/03/27}{Made \cs{gobble_setslot} a \cs{long} % macro. (LH)} % \end{macro} % % \begin{macro}{\end_do_character} % \begin{macrocode} \def\end_do_character{ \ifisglyph\slot_name\then \out_lline{)} \fi } % \end{macrocode} % \end{macro} % % \begin{macro}{\notdef_name} % \begin{macrocode} \def\notdef_name{.notdef} % \end{macrocode} % \end{macro} % % % \subsection{Slot commands that put things in a character property list} % % Here follows the active definitions for those slot commands that % causes things to be put in |CHARACTER| property lists. % % \begin{macro}{\vpl_nextlarger} % |\vpl_nextlarger|\marg{name} produces a |NEXTLARGER| entry. % \begin{macrocode} \def\vpl_nextlarger#1{ \get_slot_num{#1} \ifnum -1<\result \out_lline{(NEXTLARGER~D~\the\result)~(COMMENT~#1)} \else \immediate\write16{Warning:~\string\nextlarger\space for~unknown~slot~`#1'} \fi } % \end{macrocode} % \end{macro} % % \begin{macro}{\vpl_varchar} % \begin{macro}{\end_vpl_varchar} % |\vpl_varchar| \meta{varchar commands} |\end_vpl_varchar| produces % a |VARCHAR| entry. % % \begin{macrocode} \def\vpl_varchar{\out_lline{(VARCHAR}} % \end{macrocode} % \begin{macrocode} \def\end_vpl_varchar{\out_llline{)}} % \end{macrocode} % \end{macro} \end{macro} % % % \begin{macro}{\vpl_vartop} % \begin{macrocode} \def\vpl_vartop#1{ \get_slot_num{#1} \ifnum -1<\result \out_llline{(TOP~D~\the\result)~(COMMENT~#1)} \else \immediate\write16{Warning:~\string\vartop\space for~unknown~slot~`#1'} \fi } % \end{macrocode} % \end{macro} % % \begin{macro}{\vpl_varmid} % \begin{macrocode} \def\vpl_varmid#1{ \get_slot_num{#1} \ifnum -1<\result \out_llline{(MID~D~\the\result)~(COMMENT~#1)} \else \immediate\write16{Warning:~\string\varmid\space for~unknown~slot~`#1'} \fi } % \end{macrocode} % \end{macro} % % \begin{macro}{\vpl_varbot} % \begin{macrocode} \def\vpl_varbot#1{ \get_slot_num{#1} \ifnum -1<\result \out_llline{(BOT~D~\the\result)~(COMMENT~#1)} \else \immediate\write16{Warning:~\string\varbot\space for~unknown~slot~`#1'} \fi } % \end{macrocode} % \end{macro} % % \begin{macro}{\vpl_varrep} % \begin{macrocode} \def\vpl_varrep#1{ \get_slot_num{#1} \ifnum -1<\result \out_llline{(REP~D~\the\result)~(COMMENT~#1)} \else \immediate\write16{Warning:~\string\varrep\space for~unknown~slot~`#1'} \fi } % \end{macrocode} % \end{macro} % % % \subsection{Saved map commands} % % The following commands (and |\vpl_scale|, which is defined above) can % be used in the \meta{mapcommands} glyph parameter. % % \begin{macro}{\vpl_raw} % This macro writes the entries in a \texttt{MAP} that are needed for % the given raw character. Note that the `at' comment below gives the % scaling relative to the atsize of the virtual font, not the physical % atsize. % \SortIndex{SELECTFONT property}{\texttt{SELECTFONT} property} % \begin{macrocode} \def\vpl_raw#1#2#3{ \global\next_mapfont=\csname\the\mapfont_scaling-#1\endcsname \ifnum \next_mapfont=\prev_mapfont \else \out_llline{(SELECTFONT~\vpl_int\next_mapfont)~ (COMMENT~#1~at~ \expandafter\lose_measure \the\mapfont_scaling)} \fi \out_llline{(SETCHAR~D~#2)~(COMMENT~#3)} \global\prev_mapfont=\next_mapfont } % \end{macrocode} % \end{macro} % % \begin{macro}{\vpl_rule} % \begin{macrocode} \def\vpl_rule#1#2{ \a_dimen=\make_factor{#2}\mapfont_scaling \b_dimen=\make_factor{#1}\mapfont_scaling \out_llline{(SETRULE~\vpl_real\a_dimen\space\vpl_real\b_dimen)} } % \end{macrocode} % \end{macro} % % \begin{macro}{\vpl_special} % \begin{macro}{\vpl_warning} % \begin{switch}{warningspecials} % \changes{1.913}{2000/02/26}{Switch controlling whether % \cs{glyphwarning}s should put \texttt{SPECIALS} in the VPL was % added. (LH)} % \begin{macrocode} \def\vpl_special#1{ \out_llline{(SPECIAL~#1)}} % \end{macrocode} % \begin{macrocode} \def\vpl_warning#1{ \ifwarningspecials \out_llline{(SPECIAL~Warning:~#1)} \fi \immediate\write16{Warning:~#1.} } % \end{macrocode} % \begin{macrocode} \newif\ifwarningspecials \warningspecialstrue % \end{macrocode} % \end{switch}\end{macro}\end{macro} % % \begin{macro}{\vpl_movert} % \begin{macro}{\vpl_moveup} % \begin{macrocode} \def\vpl_movert#1{ \a_dimen=\make_factor{#1}\mapfont_scaling \out_llline{(MOVERIGHT~\vpl_real\a_dimen)} } % \end{macrocode} % \begin{macrocode} \def\vpl_moveup#1{ \a_dimen=\make_factor{#1}\mapfont_scaling \out_llline{(MOVEUP~\vpl_real\a_dimen)} } % \end{macrocode} % \end{macro} \end{macro} % % \begin{macro}{\vpl_push} % \begin{macro}{\vpl_pop} % \begin{macrocode} \def\vpl_push{\out_llline{(PUSH)}} % \end{macrocode} % \begin{macrocode} \def\vpl_pop{\out_llline{(POP)}} % \end{macrocode} % \end{macro} \end{macro} % % % \subsection{Tidying up} % % \begin{macro}{\make_tidy} % If a VPL file was written, the tidying up consists of clearing the % list of mapfont numbers, since that is stored globally. If a PL % file was written, the tidying up consists of writing a % \texttt{DESIGNUNITS} property for those fonts which need one. % \begin{macrocode} \def\make_tidy#1{ \tidying_up_hook \if_including_map_ \a_count=0 \loop\ifnum \a_count<\font_count \edef\a_macro{\csname~f-\the\a_count\endcsname} \global\x_cs\let\a_macro\x_relax \advance\a_count by 1 \repeat \global\font_count=0 \else \ifdim \rawfont_scaling<\z@ \fontinstwarning{ETX~to~(V)PL}{The~font~ \out_filename\space doesn't~contain~any~characters} \global\rawfont_scaling=\p@ \fi \ifdim \rawfont_scaling=\p@ \else \out_line{(DESIGNUNITS~\vpl_real\rawfont_scaling)} \fi \fi } % \end{macrocode} % \end{macro} % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % \section{Font installation commands and \texttt{.fd} files} % % \DescribeMacro{\installfonts} % \DescribeMacro{\endinstallfonts} % The call % \begin{quote} % |\installfonts| \meta{install commands} |\endinstallfonts| % \end{quote} % is the top-level interface for installing a number of fonts % and creating |.fd| files for them. % % \DescribeMacro{\installfamily} % \DescribeMacro{\installfont} % \DescribeMacro{\installrawfont} % The \meta{install commands} are: % \begin{isyntax} % |\installfamily|\marg{encoding}\marg{family}\marg{FD-commmands}\\ % |\installfont|\marg{font-name}\marg{file-list}\marg{etx}\penalty0 % \marg{encoding}\marg{family}\marg{series}\marg{shape}\marg{size}\\ % |\installrawfont|\marg{font-name}\marg{file-list}\marg{etx}^^A % \penalty0 % \marg{encoding}\marg{family}\marg{series}\marg{shape}\marg{size}\\ % |\installfontas|\marg{font-name}\penalty0\marg{encoding}^^A % \marg{family}\marg{series}\marg{shape}\marg{size} % \end{isyntax} % % Each |\installfamily| command causes the generation of an |.fd| file % for \meta{encoding} and \meta{family}, which is writen out by the time % |\endinstallfonts| is processed. % % Each |\installfont| generates a |.vpl| font by calling |\etxtovpl| % and adds an |.fd| entry. % Each |\installrawfont| generates a ligfull |.pl| font by calling % |\etxtopl| and adds an |.fd| entry. (Raw |.pl| fonts, containing only % the glyph metrics without any ligaturing or kerning information, % are also generated by |\mtxtopl| called from |\transformfont| % statements.) % % \changes{1.912}{2000/01/15}{\cs{install}\dots\ commands updated to % set \cs{setsomething_global} to \cs{global} around themselves. This % reduces problems with assignments ``not working'' due to the % unintuitive grouping. (LH) Problem pointed out by Hilmar % Schlegel, , and others.} % % \begin{macro}{\installfonts} % Initializes the |\family_toks| token register, which is used to store % the information which is written out to |.fd| files at the end of the % job. % % \begin{macrocode} \newtoks\family_toks \def\installfonts{ \bgroup \global\family_toks={} \gdef\prev_file_list{} \global\let\setsomething_global=\global } % \end{macrocode} % \end{macro} % % \begin{macro}{\installfamily} % |\installfamily|\marg{encoding}\marg{family}\marg{FD-commmands} % % Adds the command % \begin{quote} % |\fd_family|\marg{encoding}\marg{family}\marg{FD-commmands} % \end{quote} % to the token list |\family_toks| and defines a macro % |\|\meta{encoding}|-|\meta{family}.^^A % \DescribeMacro{\ENCODING-FAMILY} % % \begin{macrocode} \def\installfamily#1#2#3{ \global\family_toks= \expandafter{\the\family_toks\fd_family{#1}{#2}{#3}} \global\x_cs\let{#1-#2}\empty_command } % \end{macrocode} % \end{macro} % % \begin{macro}{\installfont} % \begin{macro}{\installrawfont} % \changes{1.904}{1999/06/16}{Added \cs{record_usage}. (LH)} % \multchanges{\cs{installfont}\cs{installrawfont}}{1.913}{2000/03/21} % {Moved some code from \cs{install_font} to these commands. (LH)} % |\installfont|\marg{font-name}\marg{file-list}\marg{etx}\\ % \vadjust{}\qquad \marg{encoding}\marg{family}\marg{series}^^A % \marg{shape}\marg{size}\\ % |\installrawfont|\marg{font-name}\marg{file-list}\marg{etx}\\ % \vadjust{}\qquad \marg{encoding}\marg{family}\marg{series}^^A % \marg{shape}\marg{size} % % \begin{macrocode} \def\installfont#1#2#3#4#5#6#7#8{ \global\let\setsomething_global=\x_relax \input_metrics{}{#2} \etxtovpl{#3}{#1} \installfontas{#1}{#4}{#5}{#6}{#7}{#8} \global\let\setsomething_global=\global } \def\installrawfont#1#2#3#4#5#6#7#8{ \global\let\setsomething_global=\x_relax \xdef\out_filename{#1} \input_metrics{\let\storemapdata=\installraw_storemap}{#2} \let\storemapdata=\gobble_three \etxtopl{#3}{#1} \record_usage{#1} \installfontas{ \ifdim \rawfont_scaling=\p@ \else [\expandafter\lose_measure\the\rawfont_scaling]~ \fi #1 }{#4}{#5}{#6}{#7}{#8} \global\let\setsomething_global=\global } % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\installraw_storemap} % The |\installraw_storemap| macro is a definition of |\storemapdata| % that is used when the metrics for a ligful PL file is being inputed. % Its job is to write a |\storemapdata| command for this PL to the % transforms record file if the PL being written does not have the % same name as the MTX that the metrics are taken from (the % information is already stored if both files have the same name). % |\out_filename| is prematurely set by |\installrawfont| (i.e., long % before the PL file is actually opened) so that it can be used in % comparing the file names. % \changes{1.913}{1999/03/23}{Macro added. (LH)} % \begin{macrocode} \def\installraw_storemap#1#2#3{ \def\a_macro{#1} \ifx \a_macro\out_filename \else \record_transform{\out_filename}{\string\frommtx{#1}}{}\if_false \fi } % \end{macrocode} % \end{macro} % % % \begin{macro}{\input_metrics} % The |\input_metrics| macro takes a comma-separated list of metric % files as its second argument and sees to that exactly these metrics % are loaded. If the list is identical to that used in the last call % to |\input_metrics|, then this is already the case and % |\input_metrics| simply refrains from flushing those previous % metrics from \TeX's memory. Otherwise it closes a group (flushing % the metrics from a previous call), opens a group (so that these % metrics can be flushed at the next |\installfont| or % |\installrawfont| command, if necessary), and starts inputting the % metrics files in question. % % The first argument consists of code that will be executed after the % group has been closed and opened, but before any metrics is inputed. % \changes{1.900}{1999/02/13} % {Use \cs{process_csep_list} for file-list. (LH)} % \changes{1.914}{2000/05/26}{Redefined to suite \cs{file_list_metrics}. % In particular, there will now be a comma at the end of % \cs{curr_file_list} and \cs{prev_file_list}. (LH)} % \begin{macrocode} \def\input_metrics#1#2{ \let\metrics=\file_list_metrics \xdef\curr_file_list{#2,} \let\metrics=\x_relax \ifx\prev_file_list\curr_file_list\else \egroup\bgroup #1 \expandafter\process_csep_list \expandafter\input_mtx_file \curr_file_list\process_csep_list, \global\let\prev_file_list=\curr_file_list \fi } % \end{macrocode} % \end{macro} % % \begin{macro}{\file_list_metrics} % The |\file_list_metrics| macro is a definition of |\metrics| that % is used in the \meta{file-list} argument of |\install|\-|font| and % |\install|\-|raw|\-|font| when that is |\xdef|ed by |\input_metrics|. % This special definition prevents the succeeding \meta{metric % commands} from getting expanded. % \changes{1.914}{2000/05/26}{Macro added. (LH)} % \begin{macrocode} \def\file_list_metrics#1,{ \iffalse{\fi} \a_toks=\expandafter{\curr_file_list\x_relax#1,} \xdef\curr_file_list{\the\a_toks \iffalse}\fi } % \end{macrocode} % \end{macro} % % \begin{macro}{\installfontas} % The |\installfontas| command has the syntax % \begin{isyntax} % |\installfontas|\marg{font-info}\marg{encoding}\marg{family}^^A % \penalty0\marg{series}\penalty0\marg{shape}\penalty0\marg{size} % \end{isyntax} % The precise definition of a \meta{font-info} can be found in % \cite[Sec.~4]{fntguide}, here it suffices to say that a font name % (name of (V)PL file) is a valid \meta{font-info}. The |\installfontas| % command adds an entry for the \meta{font-info} font to a font % definition file, giving it the NFSS attributes \meta{encoding}^^A % \texttt{/}\nolinebreak[1]\meta{family}\texttt{/}\nolinebreak[1]^^A % \meta{series}\texttt{/}\nolinebreak[1]\meta{shape}\texttt{/}^^A % \nolinebreak[1]\meta{size}. The substitution mechanism will act on % \meta{series} and \meta{shape}, and it is therefore possible that % \meta{font-info} will appear in more than one |\Declare|\-|Font|\-^^A % |Shape| command. \meta{size} can be either some \meta{size-infos}, % as defined in \cite[Sec.~4]{fntguide}, or a \package{fontinst} % shorthand for a such, declared using |\declaresize|. % \changes{1.912}{2000/01/16}{Command added. (LH)} % \changes{1.913}{2000/03/02}{Specification changed to allow % arbitrary \meta{font-info}s as first argument. (LH)} % \begin{macrocode} \def\installfontas#1#2#3#4#5#6{ \x_cs\ifx{#2-#3-#4-#5}\x_relax \let\do_shape=\x_relax \x_cs\xdef{#2-#3}{ \x_cs\ifx{#2-#3}\x_relax\else \csname#2-#3\endcsname \fi \do_shape{#2}{#3}{#4}{#5} } \fi \let\do_size=\x_relax \x_cs\xdef{#2-#3-#4-#5}{ \x_cs\ifx{#2-#3-#4-#5}\x_relax\else \csname#2-#3-#4-#5\endcsname \fi \do_size{#6}{#1} } } % \end{macrocode} % \end{macro} % % \begin{macro}{\endinstallfonts} % Finish the installation by processing the |\family_toks| % token register, which contains the accumulated information % to be written out to |.fd| files. % % \begin{macrocode} \def\endinstallfonts{ \global\let\setsomething_global=\x_relax \let\do_shape=\fd_shape \let\do_size=\fd_size \the\family_toks \global\family_toks{} \egroup } % \end{macrocode} % \end{macro} % % \begin{macro}{\input_mtx_file} % The |\input_mtx_macro| takes one undelimited argument. It % interprets this argument as if it was one item in the \meta{file-list} % argument of |\install|\-|font| or |\install|\-|rawfont|, and does % the corresponding processing. The argument should be one of the % following four things: % \begin{quote} % \meta{font}\\ % \meta{font}\verb*| scaled |\meta{rawscale factor}\\ % |\metrics| \meta{metric commands}\\ % \meta{nothing} % \end{quote} % If, in the first two cases, an MTX file for \meta{font} does not % exist then it is generated on the fly from a corresponding |.pl|, % |.afm|, or |.vpl| file in the call to |\fromany|. In the third % case, the \meta{metric commands} simply get executed. In the fourth % case, nothing happens. % % \changes{1.904}{1999/06/16}{Now using \cs{fromany} to make an MTX % file when necessary. Furthermore testing for empty argument using % \cs{ifx} rather than \cs{if}. (LH)} % \changes{1.912}{2000/01/15}{Added error message. (LH) Suggested by % Alexei Kostin.} % \changes{1.914}{2000/05/26}{Can now accept arbitrary metric % commands in argument. (LH)} % \begin{macrocode} \def\input_mtx_file#1{ \ifx\x_relax#1\x_relax % \end{macrocode} % This tests for an empty argument, but it also lets explicit metric % commands be executed. % \begin{macrocode} \else \get_file_name #1~scaled~1000~; \fromany\file_name \ifisstr{afm-name}\then \inputmtx\file_name \else \fontinsterror{\string\install...}{ Font/MTX~file~\file_name\space not found }{ You~can~insert~an~\string\inputmtx\space command~here \messagebreak to~input~some~other~MTX~file~instead. \ifisint{rawscale}\then \messagebreak The~requested~raw~scaling~will~then~be~applied~on~that. \fi } \fi \fi } % \end{macrocode} % \end{macro} % % \begin{macro}{\get_file_name} % The macro |\get_file_name| is expanded in the following context % \begin{quote} % |\get_file_name| \meta{filename}\verb*+ scaled +\relax % \meta{scale}\verb*+ +\meta{junk}\,|;| % \end{quote} % % \begin{macrocode} \def\get_file_name #1~scaled~#2~#3;{ \edef\file_name{#1} \ifnum#2=\one_thousand \unsetint{rawscale} \else \x_resetint{rawscale}{#2} \fi } % \end{macrocode} % \changes{1.900}{1999/02/05}{Changed \cs{setint} to \cs{resetint}. % (LH)} % \end{macro} % % % \subsection{Writing font definition files} % % \begin{macro}{\fd_family} % |\fd_family{ENCODING}{FAMILY}{FD-COMMANDS}| % % Writes out an |.fd| file for the specified |ENCODING| and |FAMILY| % processing the accumulated information and default substitutions. % % \begin{macrocode} \def\fd_family#1#2#3{ \a_toks{#3} \edef\lowercase_file{\lowercase{ \edef\noexpand\lowercase_file{#1#2.fd}}} \lowercase_file \open_out{\lowercase_file} \out_line{\percent_char~Filename:~\lowercase_file} \out_line{\percent_char~Created~by:~tex~\jobname} \out_line{\percent_char~Created~using~fontinst~v\fontinstversion} \out_line{} \out_line{\percent_char~THIS~FILE~SHOULD~BE~PUT~IN~A~TEX~INPUTS~ DIRECTORY} \out_line{} \out_line{\string\ProvidesFile{\lowercase_file}} \out_lline{[ \the\year/ \ifnum10>\month0\fi\the\month/ \ifnum10>\day0\fi\the\day\space Fontinst~v\fontinstversion\space font~definitions~for~#1/#2. ]} \out_line{} \out_line{\string\DeclareFontFamily{#1}{#2}{\the\a_toks}} { \csname #1-#2\endcsname \out_line{} \let\do_shape=\substitute_shape \csname #1-#2\endcsname \let\do_shape=\remove_shape \csname #1-#2\endcsname } \x_cs\g_let{#1-#2}\x_relax \out_line{} \out_line{\string\endinput} \close_out{Font~definitions} } % \end{macrocode} % \end{macro} % % \begin{macro}{\fd_shape} % |\fd_shape{ENCODING}{FAMILY}{SERIES}{SHAPE}| % % \begin{macrocode} \def\fd_shape#1#2#3#4{ \out_line{} \out_line{\string\DeclareFontShape{#1}{#2}{#3}{#4}\left_brace_char} \csname #1-#2-#3-#4\endcsname \x_cs\g_let{#1-#2-#3-#4}\empty_command \out_line{\right_brace_char{}} } % \end{macrocode} % \end{macro} % % \begin{macro}{\fd_size} % |\fd_size{SIZE}{FONT-NAME}| % % \begin{macrocode} \def\fd_size#1#2{ \x_cs\ifx{siz-#1}\x_relax \out_lline{#1~#2} \else \out_lline{\csname siz-#1\endcsname\space #2} \fi } % \end{macrocode} % \end{macro} % % \begin{macro}{\remove_shape} % |\remove_shape{ENCODING}{FAMILY}{SERIES}{SHAPE}| % % \begin{macrocode} \def\remove_shape#1#2#3#4{ \x_cs\g_let{#1-#2-#3-#4}\x_relax } % \end{macrocode} % \end{macro} % % \begin{macro}{\substitute_shape} % |\substitute_shape{ENCODING}{FAMILY}{SERIES}{SHAPE}| % % \begin{macrocode} \def\substitute_shape#1#2#3#4{ \edef\orig_shape{#4} \substitute_series{#1}{#2}{#3}{\orig_shape} \x_cs\ifx{sub-\orig_shape}\x_relax\else \edef\subst_shape{\csname sub-\orig_shape\endcsname} \x_cs\ifx{#1-#2-#3-\subst_shape}\x_relax \out_line{ \string\DeclareFontShape{#1}{#2}{#3}{\subst_shape}{ <->\csname typ-\orig_shape\endcsname\space *~#2/#3/\orig_shape }{} } \x_cs\let{#1-#2-#3-\subst_shape}\empty_command \substitute_shape{#1}{#2}{#3}{\subst_shape} \fi \fi } % \end{macrocode} % \end{macro} % % \begin{macro}{\substitute_series} % |\substitute_series{ENCODING}{FAMILY}{SERIES}{SHAPE}| % % \begin{macrocode} \def\substitute_series#1#2#3#4{ \edef\orig_series{#3} \x_cs\ifx{sub-\orig_series}\x_relax\else \edef\subst_series{\csname sub-\orig_series\endcsname} \x_cs\ifx{#1-#2-\subst_series-#4}\x_relax \out_line{ \string\DeclareFontShape{#1}{#2}{\subst_series}{#4}{ <->\csname typ-\orig_series\endcsname\space *~#2/\orig_series/#4 }{} } \x_cs\let{#1-#2-\subst_series-#4}\empty_command \substitute_series{#1}{#2}{\subst_series}{#4} \fi \fi } % \end{macrocode} % \end{macro} % % \begin{macro}{\substitutesilent} % \begin{macro}{\substitutenoisy} % |\substitutesilent{TO}{FROM}|\\ % |\substitutenoisy{TO}{FROM}| % % Specifies a default substitution for family or shape |TO|, % which is substituted by family or shape |FROM|. % % \begin{macrocode} \def\substitutesilent#1#2{ \x_cs\def{sub-#2}{#1} \x_cs\def{typ-#2}{ssub} } \def\substitutenoisy#1#2{ \x_cs\def{sub-#2}{#1} \x_cs\def{typ-#2}{sub} } % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macrocode} \substitutesilent{bx}{b} \substitutesilent{b}{bx} \substitutesilent{b}{sb} \substitutesilent{b}{db} \substitutesilent{m}{mb} \substitutesilent{m}{l} % \end{macrocode} % \begin{macrocode} \substitutenoisy{ui}{it} % \end{macrocode} % % I don't think we want these since in OT1 encoding it will % cause the old || vs || problem. (ASAJ) % --- Oh yes we do. (SPQR) % % \begin{macrocode} \substitutesilent{sl}{it} \substitutesilent{it}{sl} % \end{macrocode} % % % \subsection{Default encodings and font sizes} % % \begin{macro}{\declareencoding} % |\declareencoding{CODINGSCHEME}{ENCODING}| % % Declare a macro |\enc-CODINGSCHEME| which expands to |ENCODING|. % This is used to determine the encoding in |\pltomtx|. % % \begin{macrocode} \def\declareencoding#1#2{\x_cs\edef{enc-#1}{#2}} % \end{macrocode} % \end{macro} % % Old \TeX{} text font encodings. % \begin{macrocode} \declareencoding{TEX~TEXT}{OT1} \declareencoding{TEX~TEXT~WITHOUT~F-LIGATURES}{OT1} \declareencoding{TEX~TYPEWRITER~TEXT}{OT1TT} % \end{macrocode} % % Old \TeX{} math font encodings. % \begin{macrocode} \declareencoding{TEX~MATH~ITALIC}{OML} \declareencoding{TEX~MATH~SYMBOLS}{OMS} \declareencoding{TEX~MATH~EXTENSION}{OMX} \declareencoding{LATEX~SYMBOLS}{lasy} % \end{macrocode} % % Euler math font encodings. % \begin{macrocode} \declareencoding{TEX~TEXT~SUBSET}{eufrak} \declareencoding{TEX~MATH~ITALIC~SUBSET}{eurm} \declareencoding{TEX~MATH~SYMBOLS~SUBSET}{euscr} \declareencoding{EULER~SUBSTITUTIONS~ONLY}{euex} % \end{macrocode} % % New \TeX{} text font encodings. % \begin{macrocode} \declareencoding{EXTENDED~TEX~FONT~ENCODING~-~LATIN}{T1} \declareencoding{TEX~TEXT~COMPANION~SYMBOLS~1---TS1}{TS1} % \end{macrocode} % % Rencoded PostScript font encdings. % \begin{macrocode} \declareencoding{TEXBASE1ENCODING}{8r} \declareencoding{TEX~TYPEWRITER~AND~WINDOWS~ANSI}{8y} % \end{macrocode} % % \begin{macro}{\declaresize} % |\declaresize{FONTSIZE}{LATEXSIZE}| % % \begin{macrocode} \def\declaresize#1#2{\x_cs\edef{siz-#1}{#2}} % \end{macrocode} % \end{macro} % % Default sizes. An empty size argument is equivalent to |<->|, % for use with scalable fonts. % % \begin{macrocode} \declaresize{}{<->} \declaresize{5}{<5>} \declaresize{6}{<6>} \declaresize{7}{<7>} \declaresize{8}{<8>} \declaresize{9}{<9>} \declaresize{10}{<10>} \declaresize{11}{<10.95>} \declaresize{12}{<12>} \declaresize{14}{<14.4>} \declaresize{17}{<17.28>} \declaresize{20}{<20.74>} \declaresize{25}{<24.88>} % \end{macrocode} % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % \section{Debugging} % % \begin{macro}{\NOFILES} % |\NOFILES| switches off file generation, and causes % \package{fontinst} to only generate empty files. It only affects the % user level commands, so it is primarily of use when debugging % commands that build on these, such as for example the % |\latin|\-|family| command. % \changes{1.914}{2000/05/20}{Added \cs{reglyphfont}. (LH)} % \begin{macrocode} \def\NOFILES{ \def\transformfont##1##2{ \touch_file{##1.mtx} \touch_file{##1.pl} } \def\reglyphfont##1##2{\touch_file{##1.mtx}} \def\installfonts{} \def\endinstallfonts{} \def\installfont##1##2##3##4##5##6##7##8{ \touch_file{##1.vpl} } \def\installrawfont##1##2##3##4##5##6##7##8{ \touch_file{##1.pl} } \def\installfamily##1##2##3{\touch_file{##1##2.fd}} } % \end{macrocode} % \end{macro} % % \begin{macro}{\touch_file} % \begin{macrocode} \def\touch_file#1{ \edef\lowercase_file{\lowercase{ \edef\noexpand\lowercase_file{#1}}} \lowercase_file \open_out{\lowercase_file} \out_line{\percent_char~TEST~FILE.} \out_line{\percent_char~Created~whilst~debugging~fontinst.} \close_out{Test~file} } % % \end{macrocode} % \end{macro} % % \Finale \endinput