Как правильно настроить резервный шрифт?

16

TL; DR: Какой простой способ надежно сказать: использовать Consolas в качестве шрифта по умолчанию, FreeMono для символов, не поддерживаемых Consolas, и Symbola для символов, не поддерживаемых обоими?

Поскольку мой основной программный шрифт не охватывает все математические символы, которые мне нужны, я изначально настроил откат шрифта, как показано ниже:

(set-fontset-font t 'unicode (font-spec :name "FreeMono") nil 'append)
(set-fontset-font t 'unicode (font-spec :name "Symbola") nil 'append)

К сожалению, это также изменило шрифт для некоторых символов, которые поддерживает мой основной шрифт, поэтому я изменил его на

(set-fontset-font t 'unicode (font-spec :name "Consolas") nil)
(set-fontset-font t 'unicode (font-spec :name "FreeMono") nil 'append)
(set-fontset-font t 'unicode (font-spec :name "Symbola") nil 'append)

Если мое понимание верно, это должно гарантировать, что символы, которые Consolas не может обработать, обрабатываются FreeMono, если только у FreeMono их нет, и в этом случае они должны отображаться с помощью Symbola. Это также мое понимание, что tделает то же самое, что и "fontset-default"выше.

К сожалению, все еще были случаи, когда правильный шрифт не был выбран; Я обнаружил, что меняется на

(set-fontset-font t 'unicode (font-spec :name "Consolas") nil)
(set-fontset-font t 'unicode (font-spec :name "FreeMono") nil 'append)
(set-fontset-font t 'unicode (font-spec :name "Symbola") nil 'append)
(set-fontset-font "fontset-startup" 'unicode (font-spec :name "Consolas") nil)
(set-fontset-font "fontset-startup" 'unicode (font-spec :name "FreeMono") nil 'append)
(set-fontset-font "fontset-startup" 'unicode (font-spec :name "Symbola") nil 'append)

работал лучше, но не всегда: изменение размера шрифта с помощью

(set-face-attribute 'default nil :height some-size)

вызвал игнорирование аварийных откликов из-за создания новых наборов шрифтов.

Мое текущее решение состоит в том, чтобы сделать

(set-fontset-font fontset 'unicode (font-spec :name "Consolas") nil)
(set-fontset-font fontset 'unicode (font-spec :name "FreeMono") nil 'append)
(set-fontset-font fontset 'unicode (font-spec :name "Symbola") nil 'append)

на каждом наборе шрифтов ( fontset-list), после каждого изменения размера шрифта.

Как правильно установить резервный шрифт?

Примечание : в целях тестирования, здесь есть несколько математических символов: ℕ𝓟⧺×≠≥≤±¬∨∧∃∀λ⟿⟹⊥⊤⊢
Ссылки : Руководство Emacs по наборам шрифтов и по изменению наборов шрифтов.

Клеман
источник
2
У меня есть мысль, которая на самом деле не решает вашу проблему, но - если вам нужны математические и т. Д. Символы для теорем и научных документов, почему бы вам не использовать TeX и AucTeX для этого? Это избавило бы от необходимости использовать X (или Mac или Windows, в зависимости от того, что вы запускаете) резервные копии шрифтов и предоставило бы вам высококачественные документы и фрагменты (например, для режима org).
запоздалая мысль: шрифт UTF-8 с полным набором символов должен полностью устранить вашу проблему (например, GNU Unifont), и когда есть выбор между причудливым шрифтом и требуемыми символами, я бы выбрал последний.
2
@kuli Вы слишком пессимистичны. См. Github.com/cpitclaudel/monospacifier
Иста
Я не могу вспомнить, где я это читал, но, по-моему, Эли Зарецкий где-то ответил на аналогичный вопрос. Вы думаете о fontsetнеправильном пути. Emacs на самом деле не проверяет каждый отображаемый символ, знает ли шрифт, как его отобразить, или нет. Это было бы слишком интенсивно в вычислительном отношении. Таким образом, не существует «запасного» механизма как такового. Вам следует установить шрифт по умолчанию, а затем вручную изменить набор шрифтов по умолчанию в определенных диапазонах для отображения с использованием разных шрифтов. Эта процедура является ручной или, возможно, пакет unicodeможет помочь.
GenaU
@GenaU Я, возможно, неправильно понимаю, но Emacs проверяет; просто не каждый шрифт, только те, которые появляются в наборе шрифтов.
Климент

Ответы:

0

Для тех, кто не умеет читать документацию Emacs.

Выбор шрифта

Прежде чем Emacs сможет нарисовать символ на графическом дисплее, он должен выбрать «шрифт» для этого символа. Обычно Emacs автоматически выбирает шрифт на основе граней, назначенных этому персонажу, в частности, атрибутов граней ': family', ': weight', ': slant' и ': width'. Выбор шрифта также зависит от отображаемого символа; некоторые шрифты могут отображать только ограниченный набор символов. Если ни один из доступных шрифтов не соответствует требованиям, Emacs ищет «наиболее подходящий шрифт». Переменные в этом разделе управляют тем, как Emacs делает этот выбор.

face-font-family-alternatives

Специально проверено использование символов в вопросе, проверка символов с
describe-character. Каждый персонаж использует один из бесплатных шрифтов: Consolas, FreeMono, Symbola. Установка шрифта рамки на Consola set-frame-font.

До сих пор 14 голосов, ответ отрицателен, и наука ЕС до сих пор не может решить эту загадку.

Александр Карбивничий
источник
Благодарность! Рассматривали ли вы это как ответ на мой комментарий выше, а не как отдельный ответ?
Clément
1
(Я должен уточнить , что я тестировал тоже на Emacs 26, и ваш ответ не представляется к работе: я использовал (setq face-font-family-alternatives '(("Consolas" "FreeMono" "Symbola"))), а затем M-x set-frame-font RET Consolas RET, персонажи используют сочетание Consolas и Segoe UI Symbol)
Clément
Я тестировал на Manjaro Arch Linux эту последовательность: ℕ𝓟⧺ × ≠ ≥≤ ± ¬∨∧∃∀λ⟿⟹⊥⊤⊢; Я не проверял, что происходит, если какой-то шрифт не установлен. Это может быть возможно. Потому что имена шрифтов вводятся вручную, а не из списка существующих.
Александр Карбивничий
Я протестировал со всеми установленными шрифтами в списке, в emacs -Q.
Клеман
Опция @ Clément emacs -Q сильно мешает: --no-x-resources. Может быть, проблема в этом. Для меня Консолас стартует только с этого символа: «×». И первые два "ℕ𝓟" FreeMono и Symbola.
Александр Карбивничий
-1

M-x customize-variable face-font-family-alternatives

Есть список, который выглядит примерно так:

(("Monospace" "courier" "fixed")
 ("Monospace Serif" "Courier 10 Pitch" "Consolas" "Courier Std" "FreeMono" "courier" "fixed")
 ("courier" "CMU Typewriter Text" "fixed")
 ("Sans Serif" "helv" "helvetica" "arial" "fixed")
 ("helv" "helvetica" "arial" "fixed"))

Добавьте вашу последовательность в customizeбуферный интерфейс:

("Consolas" "FreeMono" "Symbola")

Если определенное семейство указано, но не существует, эта переменная определяет альтернативные семейства шрифтов, которые нужно попробовать. Каждый элемент должен иметь эту форму:

 (FAMILY ALTERNATE-FAMILIES...)

Если FAMILY указан, но недоступен, Emacs будет пробовать другие семейства, указанные в ALTERNATE-FAMILIES, один за другим, пока не найдет семейство, которое существует.

Как использовать face-font-family-alternatives:

В вашем буфере: M-x set-frame-font

Выберите шрифт из списка. Выбранный шрифт будет определять, какую последовательность поиска шрифтов face-font-family-alternativesиспользовать. В этом примере Консолас .

Чтобы проверить, какое семейство шрифтов использовалось для отображения символа: M-x describe-char

Александр Карбивничий
источник
Благодарность! Но я не думаю, что это отвечает на вопрос. AFAICT, предложенная вами конфигурация будет использовать FreeMono, если шрифт Consolas недоступен, но не будет использовать FreeMono для символов, не поддерживаемых Consolas.
Клеман