Высота строки с символами Юникода

23

Некоторые символы Unicode приводят к тому, что строка, на которой они отображаются, является довольно большой. Например, серьезный акцент «̀» добавляет около 2,5 строк пространства над и под ним. Другие символы, вызывающие такое поведение, включают греческую букву «ϕ» (фи) или подмножество «⫅». Другие символы, такие как map-to "⤇", добавляют только около 0.5 строк с каждой стороны.

Я столкнулся с этой проблемой при чтении источника, julia-mode.elкоторый содержит большое количество таких символов для замены LaTeX.

Почему это происходит и можно ли это исправить?

Редактировать: я использую Ubuntu 14.04 LTS с Emacs 24.3.1. По умолчанию я использую шрифт «Ubuntu Mono 13», но другие шрифты иногда используются для отображения символов. Я не установил никаких пакетов для явного управления юникодом, и эту проблему можно воспроизвести с помощью команды emacs -Q.

Патрик Стил
источник
3
Вероятно, это связано с установленными вами шрифтами. Может помочь использование шрифта со встроенной поддержкой Unicode (например, DejaVu Sans Mono).
Крис
Пожалуйста, отредактируйте ваш вопрос и добавьте информацию о вашей ОС, вашей версии Emacs и шрифтах, которые вы используете для Emacs.
Лунный Рог
Также укажите, используете ли вы какой-либо пакет / команду для настройки юникода. Или вы просто используете то, что вышло из коробки.
Малабарба
Согласитесь на шрифт: я использую DejaVu Sans Mono и символы юникода отображаются без какой-либо видимой разницы в вертикальном межстрочном интервале.
Дан
У меня фактически установлен DejaVu Sans Mono, и он используется для некоторых символов, например, «ϛ». Таким образом, кажется, что для Phi выбирается другой шрифт, а именно: "xft: -unknown-Latin Modern Math-normal-normal-normal- -17- - - - * - 0-iso10646-1".
Патрик Стил

Ответы:

7

Это происходит потому, что Emacs использует разные шрифты для разных частей набора символов Unicode. Вы можете проверить, какой шрифт используется, поместив курсор на символ и нажав C-u C-x =. Например, с моей конфигурацией по ASCII-символу, который я получаю nil:-apple-Consolas-medium-normal-normal-*-14-*-*-*-m-0-iso10646-1 (#x88), но по ⧺, который я получаю nil:-apple-Symbola-medium-normal-normal-*-14-*-*-*-p-0-iso10646-1 (#xCE1)(другими словами, он использует Consolas для ASCII и Symbola для некоторых специальных символов). Разные шрифты имеют разную высоту, и Emacs всегда будет предоставлять достаточно места в высоте строки для отображения самого высокого шрифта. По умолчанию Emacs будет пытаться использовать системные шрифты, которые работают, но это часто приводит к ужасным результатам.

Решение, которое я нашел для проблемы с высотой строки, к сожалению, довольно раздражает: я просматриваю проблемные символы, которые нахожу, и использую set-fontset-fontих для установки шрифта / размера, который не влияет на высоту строки. Код для этого доступен в моей конфигурации , но он уродлив и все еще не совершенен. Если у кого-то есть лучшее решение, мне было бы интересно услышать его.

shosti
источник
1
Я думаю, что более простым подходом может быть использование юникод-шрифтов , как в моем ответе; это работает для вас?
Кирилл
@Kirill: юникод-шрифты выглядят действительно интересно, но я не уверен, что это решит эту конкретную проблему без значительных настроек (я не пробовал, поэтому могу ошибаться). Основная проблема заключается в том, что разные шрифты с одинаковым размером имеют разную высоту строки, поэтому каждый шрифт необходимо настраивать до тех пор, пока он не достигнет (приблизительно) одинаковой высоты строки. Unicode-шрифты не выглядят так, как будто легко настраивать размеры шрифтов.
Шости
Да, я думаю, что это правда, но это позволяет легко выбирать шрифты для целых блоков символов, поэтому вам не нужно самостоятельно искать отдельные символы вручную.
Кирилл
6

Я использую агда-режим с большим количеством математических символов, и у меня была такая же проблема. Раньше единственным реальным решением было, как подсказывает @shosti: настройка сопоставления шрифтов. В моем случае мне пришлось отключить несколько шрифтов, потому что, хотя у меня были установлены шрифты с определенными определенными глифами, emacs часто выбирал неправильный (отображая блоки). На OSX вроде бы хуже, но я видел и на Linux. Так что просто установить правильные шрифты было недостаточно.

Теперь я использую отличный пакет Unicode-Fonts от Roland Walker . (Я бы порекомендовал установить его через MELPA.) Это в значительной степени устранило проблему полностью.

Я положил это в мой файл инициализации:

(unicode-fonts-setup)
(set-frame-font "PragmataPro 12")

Я использую PragmataPro по умолчанию, но любой другой шрифт с хорошим покрытием тоже подойдет, и вы можете настроить вещи с помощью пакета, если это необходимо.

darinmorrison
источник
4

У меня уже была эта проблема в другом вопросе без ответа здесь . Я ожидаю, что разные шрифты одинакового размера будут иметь одинаковую высоту, но, похоже, это не так, поэтому я покажу свой специальный подход к решению этой проблемы.

Оставляя в стороне акценты и фокусируясь только на простых символах, разные шрифты необходимы для отображения всех разных символов просто потому, что некоторые шрифты пропускают целые блоки символов, которые присутствуют в других шрифтах. Чтобы убедиться, что у необычных символов (таких как «𝚫») есть хотя бы один шрифт, установите такой шрифт, как Symbola, и просмотрите список шрифтов в файле readme пакета unicode-fonts .

Если вы установите пакет unicode-fontsи несколько хороших шрифтов, все символы должны поддерживаться, но некоторые из них будут иметь неверную высоту отображения в emacs.

Предположим, что Монако имеет неверную высоту, но символьные символы имеют правильную высоту для математических символов (например, ПОДВОД ИЛИ РАВНО В; используйте C-x 8 RETили insert-charдля проверки различных символов.). В моем случае было недостаточно использовать Монако, символы Noto Sans и символы Apple; один хороший шрифт для меня был DejaVu Sans Mono.

Во-первых, вы можете запретить unicode-fontsиспользование Монако, добавив его в unicode-fonts-skip-fonts; какой бы шрифт он ни выбрал, следующий может иметь правильную высоту. В качестве альтернативы, вы можете указать unicode-fontsиспользовать определенный шрифт для блока Unicode (например, «Математические операторы; вот список всех блоков» ), изменив запись в unicode-fonts-block-font-mapping.

Во-вторых, вы можете легко сделать это вручную для очень точного набора символов с помощью set-fontset-font. Если Symbola является хорошим шрифтом для математических символов (в данном случае это диапазон 0x2100..0x23ff), должно работать следующее:

(set-fontset-font t '(#x2100 . #x23ff)
  ;; this should throw an error if there is no such font
  (font-xlfd-name (find-font (font-spec :family "Symbola"))))

Другие диапазоны , которые я должен изменить себя были 2000..206f, 27c0..27ff, 2900..2bff, 1d400..1d7ff.

Наконец, нет необходимости искать неправильно настроенные символы вручную. Предполагая, unicode-fontsчто установлена, следующая функция сгенерирует список всех символов с неправильной высотой:

(defun debug-unicode-heights (&optional block-name)
  "Find all characters in a given block that have incorrect heights.

BLOCK-NAME can be anything that
`unicode-fonts-debug-insert-block' accepts, such as `'all-math',
or a string naming a Unicode block."
  (interactive "sBlock name:")
  (unless block-name (setq block-name 'all-math))
  (let ((buffer (generate-new-buffer (format "debug-unicode-heights:%s" block-name)))
        expected-height
        bad-characters)
    (pop-to-buffer buffer)
    (with-current-buffer buffer
      (unicode-fonts-debug-insert-block block-name)
      (goto-char (point-min))
      (setq expected-height (line-pixel-height))
      ;; (message "Expected height %d" expected-height)
      (while (< (point) (point-max))
        (if (or (= (line-pixel-height) expected-height)
                ;; Some characters are invalid, they have no name
                ;; (their name is just their hex code), and their
                ;; heights do not matter to us.
                (looking-at-p "^.[^\"]*\"#"))
            (delete-region (line-beginning-position)
                           (1+ (line-end-position)))
          (push (char-after (line-beginning-position)) bad-characters)
          (forward-line))))
    ;; (display-message-or-buffer buffer)
    (apply #'string (reverse bad-characters))))

Например:

M-: (debug-unicode-heights 'all-math)

а потом

M-: (debug-unicode-heights 'all-greek)

покажет все плохие математические символы. Затем вы можете проверить, с каким шрифтом они отображаются, и изменить его.

У меня OS X 10.9.5, поэтому мои настройки шрифта, вероятно, будут отличаться от ваших. Не нужно устанавливать unicode-fonts; Вы можете вручную указать предпочитаемый шрифт, set-fontset-fontесли обнаружите, что настройки по умолчанию в emacs не работают.

PS Есть альтернатива: когда шрифт постоянно слишком велик / мал, вы можете добавить запись, чтобы face-font-rescale-alistemacs всегда умножал размер этого шрифта на коэффициент, скажем, 0,95, например, так:

(add-to-list 'face-font-rescale-alist (cons (font-spec :family "STIXGeneral") 0.95) t)

Когда я попробовал это, это не совсем сработало (мой отчет об ошибках здесь ), но это также возможный подход.

Кирилл
источник
Советы по поводу, set-fontset-fontкажется, на самом деле требуется только один. Мне нужно было только оценить, например (set-fontset-font t '(#x1d400 . #x1d7ff) "Symbola"), создание фрейма ( window-setup-hookчтобы заставить его работать emacs --daemon) и установить пакет ttf-ancient-fonts с Symbola под Debian .
августа
2

Это ошибка; это закреплено в багажнике. Эта проблема вызвана неверной информацией о высоте строк в шрифтах TeX, к которым, как правило, обращается Emacs, если не может найти символ.

В ветке об ошибках в emacs-bug содержится гораздо больше информации.

Клеман
источник