%% This is part of the OpTeX project, see http://petr.olsak.net/optex

\_codedecl \typosize {Font managing macros from OPmac <2022-02-22>} % preloaded in format

   \_doc -----------------------------
   \`\typosize` `[<font-size>/<baselineskip>]` sets given parameters.
   It sets text font size by the \^`\setfontsize` macro and math font sizes
   by setting internal macros \^`\_sizemtext`, \^`\_sizemscript` and
   \^`\_sizemsscript`. It uses common concept font sizes: 100\,\%,
   70\,\% and 50\,\%.
   The \^`\_setmainvalues` sets the parameters as main values when
   the `\_typosize` is called first.
   \_cod -----------------------------

\_protected\_def \_typosize [#1/#2]{%
   \_textfontsize{#1}\_mathfontsize{#1}\_setbaselineskip{#2}%
   \_setmainvalues \_ignorespaces
}
\_protected\_def \_textfontsize #1{\_if$#1$\_else \_setfontsize{at#1\_ptunit}\_fi}

\_def \_mathfontsize #1{\_if$#1$\_else
    \_tmpdim=#1\_ptunit
    \_edef\_sizemtext{\_ea\_ignorept \_the\_tmpdim \_ptmunit}%
    \_tmpdim=0.7\_tmpdim
    \_edef\_sizemscript{\_ea\_ignorept \_the\_tmpdim \_ptmunit}%
    \_tmpdim=#1\_ptunit \_tmpdim=0.5\_tmpdim
    \_edef\_sizemsscript{\_ea\_ignorept \_the\_tmpdim \_ptmunit}%
    \_fi
}
\_public \typosize ;

   \_doc -----------------------------
   \`\typoscale` `[<font-factor>/<baseline-factor>]` scales
   font size and baselineskip by given factors in respect to current values.
   It calculates the \^`\typosize` parameters and runs the \^`\typosize`.
   \_cod -----------------------------

\_protected\_def \_typoscale [#1/#2]{%
   \_ifx$#1$\_def\_tmp{[/}\_else
      \_settmpdim{#1}\_optsize
      \_edef\_tmp{[\_ea\_ignorept\_the\_tmpdim/}\_fi
   \_ifx$#2$\_edef\_tmp{\_tmp]}\_else
      \_settmpdim{#2}\_baselineskip
      \_edef\_tmp{\_tmp \_ea\_ignorept\_the\_tmpdim]}\_fi
   \_ea\_typosize\_tmp
}
\_def\_settmpdim#1#2{%
   \_tmpdim=#1pt \_divide\_tmpdim by1000
   \_tmpdim=\_ea\_ignorept \_the#2\_tmpdim
}
\_public \typoscale ;

   \_doc -----------------------------
   \`\_setbaselineskip` `{<baselineskip>}` sets new `\baselineskip` and
   more values of registers which are dependent on the `<baselineskip>`
   including the \^`\strutbox`.
   \_cod -----------------------------

\_def \_setbaselineskip #1{\_if$#1$\_else
   \_tmpdim=#1\_ptunit
   \_baselineskip=\_tmpdim \_relax
   \_bigskipamount=\_tmpdim plus.33333\_tmpdim minus.33333\_tmpdim
   \_medskipamount=.5\_tmpdim plus.16666\_tmpdim minus.16666\_tmpdim
   \_smallskipamount=.25\_tmpdim plus.08333\_tmpdim minus.08333\_tmpdim
   \_normalbaselineskip=\_tmpdim
   \_jot=.25\_tmpdim
   \_maxdepth=.33333\_tmpdim
   \_setbox\_strutbox=\_hbox{\_vrule height.709\_tmpdim depth.291\_tmpdim width0pt}%
   \_fi
}

   \_doc -----------------------------
   \`\_setmainvalues` sets the current font size and `\baselineskip`
   values to the \`\mainfosize` and \hbox{\`\mainbaselineskip`} registers
   and loads fonts at given sizes.
   It redefines itself as \`\_setmainvaluesL`
   to set the main values only first. The \^`\_setmainvaluesL` does only
   fonts loading.
   \nl
   \`\scalemain` returns to these values if they were set. Else they are set
   to 10/12\,pt.
   \nl
   \`\mfontsrule` gives the rule how math fonts are loaded when \^`\typosize`
   or \^`\typoscale` are used. The value of \^`\mfontsrule` can be:
   \begitems
   * 0: no math fonts are loaded. User must use \^`\normalmath` or \^`\boldmath` explicitly.
   * 1: `\_normalmath` is run if \^`\typosize`/\^`\typoscale` are used
        first or they are run at outer group level. No
        `\everymath`/`\everydisplay` are set in this case. If
        \^`\typosize`/\^`\typoscale` are run repeatedly in a group then `\_normalmath` is
        run only when math formula occurs. This is done using
        `\everymath`/`\everydisplay` and \^`\_setmathfonts`.
        \^`\mfontsrule=1` is default.
   * 2: `\_normalmath` is run whenever \^`\typosize`/\^`\typoscale` are used.
        `\everymath`/`\everydisplay` registers are untouched.
   \enditems
   \_cod -----------------------------

\_newskip   \_mainbaselineskip   \_mainbaselineskip=0pt \_relax
\_newdimen  \_mainfosize         \_mainfosize=0pt
\_newcount  \_mfontsrule         \_mfontsrule=1

\_def\_setmainvalues {%
   \_mainbaselineskip=\_baselineskip
   \_mainfosize=\_optsize
   \_topskip=\_mainfosize \_splittopskip=\_topskip
   \_ifmmode \_else \_rm \_fi                % load and initialize \rm variant
   \_ifnum \_mfontsrule>0 \_normalmath \_fi  % load math fonts first
   \_let \_setmainvalues =\_setmainvaluesL
}
\_def\_setmainvaluesL {\_relax \_ifmmode \_else \_rm \_fi % load text font
   \_ifcase \_mfontsrule                                  % load math fonts
   \_or \_ifnum\_currentgrouplevel=0 \_normalmath
        \_else \_everymath={\_setmathfonts}\_everydisplay={\_normalmath}%
               \_let\_runboldmath=\_relax \_fi
   \_or \_normalmath \_fi}
\_def\_scalemain {%
   \_ifdim \_mainfosize=\_zo
       \_mainfosize=10pt  \_mainbaselineskip=12pt
       \_let \_setmainvalues=\_setmainvaluesL
    \_fi
   \_optsize=\_mainfosize  \_baselineskip=\_mainbaselineskip
}
\_public \scalemain \mainfosize \mainbaselineskip \mfontsrule ;

   \_doc -----------------------------
   Suppose following example:
   `{\typosize[13/15] Let $M$ be a subset of $R$ and $x\in M$...}`
   If \^`\mfontsrule=1` then \^`\typosize` does not load math fonts
   immediatelly but at the first math formula. It is done by `\everymath`
   register, but the contents of this register is processed inside the math
   group. If we do `\everymath={\_normalmath}` then this complicated macro
   will be processed three times in your example above. We want only one
   pocessing, so we do `\everymath={`\`\_setmathfonts``}` and
   this macro closes math mode first, loads fonts and opens math mode again.
   \_cod -----------------------------

\_def\_setmathfonts{$\_normalmath\_everymath{}\_everydisplay{}$}

   \_doc -----------------------------
   \`\thefontsize` `[<size>]` and \`\thefontscale` `[<factor>]`
    do modification of the size of the current font. They are implemented by the
   \^`\newcurrfontsize` macro.
   \_cod -----------------------------

\_protected\_def\_thefontsize[#1]{\_if$#1$\_else
     \_tmpdim=#1\_ptunit
     \_newcurrfontsize{at\_tmpdim}%
  \_fi
  \_ignorespaces
}
\_protected\_def\_thefontscale[#1]{\_ifx$#1$\_else
     \_tmpdim=#1pt \_divide\_tmpdim by1000
     \_tmpdim=\_ea\_ea\_ea\_ignorept \_pdffontsize\_font \_tmpdim
     \_newcurrfontsize{at\_tmpdim}%
  \_fi
  \_ignorespaces
}
\_public \thefontsize \thefontscale ;

   \_doc -----------------------------
   \`\em` keeps the weight of the current variant and switches
   roman $\leftrightarrow$ italic. It adds the italic correction by
   the \`\_additcorr` and \`\_afteritcorr` macros. The second does not
   add italic correction if the next character is dot or comma.
   \_cod -----------------------------

\_protected\_def\_em {%
   \_ea\_ifx \_the\_font \_tenit \_additcorr \_rm  \_else
   \_ea\_ifx \_the\_font \_tenbf \_bi\_aftergroup\_afteritcorr\_else
   \_ea\_ifx \_the\_font \_tenbi \_additcorr \_bf  \_else
   \_it \_aftergroup\_afteritcorr\_fi\_fi\_fi
}
\_def\_additcorr{\_ifhmode \_ifdim\_lastskip>\_zo
   \_skip0=\_lastskip \_unskip \_additcorrA \_hskip\_skip0 \_else \_additcorrA \_fi\_fi}
\_def\_additcorrA{\_ifnum\_lastpenalty=\_zo \_italcorr \_else
    \_ea\_unpenalty \_ea\_italcorr \_ea\_penalty \_the\_lastpenalty \_relax \_fi}
\_def\_afteritcorr{\_futurelet\_next\_afteritcorrA}
\_def\_afteritcorrA{\_ifhmode \_ifx\_next.\_else\_ifx\_next,\_else \_italcorr \_fi\_fi\_fi}
\_let\_italcorr=\/

   \_doc -----------------------------
   The \`\boldify` macro does `\let\rm\bf`, `\let\it\bi` and
   `\let\normalmath=\boldmath`. All following text will be in bold.
   If should be used after \^`\typosize` or \^`\typoscale` macros.\nl
   The internal \`\_runboldmath` macro runs `\_boldmath` immediatelly
   if no delay of the math font loading is set by \^`\_setmainvaluesL`.\nl
   The `\rm`, `\it` in math mode must keep its original meaning.
   \_cod -----------------------------

\_protected\_def \_boldify {%
   \_let \_setmainvalues=\_setmainvaluesL
   \_let\it =\_bi \_let\rm =\_bf \_let\_normalmath=\_boldmath \_bf
   \_runboldmath
   \_ifx\_ncharrmA\_undefined \_protected\_addto\rm{\_fam0 }\_protected\_addto\it{\_fam1 }%
   \_else \_protected\_def\rm {\_fmodbf \_fontsel \_marm}%
          \_protected\_def\it {\_fmodbi \_fontsel \_mait}%
   \_fi
}
\_def\_runboldmath{\_boldmath}

\_public \em \boldify ;

   \_doc -----------------------------
   We need to use a font selector for default pagination. Because we don't
   know what default font size will be selected by the user, we use this
   \`\_rmfixed` macro. It sets the `\rm` font from the default font size
   (declared by first \^`\typosize` command and redefines itself be only
   the font switch for the next pages.
   \_cod -----------------------------

\_def \_rmfixed {% used in default \footline
   {\_ifdim\_mainfosize=0pt \_mainfosize=10pt \_fi
    \_fontdef\_tenrm{\_setfontsize{at\mainfosize}\_resetmod\_rm}%
    \_glet\_rmfixed=\_tenrm}% next use will be font switch only
   \_rmfixed
}
\_let \rmfixed = \_tenrm % user can redefine it

\_endcode % -------------------------------------

History:
2024-01-25 \em: \_additcorr reimplemented to be more robust
2022-02-22 \_setmainvalues: only \rm initialized
2021-03-10 \boldify corrected
2021-03-09 \mfontsrule and \_setmathfonts introduced
2020-12-12 \_rmfixed fixed
2020-04-28 \boldify: removed \let\_rm=\_bf
2020-04-14 \_setmainvaluesL: \_ifmmode test added
2020-03-27 \_setmainvalues: \_splittopskip=\_topskip added
