Ошибка «Размер слишком большой», когда \setmathfont имеет опцию Scale=MatchLowercase

Ошибка «Размер слишком большой», когда \setmathfont имеет опцию Scale=MatchLowercase
\documentclass{article}
\usepackage{unicode-math}
\setmainfont{Georgia}
\setmathfont[Scale=MatchLowercase]{Cambria Math}
\begin{document}
n $n \sqrt[n]{n}$
\end{document}

Приведенный выше код при наборе с помощью XeTeX выдает ошибку «Размер слишком большой». Удаление [Scale=MatchLowercase]решает эту проблему, но мне нужна опция для комбинации других используемых мной текстовых и математических шрифтов.

Эта проблема, похоже, возникла недавно. Последний раз я набирал документ XeTeX, который использует unicode-mathи содержит, \sqrt[n]{n}около года назад, и тогда этой проблемы не было. Что-то не так содна из последних версийиз unicode-math, а именно 0,8м или 0,8н?

Тем не менее, выходной файл PDF в порядке. Я не уверен, стоит ли мне беспокоиться, но необходимость постоянно игнорировать ошибку неудобна. В качестве обходного пути я ^{1/n}пока буду использовать нотацию.

решение1

Обновлять

Начиная с unicode-math версии 0.8o (04.03.2019) эта ошибка исправлена ​​для обычного Scaleиспользования. Обновление включаетвариант ответа Ульрики Фишер, и что еще важнее,более небрежная настройка размеров шрифта в fam 2 и 3.

Изменение от ScaleAgain = 1.00001и ScaleAgain = 0.99999к ScaleAgain = 1.0001и ScaleAgain = 0.9999эффективносниженверхняя граница множества Бв теореме 1 ниже. Множество Бтеперь заканчивается около  k=10000, что около . Это означает, что Scale=0.153пока запрошенный пользовательScaleвыше 0.153, то unicode-mathразмеры шрифта будут установлены правильно.

Если запрошенный Scaleменьше 0,153, то проблема с размером шрифта сохраняется. Но считалось, что обычное использование никогда не приведет к Scale=0.153или ниже, поэтому мы в безопасности для большинства частей. Смотрите более подробный анализздесьиздесь.


Старые ответы

Хотя я согласен с Ульрике Фишер, что это unicode-mathошибка, боюсь, что мне придется не согласиться с утверждением, что « \__um_fontdimen_to_percent:nNсломано». Действительно, использование \dim_to_decimal_in_sp:n— это большое улучшение, но этонетгде кроется настоящая проблема. Сначала я представлю свое решение, а затем попытаюсь обсудить первопричину.

Обратите внимание, что следующее решение является временным, пока unicode-mathэта проблема не будет исправлена ​​в следующем выпуске.


Решение

Для относительно простого решения можно использовать новую функцию, ScaleAgainпозволяющую слегка исказить размер шрифта (это не будет заметно человеческому глазу):

\documentclass{article}
\usepackage{unicode-math}% v0.8n, 2019/02/15
\setmainfont{Georgia}
\setmathfont[Scale=MatchLowercase,ScaleAgain=0.99999]{Cambria Math}
\begin{document}
n $n \sqrt[n]{n}$
\end{document}

ScaleAgain

На практике вам придется попробовать диапазон ScaleAgainоколо 1, чтобы скомпилировать. Опять же, это будет исправлено в следующем выпуске unicode-math.


Теорема о поведении переполнения unicode-math v0.8n

Для тех, кого интересует странное поведение переполнения, вот теорема, основанная на двух фиксированных ScaleAgainмножителях в unicode-math v0.8n.

Сначала идет визуализация того, какие Scaleиз них безопасны, а какие могут вызвать проблемы:

Около Scale=1:
масштаб1
Около Scale=1.2:
масштаб1.2
Около Scale=1.5:
масштаб1.5

Всезеленыйсегменты линии представляют собой безопасные Scaleфакторы, в то время каккрасныйпроблемные сегменты представляют собой линейные сегменты.

Вот строгое математическое описание:
Теорема

В частности, Scale=1.031369386, Scale=1.031374755, Scale=1.031384644иScale=1.031390014 все ведут к ! Dimension too large. Около Scale=1.03138:
масштаб1.03138


Обсуждения

X-высоты Georgia и Cambria Math равны, соответственно, 986/2048и 956/2048. И Scale=MatchLowercaseправильно преобразуется в Scale=1.03138. fontspecТеперь, если бы мы применилипредложил переопределение\__um_fontdimen_to_percent:nNПри использовании современной латинской математики мы были бы удивлены, если бы узнали, что:

\documentclass{article}
\usepackage{unicode-math}% v0.8n, 2019/02/15
% https://tex.stackexchange.com/a/475802, by Ulrike Fischer:
\ExplSyntaxOn
\cs_set:Nn \__um_fontdimen_to_percent:nN
  {
    \fp_eval:n { \dim_to_decimal_in_sp:n { \fontdimen #1 #2 } / 100 }
  }
\ExplSyntaxOff

\newcommand*\tempscale{1.03138}% Also fails at 1.02, 1.05, 1.07
\setmathfont[Scale=\tempscale]{latinmodern-math.otf}

\begin{document}
n $n \sqrt[n]{n}$
\end{document}

все равно выдает ! Dimension too large.ошибку.

Еще более странно, если вместо этого использовать масштабный коэффициент или  1.031371.03139то ваш пример Georgia + Cambria Math успешно скомпилируется, как и мой пример Latin Modern Math (с переопределением или без него \__um_fontdimen_to_percent:nN).

Первопричиной проблемы является новая функция ScaleAgainот fontspec, которая призвана решить давнюю проблему (см.Размещение надстрочного индекса с использованием unicode-math с масштабированиемиПараметр масштабирования не полностью работает с LuaLaTeX). Ах да, и еще тот факт, что TeX «не силен в математике».

Чтобы правильно настроить размеры устаревшего шрифта, связанного с математикой, unicode-mathнеобходимо загрузить тот же математический шрифт.три раза. Но TeX не позволяет загружать один и тот же шрифт дважды в одном и том же размере, поэтому unicode-mathон должен загружать шрифт в немного разных размерах во второй и третий раз. Эти немного разные размеры получаются с помощьюкомпаундированиепредыдущий масштабный фактор. Это была главная причина, которая ScaleAgainбыла введена в  fontspec, так что unicode-mathможно сделать ScaleAgain=1.00001во 2-й раз и ScaleAgain=0.99999в 3-й раз. Какмой комментарийкак было отмечено, иногда unicode-mathне удается различить три размера из-за двоичной арифметики TeX.

Вашему примеру «не повезло», и у вас есть Scale=1.03138, что переводится как Round( 1.03138 * 2^16 ) = 67593. После ScaleAgain=1.00001, TeX видит 1.03139, что переводится как Round( 1.03139 * 2^16 ) = 67593. Поэтому TeX думает, что второе семейство и первое семейство — это один и тот же шрифт, и приступает к перезаписи fontdimen в соответствии с инструкцией unicode-math. Это вызывает переполнение, потому что новые fontdimen больше не являются процентами, которые меньше единицы, а теперь являются физическими длинами, которые могут быть довольно большими.

С помощью \setmathfont[Scale=MatchLowercase,ScaleAgain=0.99999]{Cambria Math}, мы, по сути, пытаемся предотвратить случайную загрузку TeX математического шрифта того же размера.

решение2

На мой взгляд, определение \__um_fontdimen_to_percent:nNневерное, его следует использовать \dim_to_decimal_in_spвместо\dim_to_decimal:n

\documentclass{article}
\usepackage{unicode-math}
\ExplSyntaxOn
\cs_set:Nn \__um_fontdimen_to_percent:nN
  {
    \fp_eval:n { \dim_to_decimal_in_sp:n {  \fontdimen #1 #2 } / 100 }
  }
\ExplSyntaxOff
\setmainfont{Georgia}
\setmathfont[Scale=MatchLowercase]{Cambria Math}

\begin{document}
n $n \sqrt[n]{n}$
\end{document}

Связанный контент