Hauteur de ligne avec caractères unicode

23

Certains caractères Unicode font que la ligne sur laquelle ils sont affichés est assez grande. Par exemple, un accent grave "̀" ajoute environ 2,5 lignes d'espace au-dessus et en dessous. Les autres caractères qui provoquent ce comportement incluent la lettre grecque "ϕ" (phi) ou le sous-ensemble "⫅". D'autres caractères tels que les cartes vers "⤇" n'ajoutent qu'environ 0,5 ligne de chaque côté.

J'ai rencontré ce problème lors de la lecture de la source julia-mode.elqui contient un grand nombre de ces caractères pour la substitution LaTeX.

Pourquoi cela se produit-il et peut-il être corrigé?

Edit: j'utilise Ubuntu 14.04 LTS avec Emacs 24.3.1. Par défaut, j'utilise la police "Ubuntu Mono 13" mais d'autres polices sont parfois utilisées pour afficher les caractères. Je n'ai installé aucun package pour gérer explicitement unicode, et ce problème est reproductible à l'aide de la commande emacs -Q.

Patrick Steele
la source
3
Ceci est probablement lié aux polices que vous avez installées. L'utilisation d'une police avec un support décent Unicode intégré (par exemple DejaVu Sans Mono) peut aider.
Chris
Veuillez modifier votre question et ajouter des informations sur votre système d'exploitation, votre version d'Emacs et les polices que vous utilisez pour Emacs.
lunaryorn
Indiquez également si vous utilisez un package / une commande pour configurer unicode. Ou vous utilisez simplement ce qui est sorti de la boîte.
Malabarba
D'accord sur la police: j'utilise DejaVu Sans Mono et les caractères unicode sont rendus sans aucune différence visible dans l'espacement des lignes verticales.
Dan
En fait, DejaVu Sans Mono est installé et il est utilisé pour certains caractères, par exemple "ϛ". Il semble donc sélectionner une police différente pour Phi, à savoir "xft: -unknown-Latin Modern Math-normal-normal-normal- -17- - - - * - 0-iso10646-1".
Patrick Steele

Réponses:

7

Cela se produit car Emacs utilise différentes polices pour différentes parties du jeu de caractères Unicode. Vous pouvez vérifier la police utilisée en positionnant le curseur sur un caractère et en appuyant sur C-u C-x =. Par exemple, avec ma configuration sur un caractère ASCII nil:-apple-Consolas-medium-normal-normal-*-14-*-*-*-m-0-iso10646-1 (#x88), j'obtiens , mais sur un ⧺ j'obtiens nil:-apple-Symbola-medium-normal-normal-*-14-*-*-*-p-0-iso10646-1 (#xCE1)(en d'autres termes, il utilise Consolas pour ASCII et Symbola pour certains caractères spéciaux). Différentes polices ont des hauteurs différentes et Emacs donnera toujours suffisamment d'espace dans la hauteur de ligne pour afficher la police la plus haute. Par défaut, Emacs essaiera d'utiliser des polices dépendantes du système qui fonctionnent, mais cela conduit souvent à des résultats moches.

La solution que j'ai trouvée au problème de hauteur de ligne est malheureusement plutôt ennuyeuse: je passe en revue les caractères problématiques que je trouve et utilise set-fontset-fontpour les définir sur une police / taille qui n'affecte pas la hauteur de ligne. Le code pour ce faire est disponible dans ma configuration , mais c'est moche et toujours pas parfait. Si quelqu'un a une meilleure solution, je serais intéressé de l'entendre.

shosti
la source
1
Je pense qu'une approche plus simple pourrait être d'utiliser des polices unicode , comme dans ma réponse; est-ce que ça marche pour toi?
Kirill
@Kirill: les polices unicode semblent vraiment intéressantes, mais je ne suis pas sûr que cela résoudra ce problème spécifique sans peaufinage significatif (je ne l'ai pas essayé, donc je peux me tromper). Le problème racine est que différentes polices de même taille ont des hauteurs de ligne différentes, donc chaque police doit être modifiée jusqu'à ce qu'elle ait (approximativement) la même hauteur de ligne. les polices unicode ne semblent pas faciliter la modification des tailles de police.
shosti
Oui, je pense que c'est vrai, mais cela facilite la sélection de polices pour des blocs entiers de caractères, vous n'avez donc pas besoin de rechercher vous-même les caractères individuellement complètement manuellement.
Kirill
6

J'utilise le mode agda avec beaucoup de symboles mathématiques et j'ai eu le même problème. Auparavant, la seule vraie solution était comme le suggère @shosti: la personnalisation des mappages de polices. Dans mon cas, j'ai dû désactiver un certain nombre de polices car même si j'avais des polices installées avec des glyphes particuliers définis, emacs choisissait souvent la mauvaise (affichage des cases). Semblait être pire sur OSX mais je l'ai vu aussi sur Linux. Donc, avoir les bonnes polices installées n'était pas suffisant.

Ce que je fais maintenant, c'est utiliser l'excellent package de polices unicode de Roland Walker . (Je recommanderais de l'installer via MELPA.) Cela a pratiquement éliminé le problème.

Je mets ceci dans mon fichier init:

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

J'utilise PragmataPro par défaut, mais toute autre police avec une bonne couverture fonctionnera aussi et vous pouvez personnaliser les choses avec le package si nécessaire.

darinmorrison
la source
4

J'ai déjà eu ce problème dans une autre question sans réponse ici . Je m'attendrais à ce que différentes polices de même taille aient les mêmes hauteurs, mais cela ne semble pas être le cas, je vais donc montrer mon approche ad hoc pour résoudre ce problème.

En laissant de côté les accents et en se concentrant uniquement sur les caractères simples, différentes polices sont nécessaires pour afficher tous les différents caractères simplement parce que certaines polices omettent des blocs entiers de caractères qui sont présents dans d'autres polices. Pour vous assurer que les caractères inhabituels (tels que "𝚫") ont au moins une police pour eux, installez une police telle que Symbola et consultez la liste des polices dans le fichier Lisez -moi du package unicode-fonts .

Si vous installez le package unicode-fontset un certain nombre de bonnes polices, tous les caractères doivent être pris en charge, mais certains auront des hauteurs affichées incorrectes dans emacs.

Supposons que Monaco ait des hauteurs incorrectes, mais Symbola semble avoir des hauteurs correctes pour les symboles mathématiques (tels que SOUS-ENSEMBLE OU ÉGAL À ⊆; utilisez C-x 8 RETou insert-charpour tester différents caractères.). Dans mon cas, ne pas utiliser Monaco, Noto Sans Symbols et Apple Symbols était suffisant; une bonne police pour moi était DejaVu Sans Mono.

La première chose est que vous pouvez interdire unicode-fontsd'utiliser Monaco en l'ajoutant à unicode-fonts-skip-fonts; quelle que soit la police qu'il sélectionne ensuite peut avoir la bonne hauteur. Alternativement, vous pouvez dire unicode-fontsd'utiliser une police spécifique pour un bloc Unicode (comme les opérateurs mathématiques; voici une liste de tous les blocs ) en modifiant une entrée de unicode-fonts-block-font-mapping.

La seconde est que vous pouvez facilement le faire manuellement pour un ensemble de caractères très précis en utilisant set-fontset-font. Si Symbola est une bonne police pour les symboles mathématiques (dans ce cas, la plage 0x2100..0x23ff), ce qui suit devrait fonctionner:

(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"))))

D' autres gammes que je avais besoin de me modifier étaient 2000..206f, 27c0..27ff, 2900..2bff, 1d400..1d7ff.

Enfin, il n'est pas nécessaire de rechercher manuellement les caractères mal configurés. En supposant qu'il unicode-fontssoit installé, la fonction suivante générera une liste de tous les caractères avec des hauteurs incorrectes:

(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))))

Par exemple:

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

et alors

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

montrerait tous les mauvais symboles mathématiques. Vous pouvez ensuite examiner la police avec laquelle ils sont affichés et la modifier.

J'ai OS X 10.9.5, donc mes paramètres de police seraient probablement différents des vôtres. Il n'est pas nécessaire d'installer unicode-fonts; il est possible de spécifier manuellement vos choix de police préférés entièrement set-fontset-fontchaque fois que vous constatez que les choix par défaut d'emacs ne fonctionnent pas bien.

PS Il existe une alternative: quand une police est toujours trop grande / petite, vous pouvez ajouter une entrée face-font-rescale-alistpour dire à emacs de toujours multiplier la taille de cette police par un facteur de, disons, 0,95, comme ceci:

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

Quand j'ai essayé, cela n'a pas tout à fait fonctionné correctement (mon rapport de bogue est ici ), mais c'est également une approche possible.

Kirill
la source
Le conseil set-fontset-fontsemble être le seul requis en fait. Je n'ai eu qu'à évaluer, par exemple, la (set-fontset-font t '(#x1d400 . #x1d7ff) "Symbola")création de trames ( window-setup-hook; pour le faire fonctionner emacs --daemon), et installer le paquet ttf-ancient-fonts contenant Symbola sous Debian .
nberth
2

Ceci est un bug; il est fixé dans le coffre. Le problème est dû à des informations de hauteur de ligne incorrectes sur les polices TeX, qui se trouvent être celles vers lesquelles Emacs revient s'il ne trouve pas de caractère.

Le fil de bogue sur emacs-bug a beaucoup plus d'informations.

Clément
la source