% Unofficial fontinst 1.7 % ----------------------- % % This file is part of an unofficial fontinst 1.7. It was created % by Sebastian Rahtz (s.rahtz@elsevier.co.uk) and not by Alan Jeffrey % (the real author of fontinst). Please contact Sebastian with % any questions or complaints % % Some catcode assignments just in case we're in iniTeX: \catcode`\{=1 \catcode`\}=2 \catcode`\#=6 \catcode`\^=7 % The current versions: \def\fontinstversion{1.7} \message{v\fontinstversion, 1998/05/19, hacked SPQR} % Copyright 1993, 1994, 1995 Alan Jeffrey. %%%%%%%%%%%%%%% SAVE CATCODES %%%%%%%%%%%%%%% % % Save the current values of the catcodes of space, @, NL, ~ and _. % _ and @ are made letters, ~ is a space, and space and NL are ignored. \edef\spacecatcode{\the\catcode`\ } \edef\atcatcode{\the\catcode`\@} \edef\nlcatcode{\the\catcode`\^^M} \edef\underscorecatcode{\the\catcode`\_} \edef\tildecatcode{\the\catcode`\~} \catcode`\ =9 \catcode`\^^M=9 \catcode`\@=11 \catcode`\_=11 \catcode`\~=10 %%%%%%%%%%%%%%% STUFF FROM PLAIN %%%%%%%%%%%%%%% % % If we're running in iniTeX we input some definitions taken from % plain. \ifx\@ne\undefined_command \input fontinst.ini\relax \fi %%%%%%%%%%%%%%% SOME TEMPORARY VARIABLES %%%%%%%%%%%%%%% \newcount\a_count \newcount\b_count \newcount\c_count \newcount\d_count \newcount\e_count \newcount\f_count \newcount\g_count \newdimen\a_dimen \newdimen\b_dimen \newdimen\c_dimen \newdimen\d_dimen \newtoks\a_toks \newtoks\b_toks \newtoks\c_toks %%%%%%%%%%%%%%% SOME GLOBAL VARIABLES %%%%%%%%%%%%%%% \newwrite\out_file %%%%%%%%%%%%%%% SOME CONSTANTS %%%%%%%%%%%%%%% \mathchardef\one_thousand=1000 \mathchardef\max_mathchardef="7FFF %%%%%%%%%%%%%%% TRIGONOMETRY %%%%%%%%%%%%%%% % % Include David Carlisle's trigonometry macros, % First do some hacks to get round all that \NeedsTeXFormat{LaTeX2e} % stuff that David put in :-) \def\NeedsTeXFormat#1{} \def\ProvidesPackage#1 [#2]{} \let\@tempdima\a_dimen \let\@tempdimb\b_dimen \input trig.sty %%%%%%%%%%%%%%% SOME USEFUL TEX HACKS %%%%%%%%%%%%%%% \def\x_cs#1#2{\expandafter#1\csname#2\endcsname} \def\gobble_one#1{} \def\gobble_two#1#2{} \def\gobble_three#1#2#3{} \def\identity_one#1{#1} \def\first_char#1#2={#1} \def\g_let{\global\let} \def\empty_command{} \bgroup \catcode`\[=1 \catcode`\]=2 \catcode`\%=12 \catcode`\{=12 \catcode`\}=12 \gdef\percent_char[%] \gdef\left_brace_char[{] \gdef\right_brace_char[}] \egroup { \catcode`\p=12 \catcode`\t=12 \gdef\lose_measure#1pt{#1} } \def\add_to#1#2{ \ifx#1\relax \def#1{#2} \else \expandafter\def\expandafter#1\expandafter{#1#2} \fi } \let\x_relax=\relax \def\open_out#1{\immediate\openout\out_file=#1 \def\out_filename{#1}} \def\out_line#1{\immediate\write\out_file{#1}} \def\out_lline#1{\out_line{\space\space\space#1}} \def\out_llline#1{\out_lline{\space\space\space#1}} \def\close_out#1{\immediate\write16{#1~written~on~\out_filename.} \immediate\closeout\out_file} % The command \do, protected from expansion. \def\never_do{\noexpand\do} % In order to write macros that expand out to nested if-statements, % I say: % % \ifblah...\then...\else...\fi % % In order to match the \fi, \then has to be an \if. \let\then=\iffalse \def\if_false{\iffalse} \def\if_true{\iftrue} % \if_or...\or_else...\then gives the disjunction of two booleans. \def\if_or#1\or_else#2\then{ #1\then \expandafter\if_true \else #2\then \expandafter\expandafter\expandafter\if_true \else \expandafter\expandafter\expandafter\if_false \fi \fi } % \if_file_exists checks to see if a file exits, using \openin. \def\if_file_exists#1\then{ \immediate\openin1=#1\relax \ifeof1\relax \immediate\closein1 \expandafter\if_false \else \immediate\closein1 \expandafter\if_true \fi } % If \@@input is defined, I'll assume it's the LaTeX version of the TeX % input primitive. I need this so that I can say % \expandafter\primitiveinput foo, which doesn't work with the LaTeX % version of \input. \x_cs\ifx{@@input}\relax \let\primitiveinput=\input \else \let\primitiveinput=\@@input \fi %%%%%%%%%%%%%%% SETTING VARIABLES %%%%%%%%%%%%%%% % % The macros: % % \setint{INT}{INTEGER EXPRESSION} % \setstr{STR}{STRING} % \setdim{DIM}{DIMENSION} % \setcommand \COMMAND DEFINITION % % define new macros \i-INT, \s-STR, \d-DIM or \COMMAND. The macros: % % \resetint{INT}{INTEGER EXPRESSION} % \resetstr{STR}{STRING} % \resetdim{DIM}{DIMENSION} % \resetcommand \COMMAND DEFINITION % % redefine the macros \i-INT, \s-STR, \d-DIM or \COMMAND. The macros: % % \int{INT} % \str{STR} % \dim{DIM} % \COMMAND % % return the values of \i-INT, \s-STR, \d-DIM or \COMMAND. The macros: % % \ifisint{INT}\then % \ifisstr{STR}\then % \ifisdim{DIM}\then % \ifiscommand\COMMAND\then % % return \if_true if \i-INT, \s-STR or \d-DIM have been defined, and % \if_false otherwise. % % \unsetint{INT} % \unsetstr{STR} % \unsetdim{DIM} % \unsetcommand \COMMAND % % undefine \i-INT, \s-STR, \d-DIM or \COMMAND. % % Integers are kept as \mathchardef's if possible. I compared the % version where you try to keep ints as mathchardefs with the version % where you don't bother, and for a sample font without mathchardefs I % got: % % 114673 words of memory out of 150001 % Time elapsed: 135.0 seconds % % and with, I got: % % 114050 words of memory out of 150001 % Time elapsed: 134.5 seconds % % so I've saved a little memory and time. Not brilliant, but I may as % well keep it in. \def\setint#1#2{ \x_cs\ifx{i-#1}\relax \resetint{#1}{#2} \fi } \def\setstr#1#2{\x_cs\ifx{s-#1}\relax \x_cs\edef{s-#1}{#2}\fi} \def\setdim#1#2{\x_cs\ifx{d-#1}\relax \a_dimen=#2\relax\x_cs\edef{d-#1}{\the\a_dimen}\fi} \def\setcommand#1{\ifx#1\undefined_command \expandafter\def\expandafter#1\else \expandafter\def\expandafter\a_command\fi} \def\resetint#1#2{ \eval_expr{#2} \ifnum\result<\max_mathchardef \ifnum\result<0 \x_cs\edef{i-#1}{\the\result} \else \x_cs\mathchardef{i-#1}=\result \fi \else \x_cs\edef{i-#1}{\the\result} \fi } \def\resetstr#1#2{\x_cs\edef{s-#1}{#2}} \def\resetdim#1#2{\a_dimen=#2\x_cs\edef{d-#1}{\the\a_dimen}} \def\resetcommand#1{\def#1} \def\int#1{\csname~i-#1\endcsname} \def\str#1{\csname~s-#1\endcsname} \def\dim#1{\csname~d-#1\endcsname} \def\ifisint#1\then{\x_cs\ifx{i-#1}\relax\expandafter\if_false \else\expandafter\if_true\fi} \def\ifisstr#1\then{\x_cs\ifx{s-#1}\relax\expandafter\if_false \else\expandafter\if_true\fi} \def\ifisdim#1\then{\x_cs\ifx{d-#1}\relax\expandafter\if_false \else\expandafter\if_true\fi} \def\ifiscommand#1\then{\ifx#1\undefined_command\expandafter\if_false \else\expandafter\if_true\fi} \def\unsetint#1{\x_cs\let{i-#1}\relax} \def\unsetstr#1{\x_cs\let{s-#1}\relax} \def\unsetdim#1{\x_cs\let{d-#1}\relax} \def\unsetcommand#1{\let#1=\undefined_command} %%%%%%%%%%%%%%% INTEGER EXPRESSIONS %%%%%%%%%%%%%%% % % The macro: % % \eval_expr{INTEGER EXPRESSION} % % globally assigns \result to the value of INTEGER EXPRESSION, and % changes the value of no other counters. \newcount\result \def\eval_expr#1{\global\result=#1\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} % \neg{INTEGER EXPRESSION} % \add{INTEGER EXPRESSION}{INTEGER EXPRESSION} % \sub{INTEGER EXPRESSION}{INTEGER EXPRESSION} % \mul{INTEGER EXPRESSION}{INTEGER EXPRESSION} % \div{INTEGER EXPRESSION}{INTEGER EXPRESSION} % \scale{INTEGER EXPRESSION}{INTEGER EXPRESSION} % \max{INTEGER EXPRESSION}{INTEGER EXPRESSION} % \min{INTEGER EXPRESSION}{INTEGER EXPRESSION} \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\scale#1#2{#1{\a_count=\result\eval_expr{#2} \global\multiply\result by \a_count \global\divide\result by \one_thousand}} \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}} %%%%%%%%%%%%%%% CONVERTING AN ENC FILE TO AN ETX FILE %%%%%%%%%%%%%%% % % The macro: % % \enctoetx{ENCFILE}{ETXFILE} % % reads ENCFILE.enc and writes the same information to ETXFILE.etx, % in a format TeX can read more easily. \newif\ifmissingslots { \catcode`\/=\active \catcode`\]=\active \gdef\enctoetx#1#2{{ \catcode`\/=\active \catcode`\]=\active \def/##1[{ \a_count=0 \global\missingslotsfalse \def/####1~{ \csname~o-####1\endcsname{ \ifmissingslots \out_line{\string\nextslot{\the\a_count}} \fi \global\missingslotsfalse \out_line{\string\setslot{####1}} \out_line{\string\endsetslot} \out_line{} } \advance\a_count by 1 } } \def]~def{} \make_etx{#1}{#2} }} } \x_cs\def{o-.notdef}#1{\global\missingslotstrue} \def\make_etx#1#2{ \open_out{\temp_prefix#2.etx} \out_line{\percent_char~Filename:~#2.etx} \out_line{\percent_char~Created~by:~tex~\jobname} \out_line{\percent_char~Created~using:~\string\enctoetx{#1}{#2}} \out_line{} \out_line{\percent_char~This~file~contains~the information~of~#1.enc~in~a~form} \out_line{\percent_char~more~easily~read~by~TeX. It~is~used~by~the~fontinst~package.} \out_line{} \out_line{\percent_char~THIS~FILE~CAN~BE~DELETED.} \out_line{} \out_line{\string\relax} \out_line{} \out_line{\string\documentstyle[fontdoc,twocolumn]{article}} \out_line{} \out_line{\string\begin{document}} \out_line{} \out_line{This~document~describes~the~#1~encoding.} \out_line{It~was~automatically~generated~by~the} \out_line{{\string\tt\space~fontinst}~package.} \out_line{} \out_line{\string\encoding} \out_line{} \out_line{\string\needsfontinstversion{\fontinstversion}} \out_line{} \primitiveinput #1.enc\relax \out_line{} \out_line{\string\endencoding} \out_line{} \out_line{\string\end{document}} \close_out{Encoding~vector} } %%%%%%%%%%%%%%% CONVERTING AN AFM FILE TO AN MTX FILE %%%%%%%%%%%%%%% % % The macro: % % \afmtomtx{AFMFILE}{MTXFILE} % % reads ETXFILE.etx and AFMFILE.afm, and writes the same information % out to MTXFILE.mtx. \newcount\minimum_kern \def\afmtomtx#1#2{{ \open_out{\temp_prefix#2.mtx} \def\raw_font_name{#2} \_italicfalse \setint{minimumkern}{0} \minimum_kern=\int{minimumkern} \out_line{\percent_char~Filename:~#2.mtx} \out_line{\percent_char~Created~by:~tex~\jobname} \out_line{\percent_char~Created~using:~\string\afmtomtx{#1}{#2}} \out_line{} \out_line{\percent_char~This~file~contains~the information~of~#1.afm~in~a~form} \out_line{\percent_char~more~easily~read~by~TeX.~ It~is~used~by~the~fontinst~package.} \out_line{} \out_line{\percent_char~THIS~FILE~CAN~BE~DELETED.} \out_line{} \out_line{\string\relax} \out_line{\string\metrics} \out_line{} \out_line{\string\needsfontinstversion{\fontinstversion}} \out_line{} \catcode`\^^M=12 \catcode`\ =10 \expandafter\afm_line\primitiveinput #1.afm\relax \out_line{} \out_line{\string\endmetrics} \close_out{Metrics} }} % The variable \if_italic is set true if the font is italic. \newif\if_italic % The command \afm_line reads to the end of the line, calls % \afm_command on that line, then calls \afm_line again. {\catcode`\^^M=12 \gdef\afm_line#1 {\afm_command#1~\end_of_line\afm_line}} % The command \afm_command reads the first word FOO, and calls afm-FOO. % If this does not exist, then \gobble_one_line will eat up the rest of the % line. \def\afm_command#1~{\csname~afm-#1\endcsname\gobble_one_line} \def\gobble_one_line#1\end_of_line{} % This all stops when we reach the command EndFontMetrics. \x_cs\def{afm-EndFontMetrics}#1\afm_line{} % To define an afm command, you say \afm_def{COMMAND}(PATTERN){RESULT} \def\afm_def#1(#2)#3{\x_cs\def{afm-#1} \gobble_one_line#2\end_of_line{#3}} % For example, we can define the following afm commands: \afm_def{CharWidth}(#1){\charxwidth=#1\relax} \afm_def{XHeight}(#1){\out_line{\string\setint{xheight}{#1}}} \afm_def{ItalicAngle}(#1){\calculate_it_slant{#1}} \afm_def{Ascender}(#1){\out_line{\string\setint{ascender}{#1}}} \afm_def{CapHeight}(#1){\out_line{\string\setint{capheight}{#1}}} \afm_def{UnderlineThickness}(#1){\out_line{\string \setint{underlinethickness}{#1}}} % -from Thierry Bouche % 1997/02/07, to get fontdimens comparable to EC fonts \afm_def{Descender}(#1){\out_line{\string\setint{descender_neg}{#1}}} \afm_def{FontBBox}(#1~#2~#3~#4){% \out_line{\string\setint{maxheight}{#4}} \out_line{\string\setint{maxdepth_neg}{#2}} } % end -thb- \afm_def{IsFixedPitch}(#1){ \if\first_char#1=f \else\out_line{\string\setint{monowidth}{1}} \fi } \afm_def{KP}(#1~#2~#3~#4){ \ifnum#3>\minimum_kern\relax \out_line{\string\setkern{#1}{#2}{#3}} \else\ifnum#3<-\minimum_kern\relax \out_line{\string\setkern{#1}{#2}{#3}} \fi\fi } \afm_def{KPX}(#1~#2~#3~#4){ \ifnum#3>\minimum_kern\relax \out_line{\string\setkern{#1}{#2}{#3}} \else\ifnum#3<-\minimum_kern\relax \out_line{\string\setkern{#1}{#2}{#3}} \fi\fi } \afm_def{C}(#1~;#2){\init_afm{#1}\do_list[#2]\afm_char} \afm_def{CH}(#1~;#2){\init_afm{#1}\do_list[#2]\afm_char} \afm_def{CC}(#1~#2~;#3){\init_cc{#1}\do_list[#3]\cc_char} % When parsing a character, we set the values of the following % variables: \newcount\char_slot \newcount\char_x_width \newcount\x_width \newcount\bbox_llx \newcount\bbox_lly \newcount\bbox_urx \newcount\bbox_ury \let\char_name=\empty_command % \init_afm initializes the variables the AFM character list writes to. \def\init_afm#1{ \char_slot=#1\relax \x_width=\char_x_width \bbox_llx=0 \bbox_lly=0 \bbox_urx=0 \bbox_ury=0 \let\char_name=\empty_command } % \afm_char writes the values of these variables to the MTX file, and % saves them in a macro \g-GLYPHNAME, in the form: % % {WIDTH}{HEIGHT}{DEPTH}{ITALIC} % % These are needed, because the (grumble grumble) syntax of CC commands % doesn't include the glyph measurements, so we have to remember them. \def\afm_char{ \a_count=-\bbox_lly \if_italic \b_count=-\x_width \advance\b_count by \bbox_urx \ifnum\b_count>0\else \b_count=0 \fi \else \b_count=0 \fi \out_line{ \ifnum\char_slot>-1 \string\setrawglyph \else \string\setnotglyph \fi {\char_name} {\raw_font_name} {10pt} {\the\char_slot} {\the\x_width} {\the\bbox_ury} {\the\a_count} {\the\b_count} } } % \init_cc and \cc_char write out a composite character glyph. \def\init_cc#1{% \out_line{\string\setglyph{#1}} \def\char_name{#1} } \def\cc_char{% \out_lline{\string\samesize{\char_name-not}} \out_line{\string\endsetglyph} } % To set the italic angle, we need to calculate the tangent of the % angle that the afm file contains. This is done with David % Carlisle's trig macros. We need to do a bit of trickery to strip % off any spaces which may have crept into the end of the angle, since % the trig macros don't like space at the end of their argument. \def\calculate_it_slant#1{ \edef\theangle{\strip_spaces#1~\end_strip_spaces} \CalculateTan{\theangle} \a_dimen=-\one_thousand sp \a_dimen=\UseTan{\theangle}\a_dimen \a_count=\a_dimen \out_line{\string\setint{italicslant}{\the\a_count}} \ifnum\a_count>0~\_italictrue \else \_italicfalse \fi } \def\strip_spaces#1~#2\end_strip_spaces{#1} % To process a list of commands separated by semi-colons, we call % \do_list[LIST]. This works in a similar way to \afm_line. \def\do_list[~#1~#2;~#3]{ \csname~list-#1\endcsname\gobble_one_semi#2; \ifx\relax#3\relax\expandafter\gobble_one \else\expandafter\identity_one\fi {\do_list[~#3]} } \def\gobble_one_semi#1;{} % There is an analagous \listdef for defining commands to be used % inside lists. \def\list_def#1(#2)#3{\x_cs\def{list-#1}\gobble_one_semi#2~;{#3}} % For example, these are the commands that are used in giving % character metrics: \list_def{W}(#1~#2){\x_width=#1\relax} \list_def{WX}(#1){\x_width=#1\relax} \list_def{WY}(#1){} \list_def{N}(#1){\def\char_name{#1}} \list_def{B}(#1~#2~#3~#4){ \bbox_llx=#1\relax \bbox_lly=#2\relax \bbox_urx=#3\relax \bbox_ury=#4\relax } \list_def{PCC}(#1~#2~#3){ \out_lline{\string\glyphpcc{#1}{#2}{#3}} } %%%%%%%%%%%%%%% CONVERTING A PL FILE TO AN MTX FILE %%%%%%%%%%%%%%% % % The macro: % % \pltomtx{PLFILE}{MTXFILE} % % reads PLFILE.pl, and writes the same information % out to MTXFILE.mtx. It can't cope with SKIP commands. \def\pltomtx#1#2{{ \def\raw_font_name{#1} \open_out{\temp_prefix#2.mtx} \out_line{\percent_char~Filename:~#2.mtx} \out_line{\percent_char~Created~by:~tex~\jobname} \out_line{\percent_char~Created~using:~\string\pltomtx{#1}{#2}} \out_line{} \out_line{\percent_char~This~file~contains~the~ information~of~#1.pl~in~a~form} \out_line{\percent_char~more~easily~read~by~TeX.~ It~is~used~by~the~fontinst~package.} \out_line{} \out_line{\percent_char~THIS~FILE~CAN~BE~DELETED.} \out_line{} \out_line{\string\relax} \out_line{\string\metrics} \out_line{} \out_line{\string\needsfontinstversion{\fontinstversion}} \out_line{} \catcode`\(=0 \catcode`\)=9 \let\/=\ignore_parens \let\do_pl_glyph=\relax \primitiveinput #1.pl\relax \do_pl_glyph \out_line{} \out_line{\string\endmetrics} \close_out{Metrics} }} % To parse a PL file, we first make ( the escape character, make ) % ignored, then define the various PL commands. % % We can ignore a parenthesis matched string by making ( and ) the % group delimiters, then gobbling them up. \def\ignore_parens{\bgroup\catcode`(=1 \catcode`)=2 \relax \expandafter\expandafter\expandafter\gobble_parens \iftrue\expandafter{\else}\fi} \def\gobble_parens#1{\egroup} % Convert a PL real to an AFM unit, assuming it contains a decimal % point. \def\pl_real#1{\pl_realer(#1000)} \def\pl_realer(#1.#2#3#4#5){#1#2#3#4} % Convert a PL int to a TeX int, assuming it's prefixed by C, D, O, or % H. \def\pl_int#1#2{ \ifx#1C `#2 \else\ifx#1D #2 \else\ifx#1O '#2 \else\ifx#1H "#2 \else\errmessage{Unknown~PL~number~prefix~`#1'} \fi\fi\fi\fi } % Many of the PL commands are ignored, and I'm assuming the R's are in % the places tftopl puts them, which is a bit naughty of me... \let\COMMENT=\ignore_parens \let\FAMILY=\ignore_parens \let\FACE=\ignore_parens \let\CHECKSUM=\ignore_parens \let\BOUNDARYCHAR=\ignore_parens \let\LIG=\ignore_parens \let\NEXTLARGER=\ignore_parens \let\VARCHAR=\ignore_parens % When we reach a CODINGSCHEME instruction, we read the coding string, % and read in the corresponding etx file. \def\CODINGSCHEME{\bgroup\catcode`\)=12\relax\CODINGSCHEME_cont} \def\CODINGSCHEME_cont#1){ \egroup \x_cs\ifx{enc-#1}\relax \errhelp{The~encoding~`#1'~has~not~been~declared.^^J You~should~declare~it~with~\string\declareencoding{#1}{ETXFILE}.^^J Press~~to~carry~on~with~fingers~crossed,^^J or~X~~to~exit.} \errmessage{Undeclared~encoding~`#1'} \else \def\do_slot{\x_cs\let{name-\the\slot_number}\slot_name} \catcode`\(=12 \catcode`\)=12 \x_cs\inputetx{enc-#1}\relax \catcode`\(=0 \catcode`\)=9 \fi } \def\DESIGNSIZE~#1~#2~{ \a_dimen=#2pt \out_line{\string\setdim{designsize}{\the\a_dimen}} } \let\FONTDIMEN=\relax \def\SLANT~R~#1~{\out_line{\string\setint{italicslant}{\pl_real{#1}}}} \def\SPACE~R~#1~{\out_line{\string\setint{interword}{\pl_real{#1}}}} \def\STRETCH~R~#1~{\out_line{\string\setint{stretchword}{\pl_real{#1}}}} \def\SHRINK~R~#1~{\out_line{\string\setint{shrinkword}{\pl_real{#1}}}} \def\XHEIGHT~R~#1~{\out_line{\string\setint{xheight}{\pl_real{#1}}}} \def\QUAD~R~#1~{\out_line{\string\setint{quad}{\pl_real{#1}}}} \def\EXTRASPACE~R~#1~{\out_line{\string\setint{extraspace}{\pl_real{#1}}}} \def\DEFAULTRULETHICKNESS~R~#1~{ \out_line{\string\setint{underlinethickness}{\pl_real{#1}}} } \def\HEADER~#1~#2~#3~#4~{} \def\SEVENBITSAFEFLAG~#1~{} \def\PARAMETER~#1~#2~#3~#4~{} \def\NUM#1~#2~#3~{} \def\DENOM#1~#2~#3~{} \def\SUP#1~#2~#3~{} \def\SUB#1~#2~#3~{} \def\SUBDROP~#1~#2~{} \def\SUPDROP~#1~#2~{} \def\DELIM#1~#2~#3~{} \def\AXISHEIGHT~#1~#2~{} \def\BIGOPSPACING#1~#2~#3~{} \def\LIGTABLE{\let\do=\never_do\let\temp_command\empty_command} \def\LABEL~#1~#2~{\edef\temp_command{\temp_command\do{\pl_int{#1}{#2}}}} \def\STOP{\let\temp_command\empty_command} \def\SKIP~#1~#2~{\immediate\write16{Warning:~SKIP~instruction~ignored.}} \def\KRN~#1~#2~R~#3~{ \edef\do{\noexpand\write_pl_krn{\pl_int{#1}{#2}}{\pl_real{#3}}} \temp_command \let\do=\never_do } \def\write_pl_krn#1#2#3{ \f_count=#1 \g_count=#3 \out_line{\string\setkern{\csname~name-\the\g_count\endcsname} {\csname~name-\the\f_count\endcsname} {#2}} } \def\CHARWD~R~#1~{\b_count=\pl_real{#1}} \def\CHARHT~R~#1~{\c_count=\pl_real{#1}} \def\CHARDP~R~#1~{\d_count=\pl_real{#1}} \def\CHARIC~R~#1~{\e_count=\pl_real{#1}} \def\CHARACTER~#1~#2~{ \do_pl_glyph \a_count=\pl_int{#1}{#2} \b_count=0 \c_count=0 \d_count=0 \e_count=0 \let\do_pl_glyph=\write_pl_glyph } \def\write_pl_glyph{ \x_cs\ifx{name-\the\a_count}\relax\else \out_line{\string\setrawglyph {\csname~name-\the\a_count\endcsname} {\raw_font_name} {\the\a_dimen} {\the\a_count} {\the\b_count} {\the\c_count} {\the\d_count} {\the\e_count}} \fi } %%%%%%%%%%%%%%% ENCODING FILES %%%%%%%%%%%%%%% % % The macro: % % \inputetx{FILENAME} % % inputs FILENAME.etx, ignoring anything between \relax and \encoding, % and anything after \endencoding. % lowercase name before opening \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 \let\endencoding=\endinput \primitiveinput \lowercase_file.etx\x_relax \let\relax=\x_relax } % \setslot{NAME} SLOT COMMANDS \endsetslot % % Sets \slot_number to the current slot, \slot_name to NAME, and calls % \do_slot at the beginning of the slot and \end_do_slot at the end. By % default, \do_slot and \end_do_slot do nothing, but this is over-ridden % later. \newcount\slot_number \def\setslot#1{\edef\slot_name{#1}\do_slot} \def\endsetslot{\end_do_slot\advance\slot_number by 1\relax} \let\do_slot\empty_command \let\end_do_slot\empty_command % The SLOT COMMANDS are: % % \nextslot{INTEGER EXPRESSION} % % Sets \slot_number. % % \ligature{LIG}{GLYPH}{GLYPH} % \nextlarger{GLYPH} % \varchar VARCHAR COMMANDS \endvarchar % \comment{TEXT} % \usedas{COMMAND}{TYPE} % % By default, these do nothing, but are over-ridden later. \def\nextslot#1{\slot_number=#1\relax} \let\ligature=\gobble_three \let\nextlarger=\gobble_one \let\varchar=\empty_command \let\endvarchar=\empty_command \let\usedas=\gobble_two \let\comment=\gobble_one % The VARCHAR COMMANDS are: % % \vartop{GLYPH} % \varmid{GLYPH} % \varbot{GLYPH} % \varrep{GLYPH} \let\vartop=\gobble_one \let\varmid=\gobble_one \let\varbot=\gobble_one \let\varrep=\gobble_one %%%%%%%%%%%%%%% METRIC FILES %%%%%%%%%%%%%%% % % The macro: % % \inputmtx{FILENAME} % % inputs FILENAME.mtx, ignoring anything between \relax and \metrics, % and anything after \endmetrics. \def\inputmtx#1{ \a_count=0 \def\relax{\let\relax=\x_relax\iffalse} \let\metrics=\fi \let\endmetrics=\endinput \primitiveinput #1.mtx\x_relax \let\relax=\x_relax } % The kerning information is kept in the macros \l-NAME and \r-NAME, % containing information about how NAME kerns on the left and on the % right, respectively. The \l-NAME macro should expand out to a series of % \k\r-NAME\AMOUNT macros, and vice versa. % % Where possible, we avoid re-scaling, which saves a bit of time and memory. % With a sample font, the version where we didn't avoid re-scaling used: % % 114050 words of memory out of 150001 % Time elapsed: 134.5 seconds % % whereas the version where we do avoid it used: % % 113786 words of memory out of 150001 % Time elapsed: 124.9 seconds % % We keep the names of the glyphs to kern with as \l-NAME and \r-NAME to % save on token space, and this got the resources used down to: % % 88574 words of memory out of 150001 % Time elapsed: 106.1 seconds % % Keeping track of the kern amounts as \AMOUNT got the resources used % down to: % % 75424 words of memory out of 150001 % Time elapsed: 97.2 seconds % % Mind you, I then added all the \transformfont stuff, and it went back to: % % 77079 words of memory out of 150001 % Time elapsed: 97.7 seconds \def\setkern#1#2#3{ \x_cs\ifx{i-rawscale}\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} } \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\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 } \def\kerning#1#2{0\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} } % The glyph information is kept in the macros \g-NAME, which expands % out to: % % {WIDTH}{HEIGHT}{DEPTH}{ITALIC} % {MAPCOMMANDS}{MAPFONTS} % % where the MAPCOMMANDS will write out VPL MAP fragments to a VPL % file, and the MAPFONTS will produce any MAPFONT instructions that % are needed. \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} \def\mapcommands{\glyph_parameter\fifth_of_six} \def\mapfonts{\glyph_parameter\sixth_of_six} \def\glyph_parameter#1#2{ \expandafter\expandafter\expandafter #1\csname~g-#2\endcsname } \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} % These are the commands allowed inside a glyph. They are initally set % to \relax, so we can \edef with them safely. \let\saved_scale\relax \let\saved_mapfont\relax \let\saved_raw\relax \let\saved_rule\relax \let\saved_special\relax \let\saved_warning\relax \let\saved_movert\relax \let\saved_moveup\relax \let\saved_push\relax \let\saved_pop\relax % When the glyph is being constructed by \setglyph...\endsetglyph, the % values of each of these parameters are kept in the following % variables. Except for \glyphwidth, these are kept globally, so they % survive through \push ... \pop pairs. \newcount\glyph_width \newcount\glyph_height \newcount\glyph_depth \newcount\glyph_italic \newtoks\glyph_map_commands \newtoks\glyph_map_fonts % In addition, the current vertical offset is kept locally in % \glyph_voffset. \newcount\glyph_voffset % The \setglyph{NAME} command defines \g-NAME, unless \g-NAME has already % been defined. \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{} \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_map_commands={} \global\glyph_map_fonts={} } \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 \def\setrawglyph#1#2#3#4#5#6#7#8{ \x_cs\ifx{g-#1}\relax \x_cs\ifx{i-rawscale}\relax \x_cs\def{g-#1}{ {#5} {#6} {#7} {#8} {\saved_raw{#2}{#4}{#1}} {\saved_mapfont{#2}{#3}} } \else \eval_expr_to\e_count{\int{rawscale}} \eval_expr_to\a_count{\scale{#5}\e_count} \eval_expr_to\b_count{\scale{#6}\e_count} \eval_expr_to\c_count{\scale{#7}\e_count} \eval_expr_to\d_count{\scale{#8}\e_count} \x_cs\edef{g-#1}{ {\the\a_count} {\the\b_count} {\the\c_count} {\the\d_count} {\saved_scale{\the\e_count} {\saved_raw{#2}{#4}{#1}}} {\saved_scale{\the\e_count} {\saved_mapfont{#2}{#3}}} } \fi \fi } \def\setnotglyph#1#2#3#4#5#6#7#8{ \x_cs\ifx{g-#1-not}\relax \x_cs\ifx{i-rawscale}\relax \x_cs\def{g-#1-not}{ {#5} {#6} {#7} {#8} {} {} } \else \eval_expr_to\e_count{\int{rawscale}} \eval_expr_to\a_count{\scale{#5}\e_count} \eval_expr_to\b_count{\scale{#6}\e_count} \eval_expr_to\c_count{\scale{#7}\e_count} \eval_expr_to\d_count{\scale{#8}\e_count} \x_cs\edef{g-#1-not}{ {\the\a_count} {\the\b_count} {\the\c_count} {\the\d_count} {} {} } \fi \fi } \def\unsetglyph#1{\x_cs\let{g-#1}\relax} % The glyph commands are: \def\glyph#1#2{ \eval_expr_to\b_count{#2} \eval_expr_to\glyph_width{\add\glyph_width{\scale\b_count{\width{#1}}}} \g_eval_expr_to\glyph_height{\max\glyph_height {\add{\scale\b_count{\height{#1}}}\glyph_voffset}} \g_eval_expr_to\glyph_depth{\max\glyph_depth {\sub{\scale\b_count{\depth{#1}}}\glyph_voffset}} \g_eval_expr_to\glyph_italic{\scale\b_count{\italic{#1}}} \edef\temp_command{\the\glyph_map_commands \saved_scale{\the\b_count}{\mapcommands{#1}}} \global\glyph_map_commands\expandafter{\temp_command} \edef\temp_command{\the\glyph_map_fonts \saved_scale{\the\b_count}{\mapfonts{#1}}} \global\glyph_map_fonts\expandafter{\temp_command} } \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\temp_command{\the\glyph_map_commands \saved_rule{\the\b_count}{\the\c_count}} \global\glyph_map_commands\expandafter{\temp_command} } \def\glyphspecial#1{ \edef\temp_command{\the\glyph_map_commands\saved_special{#1}} \global\glyph_map_commands\expandafter{\temp_command}} \def\glyphwarning#1{ \edef\temp_command{\the\glyph_map_commands\saved_warning{#1}} \global\glyph_map_commands\expandafter{\temp_command}} \def\movert#1{ \eval_expr{#1} \ifnum\result=0\else \advance\glyph_width by \result \edef\temp_command{\the\glyph_map_commands\saved_movert{\the\result}} \global\glyph_map_commands\expandafter{\temp_command} \fi} \def\moveup#1{ \eval_expr{#1} \ifnum\result=0\else \advance\glyph_voffset by \result \edef\temp_command{\the\glyph_map_commands\saved_moveup{\the\result}} \global\glyph_map_commands\expandafter{\temp_command} \fi} \def\push{\bgroup \edef\temp_command{\the\glyph_map_commands\saved_push} \global\glyph_map_commands\expandafter{\temp_command}} \def\pop{\egroup \edef\temp_command{\the\glyph_map_commands\saved_pop} \global\glyph_map_commands\expandafter{\temp_command}} \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} % Some syntactic sugar... \glyphpcc could do with optimization... \def\glyphpcc#1#2#3{ \push \movert{#2} \moveup{#3} \glyph{#1}{\one_thousand} \pop } \def\samesize#1{ \expandafter\expandafter\expandafter \same_size\csname g-#1\endcsname } \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 } % The control flow command: \def\ifisglyph#1\then{ \x_cs\ifx{g-#1}\relax \expandafter\if_false \else \expandafter\if_true \fi } %%%%%%%%%%%%%%% CONVERTING AN ETX FILE TO A (V)PL FILE %%%%%%%%%%%%%%% % % The macro: % % \etxtovpl{ENCODING}{VPLFILE} % % writes a virtual font (as a virtual property list) with the encoding % ENCODING. % % The macro: % % \etxtopl{ENCODING}{VPLFILE} % % writes a font (as a property list) with the encoding ENCODING. \def\etxtovpl#1#2{{ \def\vpl_extension{vpl} \def\vpl_title{VTITLE} \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} \let\make_mapfonts\gobble_one \let\do_character_map\relax \etx_to_font{#1}{#2} }} \def\etx_to_font#1#2{ \def\do_slot{\resetint\slot_name\slot_number} \inputetx{#1} \open_out{#2.\vpl_extension} \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~with)} \out_line{(COMMENT~\vpl_to_vf{#2})} \out_line{} \out_line{(COMMENT~THIS~FILE~CAN~THEN~BE~DELETED.)} \out_line{} \make_font{#1} \out_line{} \out_line{(COMMENT~END~OF~FILE~#2.\vpl_extension)} \close_out{\vpl_Font} } % \afmconvert\DIMEN=INTEGER EXPRESSION; % 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 131pt, to try to minimize rounding errors. \newdimen\scaled_design_size \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 } % The commands \vpl_real\dimen or \vpl_int\count print a dimension or % integer in (V)PL syntax. \def\vpl_real#1{R~\expandafter\lose_measure\the#1} \def\vpl_int#1{D~\the#1} % \make_font{ENCODING} makes a VPL file. \newdimen\side_bearings \newcount\boundary_char \def\make_font#1{ \make_header{#1} \make_mapfonts{#1} \make_fontdimens{#1} \make_ligtable{#1} \make_characters{#1} \make_tidy{#1} } % \make_header \def\make_header#1{ \global\font_count=0 \setdim{designsize}{10pt} \scaled_design_size=\dim{designsize} \out_line{(DESIGNSIZE~\vpl_real\scaled_design_size)} \out_line{(DESIGNUNITS~\vpl_real\scaled_design_size)} \setstr{codingscheme}{UNKNOWN} \out_line{(CODINGSCHEME~\str{codingscheme})} \ifisint{boundarychar}\then \boundary_char=\int{boundarychar} \out_line{(BOUNDARYCHAR~\vpl_int\boundary_char)} \else \boundary_char=-1 \fi \setint{letterspacing}{0} \afm_convert\side_bearings=\div{\int{letterspacing}}{2}; \ifdim\side_bearings=0pt \let\do_character_sidebearings=\relax \fi \out_line{} } % \make_mapfonts \def\make_mapfonts#1{ \let\saved_scale\vpl_scale \let\saved_mapfont\vpl_mapfont \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 \let\do_slot=\do_mapfont \inputetx{#1} \out_line{} } % \make_fontdimens \def\make_fontdimens#1{ \out_line{(FONTDIMEN} \ifisint{fontdimen(1)}\then \a_dimen=\int{fontdimen(1)}pt \divide\a_dimen by \one_thousand \out_lline{(PARAMETER~D~1~\vpl_real\a_dimen)} \fi \a_count=2 \loop\ifnum\a_count<256 {\ifisint{fontdimen(\the\a_count)}\then \afm_convert\a_dimen=\int{fontdimen(\the\a_count)}; \out_lline{(PARAMETER~\vpl_int\a_count\space\vpl_real\a_dimen)} \fi} \advance\a_count by 1 \repeat \out_lline{)} \out_line{} } % \make_ligtable \def\make_ligtable#1{ \bgroup \out_line{(LIGTABLE} \let\do_slot=\relax \let\end_do_slot=\vpl_kerning \let\ligature=\vpl_ligature \let\k=\vpl_kern \inputetx{#1} \out_lline{)} \egroup \out_line{} } \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 \inputetx{#1} \egroup } % \make_tidy \def\make_tidy#1{ \a_count=0\loop\ifnum\a_count<\font_count \edef\temp_command{\csname~f-\the\a_count\endcsname} \global\x_cs\let\temp_command\relax \advance\a_count by 1 \repeat \global\font_count=0 } % \vpl_ligature{TYPE}{NAME}{NAME} produces a ligtable entry for glyph % \slot_name. \def\vpl_ligature#1#2#3{ \ifisint{#2}\then \ifisint{#3}\then \ifisglyph{#3}\then \a_count=\int{#2} \b_count=\int{#3} \vpl_liglabel \out_lline{(#1~\vpl_int\a_count\space \vpl_int\b_count)~ (COMMENT~#2~#3)} \else \immediate\write16{Warning:~\string\ligature\space for~unknown~slot~`#3'.} \fi \else \immediate\write16{Warning:~\string\ligature\space for~unknown~slot~`#3'.} \fi \else \immediate\write16{Warning:~\string\ligature\space for~unknown~slot~`#2'.} \fi } % \vpl_kerning writes out kerning instructions. \def\vpl_kerning{\csname~r-\slot_name\endcsname\vpl_ligstop} % \vpl_kern\l-NAME\AMOUNT writes out a kern instruction. \def\vpl_kern#1#2{ \edef\temp_command{\expandafter\gobble_three\string#1} \ifisint\temp_command\then \vpl_liglabel \a_count=\int\temp_command \afm_convert\a_dimen=\expandafter\gobble_one\string#2; \out_lline{ (KRN~\vpl_int\a_count\space \vpl_real\a_dimen)~ (COMMENT~\temp_command) } \fi } % \vpl_liglabel writes out a LIGLABEL instruction if appropriate. \def\out_liglabel{ \out_lline{(LABEL~\vpl_int\slot_number)~(COMMENT~\slot_name)} \ifnum\slot_number=\boundary_char \out_lline{(LABEL~BOUNDARYCHAR)} \fi \let\vpl_liglabel=\relax \let\vpl_ligstop=\out_ligstop } \let\vpl_liglabel=\out_liglabel % \vpl_ligstop writes out a LIGSTOP instruction if appropriate. \def\out_ligstop{\out_lline{(STOP)} \let\vpl_liglabel=\out_liglabel \let\vpl_ligstop=\relax} \let\vpl_ligstop=\relax % \do_mapfont produces a MAPFONT entry for each font used by glyph % \slot_name. \def\do_mapfont{ \ifisglyph\slot_name\then \mapfonts\slot_name \fi } % The following commands can be used in a mapfont: \def\vpl_scale#1#2{{ \divide \scaled_design_size by 8 \multiply \scaled_design_size by #1 \divide \scaled_design_size by \one_thousand \multiply \scaled_design_size by 8 #2 }} \def\vpl_mapfont#1#2{ \a_dimen=#2 \x_cs\ifx{#1-\the\scaled_design_size}\relax \x_cs\xdef{#1-\the\scaled_design_size}{\the\font_count} \x_cs\xdef{f-\the\font_count}{#1-\the\scaled_design_size} \out_line{(MAPFONT~\vpl_int\font_count\space (FONTNAME~#1)~ (FONTDSIZE~\vpl_real\a_dimen)~ (FONTAT~\vpl_real\scaled_design_size))} \global\advance\font_count by 1 \fi } \newcount\font_count \newcount\next_mapfont \newcount\prev_mapfont % \do_character produces a character entry for glyph \slot_name in slot % \slot_number. First of all, the version with letterspacing: \newdimen\curr_bearings \def\do_character{ \x_cs\ifx{g-\slot_name}\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; \do_character_sidebearings \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 \do_character_map \fi \fi } % \do_character_sidebearings \def\do_character_sidebearings{ \ifisint{\slot_name-spacing}\then \afm_convert\curr_bearings=\int{\slot_name-spacing}; \divide\curr_bearings by 2 \else \curr_bearings=\side_bearings \fi \afm_convert\a_dimen=\width\slot_name; \advance\a_dimen by 2\curr_bearings } \def\do_character_map{ \global\prev_mapfont=0 \out_lline{(MAP} \ifdim \curr_bearings=0pt \mapcommands\slot_name \else \out_llline{(MOVERIGHT~\vpl_real\curr_bearings)} \mapcommands\slot_name \out_llline{(MOVERIGHT~\vpl_real\curr_bearings)} \fi \out_llline{)} } % Now the version without: \def\do_character_no_letterspacing{ \x_cs\ifx{g-\slot_name}\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 } % Gobble a set_slot \def\gobble_setslot#1\endsetslot{\endsetslot} \def\end_do_character{ \ifisglyph\slot_name\then \out_lline{)} \fi } \def\notdef_name{.notdef} % \vpl_nextlarger{NAME} produces a NEXTLARGER entry. \def\vpl_nextlarger#1{ \ifisint{#1}\then \out_lline{(NEXTLARGER~D~\the\int{#1})~(COMMENT~#1)} \else \immediate\write16{Warning:~\string\nextlarger\space for~unknown~slot~`#1'} \fi } % \vpl_varchar VARCHAR COMMANDS \end_vpl_varchar produces a VARCHAR entry. \def\vpl_varchar{\out_lline{(VARCHAR}} \def\vpl_vartop#1{ \ifisint{#1}\then \out_llline{(TOP~D~\the\int{#1})~(COMMENT~#1)} \else \immediate\write16{Warning:~\string\vartop\space for~unknown~slot~`#1'} \fi } \def\vpl_vartop#1{ \ifisint{#1}\then \out_llline{(TOP~D~\the\int{#1})~(COMMENT~#1)} \else \immediate\write16{Warning:~\string\vartop\space for~unknown~slot~`#1'} \fi } \def\vpl_varmid#1{ \ifisint{#1}\then \out_llline{(MID~D~\the\int{#1})~(COMMENT~#1)} \else \immediate\write16{Warning:~\string\varmid\space for~unknown~slot~`#1'} \fi } \def\vpl_varbot#1{ \ifisint{#1}\then \out_llline{(BOT~D~\the\int{#1})~(COMMENT~#1)} \else \immediate\write16{Warning:~\string\varbot\space for~unknown~slot~`#1'} \fi } \def\vpl_varrep#1{ \ifisint{#1}\then \out_llline{(REP~D~\the\int{#1})~(COMMENT~#1)} \else \immediate\write16{Warning:~\string\varrep\space for~unknown~slot~`#1'} \fi } \def\end_vpl_varchar{\out_llline{)}} % The following commands can be used in a glyph: \def\vpl_raw#1#2#3{ \global\next_mapfont=\csname~#1-\the\scaled_design_size\endcsname\relax \ifnum\next_mapfont=\prev_mapfont\else \out_llline{(SELECTFONT~\vpl_int\next_mapfont)~ (COMMENT~#1~at~\the\scaled_design_size)} \fi \out_llline{(SETCHAR~D~#2)~(COMMENT~#3)} \global\prev_mapfont=\next_mapfont } \def\vpl_rule#1#2{ \afm_convert\a_dimen=#1; \afm_convert\b_dimen=#2; \out_llline{(SETRULE~\vpl_real\b_dimen\space~\vpl_real\a_dimen)} } \def\vpl_special#1{\out_llline{(SPECIAL~#1)}} \def\vpl_warning#1{ \out_llline{(SPECIAL~Warning:~#1)} \immediate\write16{Warning:~#1.} } \def\vpl_movert#1{ \afm_convert\a_dimen=#1; \out_llline{(MOVERIGHT~\vpl_real\a_dimen)} } \def\vpl_moveup#1{ \afm_convert\a_dimen=#1; \out_llline{(MOVEUP~\vpl_real\a_dimen)} } \def\vpl_push{\out_llline{(PUSH)}} \def\vpl_pop{\out_llline{(POP)}} %%%%%%%%%%%%%%% CONVERTING AN MTX FILE TO A PL FILE %%%%%%%%%%%%%%% % % The macro: % % \mtxtopl{MTXFILE}{PLFILE} % % writes a font from the \rawglyph instructions in PLFILE. It ignores % any font dimensions and kerning, so the resulting font is only useful % for generating virtual fonts from. \def\mtxtopl#1#2{{ \open_out{#2.pl} \out_line{(COMMENT~raw~font~#2~created~by~fontinst~v\fontinstversion)} \out_line{} \out_line{(COMMENT~Filename:~#2.pl)} \out_line{(COMMENT~Created~by:~tex~\jobname)} \out_line{(COMMENT~Created~using:~\string\mtxtopl{#1}{#2})} \out_line{} \out_line{(COMMENT~This~file~can~be~turned~into~a~TeX~font~with)} \out_line{(COMMENT~pltotfm~#2.pl~#2.tfm)} \out_line{} \out_line{(COMMENT~THIS~FILE~CAN~THEN~BE~DELETED.)} \out_line{} \out_line{(DESIGNSIZE~R~10.0)} \out_line{(DESIGNUNITS~R~10.0)} \out_line{} \scaled_design_size=10pt \let\setglyph=\iffalse \let\endsetglyph=\fi \let\setkern=\gobble_three \let\setrawglyph=\pl_raw_glyph \inputmtx{#1} \out_line{} \out_line{(COMMENT~END~OF~FILE~#2.pl)} \close_out{Raw~font} }} \def\pl_raw_glyph#1#2#3#4#5#6#7#8{ \a_count=#4 \afm_convert\a_dimen=#5; \afm_convert\b_dimen=#6; \afm_convert\c_dimen=#7; \afm_convert\d_dimen=#8; \out_line{(CHARACTER~\vpl_int\a_count\space(COMMENT~#1)} \out_lline{(CHARWD~\vpl_real\a_dimen)} \out_lline{(CHARHT~\vpl_real\b_dimen)} \out_lline{(CHARDP~\vpl_real\c_dimen)} \out_lline{(CHARIC~\vpl_real\d_dimen)} \out_lline{)} } %%%%%%%%%%%%%%% WRAPPING IT UP %%%%%%%%%%%%%%% % % The macro: % % \installfonts INSTALL COMMANDS \endinstallfonts % % is the top-level interface for installing a number of fonts and % creating FD files for them. % % The INSTALL COMMANDS are: % % \installfamily{ENCODING}{FAMILY}{FD-COMMANDS} % \installfont{FONT-NAME}{FILE-LIST}{ETX} % {ENCODING}{FAMILY}{SERIES}{SHAPE}{SIZE} % \installrawfont{FONT-NAME}{FILE-LIST}{ETX} % {ENCODING}{FAMILY}{SERIES}{SHAPE}{SIZE} \def\declareencoding#1#2{\x_cs\edef{enc-#1}{#2}} \declareencoding{EXTENDED~TEX~FONT~ENCODING~-~LATIN}{T1} \declareencoding{TEX~TEXT}{OT1} \declareencoding{TEX~TEXT~WITHOUT~F-LIGATURES}{OT1} \declareencoding{TEX~TYPEWRITER~TEXT}{OT1TT} \declareencoding{TEX~MATH~ITALIC}{OML} \declareencoding{TEX~MATH~SYMBOLS}{OMS} \declareencoding{TEX~MATH~EXTENSION}{OMX} \declareencoding{TEXBASE1ENCODING}{8r} \def\declaresize#1#2{\x_cs\edef{siz-#1}{#2}} \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>} \def\installfonts{ \bgroup \global\family_toks={} \gdef\prev_file_list{} } \newtoks\family_toks \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 } % \installfont{FONT-NAME}{FILE-LIST}{ETX} % {ENCODING}{FAMILY}{SERIES}{SHAPE}{SIZE} \def\installfont#1#2#3#4#5#6#7#8{ \install_font{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}{\etxtovpl} } % \installrawfont{FONT-NAME}{FILE-LIST}{ETX} % {ENCODING}{FAMILY}{SERIES}{SHAPE}{SIZE} \def\installrawfont#1#2#3#4#5#6#7#8{ \install_font{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}{\etxtopl} } % \install_font{FONT-NAME}{FILE-LIST}{ETX} % {ENCODING}{FAMILY}{SERIES}{SHAPE}{SIZE}{CONVERTER} \def\install_font#1#2#3#4#5#6#7#8#9{ \xdef\curr_file_list{#2} \ifx\prev_file_list\curr_file_list\else \egroup\bgroup \expandafter\input_mtx_files\curr_file_list, \relax,\end_input_mtx_files \global\let\prev_file_list=\curr_file_list \fi #9{#3}{#1} \x_cs\ifx{#4-#5-#6-#7}\relax \let\do_shape=\relax \x_cs\xdef{#4-#5}{ \x_cs\ifx{#4-#5}\relax\else \csname#4-#5\endcsname \fi \do_shape{#4}{#5}{#6}{#7} } \fi \let\do_size=\relax \x_cs\xdef{#4-#5-#6-#7}{ \x_cs\ifx{#4-#5-#6-#7}\relax\else \csname#4-#5-#6-#7\endcsname \fi \do_size{#8}{#1} } } % \endinstallfonts \def\endinstallfonts{ \let\do_shape=\fd_shape \let\do_size=\fd_size \the\family_toks \global\family_toks{} \egroup } % \input_mtx_files{FILE-LIST} \def\input_mtx_files#1,#2\end_input_mtx_files{ \if\relax#1 \expandafter\gobble_one \else \expandafter\identity_one \fi{ \input_mtx_file{#1} \input_mtx_files#2\end_input_mtx_files } } % \input_mtx_file{FILE} \def\input_mtx_file#1{ \if\relax#1\relax\else \get_file_name #1~scaled~1000~; \if_file_exists{\file_name.mtx}\then \inputmtx\file_name \else % % changed the order (SPQR, 15/1/97) because of % cmr*.afm files found in $TEXMF/fonts/afm hierarchy % \if_file_exists{\file_name.pl}\then \pltomtx\file_name\file_name \else \if_file_exists{\file_name.afm}\then \afmtomtx\file_name\file_name \mtxtopl\file_name\file_name \fi \fi \inputmtx\file_name \fi \fi } % \get_file_name FILENAME scaled SCALE JUNK ; \def\get_file_name #1~scaled~#2~#3;{ \edef\file_name{#1} \ifnum#2=\one_thousand \unsetint{rawscale} \else \setint{rawscale}{#2} \fi } % \fd_family{ENCODING}{FAMILY}{FD-COMMANDS} \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}\relax \out_line{} \out_line{\string\endinput} \close_out{Font~definitions} } % \substitute_shape{ENCODING}{FAMILY}{SERIES}{SHAPE} \def\substitute_shape#1#2#3#4{ \edef\orig_shape{#4} \substitute_series{#1}{#2}{#3}{\orig_shape} \x_cs\ifx{sub-\orig_shape}\relax\else \edef\subst_shape{\csname sub-\orig_shape\endcsname} \x_cs\ifx{#1-#2-#3-\subst_shape}\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 } % \substitute_series{ENCODING}{FAMILY}{SERIES}{SHAPE} \def\substitute_series#1#2#3#4{ \edef\orig_series{#3} \x_cs\ifx{sub-\orig_series}\relax\else \edef\subst_series{\csname sub-\orig_series\endcsname} \x_cs\ifx{#1-#2-\subst_series-#4}\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 } % \substitutesilent{FROM}{TO} % \substitutenoisy{FROM}{TO} \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} } % Default substitutions. \substitutenoisy{ui}{it} \substitutesilent{bx}{b} \substitutesilent{b}{bx} \substitutesilent{b}{sb} \substitutesilent{b}{db} \substitutesilent{m}{mb} % UV added 1998/04/30 \substitutesilent{m}{l} %\substitutesilent{l}{m} % UV: do we need this? % I don't think we want these: oh yes we do (SPQR) % \substitutesilent{sl}{it} \substitutesilent{it}{sl} % % since in OT1 encoding it will cause the old vs % problem. % \remove_shape{ENCODING}{FAMILY}{SERIES}{SHAPE} \def\remove_shape#1#2#3#4{ \x_cs\g_let{#1-#2-#3-#4}\relax } % \fd_shape{ENCODING}{FAMILY}{SERIES}{SHAPE} \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{}} } % \fd_size{SIZE}{FONT-NAME} \def\fd_size#1#2{ \x_cs\ifx{siz-#1}\relax \out_lline{#1~#2} \else \out_lline{\csname siz-#1\endcsname\space #2} \fi } %%%%%%%%%%%%%%% FONT TRANSFORMS %%%%%%%%%%%%%%% % % The macro: % % \transformfont{FONT-NAME}{TRANSFORMED FONT} % % transforms a raw font. The TRANSFORMED FONT commands are: % % \fromafm{AFM} % \scalefont{INTEGER EXPRESSION}{TRANSFORMED FONT} % \xscalefont{INTEGER EXPRESSION}{TRANSFORMED FONT} % \yscalefont{INTEGER EXPRESSION}{TRANSFORMED FONT} % \slantfont{INTEGER EXPRESSION}{TRANSFORMED FONT} % \reencodefont{ETX}{TRANSFORMED FONT} % \def\transformfont#1#2{{ \unsetstr{afm-name} \unsetstr{etx-name} \resetint{x-scale}{\one_thousand} \resetint{y-scale}{\one_thousand} \resetint{slant-scale}{0} #2 \mtxtomtx{\str{afm-name}}{#1} \mtxtopl{#1}{#1} }} \def\fromafm#1{ \setstr{afm-name}{#1} \afmtomtx{#1}{#1} \mtxtopl{#1}{#1} } \def\frommtx{ \setstr{afm-name} } \def\frompl#1{ \setstr{afm-name}{#1} \pltomtx{#1}{#1} } \def\scalefont#1#2{ \resetint{x-scale}{#1} \resetint{y-scale}{\int{x-scale}} #2 } \def\xscalefont#1#2{ \resetint{x-scale}{#1} #2 } \def\yscalefont#1#2{ \resetint{y-scale}{#1} #2 } \def\slantfont#1#2{ \resetint{slant-scale}{#1} #2 } \def\reencodefont#1#2{ \resetstr{etx-name}{#1} #2 } % The macro: % % \mtxtomtx{MTX}{MTX} % % Converts the first MTX file to the second, using the current values of % \int{x-scale}, \int{y-scale}, \int{slant-scale} and \str{etx-name}. % NOTE: this doesn't convert arbitrary MTX files, just ones created with % \afmtomtx. \def\mtxtomtx#1#2{{ \ifisstr{etx-name}\then \def\do_slot{\resetint\slot_name\slot_number} \inputetx{\str{etx-name}} \fi \open_out{\temp_prefix#2.mtx} \def\raw_font_name{#2} \out_line{\percent_char~Filename:~#2.mtx} \out_line{\percent_char~Created~by:~tex~\jobname} \out_line{\percent_char~Created~using:~\string\mtxtomtx{#1}{#2}} \out_line{} \out_line{\percent_char~This~file~is~used~by~the~fontinst~package.} \out_line{} \out_line{\percent_char~THIS~FILE~CAN~BE~DELETED.} \out_line{} \out_line{\string\relax} \out_line{\string\metrics} \out_line{} \out_line{\string\needsfontinstversion{\fontinstversion}} \out_line{} \let\setint=\mtxtomtx_setint \let\setrawglyph=\mtxtomtx_setrawglyph \let\setnotglyph=\mtxtomtx_setrawglyph \let\setkern=\mtxtomtx_setkern \let\setglyph=\mtxtomtx_setglyph \let\glyphpcc=\mtxtomtx_glyphpcc \let\samesize=\mtxtomtx_samesize \let\endsetglyph=\mtxtomtx_endsetglyph \inputmtx{#1} \out_line{} \out_line{\string\endmetrics} \close_out{Transformed~metrics} }} \def\mtxtomtx_setint#1#2{ \def\temp_command{#1} \ifx\temp_command\italicslant_name \eval_expr_to\a_count{ \add{\int{slant-scale}}{ \div{\mul{\int{x-scale}}{#2}}{\int{y-scale}} } } \else \eval_expr_to\a_count{\scale{#2}{\int{y-scale}}} \fi \out_line{\string\setint{#1}{\the\a_count}} } \def\italicslant_name{italicslant} \def\mtxtomtx_setrawglyph#1#2#3#4#5#6#7#8{ \eval_expr_to\a_count{\scale{#5}{\int{x-scale}}} \eval_expr_to\b_count{\scale{#6}{\int{y-scale}}} \eval_expr_to\c_count{\scale{#7}{\int{y-scale}}} \eval_expr_to\d_count{ \add{ \scale{#8}{\int{x-scale}} }{ \scale\b_count{\int{slant-scale}} } } \ifisstr{etx-name}\then \ifisint{#1}\then \e_count=\int{#1} \else \e_count=-1 \fi \else \e_count=#4 \fi \out_line{ \ifnum\e_count>-1 \string\setrawglyph \else \string\setnotglyph \fi {#1}{\raw_font_name}{#3}{\the\e_count} {\the\a_count}{\the\b_count}{\the\c_count}{\the\d_count} } } \def\mtxtomtx_setkern#1#2#3{ \eval_expr{\scale{\int{x-scale}}{#3}} \out_line{\string\setkern{#1}{#2}{\the\result}} } \def\mtxtomtx_setglyph#1{\out_line{\string\setglyph{#1}}} \def\mtxtomtx_samesize#1{\out_lline{\string\samesize{#1}}} \def\mtxtomtx_endsetglyph{\out_line{\string\endsetglyph}} \def\mtxtomtx_glyphpcc#1#2#3{ \eval_expr_to\b_count{\scale{\int{y-scale}}{#3}} \eval_expr_to\a_count{ \add{\scale{\int{x-scale}}{#2}}{\scale\b_count{\int{slant-scale}}} } \out_lline{\string\glyphpcc{#1}{\the\a_count}{\the\b_count}} } %%%%%%%%%%%%%%% LATIN FAMILIES %%%%%%%%%%%%%%% % % The macro: % % \latinfamily{FAMILY}{COMMANDS} % % installs a Latin font family. % (Note by ASAJ: I've commented out some of SPQR and CK's debugging % info). \def\latinfamily#1#2{ \edef\temp_command{#1} \expandafter\parse_family\temp_command \empty_command\empty_command\end_parse_family \installfonts \installfamily{T1}{#1}{#2} \installfamily{OT1}{#1}{#2} \if_file_exists{ \raw_encoding.mtx }\then \installfamily{\raw_encoding}{#1}{#2} \fi \latin_weights \endinstallfonts } % \parse_family FAMILY \end_parse_family % \parse_family FAMILY\end_parse_family % % SPQR 2/95. If the fourth parameter is x or 9, then its an % expert indication, not a variant. so initialy set \raw_variant % to #4, but unset it if the expert test succeeds. When #4 is used % for a real variant, it passes through. % % SPQR 5/95. If it *is* an expert font, then the variantness % is expressed by the encoding, not a variant letter, so % unset font_variant \def\parse_family #1#2#3#4#5\end_parse_family{ \edef\font_family{#1#2#3} \edef\font_variant{#4#5} \edef\raw_variant{#4#5} \edef\latex_family{#1#2#3#4#5} \_expert_false \ifx#4x \_expert_true \edef\raw_variant{} \edef\font_variant{#5} \setcommand\digit##1{##1} \else\ifx#49 \_expert_true \edef\raw_variant{} \edef\font_variant{#5} \setcommand\digit##1{##1oldstyle} \else \_expert_false \setcommand\digit##1{##1} \fi\fi %\if_expert_ % \immediate\write16{INFO>~parse~(expert)~#1,~#2,~#3,~#4,~#5} %\else % \immediate\write16{INFO>~parse~#1,~#2,~#3,~#4,~#5} %\fi } \newif\if_expert_ % \latin_weight{FONTWEIGHT}{LATEXWEIGHT} \def\latin_weight#1#2{ \gdef\font_weight{#1}% \gdef\latex_weight{#2}% \latin_widths } % \latin_width{FONTWIDTH}{LATEXWIDTH} \def\latin_width#1#2{ \gdef\font_width{#1} \gdef\latex_width{#2} \latin_shapes } % \latin_shape{FONTSHAPE}{RAWSHAPE}{ENCODINGSHAPE}{LATEXSHAPE} \def\latin_shape#1#2#3#4{ \gdef\font_shape{#1} \gdef\raw_shape{#2} \gdef\encoding_shape{#3} \gdef\latex_shape{#4} \immediate\write16{INFO>to~make~LaTeX~(family,weight,shape,width)~ \font_family,\latex_weight,\latex_shape,\latex_width:~seek~ \font_family\font_weight\raw_shape \raw_variant\raw_encoding\font_width} \csname fake_width_\font_width\endcsname \csname fake_shape_\raw_shape\endcsname \if_file_exists{ \font_family\font_weight\raw_shape \raw_variant\raw_encoding\font_width.mtx }\then \immediate\write16{INFO>~found~\font_family\font_weight \raw_shape\raw_variant\raw_encoding\font_width.mtx} \latin_encodings \fi } % (CK) changed font faking code; based on Sebastian code (still in this file). % I am not sure that know what I am doing here; let's hope I won't be % caught... Also changed: Order of \font_width and \..._encoding in MANY % places. Also added tests which prevent multiple calls to the same font % faking routine. (Seems to be necessary in some cases and can't hurt.) % % (ASAJ) I think CK knows more about what he's doing than he's letting on... % % (UV) added another level of complexity: It appears that AFM files generated % from TrueType fonts with ttf2afm have to be reencoded to 8r directly % since reencoding them to 8a as usual would mean dropping many glyphs. % Therefore, we'll have to be prepared to check for 8r-encoded AFM files % at this place as well. \def\fake_shape_{ \if_file_exists{ \font_family\font_weight\raw_shape\raw_variant \adobe_encoding\font_width.afm }\then \if_file_exists{ \font_family\font_weight\raw_shape\raw_variant \raw_encoding\font_width.mtx }\then % no action required \else \transformfont{ \font_family\font_weight\raw_shape\raw_variant \raw_encoding\font_width }{ \reencodefont{\raw_encoding}{ \fromafm{ \font_family\font_weight\raw_shape\raw_variant \adobe_encoding\font_width } } } %%% Do a ligfull installation if possible \if_file_exists{ \raw_encoding.mtx }\then \installrawfont{ \font_family\font_weight\raw_shape\raw_variant \raw_encoding\font_width }{ \font_family\font_weight\raw_shape\raw_variant \raw_encoding\font_width, \raw_encoding }{ \raw_encoding }{ \raw_encoding }{ \latex_family }{ \latex_weight\latex_width }{ \latex_shape }{} \fi %%% End of ligfull installation \fi \fi %% begin UV: 1998/05/05 %% copy the whole block from above, replace \raw_encoding %% for \adobe_encoding and omit the \reencodefont step \if_file_exists{ \font_family\font_weight\raw_shape\raw_variant \raw_encoding\font_width.afm }\then \if_file_exists{ \font_family\font_weight\raw_shape\raw_variant \raw_encoding\font_width.mtx }\then % no action required \else %%% Do a ligfull installation if possible \if_file_exists{ \raw_encoding.mtx }\then \installrawfont{ \font_family\font_weight\raw_shape\raw_variant \raw_encoding\font_width }{ \font_family\font_weight\raw_shape\raw_variant \raw_encoding\font_width, \raw_encoding }{ \raw_encoding }{ \raw_encoding }{ \latex_family }{ \latex_weight\latex_width }{ \latex_shape }{} \fi %%% End of ligfull installation \fi \fi %% end UV: \if_expert_ \if_file_exists{ \font_family\font_weight\raw_variant\raw_shape \expert_encoding\font_width.afm }\then \if_file_exists{ \font_family\font_weight\raw_variant\raw_shape \expert_encoding\font_width.mtx }\then % no action required \else \def\_file_name{ \font_family\font_weight\raw_variant\raw_shape \expert_encoding\font_width } \afmtomtx\_file_name\_file_name \mtxtopl\_file_name\_file_name \fi \fi \fi } \def\fake_shape_c{ \if_file_exists{ \font_family\font_weight\raw_shape\raw_variant \adobe_encoding\font_width.afm }\then \fake_shape_ \else \if_file_exists{ \font_family\font_weight\raw_shape\raw_variant \raw_encoding\font_width.afm }\then \fake_shape_ \else % If real smallcaps font doesn't exist, fake it from the roman. \def\encoding_shape{c} \def\raw_shape{} \fake_shape_ \fi \fi } \def\fake_shape_o{ \if_file_exists{ \font_family\font_weight\raw_shape\raw_variant \adobe_encoding\font_width.afm }\then \fake_shape_ \else \if_file_exists{ \font_family\font_weight\raw_shape\raw_variant \raw_encoding\font_width.afm }\then \fake_shape_ \else \fake_shape_o_raw_encoding \if_expert_ \fake_shape_o_expert_encoding \fi \fi \fi } \def\fake_shape_o_expert_encoding{ \if_file_exists{ \font_family\font_weight\raw_variant \expert_encoding\font_width.mtx }\then \if_file_exists{ \font_family\font_weight\raw_variant\font_shape \expert_encoding\font_width.mtx }\then % no action required \else \immediate\write16{ Faking~oblique~font~ \font_family\font_weight\raw_variant\font_shape \expert_encoding\font_width \space from~ \font_family\font_weight\raw_variant \expert_encoding\font_width } \transformfont{ \font_family\font_weight\raw_variant\font_shape \expert_encoding\font_width }{ \slantfont{\SlantAmount}{ \frommtx{ \font_family\font_weight\raw_variant \expert_encoding\font_width } } } \fi \fi } \def\fake_shape_o_raw_encoding{ \if_file_exists{ \font_family\font_weight\raw_variant \raw_encoding\font_width.mtx }\then \if_file_exists{ \font_family\font_weight\font_shape\raw_variant \raw_encoding\font_width.mtx }\then % no action required \else \immediate\write16{ Faking~oblique~font~ \font_family\font_weight\font_shape\raw_variant \raw_encoding\font_width \space from~ \font_family\font_weight\raw_variant \raw_encoding\font_width } \transformfont{ \font_family\font_weight\font_shape\raw_variant \raw_encoding\font_width }{ \slantfont{\SlantAmount}{ \frommtx{ \font_family\font_weight\raw_variant \raw_encoding\font_width } } } %%% Do a ligfull installation if possible \if_file_exists{ \raw_encoding.mtx }\then \installrawfont{ \font_family\font_weight\font_shape\raw_variant \raw_encoding\font_width }{ \font_family\font_weight\font_shape\raw_variant \raw_encoding\font_width, \raw_encoding }{ \raw_encoding }{ \raw_encoding }{ \latex_family }{ \latex_weight\latex_width }{ \latex_shape }{} \fi %%% End of ligfull installation \fi \fi } \let\fake_shape_i\fake_shape_ % We must do this again! \newif\if_fake_narrow_ \_fake_narrow_false \def\fakenarrow#1{ \_fake_narrow_true \gdef\fake_narrow_width{#1} } \def\fake_width_{} \def\fake_width_n{ \if_fake_narrow_ \if_file_exists{ \font_family\font_weight\raw_shape\raw_variant \adobe_encoding\font_width.afm }\then % no action required \else \if_file_exists{ \font_family\font_weight\raw_shape\raw_variant \raw_encoding\font_width.afm }\then % no action required \else \fake_width_n_raw_encoding \if_expert_ \fake_width_n_expert_encoding \fi \fi \fi \fi } \def\fake_width_n_expert_encoding{ \if_file_exists{ \font_family\font_weight\raw_variant\font_shape \expert_encoding.mtx }\then \if_file_exists{ \font_family\font_weight\raw_variant\font_shape \expert_encoding\font_width.mtx }\then % no action required \else \immediate\write16{ Faking~narrow~font~ \font_family\font_weight\raw_variant\font_shape \expert_encoding\font_width \space from~ \font_family\font_weight\raw_variant\font_shape \expert_encoding } \transformfont{ \font_family\font_weight\raw_variant\font_shape \expert_encoding\font_width }{ \xscalefont{\fake_narrow_width}{ \frommtx{ \font_family\font_weight\raw_variant\font_shape \expert_encoding } } } \fi \fi } \def\fake_width_n_raw_encoding{ \if_file_exists{ \font_family\font_weight\font_shape\raw_variant \raw_encoding.mtx }\then \if_file_exists{ \font_family\font_weight\font_shape\raw_variant \raw_encoding\font_width.mtx }\then % no action required \else \immediate\write16{ Faking~narrow~font~ \font_family\font_weight\font_shape\raw_variant \raw_encoding\font_width \space from~ \font_family\font_weight\font_shape\raw_variant \raw_encoding } \transformfont{ \font_family\font_weight\font_shape\raw_variant \raw_encoding\font_width }{ \xscalefont{\fake_narrow_width}{ \frommtx{ \font_family\font_weight\font_shape\raw_variant \raw_encoding } } } %%% Do a ligfull installation if possible \if_file_exists{ \raw_encoding.mtx }\then \installrawfont{ \font_family\font_weight\font_shape\raw_variant \raw_encoding\font_width }{ \font_family\font_weight\font_shape\raw_variant \raw_encoding\font_width, \raw_encoding }{ \raw_encoding }{ \raw_encoding }{ \latex_family }{ \latex_weight\latex_width }{ \latex_shape }{} \fi %%% End of ligfull installation \fi \fi } % \latin_encoding{FONTENCODING}{LATEXENCODING}{EXPERTISEDENCODING} % if this is an expertised family, the base font changes encoding % \def\latin_encoding#1#2#3{ \gdef\latex_encoding{#2} \if_expert_ \gdef\font_encoding{#3} \else \gdef\font_encoding{#1} \fi \gdef\expert_font{} \if_expert_ \if_file_exists{ \font_family\font_weight\raw_shape\raw_variant \expert_encoding\font_width.mtx }\then \gdef\expert_font{ \font_family\font_weight\raw_variant\raw_shape \expert_encoding\font_width, } \fi \fi \immediate\write16{INFO>run~installfont~with~ <\font_family\font_weight\font_shape\font_variant \font_encoding\font_width> <\font_family\font_weight\raw_shape\raw_variant \raw_encoding\font_width, \expert_font latin> <\latex_encoding\encoding_shape> <\latex_encoding> <\latex_family> <\latex_weight\latex_width> <\latex_shape >} \installfont{ \font_family\font_weight\font_shape\font_variant \font_encoding\font_width }{ \font_family\font_weight\raw_shape\raw_variant \raw_encoding\font_width, \expert_font latin }{ \latex_encoding\encoding_shape }{ \latex_encoding }{ \latex_family }{ \latex_weight\latex_width }{ \latex_shape }{} } %% Fontname 2.1: weight.map NFSS: LaTeX Comapion, p. 190 %% %% a Thin Hairline ul Ultra Light %% j ExtraLight el Extra Light %% l Light l Light %% r Regular Roman m Medium (normal) %% k Book m %% m Medium m (mb, as per UV) %% d Demi sb (db, as per SPQR) %% s Semibold sb Semi Bold %% b Bold b Bold %% h Heavy Heavyface eb %% c Black eb %% x ExtraBold ExtraBlack eb Extra Bold %% u Ultra UltraBlack ub Ultra Bold %% p Poster % The standard values. These may be changed, but you'd better know % what you're doing. % UV: Changes 1998/04/30 % % Changed the processing order: Do the most common shapes first. % Added new mappings for `c' (Black) and `h' (Heavy) to `eb', % changed mapping for `m' (Medium) to newly invented shape `mb'. \def\latin_weights{ \latin_weight{r}{m} \latin_weight{k}{m} \latin_weight{b}{b} \latin_weight{s}{sb} \latin_weight{d}{db} % SPQR was {d}{sb} \latin_weight{m}{mb} % UV was {m}{m} \latin_weight{c}{eb} % UV added \latin_weight{h}{eb} % UV added \latin_weight{x}{eb} \latin_weight{u}{ub} \latin_weight{l}{l} \latin_weight{i}{el} % UV should this be `j'? \latin_weight{a}{ul} % UV added } \def\latin_widths{ \latin_width{}{} \latin_width{n}{c} } \def\latin_shapes{ \latin_shape{} {} {} {n} \latin_shape{c}{c}{} {sc} \latin_shape{o}{o}{} {sl} \latin_shape{i}{i}{i}{it} } \def\latin_encodings{ \latin_encoding{7t}{OT1}{9t} \latin_encoding{8t}{T1}{9e} } \def\raw_encoding{8r} \def\adobe_encoding{8a} \def\expert_encoding{8x} \def\SlantAmount{167} %%%%%%%%%%%%%%% VERSION NUMBERS %%%%%%%%%%%%%%% % % The macro: % % \needsfontinstversion{NUMBER} % % checks the version number. \def\needsfontinstversion#1{{ \a_dimen=#1pt \b_dimen=\fontinstversion~pt\relax \ifnum\a_dimen>\b_dimen \immediate\write16{} \immediate\write16{Warning:~This~file~needs~fontinst~version~#1.} \immediate\write16{Warning:~You~are~using~version~\fontinstversion.} \immediate\write16{Warning:~This~may~cause~errors.} \immediate\write16{} \fi }} % The directory for temporary files. \def\tempfileprefix#1{\def\temp_prefix{#1}} \tempfileprefix{} %%%%%%%%%%%%%%% DEBUGGING %%%%%%%%%%%%%%% % % \NOFILES switches off file generation, and causes fontinst only to % generate empty files. \def\NOFILES{ \def\transformfont##1##2{ \touch_file{##1.pl} \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} } } \def\touch_file#1{ \open_out{#1} \out_line{\percent_char~TEST~FILE.} \out_line{\percent_char~Created~whilst~debugging~fontinst.} \close_out{Test~file} } % By default, show as much error info as you can (I assume fontinst % users are TeXperts. \errorcontextlines=999 % Set \newlinechar for \errhelp messages \newlinechar=`\^^J %%%%%%%%%%%%%%% EXIT %%%%%%%%%%%%%%% % % If \bye hasn't been defined, define it (for LaTeX). \ifx\bye\undefined_command \outer\x_cs\def{bye}{\par\vfill\supereject\@@end} \fi %%%%%%%%%%%%%%% RESTORE CATCODES %%%%%%%%%%%%%%% % % Restore the catcodes we changed. \catcode`\@=\atcatcode \catcode`\^^M=\nlcatcode \catcode`\ =\spacecatcode \catcode`\~=\tildecatcode %%%%%%%%%%%%%%% RC FILE %%%%%%%%%%%%%%% % % We input the fontinst.rc file, if it exists. \if_file_exists{fontinst.rc}\then % order changed 1997/02/07 \primitiveinput fontinst.rc \catcode`\_=\underscorecatcode \else \catcode`\_=\underscorecatcode \immediate\write16{No file fontinst.rc.} \fi %%%%%%%%%%%%%%% THE END %%%%%%%%%%%%%%% \endinput