unicode-math icon indicating copy to clipboard operation
unicode-math copied to clipboard

Discrepancies in font size selection

Open eg9 opened this issue 7 years ago • 5 comments
trafficstars

Description

The font size selected don't honor \DeclareMathSizes as set in the LaTeX kernel and differ according to the main document size.

Check/indicate

  • [x] Relevant for XeTeX
  • [x] Relevant for LuaTeX
  • [x] Issue tracker has been searched for similar issues?
  • [x] https://tex.stackexchange.com/q/438296/4427

Minimal example demonstrating the issue

\documentclass[12pt]{article}
\usepackage{unicode-math}

\newwrite\report
\immediate\openout\report=\jobname.rep

\makeatletter
\newcommand{\test}[1]{%
  \begingroup
  #1\check@mathfonts
  \immediate\write\report{\string#1--\f@size pt}%
  \immediate\write\report{\fontname\textfont0}%
  \immediate\write\report{\fontname\scriptfont0}%
  \immediate\write\report{\fontname\scriptscriptfont0}%
  \endgroup
}
\makeatother

\begin{document}

\test{\normalsize}
\test{\large}
\test{\Large}

\end{document}

Further details

When compiled, the .rep file will contain

\normalsize--12pt
[latinmodern-math.otf]:mode=base;script=math;language=DFLT; at 12.0pt
[latinmodern-math.otf]:mode=base;script=math;language=DFLT;+ssty=0; at 8.41483pt
[latinmodern-math.otf]:mode=base;script=math;language=DFLT;+ssty=1; at 5.97688pt
\large--14.4pt
[latinmodern-math.otf]:mode=base;script=math;language=DFLT; at 14.4pt
[latinmodern-math.otf]:mode=base;script=math;language=DFLT;
[latinmodern-math.otf]:mode=base;script=math;language=DFLT;+ssty=0; at 7.0pt
\Large--17.28pt
[latinmodern-math.otf]:mode=base;script=math;language=DFLT; at 17.28pt
[latinmodern-math.otf]:mode=base;script=math;language=DFLT; at 12.0pt
[latinmodern-math.otf]:mode=base;script=math;language=DFLT;

If 12pt is changed into 10pt, the sizes will be reported as

\normalsize--10pt
[latinmodern-math.otf]:mode=base;script=math;language=DFLT;
[latinmodern-math.otf]:mode=base;script=math;language=DFLT;+ssty=0; at 7.01236pt
[latinmodern-math.otf]:mode=base;script=math;language=DFLT;+ssty=1; at 4.98074pt
\large--12pt
[latinmodern-math.otf]:mode=base;script=math;language=DFLT; at 12.0pt
[latinmodern-math.otf]:mode=base;script=math;language=DFLT;+ssty=0; at 8.0pt
[latinmodern-math.otf]:mode=base;script=math;language=DFLT;+ssty=0; at 6.0pt
\Large--14.4pt
[latinmodern-math.otf]:mode=base;script=math;language=DFLT; at 14.4pt
[latinmodern-math.otf]:mode=base;script=math;language=DFLT;
[latinmodern-math.otf]:mode=base;script=math;language=DFLT;+ssty=0; at 7.0pt

eg9 avatar Jun 29 '18 10:06 eg9

I think Will Robertson has mentioned this problem back in 2015 in his TeX.SX answer and I think I know where this go wrong.

The problem is with the following implementation in um-code-fontparam.dtx (Lines 290–297, as of 2018/12/11):

\cs_new:Nn \@@_fontdimen_to_percent:nN
  {
    \fp_eval:n { \dim_to_decimal:n { \fontdimen #1 #2 } * 65536 / 100 }
  }
\cs_new:Nn \@@_fontdimen_to_scale:nN
  {
    \fp_eval:n { \@@_fontdimen_to_percent:nN {#1} #2 * \f@size } pt
  }

Apparently, \dim_to_decimal:n produces a result which is rounded by TeX to four or five decimal places (The LaTeX3 Interfaces, Chapter XIX.7, as of 2018/12/11). So we could just follow the math:

  1. For first-level script size.

    • The \fontdimen10 of Latin Modern Math is 70.
    • The result of \dim_to_decimal:n is 70 / 65536 = 0.00107.
    • The result of \@@_fontdimen_to_percent:nN is 0.00107 * 65536 / 100 = 0.7012352.

    This explains the 8.41483pt and 7.01236pt for 12pt and 10pt articles, respectively.

  2. For second-level script size.

    • The \fontdimen11 of Latin Modern Math is 50.
    • The result of \dim_to_decimal:n is 50 / 65536 = 0.00076.
    • The result of \@@_fontdimen_to_percent:nN is 0.00076 * 65536 / 100 = 0.4980736.

    This explains the 5.97688pt and 4.98074pt for 12pt and 10pt articles, respectively.

IMHO, it is perhaps better to use

\fp_eval:n { \dim_to_decimal:n { 65536 \fontdimen #1 #2 } / 100 }

BTW, I think unicode-math intentionally ignores the LaTeX kernel \DeclareMathSizes and uses OpenType parameters ScriptPercentScaleDown and ScriptScriptPercentScaleDown instead, but only at \normalsize for some reasons.

RuixiZhang42 avatar Dec 12 '18 02:12 RuixiZhang42

A full example illustrating my proposed fix:

% !TeX program = XeLaTeX
\documentclass[12pt]{article}
\usepackage{unicode-math}

\ExplSyntaxOn
\cs_set:Nn \__um_fontdimen_to_percent:nN
  {
    \fp_eval:n { \dim_to_decimal:n { 65536 \fontdimen #1 #2 } / 100 }
  }
\ExplSyntaxOff

\newwrite\report
\immediate\openout\report=\jobname.rep

\makeatletter
\newcommand{\test}[1]{%
  \begingroup
  #1\check@mathfonts
  \immediate\write\report{\string#1--\f@size pt}%
  \immediate\write\report{\fontname\textfont0}%
  \immediate\write\report{\fontname\scriptfont0}%
  \immediate\write\report{\fontname\scriptscriptfont0}%
  \endgroup
}
\makeatother

\begin{document}

\test{\normalsize}
\test{\large}
\test{\Large}

\end{document}

With 12pt, in .rep I get

\normalsize--12pt
"[latinmodern-math.otf]/OT:script=math;language=DFLT;" at 12.0pt
"[latinmodern-math.otf]/OT:script=math;language=DFLT;+ssty=0;" at 8.4pt
"[latinmodern-math.otf]/OT:script=math;language=DFLT;+ssty=1;" at 6.0pt
\large--14.4pt
"[latinmodern-math.otf]/OT:script=math;language=DFLT;" at 14.4pt
"[latinmodern-math.otf]/OT:script=math;language=DFLT;"
"[latinmodern-math.otf]/OT:script=math;language=DFLT;+ssty=0;" at 7.0pt
\Large--17.28pt
"[latinmodern-math.otf]/OT:script=math;language=DFLT;" at 17.28pt
"[latinmodern-math.otf]/OT:script=math;language=DFLT;" at 12.0pt
"[latinmodern-math.otf]/OT:script=math;language=DFLT;"

With 10pt, in .rep I get

\normalsize--10pt
"[latinmodern-math.otf]/OT:script=math;language=DFLT;"
"[latinmodern-math.otf]/OT:script=math;language=DFLT;+ssty=0;" at 7.0pt
"[latinmodern-math.otf]/OT:script=math;language=DFLT;+ssty=1;" at 5.0pt
\large--12pt
"[latinmodern-math.otf]/OT:script=math;language=DFLT;" at 12.0pt
"[latinmodern-math.otf]/OT:script=math;language=DFLT;+ssty=0;" at 8.0pt
"[latinmodern-math.otf]/OT:script=math;language=DFLT;+ssty=0;" at 6.0pt
\Large--14.4pt
"[latinmodern-math.otf]/OT:script=math;language=DFLT;" at 14.4pt
"[latinmodern-math.otf]/OT:script=math;language=DFLT;"
"[latinmodern-math.otf]/OT:script=math;language=DFLT;+ssty=0;" at 7.0pt

Yeah!!!

RuixiZhang42 avatar Dec 12 '18 14:12 RuixiZhang42

Thanks, this looks great to me. Sorry I can’t analyse this in detail right now — does this address the issue entirely or is it only part of the solution?

wspr avatar Dec 12 '18 22:12 wspr

It depends…

  • To me, the fix addresses this issue entirely in addition with my comment about unicode-math overwriting \DeclareMathSizes at \normalsize.
  • However, the original intent of this issue appears to be asking unicode-math to honor the legacy \DeclareMathSizes, thus is partly addressed.

Given that pre-multiplying 65536 results in accurate point sizes, this issue may be closed if you think that the overwriting is “by design” (i.e., we should ignore the legacy \DeclareMathSizes and use OTF parameters instead).

RuixiZhang42 avatar Dec 12 '18 22:12 RuixiZhang42

@RuixiZhang42 — thanks, I see what you mean. I think the default should be to use the font-specific scaling present in the font metadata itself (i.e., override \DeclareMathSizes by default). But... users should have a way to override (do you agree @eg9, ?). I'll leave it open to decide what the best interface for this would be.

Perhaps unicode-math should do something like \DeclareMathSizes{0}{0}{0}, then when \setmathfont runs it checks to see whether the user has called \DeclareMathSizes and if so uses the now-updated values; otherwise use the data from the font.

Alternatively, I could deprecate \DeclareMathSizes (have it call an error or warning) and just make the override one of the keyval options for \setmathfont with something like [math-sizes={12}{7}{5}].

Or both! Thoughts?

wspr avatar Dec 12 '18 22:12 wspr