Bagaimana cara mengatur font fallback dengan cara yang kuat?

16

TL; DR: Apa cara sederhana untuk mengatakan: gunakan Consolas sebagai font default, FreeMono untuk karakter yang tidak didukung oleh Consolas, dan Symbola untuk karakter yang tidak didukung oleh keduanya?

Karena font pemrograman utama saya tidak mencakup semua simbol matematika yang saya butuhkan, saya awalnya mengatur font fallback seperti yang ditunjukkan di bawah ini:

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

Sayangnya ini juga mengubah font untuk beberapa karakter yang didukung font utama saya, jadi saya mengubahnya menjadi

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

Jika pemahaman saya benar, ini harus memastikan bahwa karakter yang tidak bisa ditangani oleh Consolas ditangani oleh FreeMono, kecuali FreeMono tidak memilikinya, dalam hal ini mereka harus ditampilkan menggunakan Symbola. Juga pemahaman saya yang tmelakukan hal yang sama seperti di "fontset-default"atas.

Sayangnya, masih ada kasus-kasus di mana font yang tepat tidak dipilih; Saya menemukan bahwa berubah menjadi

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

bekerja lebih baik, tetapi tidak selalu: mengubah ukuran font menggunakan

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

menyebabkan fallback diabaikan, karena font baru dibuat.

Solusi saya saat ini adalah melakukan

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

pada setiap fontset ( fontset-list), setelah setiap perubahan ukuran font.

Apa cara yang tepat untuk mengatur font fallback?

Catatan : untuk tujuan pengujian, berikut adalah beberapa karakter matematika: ℕ𝓟⧺×≠≥≤±¬∨∧∃∀λ⟿⟹⊥⊤⊢
Referensi : Manual Emacs pada fontsets dan pada memodifikasi fontsets

Sejuk
sumber
2
Saya punya pemikiran yang tidak benar-benar menyelesaikan masalah Anda, tetapi –– jika Anda memerlukan simbol matematika dll untuk teorema dan dokumen ilmiah, mengapa Anda tidak menggunakan TeX dan AucTeX untuk itu? Ini akan membuat kerepotan dengan X (atau Mac atau Windows, tergantung pada apa yang Anda jalankan) fallback font yang tidak perlu dan memberi Anda dokumen dan snippet berkualitas tinggi (mis. Untuk mode org).
renungkan: font UTF-8 dengan set karakter lengkap harus menghapus masalah Anda sepenuhnya (mis. GNU Unifont), dan ketika ada pilihan antara font mewah dan mesin terbang yang diperlukan, saya akan memilih yang terakhir.
2
@ kuli Anda terlalu pesimis. Lihat github.com/cpitclaudel/monospacifier
Ista
Saya tidak ingat di mana saya membacanya, tetapi saya yakin Eli Zaretskii menanggapi pertanyaan serupa di suatu tempat. Anda berpikir fontsetdengan cara yang salah. Emacs sebenarnya tidak memeriksa setiap karakter yang ditampilkan apakah font tahu cara menampilkannya atau tidak. Itu akan terlalu intensif secara komputasi. Jadi tidak ada mekanisme "fallback" per se. Anda harus mengatur font default Anda dan kemudian memodifikasi font default secara manual dalam rentang tertentu untuk ditampilkan menggunakan font yang berbeda. Prosedur ini manual atau mungkin paket unicodedapat membantu.
GenaU
@ GenaU Saya mungkin salah paham, tetapi Emacs memeriksa; tidak setiap font, hanya font yang muncul dalam fontset.
Clément

Jawaban:

0

Bagi mereka yang tidak dapat membaca dokumentasi Emacs.

Pemilihan Font

Sebelum Emacs dapat menggambar karakter pada tampilan grafis, ia harus memilih "font" untuk karakter itu. Biasanya, Emacs secara otomatis memilih font berdasarkan wajah yang ditugaskan untuk karakter itu — khususnya, atribut wajah ': keluarga', ': berat', ': miring', dan ': lebar'. Pilihan font juga tergantung pada karakter yang akan ditampilkan; beberapa font hanya dapat menampilkan serangkaian karakter terbatas. Jika tidak ada font yang sesuai dengan persyaratan, Emacs mencari “font yang paling cocok”. Variabel di bagian ini mengontrol bagaimana Emacs membuat pilihan ini.

face-font-family-alternatives

Diuji secara khusus menggunakan karakter dalam pertanyaan, memeriksa karakter dengan
describe-character. Setiap karakter menggunakan salah satu font gratis: Consolas, FreeMono, Symbola. Mengatur font bingkai ke Consola oleh set-frame-font.

14 peningkatan sejauh ini, jawaban diturunkan, dan sains UE masih belum dapat menyelesaikan misteri itu.

Alexandr Karbivnichiy
sumber
Terima kasih! Apakah Anda menganggap memposting ini sebagai tanggapan atas komentar saya di atas, dan bukan jawaban yang terpisah?
Clément
1
(Saya harus mengklarifikasi bahwa saya menguji juga, pada Emacs 26, dan jawaban Anda tampaknya tidak berfungsi: Saya menggunakan (setq face-font-family-alternatives '(("Consolas" "FreeMono" "Symbola"))), kemudian M-x set-frame-font RET Consolas RET; karakter menggunakan campuran Consolas dan Simbol Segoe UI)
Clément
Saya menguji pada Manjaro Arch Linux urutan ini: ℕ𝓟⧺ × ≠ ≥≤ ± ¬∨∧∃∀λ⟿⟹⊥⊤⊢; Saya tidak menguji apa yang terjadi jika beberapa font tidak diinstal. Itu mungkin. Karena nama font dimasukkan secara manual, bukan dari daftar yang ada.
Alexandr Karbivnichiy
Saya menguji dengan semua font dalam daftar yang diinstal, dalam emacs -Q.
Clément
@ Clément emacs Opsi -Q banyak mengotori: --no-x-resources. Mungkin masalahnya ada di dalamnya. Bagi saya, Consolas hanya dimulai dari karakter ini: "×". Dan dua "ℕ𝓟" pertama FreeMono dan Symbola.
Alexandr Karbivnichiy
-1

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

Ada daftar yang terlihat seperti:

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

Tambahkan urutan Anda di customizeantarmuka penyangga:

("Consolas" "FreeMono" "Symbola")

Jika keluarga tertentu ditentukan tetapi tidak ada, variabel ini menentukan keluarga font alternatif untuk dicoba. Setiap elemen harus memiliki bentuk ini:

 (FAMILY ALTERNATE-FAMILIES...)

Jika KELUARGA ditentukan tetapi tidak tersedia, Emacs akan mencoba keluarga lain yang diberikan dalam ALTERNATE-KELUARGA, satu per satu, sampai menemukan keluarga yang ada.

Cara menggunakan face-font-family-alternatives:

Di dalam buffer Anda: M-x set-frame-font

Pilih font dari daftar. Font yang dipilih akan menentukan urutan pencarian font apa yang face-font-family-alternativesakan digunakan. Dalam contoh ini Consolas .

Untuk memeriksa jenis font apa yang digunakan untuk menampilkan karakter: M-x describe-char

Alexandr Karbivnichiy
sumber
Terima kasih! Tetapi saya tidak berpikir ini menjawab pertanyaan. AFAICT, konfigurasi yang Anda sarankan akan menggunakan FreeMono jika font Consolas tidak tersedia, tetapi tidak akan mundur ke FreeMono untuk karakter yang tidak didukung oleh Consolas.
Clément