Come posso impostare il fallback dei font in modo affidabile?


16

TL; DR: Qual è un modo semplice per dire in modo affidabile: utilizzare Consolas come carattere predefinito, FreeMono per i caratteri non supportati da Consolas e Symbola per i caratteri non supportati da entrambi?

Poiché il mio carattere di programmazione principale non copre tutti i simboli matematici di cui ho bisogno, inizialmente ho impostato il fallback dei caratteri come mostrato di seguito:

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

Purtroppo questo ha cambiato anche il carattere di alcuni dei caratteri supportati dal mio carattere principale, quindi l'ho cambiato

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

Se la mia comprensione è corretta, ciò dovrebbe garantire che i caratteri che Consolas non può gestire siano gestiti da FreeMono, a meno che FreeMono non li abbia, nel qual caso dovrebbero essere visualizzati usando Symbola. È anche mia comprensione che tfa lo stesso come "fontset-default"sopra.

Sfortunatamente, c'erano ancora casi in cui non era stato selezionato il carattere giusto; Ho scoperto che cambiando in

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

ha funzionato meglio, ma non sempre: modificando la dimensione del carattere con

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

ha fatto sì che i fallback fossero ignorati, a causa della creazione di nuovi set di caratteri.

La mia soluzione attuale è fare

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

su ogni set di caratteri ( fontset-list), dopo ogni modifica della dimensione del carattere.

Qual è il modo corretto di impostare il fallback dei caratteri?

Nota : a scopo di test, ecco alcuni caratteri matematici: ℕ𝓟⧺×≠≥≤±¬∨∧∃∀λ⟿⟹⊥⊤⊢
Riferimenti : manuale di Emacs sui set di caratteri e sulla modifica dei set di caratteri


2
Ho un pensiero che non risolve davvero il tuo problema, ma –– se hai bisogno dei simboli matematici ecc. Per teoremi e documenti scientifici, perché non usi TeX e AucTeX per questo? Ciò renderebbe inutile la seccatura con X (o Mac o Windows, a seconda di ciò che si esegue) fallback dei caratteri e fornire documenti e frammenti di alta qualità (ad es. Per la modalità org).

ripensamento: un font UTF-8 con un set di caratteri completo dovrebbe rimuovere completamente il tuo problema (ad es. GNU Unifont), e quando c'è la scelta tra font di fantasia e glifi richiesti, sceglierei quest'ultimo.

2
@kuli Sei troppo pessimista. Visita github.com/cpitclaudel/monospacifier
Ista il

Non ricordo dove l'ho letto, ma credo che Eli Zaretskii abbia risposto a una domanda simile da qualche parte. Stai pensando fontsetnel modo sbagliato. Emacs non controlla effettivamente per ogni carattere che mostra se un carattere sa come visualizzarlo o meno. Sarebbe troppo intenso dal punto di vista computazionale. Quindi non esiste un meccanismo "fallback" di per sé. È necessario impostare il tipo di carattere predefinito e quindi modificare manualmente il set di caratteri predefinito in determinati intervalli per visualizzare utilizzando tipi di carattere diversi. Questa procedura è manuale o forse il pacchetto unicodepuò essere d'aiuto.
GenaU

@GenaU Potrei essere frainteso, ma Emacs controlla; solo non tutti i caratteri, solo quelli che compaiono in un set di caratteri.
Clément il

Risposte:


0

Per coloro che non sono in grado di leggere la documentazione di Emacs.

Selezione del carattere

Prima che Emacs possa disegnare un personaggio su un display grafico, deve selezionare un “carattere” per quel personaggio. Normalmente, Emacs sceglie automaticamente un carattere in base alle facce assegnate a quel personaggio, in particolare agli attributi delle facce ": famiglia", ": peso", ": inclinazione" e ": larghezza". La scelta del carattere dipende anche dal carattere da visualizzare; alcuni caratteri possono visualizzare solo un set limitato di caratteri. Se nessun carattere disponibile soddisfa esattamente i requisiti, Emacs cerca il "carattere corrispondente più vicino". Le variabili in questa sezione controllano il modo in cui Emacs effettua questa selezione.

face-font-family-alternatives

Testato specificatamente usando i caratteri nella domanda, controllando i caratteri con
describe-character. Ogni personaggio utilizza uno dei caratteri gratuiti: Consolas, FreeMono, Symbola. Impostare il carattere del frame su Consola di set-frame-font.

Finora 14 voti positivi, risposta declassata, e la scienza dell'UE non riesce ancora a risolvere quel mistero.


Grazie! Hai considerato di pubblicare questo come una risposta al mio commento sopra, piuttosto che una risposta separata?
Clément

1
(Dovrei chiarire che ho provato anche su Emacs 26 e la tua risposta non sembra funzionare: l'ho usato (setq face-font-family-alternatives '(("Consolas" "FreeMono" "Symbola"))), quindi M-x set-frame-font RET Consolas RET; i personaggi usano un mix di Consolas e Segoe UI Symbol)
Clément

Ho testato su Manjaro Arch Linux questa sequenza: ℕ𝓟⧺ × ≠ ≥≤ ± ¬∨∧∃∀λ⟿⟹⊥⊤⊢; Non ho testato cosa succede se alcuni font non sono installati. Può essere possibile. Perché i nomi dei caratteri vengono inseriti manualmente, non da un elenco di quelli esistenti.
Alexandr Karbivnichiy il

Ho provato con tutti i caratteri nell'elenco installato, in emacs -Q.
Clément,

@ Clément emacs -Q L'opzione impila molto: --no-x-risorse. Forse il problema sta nel fatto. Per me, le Console partono solo da questo carattere: "×". E i primi due "ℕ𝓟" FreeMono e Symbola.
Alexandr Karbivnichiy,

-1

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

C'è un elenco simile a:

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

Aggiungi la tua sequenza nell'interfaccia customizebuffer:

("Consolas" "FreeMono" "Symbola")

Se viene specificata una determinata famiglia ma non esiste, questa variabile specifica famiglie di caratteri alternative da provare. Ogni elemento dovrebbe avere questa forma:

 (FAMILY ALTERNATE-FAMILIES...)

Se FAMILY è specificato ma non disponibile, Emacs proverà le altre famiglie indicate in ALTERNATE-FAMILIES, una per una, finché non troverà una famiglia che esiste.

Come usare face-font-family-alternatives:

Nel tuo buffer: M-x set-frame-font

Scegli un carattere dall'elenco. Il carattere scelto definirà quale sequenza di ricerca del carattere face-font-family-alternativesutilizzare. In questo esempio Consolas .

Per verificare quale famiglia di caratteri è stata utilizzata per visualizzare un carattere: M-x describe-char


Grazie! Ma non penso che questo risponda alla domanda. AFAICT, la configurazione che hai suggerito utilizzerà FreeMono se il carattere Consolas non è disponibile, ma non tornerà a FreeMono per i caratteri non supportati da Consolas.
Clément,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.