%%^^A%% um-code-fontparam.dtx -- part of UNICODE-MATH <wspr.io/unicode-math>
%%^^A%% Cross-platform interface for font parameters

% \section{Cross-platform interface for font parameters}
%
%    \begin{macrocode}
%<*package>
%    \end{macrocode}
%
% \XeTeX\ and \LuaTeX\ have different interfaces for math font parameters.
% We use \LuaTeX’s interface because it’s much better, but rename the primitives to be more \LaTeX3-like.
% There are getter and setter commands for each font parameter.
% The names of the parameters is derived from the \LuaTeX\ names, with underscores inserted between words.
% For every parameter \cs{Umath\meta{\LuaTeX\ name}}, we define an expandable getter command \cs{@@_\meta{\LaTeX3 name}:N} and a protected setter command \cs{@@_set_\meta{\LaTeX3 name}:Nn}.
% The getter command takes one of the style primitives (\cs{displaystyle} etc.)\ and expands to the font parameter, which is a \meta{dimension}.
% The setter command takes a style primitive and a dimension expression, which is parsed with \cs{dim_eval:n}.
%
% Often, the mapping between font dimensions and font parameters is bijective, but there are cases which require special attention:
% \begin{itemize}
% \item Some parameters map to different dimensions in display and non-display styles.
% \item Likewise, one parameter maps to different dimensions in non-cramped and cramped styles.
% \item There are a few parameters for which \XeTeX\ doesn’t seem to provide \cs{fontdimen}s; in this case the getter and setter commands are left undefined.
% \end{itemize}
%
% \paragraph{Cramped style tokens}
% \LuaTeX\ has \cs{crampeddisplaystyle} etc.,\ but they are loaded as \cs{luatexcrampeddisplaystyle} etc.\ by the \pkg{luatextra} package.
% \XeTeX, however, doesn’t have these primitives, and their syntax cannot really be emulated.
% Nevertheless, we define these commands as quarks, so they can be used as arguments to the font parameter commands (but nowhere else).
% Making these commands available is necessary because we need to make a distinction between cramped and non-cramped styles for one font parameter.
%
% \begin{macro}{\@@_new_cramped_style:N}
% \darg{command}
% Define \meta{command} as a new cramped style switch.
% For \LuaTeX, simply rename the correspronding primitive if it is not
% already defined.
% For \XeTeX, define \meta{command} as a new quark.
%    \begin{macrocode}
\cs_new_protected_nopar:Nn \@@_new_cramped_style:N
%<XE>  { \tl_const:Nn #1 { \use_none:n #1 } }
%<LU>  {
%<LU>    \cs_if_exist:NF #1
%<LU>      { \cs_new_eq:Nc #1 { luatex \cs_to_str:N #1 } }
%<LU>  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\crampeddisplaystyle}
% \begin{macro}{\crampedtextstyle}
% \begin{macro}{\crampedscriptstyle}
% \begin{macro}{\crampedscriptscriptstyle}
% The cramped style commands.
%    \begin{macrocode}
\@@_new_cramped_style:N \crampeddisplaystyle
\@@_new_cramped_style:N \crampedtextstyle
\@@_new_cramped_style:N \crampedscriptstyle
\@@_new_cramped_style:N \crampedscriptscriptstyle
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \paragraph{Font dimension mapping}
% Font parameters may differ between the styles.
% \LuaTeX\ accounts for this by having the parameter primitives take a style token argument.
% To replicate this behavior in \XeTeX, we have to map style tokens to specific combinations of font dimension numbers and math fonts (\cs{textfont} etc.).
%
% \begin{macro}{\@@_font_dimen:Nnnnn}
% \darg{style token}
% \darg{font dimen for display style}
% \darg{font dimen for cramped display style}
% \darg{font dimen for non-display styles}
% \darg{font dimen for cramped non-display styles}
% Map math style to \XeTeX\ math font dimension.
% \meta{style token} must be one of the style switches (\cs{displaystyle}, \cs{crampeddisplaystyle}, \dots).
% The other parameters are integer constants referring to font dimension numbers.
% The macro expands to a dimension which contains the appropriate font dimension.
%    \begin{macrocode}
%<*XE>
  \cs_new_nopar:Npn \@@_font_dimen:Nnnnn #1 #2 #3 #4 #5 {
    \fontdimen
    \cs_if_eq:NNTF #1 \displaystyle {
      #2 \textfont
    } {
      \cs_if_eq:NNTF #1 \crampeddisplaystyle {
        #3 \textfont
      } {
        \cs_if_eq:NNTF #1 \textstyle {
          #4 \textfont
        } {
          \cs_if_eq:NNTF #1 \crampedtextstyle {
            #5 \textfont
          } {
            \cs_if_eq:NNTF #1 \scriptstyle {
              #4 \scriptfont
            } {
              \cs_if_eq:NNTF #1 \crampedscriptstyle {
                #5 \scriptfont
              } {
                \cs_if_eq:NNTF #1 \scriptscriptstyle {
                  #4 \scriptscriptfont
                } {
%    \end{macrocode}
% Should we check here if the style is invalid?
%    \begin{macrocode}
                  #5 \scriptscriptfont
                }
              }
            }
          }
        }
      }
    }
%    \end{macrocode}
% Which family to use?
%    \begin{macrocode}
    2~
  }
%</XE>
%    \end{macrocode}
% \end{macro}
%
% \paragraph{Font parameters}
% This paragraph contains macros for defining the font parameter interface, as well as the definition for all font parameters known to \LuaTeX.
%
% \begin{macro}{\@@_font_param:nnnnn}
% \darg{name}
% \darg{font dimension for non-cramped display style}
% \darg{font dimension for cramped display style}
% \darg{font dimension for non-cramped non-display styles}
% \darg{font dimension for cramped non-display styles}
% This macro defines getter and setter functions for the font parameter \meta{name}.
% The \LuaTeX\ font parameter name is produced by removing all underscores and prefixing the result with |Umath|.
% The \XeTeX\ font dimension numbers must be integer constants.
%    \begin{macrocode}
\cs_new_protected_nopar:Nn \@@_font_param:nnnnn
%<*XE>
  {
    \@@_font_param_aux:ccnnnn { @@_ #1 :N } { @@_set_ #1 :Nn }
      { #2 } { #3 } { #4 } { #5 }
  }
%</XE>
%<*LU>
  {
    \tl_set:Nn \l_@@_tmpa_tl { #1 }
    \tl_remove_all:Nn \l_@@_tmpa_tl { _ }
    \@@_font_param_aux:ccc { @@_ #1 :N } { @@_set_ #1 :Nn }
      { Umath \l_@@_tmpa_tl }
  }
%</LU>
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@_font_param:nnn}
% \darg{name}
% \darg{font dimension for display style}
% \darg{font dimension for non-display styles}
% This macro defines getter and setter functions for the font parameter \meta{name}.
% The \LuaTeX\ font parameter name is produced by removing all underscores and prefixing the result with |Umath|.
% The \XeTeX\ font dimension numbers must be integer constants.
%    \begin{macrocode}
\cs_new_protected_nopar:Nn \@@_font_param:nnn
  {
    \@@_font_param:nnnnn { #1 } { #2 } { #2 } { #3 } { #3 }
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@_font_param:nn}
% \darg{name}
% \darg{font dimension}
% This macro defines getter and setter functions for the font parameter \meta{name}.
% The \LuaTeX\ font parameter name is produced by removing all underscores and prefixing the result with |Umath|.
% The \XeTeX\ font dimension number must be an integer constant.
%    \begin{macrocode}
\cs_new_protected_nopar:Nn \@@_font_param:nn
  {
    \@@_font_param:nnnnn { #1 } { #2 } { #2 } { #2 } { #2 }
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@_font_param:n}
% \darg{name}
% This macro defines getter and setter functions for the font parameter \meta{name}, which is considered unavailable in \XeTeX\@.
% The \LuaTeX\ font parameter name is produced by removing all underscores and prefixing the result with |Umath|.
%    \begin{macrocode}
\cs_new_protected_nopar:Nn \@@_font_param:n
%<XE>  { }
%<LU>  { \@@_font_param:nnnnn { #1 } { 0 } { 0 } { 0 } { 0 } }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@_font_param_aux:NNnnnn}
% \begin{macro}{\@@_font_param_aux:NNN}
% Auxiliary macros for generating font parameter accessor macros.
%    \begin{macrocode}
%<*XE>
\cs_new_protected_nopar:Nn \@@_font_param_aux:NNnnnn
  {
    \cs_new_nopar:Npn #1 ##1
      {
        \@@_font_dimen:Nnnnn ##1 { #3 } { #4 } { #5 } { #6 }
      }
    \cs_new_protected_nopar:Npn #2 ##1 ##2
      {
        #1 ##1 \dim_eval:n { ##2 }
      }
  }
\cs_generate_variant:Nn \@@_font_param_aux:NNnnnn { cc }
%</XE>
%<*LU>
\cs_new_protected_nopar:Nn \@@_font_param_aux:NNN
  {
    \cs_new_nopar:Npn #1 ##1
      {
        #3 ##1
      }
    \cs_new_protected_nopar:Npn #2 ##1 ##2
      {
        #3 ##1 \dim_eval:n { ##2 }
      }
  }
\cs_generate_variant:Nn \@@_font_param_aux:NNN { ccc }
%</LU>
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% Now all font parameters that are listed in the \LuaTeX\ reference follow.
%    \begin{macrocode}
\@@_font_param:nn { axis } { 15 }
\@@_font_param:nn { operator_size } { 13 }
\@@_font_param:n { fraction_del_size }
\@@_font_param:nnn { fraction_denom_down } { 45 } { 44 }
\@@_font_param:nnn { fraction_denom_vgap } { 50 } { 49 }
\@@_font_param:nnn { fraction_num_up } { 43 } { 42 }
\@@_font_param:nnn { fraction_num_vgap } { 47 } { 46 }
\@@_font_param:nn { fraction_rule } { 48 }
\@@_font_param:nn { limit_above_bgap } { 29 }
\@@_font_param:n { limit_above_kern }
\@@_font_param:nn { limit_above_vgap } { 28 }
\@@_font_param:nn { limit_below_bgap } { 31 }
\@@_font_param:n { limit_below_kern }
\@@_font_param:nn { limit_below_vgap } { 30 }
\@@_font_param:nn { over_delimiter_vgap } { 41 }
\@@_font_param:nn { over_delimiter_bgap } { 38 }
\@@_font_param:nn { under_delimiter_vgap } { 40 }
\@@_font_param:nn { under_delimiter_bgap } { 39 }
\@@_font_param:nn { overbar_kern } { 55 }
\@@_font_param:nn { overbar_rule } { 54 }
\@@_font_param:nn { overbar_vgap } { 53 }
\@@_font_param:n { quad }
\@@_font_param:nn { radical_kern } { 62 }
\@@_font_param:nn { radical_rule } { 61 }
\@@_font_param:nnn { radical_vgap } { 60 } { 59 }
\@@_font_param:nn { radical_degree_before } { 63 }
\@@_font_param:nn { radical_degree_after } { 64 }
\@@_font_param:nn { radical_degree_raise } { 65 }
\@@_font_param:nn { space_after_script } { 27 }
\@@_font_param:nnn { stack_denom_down } { 35 } { 34 }
\@@_font_param:nnn { stack_num_up } { 33 } { 32 }
\@@_font_param:nnn { stack_vgap } { 37 } { 36 }
\@@_font_param:nn { sub_shift_down } { 18 }
\@@_font_param:nn { sub_shift_drop } { 20 }
\@@_font_param:n { subsup_shift_down }
\@@_font_param:nn { sub_top_max } { 19 }
\@@_font_param:nn { subsup_vgap } { 25 }
\@@_font_param:nn { sup_bottom_min } { 23 }
\@@_font_param:nn { sup_shift_drop } { 24 }
\@@_font_param:nnnnn { sup_shift_up } { 21 } { 22 } { 21 } { 22 }
\@@_font_param:nn { supsub_bottom_max } { 26 }
\@@_font_param:nn { underbar_kern } { 58 }
\@@_font_param:nn { underbar_rule } { 57 }
\@@_font_param:nn { underbar_vgap } { 56 }
\@@_font_param:n { connector_overlap_min }
%    \end{macrocode}
%
% \subsection{Historical commands}
%
% \begin{macro}{\@@_fontdimen_to_percent:nN}
% \begin{macro}{\@@_fontdimen_pc_to_pt:nN}
% \darg{Font dimen number}
% \darg{Font `variable'}
% \cmd\fontdimen s |10|, |11|, and |65| aren't actually dimensions, they're percentage values given in units of |sp|.
% \cs{@@_fontdimen_to_percent:nn} takes a font dimension number and outputs the decimal value of the associated parameter.
% \cs{@@_fontdimen_pc_to_pt:nn} returns a dimension correspond to the current
% font size relative proportion based on that percentage.
%    \begin{macrocode}
\cs_set:Nn \@@_fontdimen_to_percent:nN
  {
    \fp_eval:n { \dim_to_decimal_in_sp:n { \fontdimen #1 #2 } / 100 }
  }
\cs_new:Nn \@@_fontdimen_pc_to_pt:nN
  {
    \fp_eval:n { \dim_to_decimal_in_sp:n { \fontdimen #1 #2 } / 100 * \f@size }
  }
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\@@_mathstyle_scale:NnnN}
% \darg{A math style (\cs{scriptstyle}, say)}
% \darg{Macro that takes a non-delimited length argument (like \cmd\kern)}
% \darg{Length control sequence to be scaled according to the math style}
% \darg{Math font face to use for the lookups}
% This macro is used to scale the lengths reported by \cmd\fontdimen\ according to the scale factor for script- and scriptscript-size objects.
%    \begin{macrocode}
\cs_new:Nn \@@_mathstyle_scale:NnnN
  {
    \ifx#1\scriptstyle
      #2 \@@_fontdimen_to_percent:nN {10} #4 #3
    \else
      \ifx#1\scriptscriptstyle
        #2 \@@_fontdimen_to_percent:nN {11} #4 #3
      \else
        #2 #3
      \fi
    \fi
  }
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
%</package>
%    \end{macrocode}

\endinput

% /©
%
% ------------------------------------------------
% The UNICODE-MATH package  <wspr.io/unicode-math>
% ------------------------------------------------
% This package is free software and may be redistributed and/or modified under
% the conditions of the LaTeX Project Public License, version 1.3c or higher
% (your choice): <http://www.latex-project.org/lppl/>.
% ------------------------------------------------
% Copyright 2006-2019  Will Robertson, LPPL "maintainer"
% Copyright 2010-2017  Philipp Stephani
% Copyright 2011-2017  Joseph Wright
% Copyright 2012-2015  Khaled Hosny
% ------------------------------------------------
%
% ©/
