Catalina menghadirkan font sistem variabel terpadu baru ke macOS.
Bagian'system-ui' dari spesifikasi CSS Fonts Module Level 4 mendefinisikan kata kunci font system-ui
yang memungkinkan developer menggunakan font sistem operasi default bawaan, yang dioptimalkan secara turbo, dilokalkan, berkualitas sangat tinggi, tidak perlu didownload, langsung di situs dan aplikasi mereka.
body {
font-family: system-ui;
}
Pilihan tipografi ini sama dengan mengatakan "gunakan font sistem default untuk lokalitas pengguna saat ini".
Di macOS, font system-ui
adalah San Francisco, font yang telah diperiksa, diuji, dan… baru-baru ini diupgrade oleh tim desain. Pertama, kita akan membahas fitur font variabel baru yang menarik di Catalina, lalu kita akan membahas beberapa bug dan cara engineer Chromium menyelesaikannya.
Postingan ini mengasumsikan bahwa Anda sudah memahami font variabel. Jika tidak, lihat Pengantar font variabel di web dan video di bawah.
Kompatibilitas browser
Pada saat penulisan, system-ui
didukung oleh Chromium (sejak 56), Edge (sejak 79), Safari (sejak 11), dan Firefox (sejak 43) tetapi dengan kata kunci -apple-system
. Lihat Dapatkah saya menggunakan font variabel? untuk mengetahui info terbaru.
Kekuatan baru
Kemampuan baru yang dibawa Catalina ke font sistem kini tersedia bagi developer web mulai Chromium 83. Font system-ui
kini memiliki lebih banyak setelan variabel: ukuran optik dan 2 penyesuaian ketebalan unik:
h1 { font-family: system-ui; font-weight: 700; font-variation-settings: 'wght' 750 ; }
h1 { font-family: system-ui; font-weight: 700; font-variation-settings: 'wght' 750, 'opsz' 20, 'GRAD' 400, 'YAXS' 400 ; }
Di Mojave, system-ui
adalah font variabel dengan hanya setelan wght
. Meskipun system-ui
di Catalina adalah font variabel dengan setelan wght
, opsz
, GRAD
, dan YAXS
.
Sepertinya ada beberapa peluang desain peningkatan progresif yang menarik bagi saya. Benar-benar pelajari kehalusan font sistem jika Anda mau.
wght
Menerima ketebalan font antara 0
dan 900
serta diterapkan secara merata ke semua karakter.
/* 0-900 */
font-variation-settings: 'wght' 750;
opsz
Penyesuaian optik mirip dengan kerning atau jarak antar-huruf, tetapi jaraknya dilakukan oleh mata manusia, bukan matematika. Nilai 19
atau di bawahnya ditujukan untuk jarak teks dan isi, sedangkan 20
atau di atasnya ditujukan untuk jarak header dan judul tampilan.
/* 19 or 20 */
font-variation-settings: 'opsz' 20;
GRAD
Mirip dengan bobot, tetapi tanpa menyentuh penspasian horizontal. Properti ini menerima nilai antara 400
dan 1000
.
/* 400-1000 */
font-variation-settings: 'GRAD' 500;
YAXS
Meregangkan glyph secara vertikal. Properti ini menerima nilai antara 400
dan 1000
.
/* 400-1000 */
font-variation-settings: 'YAXS' 500;
Menggabungkan opsi
Dengan beberapa baris CSS, kita dapat mengubah setelan font menjadi tebal pilihan kita atau mencoba kombinasi menarik lainnya:
font-weight: 700;
font-weight: bold;
font-variation-settings: 'wght' 750, 'YAXS' 600, 'GRAD' 500, 'opsz' 20;
Dengan begitu, pengguna Chromium di macOS akan melihat 750 bobot kustom yang telah diupgrade dengan beberapa penyesuaian menarik lainnya 👍
macOS 10.15 menambahkan fitur baru ke font sistemnya, dan di macOS 10.15, bug system-ui
yang rumit dicatat di pelacak bug Chromium. Apakah mereka terkait?
Lampiran: Regresi system-ui
Kisah ini dimulai dengan bug yang berbeda: #1005969. Hal ini dilaporkan terjadi pada macOS 10.15 karena jarak font system-ui
terlihat sempit dan berdesakan.

Latar belakang
Pernahkah Anda memperhatikan di macOS 10.14 bagaimana paragraf atau header Anda "berpindah" ke font yang berbeda saat ukurannya bertambah atau berkurang?
Di Mojave (macOS 10.14), font system-ui
beralih di antara dua font, bergantung pada ukuran font target. Saat teks berada di bawah 20px
, macOS menggunakan "San Francisco Text". Jika teksnya 20px
atau lebih, macOS menggunakan "San Francisco Display". Pengukuran optik dibuat secara statis dalam dua font terpisah.
Catalina (macOS 10.15) mengirimkan font variabel gabungan baru untuk San Francisco. Tidak perlu lagi mengelola "Teks" dan "Display". Variasi ini juga mendapatkan setelan variasi baru opsz
yang dijelaskan sebelumnya.
h1 {
font-variation-settings: 'opsz' 20;
}
Sayangnya, nilai opsz
default dalam font Catalina baru adalah 20
, dan engineer Chromium tidak siap menerapkan opsz
ke font sistem. Hal ini menyebabkan ukuran yang lebih kecil ditampilkan terlalu sempit.
Untuk memperbaikinya, Chromium perlu menerapkan opsz
dengan benar ke font sistem. Hal ini menyebabkan Masalah #1005969 diperbaiki. Menang! Atau apakah itu…?
Belum selesai
Di sinilah masalahnya: Chromium menerapkan opsz
, tetapi masih ada yang tidak beres. Font sistem di Mac memiliki tabel font tambahan yang disebut trak
, yang menyesuaikan jarak horizontal. Saat mengerjakan perbaikan, engineer Chromium menyadari bahwa di macOS, saat mengambil metrik horizontal dari objek CTFontRef
, metrik trak
sudah diperhitungkan dalam hasil metrik. Library pembentukan Chromium HarfBuzz
memerlukan metrik yang nilai trak
-nya belum diperhitungkan.

Secara internal, Skia (library grafis, bukan typeface dengan nama yang sama) menggunakan class CGFontRef
dari CoreGraphics
dan class CTFontRef
dari CoreText
. Karena konversi internal yang diperlukan antara objek tersebut (digunakan untuk mempertahankan kompatibilitas mundur dan mengakses API yang diperlukan di kedua class), Skia akan kehilangan informasi ketebalan dalam keadaan tertentu dan font tebal akan berhenti berfungsi. Hal ini dilacak di Masalah #1057654.
Skia masih perlu mendukung macOS 10.11 karena Chromium masih mendukungnya. Di 10.11, font "San Francisco Text" dan "San Francisco Display" bahkan bukan font variabel. Sebaliknya, setiap font adalah keluarga font terpisah untuk setiap bobot yang tersedia. Pada suatu titik, ID glyph mereka menjadi tidak sinkron satu sama lain. Jadi, jika Skia membentuk teks (mengonversi teks menjadi glif yang dapat digambar) dengan "San Francisco Text", teks tersebut akan menjadi tidak jelas jika digambar dengan "San Francisco Display", dan sebaliknya. Bahkan jika Skia hanya meminta ukuran yang berbeda, macOS mungkin beralih ke ukuran yang lain. Seharusnya salah satu font dapat selalu digunakan dan hanya perlu diskalakan (menggunakan matriks untuk menskalakannya, bukan meminta ukuran yang lebih besar), tetapi CoreText
memiliki masalah karena tidak akan menskalakan glif sbix (emoji warna) (hanya menskalakan ke bawah). Hal ini sedikit lebih rumit daripada itu. CoreText
tampaknya membatasi rentang vertikal setelah penerapan matriks, yang tampaknya terkait dengan ketidakmampuannya menggambar emoji pada sudut 45 derajat. Bagaimanapun, jika Anda ingin emoji ditampilkan besar, Anda harus membuat salinan font untuk mendapatkan versi besar.
Jadi, untuk membuat salinan objek CTFont
dalam berbagai ukuran secara internal sekaligus memastikan bahwa data font pokok yang sama digunakan, Chromium menarik CGFont
dari CTFont
, lalu membuat CTFont
baru dari CGFont
(objek CGFont
tidak bergantung pada ukuran, peralihan ajaib terjadi di tingkat CoreText
). Ini berfungsi dengan baik hingga 10.154. Di 10.15, perjalanan pulang pergi ini akhirnya kehilangan terlalu banyak informasi, sehingga menyebabkan masalah berat. Flutter mendeteksi masalah berat huruf dan perbaikan alternatif untuk mengubah ukuran dilakukan untuk membuat CTFont
baru langsung dari CTFont
asli sambil mengontrol ukuran optik secara langsung menggunakan atribut lama yang tidak didokumentasikan di CoreText
. Hal ini membuat semuanya berfungsi di 10.11 dan memperbaiki masalah lainnya (seperti menetapkan ukuran optik secara eksplisit ke nilai default).
Namun, hal ini mempertahankan lebih banyak 'keajaiban' dalam font.CoreText
Salah satunya tampaknya masih mengubah jarak antar-glyph dengan cara lain selain hanya tabel trak
(yang penerapannya sudah coba ditekan oleh Chromium melalui atribut lain yang tidak terdokumentasi).
CGFont
tidak melakukan 'keajaiban' ini, jadi mungkin Chromium bisa mengeluarkan CGFont
dari CTFont
dan hanya menggunakannya untuk mendapatkan kemajuan? Sayangnya, hal ini tidak akan berhasil karena CoreText
diketahui dapat merusak font dengan cara lain juga. Misalnya, emoji kecil akan dibuat sedikit lebih besar dari yang Anda minta (meningkatkan ukurannya sedikit). CGFont
tidak mengetahui hal ini, sehingga emoji berbasis sbix Anda akan terlalu berdekatan karena Anda mengukurnya dalam satu ukuran, tetapi CoreText
akan menggambarnya lebih besar dalam jumlah tertentu. Chromium menginginkan kemajuan CTFont
, tetapi menginginkannya tanpa pelacakan, dan sebaiknya tanpa gangguan lainnya.
Karena perbaikan masalah penspasian memerlukan serangkaian perbaikan Blink dan Skia yang saling terhubung, engineer Chromium tidak dapat "hanya mengembalikan" untuk memperbaiki masalah tersebut. Engineer Chromium juga mencoba menggunakan tanda build yang berbeda untuk mengubah jalur kode terkait font di Skia, yang memperbaiki masalah font tebal, tetapi memperburuk masalah penspasian.
Perbaikan
Pada akhirnya, tentu saja Chromium ingin memperbaiki kedua hal tersebut. Chromium kini menggunakan fungsi metrik font OpenType bawaan HarfBuzz untuk mengambil metrik horizontal langsung dari data biner dalam tabel font font sistem. Dengan menggunakan ini, Chromium menghindari CoreText
dan Skia saat font memiliki tabel trak
(kecuali saat font tersebut adalah font emoji).

Sementara itu, masih ada Masalah Skia #10123 untuk melacak perbaikan ini sepenuhnya di Skia, dan untuk kembali menggunakan Skia guna mengambil metrik font sistem dari sana, bukan perbaikan saat ini yang melalui HarfBuzz
.