Altura da linha com caracteres unicode

23

Alguns caracteres Unicode fazem com que a linha na qual eles são exibidos seja bastante grande. Por exemplo, um sotaque grave "̀" adiciona cerca de 2,5 linhas de espaço acima e abaixo dele. Outros caracteres que causam esse comportamento incluem a letra grega "ϕ" (phi) ou o subconjunto igual a "⫅". Outros caracteres, como mapas para "⤇", adicionam apenas cerca de 0,5 linhas em ambos os lados.

Eu me deparei com esse problema ao ler a fonte da julia-mode.elqual contém um grande número de caracteres para a substituição do LaTeX.

Por que isso ocorre e pode ser corrigido?

Edit: Estou usando o Ubuntu 14.04 LTS com o Emacs 24.3.1. Por padrão, eu uso a fonte "Ubuntu Mono 13", mas outras fontes são usadas para exibir caracteres. Eu tenho instalado nenhum pacote para gerenciar explicitamente unicode, e este problema é reproduzível usando o comando emacs -Q.

Patrick Steele
fonte
3
Provavelmente, isso está relacionado às fontes que você instalou. Usar uma fonte com suporte Unicode decente embutido (por exemplo, DejaVu Sans Mono) pode ajudar.
Chris
Edite sua pergunta e adicione informações sobre seu sistema operacional, sua versão do Emacs e as fontes que você usa para o Emacs.
lunaryorn 25/09/14
Mencione também se você usa algum pacote / comando para configurar o unicode. Ou você está apenas usando o que saiu da caixa.
Malabarba 25/09
Concordo com a fonte: eu uso o DejaVu Sans Mono e os caracteres unicode são renderizados sem nenhuma diferença visível no espaçamento vertical das linhas.
Dan
Na verdade, tenho o DejaVu Sans Mono instalado e ele é usado para alguns caracteres, como "ϛ". Portanto, parece estar selecionando uma fonte diferente para Phi, a saber "xft: -unknown-Latin Modern Math-normal-normal-normal- -17- - - - * - 0-iso10646-1".
Patrick Steele

Respostas:

7

Isso ocorre porque o Emacs usa fontes diferentes para diferentes partes do conjunto de caracteres Unicode. Você pode verificar qual fonte está sendo usada posicionando o cursor sobre um caractere e pressionando C-u C-x =. Por exemplo, com minha configuração com um caractere ASCII que recebo nil:-apple-Consolas-medium-normal-normal-*-14-*-*-*-m-0-iso10646-1 (#x88), mas com um ⧺ recebo nil:-apple-Symbola-medium-normal-normal-*-14-*-*-*-p-0-iso10646-1 (#xCE1)(em outras palavras, ele usa Consolas para ASCII e Symbola para alguns caracteres especiais). Fontes diferentes têm alturas diferentes, e o Emacs sempre dará espaço suficiente na altura da linha para exibir a fonte mais alta. Por padrão, o Emacs tentará usar fontes dependentes do sistema que funcionem, mas isso geralmente gera resultados feios.

Infelizmente, a solução que encontrei para o problema de altura da linha é bastante irritante: eu passo os caracteres problemáticos encontrados e os uso set-fontset-fontpara defini-los para uma fonte / tamanho que não afeta a altura da linha. O código para fazer isso está disponível na minha configuração , mas é feio e ainda não é perfeito. Se alguém tiver uma solução melhor, eu estaria interessado em ouvi-la.

shosti
fonte
1
Eu acho que uma abordagem mais simples pode ser usar fontes unicode , como na minha resposta; isso funciona para você?
Kirill
@Kirill: unicode-fonts parece realmente interessante, mas não tenho certeza de que resolverá esse problema específico sem ajustes significativos (eu não tentei, então poderia estar errado). O problema principal é que fontes diferentes com o mesmo tamanho têm alturas de linha diferentes, portanto, cada fonte precisa ser ajustada até que tenha (aproximadamente) a mesma altura de linha. unicode-fonts não parece fácil de ajustar os tamanhos das fontes.
21414 shosti
Sim, acho que é verdade, mas facilita a seleção de fontes para blocos inteiros de caracteres, para que você não precise pesquisar caracteres individuais manualmente.
19414 Kirill
6

Uso o modo agda com muitos símbolos matemáticos e tive o mesmo problema. Costumava ser a única solução real, como sugere o @shosti: personalizar os mapeamentos de fontes. No meu caso, eu tive que desativar várias fontes, porque, apesar de ter fontes instaladas com glifos específicos definidos, o emacs geralmente escolhia a fonte errada (exibindo caixas). Parecia ser pior no OSX, mas eu já vi isso no Linux também. Portanto, não basta ter as fontes corretas instaladas.

O que faço agora é usar o excelente pacote unicode-fonts de Roland Walker . (Eu recomendaria instalá-lo através do MELPA.) Isso praticamente eliminou completamente o problema.

Coloquei isso no meu arquivo init:

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

Eu uso o PragmataPro por padrão, mas qualquer outra fonte com boa cobertura funcionará também e você poderá personalizar ainda mais as coisas com o pacote, se necessário.

darinmorrison
fonte
4

Eu já tive esse problema em uma pergunta não respondida diferente aqui . Eu esperaria que fontes diferentes do mesmo tamanho tivessem as mesmas alturas, mas isso não parece ser o caso, então mostrarei minha abordagem ad-hoc para corrigir isso.

Deixando de lado os acentos e concentrando-se apenas em caracteres simples, são necessárias fontes diferentes para exibir todos os caracteres diferentes, simplesmente porque algumas fontes omitem blocos inteiros de caracteres presentes em outras fontes. Para garantir que caracteres incomuns (como "𝚫") tenham pelo menos uma fonte para eles, instale uma fonte como Symbola e consulte a lista de fontes no leia-me do pacote unicode-fonts .

Se você instalar o pacote unicode-fontse várias fontes boas, todos os caracteres deverão ser suportados, mas alguns terão alturas de exibição incorretas no emacs.

Suponha que Mônaco tenha alturas incorretas, mas Symbola pareça ter alturas corretas para símbolos matemáticos (como SUBSET DE OU IGUAL A ⊆; use C-x 8 RETou insert-charpara testar caracteres diferentes.). No meu caso, não usar Mônaco, Noto Sans Symbols e Apple Symbols foi suficiente; uma boa fonte para mim foi o DejaVu Sans Mono.

A primeira coisa é que você pode proibir o unicode-fontsuso do Mônaco adicionando-o ao unicode-fonts-skip-fonts; qualquer fonte que selecionar a seguir pode ter a altura certa. Como alternativa, você pode dizer unicode-fontspara usar uma fonte específica para um bloco Unicode (como Operadores Matemáticos; aqui está uma lista de todos os blocos ) modificando uma entrada de unicode-fonts-block-font-mapping.

A segunda é que você pode fazer isso facilmente manualmente para obter um conjunto muito preciso de caracteres usando set-fontset-font. Se Symbola é uma boa fonte para símbolos matemáticos (nesse caso, o intervalo 0x2100..0x23ff), o seguinte deve funcionar:

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

Outras faixas que eu precisava modificar me foram 2000..206f, 27c0..27ff, 2900..2bff, 1d400..1d7ff.

Por fim, não é necessário procurar caracteres mal configurados manualmente. Supondo que unicode-fontsesteja instalado, a seguinte função gerará uma lista de todos os caracteres com alturas incorretas:

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

Por exemplo:

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

e depois

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

mostraria todos os maus símbolos matemáticos. Você pode examinar com qual fonte eles são exibidos e alterá-lo.

Eu tenho o OS X 10.9.5, então minhas configurações de fonte provavelmente serão diferentes das suas. Não é necessário instalar unicode-fonts; é possível especificar manualmente suas opções de fonte preferidas inteiramente, set-fontset-fontsempre que você achar que as opções padrão do emacs não funcionam bem.

PS Existe uma alternativa: quando uma fonte é consistentemente muito grande / pequena, você pode adicionar uma entrada face-font-rescale-alistpara informar ao emacs para sempre multiplicar o tamanho dessa fonte por um fator de, por exemplo, 0,95, da seguinte forma:

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

Quando tentei isso, não funcionou direito (meu relatório de erros está aqui ), mas essa também é uma abordagem possível.

Kirill
fonte
O conselho sobre set-fontset-fontparece o único necessário, na verdade. Eu só tive que avaliar, por exemplo, (set-fontset-font t '(#x1d400 . #x1d7ff) "Symbola")na criação de quadros ( window-setup-hook; para fazê-lo funcionar emacs --daemon) e instalar o pacote ttf-ancient-fonts com o Symbola no Debian .
nberth
2

Isso é um bug; é fixado no porta-malas. O problema é causado por informações incorretas da altura da linha nas fontes TeX, que são aquelas nas quais o Emacs recorre caso não consiga encontrar um caractere.

O tópico do bug no emacs-bug tem muito mais informações.

Clemente
fonte