Wie richte ich einen robusten Fallback für Schriftarten ein?

16

TL; DR: Was ist eine einfache Möglichkeit, zuverlässig zu sagen: Verwenden Sie Consolas als Standardschriftart, FreeMono für Zeichen, die von Consolas nicht unterstützt werden, und Symbola für Zeichen, die von beiden nicht unterstützt werden?

Da meine Hauptprogrammierungsschrift nicht alle mathematischen Symbole abdeckt, die ich benötige, habe ich zunächst den Schrift-Fallback wie folgt eingerichtet:

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

Leider hat sich dadurch auch die Schriftart für einige der Zeichen geändert, die von meiner Hauptschriftart unterstützt werden, sodass ich sie in geändert habe

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

Nach meinem Verständnis sollte dies sicherstellen, dass Zeichen, mit denen Consolas nicht umgehen kann, von FreeMono verarbeitet werden, es sei denn, FreeMono verfügt nicht über diese Zeichen. In diesem Fall sollten sie mit Symbola angezeigt werden. Es ist auch mein Verständnis, tdas dasselbe wie "fontset-default"oben tut .

Leider gab es immer noch Fälle, in denen die richtige Schriftart nicht ausgewählt wurde. Das änderte sich zu

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

funktionierte besser, aber nicht immer: ändere die schriftgröße mit

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

führten dazu, dass die Fallbacks ignoriert wurden, da neue Zeichensätze erstellt wurden.

Meine aktuelle Lösung ist zu tun

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

bei jedem Fontset ( fontset-list) nach jeder Änderung der Schriftgröße.

Was ist der richtige Weg, um Font Fallback einzustellen?

Hinweis : Zu Testzwecken finden Sie hier einige mathematische Zeichen: ℕ𝓟⧺×≠≥≤±¬∨∧∃∀λ⟿⟹⊥⊤⊢
Verweise : Emacs-Handbuch zu Schriftarten und zum Ändern von Schriftarten

Clément
quelle
2
Ich habe einen Gedanken, der Ihr Problem nicht wirklich löst, aber - wenn Sie mathematische usw. Symbole für Theoreme und wissenschaftliche Dokumente benötigen, warum verwenden Sie dafür nicht TeX und AucTeX? Es würde Ärger mit X (oder Mac oder Windows, je nachdem, was Sie ausführen) unnötigen Font-Fallbacks machen und Sie mit qualitativ hochwertigen Dokumenten und Snippets versorgen (z. B. für den Organisationsmodus).
nachträglicher Gedanke: Eine UTF-8-Schriftart mit einem vollständigen Zeichensatz sollte Ihr Problem vollständig beseitigen (z. B. GNU Unifont), und wenn die Wahl zwischen einer schicken Schriftart und den erforderlichen Glyphen besteht, würde ich die letztere wählen.
2
@ kuli Du bist zu pessimistisch. Siehe github.com/cpitclaudel/monospacifier
Ista
Ich kann mich nicht erinnern, wo ich es gelesen habe, aber ich glaube, Eli Zaretskii hat irgendwo auf eine ähnliche Frage geantwortet. Sie denken fontsetfalsch. Emacs prüft nicht für jedes angezeigte Zeichen, ob eine Schrift weiß, wie sie angezeigt wird oder nicht. Das wäre zu rechenintensiv. Es gibt also keinen "Fallback" -Mechanismus an sich. Sie sollten Ihre Standardschriftart festlegen und dann die Standardschriftart in bestimmten Bereichen manuell ändern, um sie mit anderen Schriftarten anzuzeigen. Diese Prozedur ist manuell oder möglicherweise kann das Paket unicodehelfen.
Genua
@GenaU Vielleicht habe ich ein Missverständnis, aber Emacs überprüft es; Nur nicht jede Schriftart, sondern nur die, die in einem Fontset enthalten sind.
Clément

Antworten:

0

Für diejenigen, die die Emacs-Dokumentation nicht lesen können.

Schriftauswahl

Bevor Emacs ein Zeichen auf einer grafischen Anzeige zeichnen kann, muss eine „Schriftart“ für dieses Zeichen ausgewählt werden. Normalerweise wählt Emacs automatisch eine Schriftart aus, die auf den Gesichtern basiert, die diesem Zeichen zugewiesen sind, insbesondere den Gesichtsattributen ': family', ': weight', ': slant' und ': width'. Die Wahl der Schriftart hängt auch von dem anzuzeigenden Zeichen ab. Einige Schriftarten können nur eine begrenzte Anzahl von Zeichen anzeigen. Wenn keine verfügbare Schriftart genau den Anforderungen entspricht, sucht Emacs nach der „am besten passenden Schriftart“. Die Variablen in diesem Abschnitt steuern, wie Emacs diese Auswahl vornimmt.

face-font-family-alternatives

Speziell getestet mit Zeichen in der Frage, überprüfen Sie die Zeichen mit
describe-character. Jeder Buchstabe benutzt eine der freien Schriftarten: Consolas, FreeMono, Symbola. Festlegen der Frame-Schriftart auf Consola von set-frame-font.

Bisher 14 positive Stimmen, eine negative Antwort, und die EU-Wissenschaft kann dieses Rätsel immer noch nicht lösen.

Alexandr Karbivnichiy
quelle
Vielen Dank! Haben Sie in Betracht gezogen, dies als Antwort auf meinen obigen Kommentar zu veröffentlichen, anstatt als separate Antwort?
Clément
1
(Ich sollte klarstellen, dass ich auch auf Emacs 26 getestet habe und Ihre Antwort nicht zu funktionieren scheint: Ich habe es (setq face-font-family-alternatives '(("Consolas" "FreeMono" "Symbola")))dann verwendet M-x set-frame-font RET Consolas RET; die Charaktere verwenden eine Mischung aus Consolas und Segoe UI Symbol)
Clément
Ich habe diese Sequenz auf Manjaro Arch Linux getestet: ℕ𝓟⧺ × ≠ ≥≤ ± ¬∨∧∃∀λ⟿⟹⊥⊤⊢; Ich habe nicht getestet, was passiert, wenn eine Schriftart nicht installiert ist. Es kann möglich sein. Da Schriftnamen manuell eingegeben werden und nicht aus einer Liste vorhandener.
Alexandr Karbivnichiy
Ich habe mit allen Schriften in der Liste getestet emacs -Q.
Clément
@ Clément emacs -Q Option stört viel: --no-x-resources. Vielleicht liegt das Problem darin. Für mich beginnt Consolas nur mit diesem Buchstaben: "×". Und die ersten beiden "ℕ𝓟" FreeMono und Symbola.
Alexandr Karbivnichiy
-1

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

Es gibt eine Liste, die ungefähr so ​​aussieht:

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

Fügen Sie Ihre Sequenz in die customizePufferschnittstelle ein:

("Consolas" "FreeMono" "Symbola")

Wenn eine bestimmte Familie angegeben ist, diese jedoch nicht vorhanden ist, gibt diese Variable alternative Schriftfamilien an, die Sie ausprobieren möchten. Jedes Element sollte diese Form haben:

 (FAMILY ALTERNATE-FAMILIES...)

Wenn FAMILY angegeben, aber nicht verfügbar ist, probiert Emacs die anderen in ALTERNATE-FAMILIES angegebenen Familien nacheinander aus, bis eine vorhandene Familie gefunden wird.

Wie benutzt man face-font-family-alternatives:

In deinem Puffer: M-x set-frame-font

Wählen Sie eine Schriftart aus der Liste. Die gewählte Schriftart definiert die zu verwendende Schriftsuchsequenz face-font-family-alternatives. In diesem Beispiel Consolas .

So überprüfen Sie, welche Schriftfamilie zum Anzeigen eines Zeichens verwendet wurde: M-x describe-char

Alexandr Karbivnichiy
quelle
Vielen Dank! Aber ich denke nicht, dass dies die Frage beantwortet. AFAICT: In der von Ihnen vorgeschlagenen Konfiguration wird FreeMono verwendet, wenn die Consolas-Schriftart nicht verfügbar ist, es wird jedoch nicht auf FreeMono für Zeichen zurückgegriffen, die von Consolas nicht unterstützt werden.
Clément