Xterm.js: Mendukung pengikat font

Dibuat pada 8 Sep 2017  ·  54Komentar  ·  Sumber: xtermjs/xterm.js

Dukungan dihapus di https://github.com/sourcelair/xterm.js/pull/938

Itu pasti masih memungkinkan, perender perlu tahu karakter mana yang akan digabungkan.

areapi arerenderer help wanted typenhancement

Komentar yang paling membantu

Saya pikir kami tidak tertarik dengan ligatur biasa (pada kenyataannya, akan buruk untuk mengaktifkan ligatur untuk li dan semacamnya), tetapi untuk hal-hal seperti == , !== , => dan seterusnya. Berikut adalah daftar ligatur yang didukung oleh font monospace kode fira:
https://github.com/tonsky/FiraCode/blob/master/showcases/all_ligatures.png

Semua 54 komentar

Saya pikir kami tidak tertarik dengan ligatur biasa (pada kenyataannya, akan buruk untuk mengaktifkan ligatur untuk li dan semacamnya), tetapi untuk hal-hal seperti == , !== , => dan seterusnya. Berikut adalah daftar ligatur yang didukung oleh font monospace kode fira:
https://github.com/tonsky/FiraCode/blob/master/showcases/all_ligatures.png

Apa yang akan terjadi jika separuh ligatur memiliki warna yang berbeda? Bagaimana Anda mengatasinya?

@LoganDark apakah itu bekerja dengan ligatur biasa? Atau apakah mereka berpisah saat warnanya berbeda?

Tidak, dan tidak.

saya bertanya-tanya apakah mungkin untuk menarik kode render dari txtjs, karena mereka telah menemukan cara membuat ligatur, meskipun saya pikir mereka menggambar teks secara manual. http://txtjs.com/examples/Text/ligatures.html

@devsnek Saya rasa ini bukan masalah sebenarnya dalam melakukan rendering teks. Masalahnya adalah mengetahui karakter mana yang bergabung sehingga bisa digambar bersama (Saat ini "==" digambar sebagai "=" dan "=", bukan "==").

@Tyriar tidak akan

@devsnek ya, tetapi setiap sel dalam kisi digambar satu per satu dengan beberapa pengecualian (emoji, karakter unicode lebar). Ligatur harus dimasukkan dalam daftar itu. Lihat https://github.com/sourcelair/xterm.js/pull/938 untuk konteks lebih lanjut

@evanus

disclaimer: benar-benar keluar topik, hanya komentar acak

@LoganDark apakah itu bekerja dengan ligatur biasa? Atau apakah mereka berpisah saat warnanya berbeda?

Jika kita pergi dengan bagaimana emulator lain menangani mereka, mereka mendapatkan berpisah jika mereka warna yang berbeda, seperti yang diharapkan. Ini hampir menjadi persyaratan karena ini memungkinkan simbol diwakili dengan benar oleh beberapa penyorot bahasa di ViM, misalnya.

Saya pikir itu sepenuhnya dapat diterima untuk menampilkan simbol individu jika mode render _not_ sama untuk semua karakter yang mendasarinya.

@ Qix- Saran saya adalah menggambar semua teks sekaligus dan kemudian melakukan pewarnaan di pos. Itu akan menghilangkan masalah apa pun dengan ligatur, dan tidak perlu mendeteksi pasangan ligatur (meskipun itu akan merusak kompatibilitas dengan font lebar variabel, atau bahkan font monospace yang sedikit tidak aktif / tidak memiliki lebar integer)

Ligatur multiwarna @LoganDark akan terlihat aneh dan tidak akan ada cara yang jelas untuk mewarnainya secara IMO.

Ya, saya rasa ligatur multi-warna tidak akan berhasil. Ini juga bertentangan dengan cara kerjanya di bawah, di mana satu mesin terbang digambar di awal, bukan beberapa.

Sebagai klarifikasi, ini menunggu solusi yang baik untuk mendeteksi urutan karakter mana yang memiliki ligatur. Untuk melakukan ini dengan benar, mungkin akan melibatkan kode tingkat rendah yang memeriksa file font (dan karenanya perlu menjadi modul node asli dan tidak berfungsi untuk konsumen web), saya rasa informasi ini tidak diekspos ke platform web.

Sekarang hyper merilis 2.0.0 stabil, mungkin solusi pengikat membutuhkan prioritas yang lebih tinggi.

Menentukan pemetaan mesin terbang secara manual adalah hal yang sulit untuk dipecahkan. Dari apa yang dapat saya ceritakan, membuat pengalaman yang layak dari ini membutuhkan hal-hal berikut:

  1. Petakan keluarga font yang dipilih kembali ke file / buffer yang berisi data font sebenarnya (otf / ttf / woff / etc)
  2. Parsing data dari tabel
  3. Meneruskan semacam fungsi peta atau pemetaan ke xterm untuk menentukan apa yang akan dirender untuk urutan karakter tertentu

Saya telah melakukan beberapa penelusuran awal dengan Fira Code (khususnya varian font nerd) untuk mencoba mencari tahu seberapa sulit setiap langkahnya. Saya belum memutuskan apakah saya merasa cukup ambisius (atau cukup peduli dengan pengikat font) untuk melakukan ini, tetapi inilah yang saya temukan sehingga pengetahuan tidak hilang:

  • Tidak ada cara yang dapat saya temukan untuk mengambil data font menggunakan API browser, jadi ini tidak akan berfungsi sebagai fitur langsung xterm.js, tetapi lebih mungkin sebagai paket / ekstensi terpisah dengan hook yang diekspos oleh xterm.js

  • Memetakan CSS font-family nama font kembali ke file fontnya di Windows sangat menyakitkan tetapi tampaknya bisa dilakukan. Sejauh ini satu-satunya cara yang saya temukan adalah mengambil semuanya di %WINDIR%\Fonts dan mengurai setiap file yang saya temukan (spoiler: sangat lambat). Belum mencoba platform lain. (Catatan: Saya juga mencoba mengangkat nama dari registri tetapi penamaan tidak sesuai untuk beberapa font seperti yang dari font nerd. Mereka menggunakan keluarga dan subfamili "pilihan" yang tidak diambil dalam nama registri tetapi digunakan di css font-family . Jika Anda penasaran, kunci registri ada di HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts )

  • Ada pustaka bernama opentype.js yang melakukan parsing penuh tabel font OpenType dan bahkan memiliki fungsi font.stringToGlyphs(str) yang menangani ligatur dasar, tetapi ligatur untuk Kode Fira (dan beberapa jika tidak semua font ligatur umum lainnya) menggunakan fitur yang disebut alternatif kontekstual yang belum didukung oleh opentype.js (terdaftar di bawah Direncanakan ). Tabel GSUB yang diperlukan diurai menjadi JSON untuk Anda, jadi secara teoritis yang hilang hanyalah interpretasi data tabel.

  • Ligatur Kode Fira (dan saya pikir yang lain) benar-benar mengganti mesin terbang asli dengan jumlah mesin terbang yang sama, daripada satu mesin terbang ekstra lebar (untuk mempertahankan properti dari font monospace). Untuk string seperti ==> , font akan memberi tahu Anda untuk menggantinya dengan dua karakter "LIG" (pada dasarnya adalah spasi kosong), diikuti oleh mesin terbang sebenarnya untuk ligatur, yang secara teknis masih hanya satu monospace karakter lebar. Meskipun lebar terlihat tunggal, jalur karakter terakhir melampaui sisi kiri kotak pembatas karakter untuk menutupi ruang yang ditempati oleh dua karakter LIG sebelumnya. Lihat di bawah untuk visual (0 dan 600 adalah sisi kotak karakter). Saya tidak tahu apakah ini memperumit tugas perender atau apakah itu harus diubah sebelum diteruskan ke xterm.js, tetapi sesuatu yang harus diperhatikan.

image

  • Kerutan lain dalam hal ini adalah menentukan kapan harus mengevaluasi kembali ligatur. Misalnya, jika saya mengetik = empat kali berturut-turut, perilaku yang diinginkan bagi saya adalah melihat satu sama dengan, lalu ganda sama dengan ligatur, lalu tiga kali lipat sama dengan ligatur, lalu empat tanda sama dengan yang terpisah. Sebenarnya ada pemetaan dalam aturan alternatif kontekstual untuk membersihkan ligatur (yaitu jika input saat ini adalah '=' dan tiga karakter sebelumnya adalah '===', jangan memetakannya sama sekali), tetapi kami akan memiliki untuk mencari tahu bagaimana menerapkan aturan tersebut.

  • OpenType rumit. Memang, saya bukan ahli rendering font, tetapi jumlah kemungkinan variasi yang mengarah ke berbagai jenis rendering cukup banyak. Tanpa perpustakaan bawaan yang melakukan pemetaan untuk kami, saya pikir cara paling masuk akal untuk menyerang ini secara bertahap. Fira Code secara khusus menggunakan Chaining Context Substitution Format 3 , tapi saya yakin ada font populer lainnya yang menggunakan font berbeda. Karena masing-masing memiliki semantik yang sedikit berbeda, mungkin masuk akal untuk memulai dengan satu dan pergi dari sana.

@princjef Terima kasih telah berbagi eksplorasi Anda, sangat membantu! Saya juga telah memberikan beberapa pemikiran tentang topik ini beberapa hari yang lalu, dan saya sampai pada kesimpulan berikut:

  • Mendeteksi ligatur di font web menggunakan API bawaan tampaknya tidak mungkin (seperti yang Anda jelaskan)
  • Ada ligatur tertentu yang tidak masuk akal di terminal, meskipun font mendukungnya (mis. li )
  • Ada subset yang sangat kecil dari ligatur yang perlu didukung, yaitu sebagian besar ligatur Kode Fira.
  • Menambahkan dukungan untuk menggambar dan membersihkan karakter yang mencakup banyak sel sangat sulit diterapkan dengan pendekatan rendering berbasis karakter tunggal (CharAtlas) kami saat ini.

TBH, saya rasa tidak sepadan dengan upaya untuk mendukung ligatur pada kondisi saat ini 😔

@mofux Saya benar-benar berpikir saya telah menemukan cara (agak enak) untuk membuat ligatur dirender di xterm.js dengan mendekatinya dari sudut yang berbeda. Entah bagaimana saya melewatkan kanvas itu secara otomatis akan membuat ligatur untuk Anda dalam penyelidikan awal saya. Ligatur pendukung menjadi masalah memastikan bahwa karakter yang relevan dirender bersama.

Untuk itu, saya men-tweak perender teks untuk membuat karakter dengan atribut identik (fg, bg, dll.) Sebagai satu grup. Ini tidak akan membuat semua ligatur dengan benar (dan mungkin membuat beberapa yang seharusnya tidak), tapi itu harus membuat ligatur di mana saja seseorang akan melihatnya. Berikut tangkapan layar NeoVIM di aplikasi demo menggunakan Kode Fira (ditampilkan di Firefox, juga berfungsi di Chrome tetapi tidak Edge):

image

Cabang ada di sini jika orang ingin melihatnya: https://github.com/princjef/xterm.js/tree/ligature-support

Beberapa catatan tentang ini:

  • Saya belum melakukan benchmarking apa pun, tetapi saya bertaruh ini tidak akan bagus untuk performa. Dengan mengelompokkan semua karakter dengan gaya yang sama bersama-sama, atlas karakter pada dasarnya akan terlempar keluar jendela, bahkan untuk tempat yang tidak memiliki pengikat (karena kita tidak tahu di mana mereka akan / tidak akan berada). Ketika saya membuat beberapa karakter bersama-sama, saya hanya mengatur kode karakter ke Infinity untuk memastikan saya akan menghindari caching apa pun.
  • Mungkin ada beberapa kasus tepi di sekitar lebar karakter dan tumpang tindih yang tidak saya tangani dengan benar. Ini sebagian besar merupakan bukti konsep pada saat ini.

Bagaimana dengan merender teks menggunakan atlas karakter, kemudian merendernya di latar belakang sebagai blok teks saat menganggur? Jika keduanya menghasilkan gambar yang sama, Anda dapat membuang teks yang digabungkan dan beralih kembali ke atlas. Dengan memisahkan string teks di latar belakang, dimungkinkan untuk mempelajari string teks mana yang diberi ligaturasi.

Bagian rumitnya adalah bahwa rendering ligatur tidak hanya bergantung pada karakter yang diganti oleh ligatur tetapi juga konteksnya. Misalnya, '=== 1' harus membuat tiga tanda yang sama sebagai ligatur tetapi '====' harus membuat tiga tanda yang sama sebagai karakter terpisah. Tidak ada batasan seberapa besar konteks ini, jadi akan sulit dan kemungkinan rawan kesalahan untuk menentukan aturan kapan ligatur dirender hanya dari outputnya.

Pendekatan yang lebih andal (tetapi kurang portabel) adalah memiliki petunjuk tentang rentang ligatur yang disediakan oleh fungsi terpisah yang mengetahui metadata font. Kemudian semuanya kecuali rentang yang disediakan oleh fungsi eksternal dapat dirender menggunakan atlas, sementara grup yang diberikan dapat menggunakan pendekatan seperti di atas. Menentukan lokasi substitusi yang diberikan baris teks harus cukup cepat tetapi memiliki beberapa masalah yang saya jelaskan sebelumnya (terutama kecepatan / keandalan menemukan font yang tepat pada inisialisasi dan kompleksitas pemrosesan alternatif kontekstual OpenType).

Apakah masuk akal untuk memiliki pengaturan untuk mengaktifkan ligatur, yang menulis
seluruh baris sekaligus ke terminal? Sepertinya begini
menjamin perenderan yang benar, dan hasil kinerja akan diikutsertakan
orang yang lebih peduli dengan ligatur daripada kecepatan.

Pada hari Minggu, 22 Apr 2018, 16:21 Jeff Principe [email protected] menulis:

Bagian rumitnya adalah bahwa rendering ligatur bergantung
tidak hanya pada karakter yang digantikan oleh ligaturnya tetapi juga konteksnya.
Misalnya, '=== 1' harus membuat tiga tanda yang sama sebagai pengikat tapi
'====' harus membuat tiga tanda yang sama sebagai karakter terpisah.
Tidak ada batasan seberapa besar konteks ini, jadi akan sulit dan
kemungkinan rawan kesalahan untuk menentukan aturan kapan ligatur diberikan
hanya dari keluarannya.

Pendekatan yang lebih andal (tetapi kurang portabel) adalah memiliki petunjuk tentang
rentang pengikat disediakan oleh fungsi terpisah yang mengetahui font
metadata. Kemudian semuanya kecuali rentang yang disediakan oleh fungsi eksternal
dapat dirender menggunakan atlas, sedangkan kelompok yang diberikan dapat menggunakan
pendekatan seperti di atas. Menentukan lokasi substitusi
baris teks yang diberikan harus cukup cepat tetapi memiliki beberapa masalah saya
dijelaskan sebelumnya (terutama kecepatan / keandalan menemukan font yang tepat
inisialisasi dan kompleksitas pemrosesan alternatif kontekstual OpenType).

-
Anda menerima ini karena Anda berlangganan utas ini.
Balas email ini secara langsung, lihat di GitHub
https://github.com/xtermjs/xterm.js/issues/958#issuecomment-383420281 ,
atau nonaktifkan utasnya
https://github.com/notifications/unsubscribe-auth/AAKyryMlayIQijY32GpWBmpvCUi13Wfbks5trRBigaJpZM4PRej6
.

@princjef Wow, hasil edit Anda sangat mudah diikuti dan sepertinya xterm dapat mendukung ligatur dengan perender. Triknya hanyalah mencari cara untuk memetakan aturan. Ini memberi saya harapan.

@princjef investigasi yang bagus!

Tidak ada cara yang dapat saya temukan untuk mengambil data font menggunakan API browser, jadi ini tidak akan berfungsi sebagai fitur langsung xterm.js, tetapi lebih mungkin sebagai paket / ekstensi terpisah dengan hook yang diekspos oleh xterm.js

@princjef Saya melihat dukungan pengikat akhirnya hidup sebagai:

  • some-magical-package : Modul node asli menarik informasi font asli, memetakan string font web ke file jika memungkinkan. Ini bisa dilakukan dengan AsyncWorker untuk mengurangi kinerja hit. Bukan masalah besar jika ini dilakukan dengan malas dan pada peluncuran pertama perlu beberapa detik untuk memindai dan melakukan penyegaran.
  • xtermjs/xterm-ligature-support : Sebuah addon yang bergantung pada node dan menggunakan some-magical-package untuk mendapatkan dan menyimpan info fonta. Addon ini dapat melakukan pemindaian setiap kali font yang tidak dikenali terdeteksi di direktori font dan menghapus font saat dihapus. Saya mengharapkan sesuatu seperti ini sebagai API kasar:

    /** Returns a list of characters to be drawn together */
    export function getLigatures(fontFamily: string): string[] { ... }
    

Ada ligatur tertentu yang tidak masuk akal di terminal, bahkan jika font mendukungnya (mis. Li)

@mofux Saya tidak yakin kita perlu khawatir tentang ini? Jika pengguna meminta ligatur, bukankah kita harus merender semuanya?

Menambahkan dukungan untuk menggambar dan membersihkan karakter yang mencakup banyak sel sangat sulit diterapkan dengan pendekatan rendering berbasis karakter tunggal (CharAtlas) kami saat ini.

@mofux Kita seharusnya dapat dengan mudah menambahkan fungsi untuk menggambar sekumpulan karakter yang berdekatan bersama-sama.

@princjef : Saya belum melakukan benchmarking apa pun, tetapi saya bertaruh ini tidak akan baik untuk kinerja.

@wavebeem : Apakah masuk akal untuk memiliki pengaturan untuk mengaktifkan ligatur, yang menulis seluruh baris sekaligus ke terminal?

Saya berharap hal itu meniadakan hampir sepenuhnya peningkatan kinerja yang datang dengan menggunakan kanvas. Juga saya ingin menjaga jumlah opsi seminimal mungkin, kita harus mencoba sampai ke tempat di mana ligatur hanya berfungsi saat addon disertakan untuk menambahkan dukungan.

Juga berkaitan dengan kinerja, saya kemungkinan akan bekerja untuk menambahkan opsi rendering DOM fallback dalam beberapa bulan mendatang karena terlalu banyak hal yang bisa salah dengan dukungan GPU di Chromium. Lihat https://github.com/xtermjs/xterm.js/issues/1360. Ligatur akan bekerja di luar kotak dalam mode ini.

Bagaimana dengan merender teks menggunakan atlas karakter, kemudian merendernya di latar belakang sebagai blok teks saat menganggur? Jika keduanya menghasilkan gambar yang sama, Anda dapat membuang teks yang digabungkan dan beralih kembali ke atlas.

@ j-f1 ini lebih sulit dari yang terlihat. Meskipun karakter diberikan sama, karakter kedua akan berbeda karena spasi dalam atlas karakter berbeda (karakter selalu digambar pada angka bulat). Kita perlu melakukan lebih banyak rendering agar ini berfungsi dan banyak piksel diffing yang mahal.

@Tyriar Saya pikir desain umum yang Anda jelaskan masuk akal. Kami _mungkin_ dapat lolos dengan sesuatu yang tidak bergantung pada kode asli untuk menemukan font di some-magical-package , tetapi itu pasti akan tergantung pada platform / sistem file. Saya sudah mulai bermain-main dengan menguraikan pergantian pemain pengganti kontekstual tetapi sulit untuk mengatakan berapa banyak lagi yang diperlukan untuk melakukannya dengan benar.

Saya juga berpikir kita akan membutuhkan antarmuka yang sedikit berbeda dengan some-magical-package :

export function getSubstitutionRanges(fontFamily: string, text: string): Promise<[number, number][]>;

Aturan untuk menentukan ligatur itu sendiri rumit dan dimasukkan cukup jauh ke dalam font itu sendiri. Daripada meneruskan data font itu sendiri dan meletakkan beban untuk menafsirkannya di xterm.js, saya akan menyerahkannya ke lib lain dan menyuruhnya memberi tahu xterm.js karakter mana yang harus dirender bersama. Aspek lookahead / lookbehind dari konteks juga mempersulit penguraian. Misalnya, '===' dipetakan ke ligatur, tetapi tidak jika diikuti oleh tanda sama dengan lainnya.

Catatan lain tentang konsep rentang substitusi: Tidak ada penggambaran yang jelas tentang batas-batas ikatan tunggal dari apa yang dapat saya ceritakan (setidaknya saat menggunakan alternatif kontekstual). Hanya ada urutan substitusi yang diterapkan pada karakter individu. Saya telah menemukan beberapa trik untuk mencari tahu batas jika Anda memiliki ligatur yang berurutan, tetapi mungkin tidak mudah. Saya mungkin akan keliru karena secara tidak sengaja memperlakukan dua ligatur sebagai satu daripada secara tidak sengaja memisahkannya karena mereka masih harus dirender dengan benar jika dirender semua bersama sebagai satu kelompok. Satu-satunya masalah nyata yang ada adalah menerapkan gaya heterogen padanya.

Satu-satunya masalah nyata yang ada adalah menerapkan gaya heterogen padanya.

Jangan. Meneruskan setiap string gaya berkelanjutan ke fungsi secara terpisah. Anda mungkin dapat membuat pengecualian untuk teks yang digarisbawahi jika garis bawah digambar secara terpisah.

Kita mungkin bisa lolos dengan sesuatu yang tidak bergantung pada kode asli

👍

Aturan untuk menentukan ligatur itu sendiri rumit dan dimasukkan cukup jauh ke dalam font itu sendiri. Daripada meneruskan data font itu sendiri dan meletakkan beban untuk menafsirkannya di xterm.js, saya akan menyerahkannya ke lib lain dan menyuruhnya memberi tahu xterm.js karakter mana yang harus dirender bersama.

@princjef ini terdengar lebih baik, semakin sedikit xterm.js yang harus dilakukan di area ini semakin baik.

Satu-satunya masalah nyata yang ada adalah menerapkan gaya heterogen padanya.

Saya tidak berpikir ada orang lain yang mencoba melakukan ini, kita hanya perlu menambahkan ligatur untuk teks yang menggunakan gaya yang sama.

Ini terlihat bisa dilakukan di sisi font. Saya memiliki beberapa kode yang berhasil mem-parsing semua ligatur Kode Fira dan memberikan rentang yang tepat untuk menggabungkan karakter. Jika orang memiliki satu atau dua font lain yang mereka cari dukungannya, saya dapat mencoba memeriksanya juga. Sejauh ini saya hanya menerapkan jenis substitusi yang saya perlukan untuk Kode Fira, jadi beberapa variasi akan diterima untuk menggunakan jenis substitusi lainnya.

Masih perlu mencari tahu bagian pencarian font. Akan fokus pada itu selanjutnya. Ada beberapa paket di luar sana tetapi semuanya tampaknya buggy atau tidak terawat

@princjef Jika Anda ingin memeriksa fonta lain, saya menggunakan Iosevka .

Baiklah saya telah membuat sebuah paket bernama font-ligatures (alias some-magical-package ) dan beberapa paket terkait sehingga kita dapat secara efisien menemukan font yang tepat dan kemudian mencari tahu di mana ligatur untuk input teks tertentu.

Saya menghabiskan beberapa waktu untuk mengoptimalkan proses menemukan font. Pada Surface Pro 4 dengan font ~ 150 ttf / otf, saya dapat mengambil metadata font untuk semuanya dalam 300-400ms. Ini sebagian besar terikat I / O dan dapat ditendang ke latar belakang untuk beberapa siklus render pertama saat memuat, tetapi harus cukup cepat untuk dimuat pada saat pty telah dimulai dan mengeluarkan beberapa teks. Setelah dimuat, kami dapat memicu render untuk memperbarui teks apa pun yang mungkin sudah ada. Ini dapat diulangi setiap kali font berubah atau kita dapat menyimpan daftar lengkap untuk pertama kalinya (saya tetap mengambil daftar lengkapnya di awal).

Sedangkan untuk pemetaan ligatur itu sendiri, pustaka mengambil string dan mengembalikan metadata tentang ligatur font, termasuk kelompok karakter yang harus dirender bersama. CI menyertakan tes untuk setiap ligatur dalam Kode Fira, Iosevka dan Monoid, jadi saya cukup yakin bahwa itu melakukan pemrosesan dengan benar untuk jenis substitusi yang dilakukannya (meskipun saya yakin ada beberapa font di luar sana yang menggunakan jenis lain yang Saya belum menerapkan).

Namun, saya tidak menghabiskan waktu untuk mengoptimalkan / menyetel penguraian ligatur. Saya melakukan beberapa tes cepat dan sepertinya penguraian ligatur membutuhkan waktu 2-20ms untuk string dengan panjang sedang (baca: 1 baris). Masih banyak ruang untuk dioptimalkan jadi saya tidak terlalu khawatir saat ini. Saya sebagian besar ingin mengeluarkan ini untuk mendemonstrasikan antarmuka dan membiarkan orang menendang ban jika mereka mau.

Terlihat cukup keren @princjef! Apa pendapat Anda tentang menambahkan tes ke Kode Fira untuk 0xc0ffee , 0x1234 , dan 17x32 ? ( x berubah menjadi tanda waktu itu)

@princjef luar biasa!

Saya melakukan beberapa tes cepat dan sepertinya penguraian ligatur membutuhkan waktu 2-20ms untuk string dengan panjang sedang (baca: 1 baris)

Dapatkah Anda menunjukkan kepada saya beberapa kode penting yang memeriksa ini?

@ j-f1 Ya, itu juga berfungsi: https://github.com/princjef/font-ligatures/blob/master/src/index.spec.ts#L136 -L137

@Tyriar Saya baru saja menambahkan tolok ukur dasar yang dapat Anda mainkan. pola panggilan terlihat seperti node bench/lines.js <font-name> <input-text> [iterations] . Anda juga dapat meneruskan string multiline atau memperluas file input untuk teks dan itu akan menggilir baris untuk mencoba menghindari pengoptimalan yang tidak realistis agar tidak menjalankan input yang sama persis berulang kali.

Saat menulis itu, saya perhatikan bahwa bahkan ketika saya menggunakan beberapa baris input yang berbeda, itu masih mengalami peningkatan kinerja yang signifikan setelah menjalankan pertama. Untuk ~ 10 input karakter, saya melihat rata-rata sepersekian milidetik untuk Iosevka dan sedikit lebih dari setengah milidetik untuk Kode Fira. Entah saya sedang menangani kasus khusus atau Turbofan sedang bekerja, itu ajaib. Ini masih belum cukup efisien untuk digunakan sebagaimana adanya tetapi saya akan mulai fokus pada pengoptimalan kinerja selanjutnya (pada titik mana saya mungkin juga akan menambahkan patokan yang lebih baik untuk merasakan peningkatan).

Beberapa catatan:

  • Karena cara kerja penggantian, saya mengharapkan waktu eksekusi untuk menskalakan secara linier dengan ukuran input, meskipun saya belum memverifikasi ini
  • Karena jumlah ligatur dan cara kerja penggantinya, Kode Fira jauh lebih intensif untuk diurai daripada Iosevka atau Monoid. Saya secara teratur melihat butuh waktu 5-10x lebih banyak untuk melakukan Kode Fira daripada Iosevka.
  • Font tanpa pengikat berjalan lebih cepat dan dapat dioptimalkan lebih lanjut. Jika tidak ada alternatif kontekstual dalam font, saya dapat melakukan keluar cepat dengan kumpulan hasil kosong (atau kita bisa melewati panggilan di tingkat yang lebih tinggi).

Saya sudah mulai melacak aspek kinerja dalam masalah di paket yang saya buat (https://github.com/princjef/font-ligatures/issues/2). Berikut adalah bilangan awal yang disalin dari sana untuk beberapa konfigurasi (semua bilangan dikalikan dalam ms). Lima kolom angka pertama adalah per baris masukan dan dua terakhir adalah per karakter. Kolom kedua hingga terakhir adalah yang paling saya perhatikan. Saya memotret untuk ~ 0,5 mikrodetik per karakter (0,0005 dalam milidetik):

NAMA | AVG | STDEV | 5% | 50% | 95% | AVG (CHAR) | STDEV (CHAR)
----------------------- | ------- | --------- | ------ | -------- | ------- | ------------- | ----------------
Kode Fira: code.txt | 5.9570 | 12.6951 | 0,5270 | 5.1020 | 12.2330 | 0.1443531 | 0.2091743
Kode Fira: noLigatures.txt | 12.1932 | 3.4402 | 8.1420 | 12.1205 | 15.5900 | 0.1321094 | 0,0334362
Iosevka: code.txt | 0.5571 | 1.4722 | 0,0485 | 0,3215 | 1.6155 | 0,0135005 | 0,0333483
Iosevka: noLigatures.txt | 0.7476 | 0.4230 | 0.4365 | 0,6030 | 1.7725 | 0,0080998 | 0,0044501
Monoid: code.txt | 0.8896 | 1.6637 | 0,0910 | 0.6625 | 1.9225 | 0.0215566 | 0,0482166
Monoid: noLigatures.txt | 1.6661 | 0.6935 | 1.0695 | 1.4450 | 2.6910 | 0,0180521 | 0,0071922
Ubuntu Mono: code.txt | 0.0402 | 0.3935 | 0,0080 | 0,0220 | 0.0605 | 0,0009735 | 0,0090228
Ubuntu Mono: noLigatures.txt | 0.0356 | 0.0644 | 0,0120 | 0,0280 | 0.0805 | 0.0003858 | 0,0006891

Sekarang setelah ada data dasar yang baik, kami akan memiliki gagasan yang lebih baik tentang keuntungan yang diperoleh dengan setiap penyesuaian kinerja.

@Tyriar, apakah Anda memiliki preferensi tentang di mana paket xterm-ligature-support dan bagaimana paket itu sampai di sana?

Sepertinya Anda berpikir itu harus berada di bawah xtermjs org (yang terdengar masuk akal bagi saya), tetapi saya tidak memiliki kemampuan untuk membuat / mendorong ke repositori di org. Apakah Anda lebih suka saya memasukkannya ke dalam repo di bawah pengguna saya yang akan dimigrasi ke dalam org atau Anda ingin membuat repo rintisan yang dapat saya kirimkan PR?

Dari perspektif tinjauan, masuk akal untuk menyelesaikan # 1460 terlebih dahulu, jadi tidak perlu terburu-buru, tetapi saya ingin mencari tahu di mana harus membuang kode setelah siap.

@princjef Saya membuat https://github.com/xtermjs/xterm-ligature-support dan memberi Anda akses admin. Saya berasumsi Anda telah melihat cara kerja addon lainnya tetapi ini akan menjadi addon eksternal resmi pertama. Jadi gunakan addons internal dan https://github.com/CoderPad/xterm-webfont sebagai referensi untuk implementasi 😄

Saya akan segera memeriksa PR 👍

Memposting pembaruan di repo vscode di https://github.com/microsoft/vscode/issues/34103 ini, inilah pekerjaan yang tersisa sebelum kita dapat menyebutnya ditutup di xterm.js:

  • Integrasikan xtermjs / xterm-addon-ligatures ke dalam repo xtermjs / xterm.js , ini akan memungkinkan penerbitan otomatis dan memastikan tes terus lulus
  • Hubungkan ligatur ke dalam demo
  • Siapkan beberapa tes dalang yang memverifikasi pada semua penyaji (dom, kanvas, webgl) bahwa ligatur berfungsi
  • Kurangi ketergantungan sebanyak mungkin

Terima kasih untuk semua kerja keras di sini semuanya! 😄 👍

Jika saya boleh bertanya, @Tyriar , apakah ada rencana untuk dukungan browser web?

Saya juga melihat ini dapat berfungsi di browser, tetapi ini akan sangat lambat. Jika saya mungkin bertanya, seberapa lambat versi yang berfungsi di browser ini?

Terima kasih!

@ torch2424 Saya rasa tidak mungkin dengan cara kerja penyaji karena dukungan ligatur bergantung pada parsing file font (tanpa hardcode seperti ligatur apa yang tersedia yang disediakan oleh pengguna).

@Tyriar Terima kasih atas tanggapan cepat!

Itu sangat disayangkan, tapi lebih menyenangkan untuk dimiliki. Kami telah mempertimbangkan versi elektron, jadi mungkin kami akan memilikinya sebagai fitur yang disertakan 😄 Terima kasih!

Hmm saya pikir itu harus mungkin, baik dengan menggunakan font web dan memuat file font yang sama (urgh) ke dalam ranah JS untuk mengekstrak data ligatur. Tidak yakin apakah ini layak / layak dilakukan dengan cara ini, karena pencabutan ligatur cukup besar dalam kinerja. Tidak yakin tentang penggunaan mem, file font bisa menjadi sangat besar, mungkin @princjef memiliki beberapa angka tentang perilaku runtime?

Sudah lama sejak saya memeriksanya, tetapi ingatan saya adalah bahwa tidak ada API bawaan untuk mengekstrak informasi font mentah di browser bahkan untuk font web.

Jika Anda memuat font web Anda sendiri secara manual dari sebuah file dan secara terpisah menyuntikkan konten file yang sama ke dalam kode untuk penguraian ligatur, secara teoritis dapat dilakukan tanpa harus melepaskan pengoptimalan cache mesin terbang di perender. Meskipun demikian, addon yang ada tidak dirancang dengan kasus penggunaan tersebut karena memerlukan lebih banyak koordinasi dan kabel manual daripada casing non-browser.

Tidak yakin apakah ini layak / layak dilakukan dengan cara ini, karena pencabutan ligatur cukup besar dalam kinerja. Tidak yakin tentang penggunaan mem, file font bisa menjadi sangat besar

Ini pasti bisa menjadi masalah untuk font tertentu. Paket pemrosesan ligatur sangat dioptimalkan untuk efisiensi pencarian / deteksi, yang untuk saat ini mengorbankan waktu pemuatan dan konsumsi memori yang lebih lama. Ini akan sangat bervariasi dari font ke font, tetapi merupakan pertimbangan yang baik untuk diingat.

Bahkan jika mengekstrak informasi ligatur dimungkinkan, API web menggunakan titik kode teks / karakter, sementara ligatur di dalam font menggunakan indeks mesin terbang khusus font yang tidak dapat diteruskan langsung ke API web untuk menggambar.

@princjef Terima kasih atas perhatiannya, ini kedengarannya terlalu merepotkan, imho tidak sepadan dengan manfaat yang diberikannya sesudahnya.

@khaledhosny Idenya lebih banyak tentang mendapatkan info ligatur dari font di JS sambil tetap bekerja dengan titik kode dan membiarkan perender font browser melakukan hal-hal tingkat rendah (karena menggunakan font yang sama). Tidak yakin apakah ekstraksi mesin terbang dan rendering sendiri bahkan mungkin hanya dilakukan di JS (lol, penyaji font berbasis JS? Bahkan jika ini bisa dilakukan, imho itu akan memiliki kinerja yang sangat buruk).

Perbarui ini, saya baru saja menggabungkan addon ligatur ke dalam basis kode (https://github.com/xtermjs/xterm.js/pull/2847), mungkin masih sedikit rusak tetapi sulit untuk mengatakannya tanpa pengaturan pengujian integrasi ( https://github.com/xtermjs/xterm.js/issues/2896).

Saat ini addon hanya berjalan di browser + runtime node (mis. Elektron), saya datang dengan proposal yang saya harapkan hanya berfungsi di browser yang akan membiarkan kami melepaskan node deps dan membawanya ke VS Code (https: / /github.com/microsoft/vscode/issues/34103). Ini diberi label dengan bantuan yang diinginkan jika ada yang ingin mencobanya https://github.com/xtermjs/xterm.js/issues/2897.

Kita harus melihat ke dalam menggunakan API Akses Font (saat ini dalam percobaan awal) untuk addon ligatur.

Saya menggunakan ttyd yang membagikan terminal melalui web, dan menggunakan xterm.js. seperti yang Anda lihat pada gambar di bawah, ikon tidak dimuat dengan benar. mereka terlihat di terminal aslinya. tapi di web mereka hilang.

image

@UziTech oh wow, itu terlihat luar biasa! Saya pikir pekerjaan apa pun yang dilakukan di area ini harus melihat ke depan sehingga kami dapat memanfaatkannya dengan API akses font.

@UziTech @Tyriar @princjef
Saya pikir kode untuk API akses font dapat dimasukkan ke dalam font-ligatures paket.
Setelah mendeteksi apakah prosesnya ada di browser atau node / electron, ia dapat memutuskan apakah akan memanggil API akses font atau menggunakan metode saat ini.

Saya telah membuat konsep bukti hacky dan menjalankannya di demo di garpu saya (cabang localFonts)
Screenshot 2021-01-17 at 18 39 27

Anda dapat mencobanya setelah mengaktifkan #font-access di chrome://flags (perlu menyegarkan sekali setelah mengizinkan akses ke font)

Saya dapat mencoba dan membuka pr jika ini terlihat bagus untuk Anda.

Setelah mendeteksi apakah prosesnya ada di browser atau node / electron, ia dapat memutuskan apakah akan memanggil API akses font atau menggunakan metode saat ini.

Kami akhirnya akan mengalami masalah dengan solusi ini karena proyek yang hanya web akan mengalami masalah dalam menggabungkan node deps. Saya tidak punya jawaban untuk itu, tetapi saya juga berpikir kita harus membalik default (akhirnya?) Dan default ke akses font jika deteksi fitur berhasil, jika tidak mundur.

Juga kerja bagus membuatnya berhasil! Itu luar biasa 😍

Kita dapat require mereka setelah deteksi fitur hanya jika diperlukan.
Dan proyek khusus web yang bergantung dapat menandainya sebagai eksternal selama penggabungan.

Kami dapat memiliki api akses font sebagai default setelah tersedia di seluruh browser, saya kira.

👍 Saya mungkin terlalu banyak memikirkan masalah bundler karena Anda menyebutkan ada beberapa solusi. Saya berharap kami akan menghentikan / menghapus opsi Electron setelah akses font diaktifkan di Electron.

@Tyriar, bisakah kita mendapatkan rilis addon ligatur dengan pembaruan di font-finder segera?

@UziTech [email protected] harus memilikinya, saya telah membuat pengingat untuk mengubah versi 4.10 https://github.com/xtermjs/xterm.js/issues/3220

Saya telah membuka princjef / font-ligatures # 22 sebagai langkah pertama untuk menyelesaikannya

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

Mlocik97-issues picture Mlocik97-issues  ·  3Komentar

jerch picture jerch  ·  3Komentar

zhangjie2012 picture zhangjie2012  ·  3Komentar

goxr3plus picture goxr3plus  ·  3Komentar

Tyriar picture Tyriar  ·  4Komentar