Thêm nhiều tuỳ chọn phông chữ có thể thay đổi cho phông chữ giao diện người dùng hệ thống của macOS trong Chromium 83

Catalina mang đến một phông chữ hệ thống biến thể hợp nhất mới cho macOS.

Mục "system-ui" của thông số kỹ thuật Mô-đun phông chữ CSS cấp 4 xác định từ khoá phông chữ system-ui cho phép nhà phát triển sử dụng phông chữ hệ điều hành mặc định, được tích hợp sẵn, được tối ưu hoá, được bản địa hoá, có chất lượng cực cao, không cần tải xuống ngay trong trang web và ứng dụng của họ.

body {
  font-family: system-ui;
}

Lựa chọn kiểu chữ này tương tự như việc nói "sử dụng phông chữ hệ thống mặc định cho ngôn ngữ hiện tại của người dùng này".

Trên macOS, phông chữ system-ui là San Francisco. Đây là phông chữ mà một nhóm thiết kế đã xem xét, thử nghiệm và... nâng cấp gần đây! Trước tiên, chúng ta sẽ tìm hiểu về các tính năng phông chữ biến mới thú vị trong Catalina, sau đó sẽ tìm hiểu một số lỗi và cách các kỹ sư Chromium khắc phục các lỗi đó.

Bài đăng này giả định rằng bạn đã làm quen với phông chữ có thể thay đổi. Nếu chưa, hãy xem phần Giới thiệu về phông chữ biến thể trên web và video bên dưới.

Khả năng tương thích với trình duyệt

Tại thời điểm viết bài, system-ui được hỗ trợ từ Chromium (kể từ phiên bản 56), Edge (kể từ phiên bản 79), Safari (kể từ phiên bản 11) và từ Firefox (kể từ phiên bản 43) nhưng với từ khoá -apple-system. Hãy xem phần Tôi có thể sử dụng phông chữ biến không? để biết thông tin cập nhật.

Sức mạnh mới

Kể từ Chromium 83, các tính năng mới mà Catalina mang đến phông chữ hệ thống hiện đã được cung cấp cho các nhà phát triển web. Phông chữ system-ui hiện có nhiều chế độ cài đặt biến hơn: tính năng định cỡ quang học và 2 chế độ điều chỉnh độ đậm riêng biệt:

Mojave
h1 {
  font-family: system-ui;
  font-weight: 700;
  font-variation-settings:
    'wght' 750
  ;
}
Catalina
h1 {
  font-family: system-ui;
  font-weight: 700;
  font-variation-settings:
    'wght' 750,
    'opsz' 20,
    'GRAD' 400,
    'YAXS' 400
  ;
}

Trên Mojave, system-ui là một phông chữ biến đổi chỉ có chế độ cài đặt wght. Trong khi system-ui trên Catalina là một phông chữ biến đổi với các chế độ cài đặt wght, opsz, GRADYAXS.

Có vẻ như một số cơ hội thiết kế nâng cao tiến bộ gọn gàng cho tôi! Hãy tìm hiểu sâu về sự tinh tế của phông chữ hệ thống nếu bạn muốn.

wght

Chấp nhận độ đậm phông chữ từ 0 đến 900 và được áp dụng như nhau cho tất cả các ký tự.

/* 0-900 */
font-variation-settings: 'wght' 750;

opsz

Kích thước quang học tương tự như khoảng cách góc hoặc khoảng cách chữ cái, nhưng khoảng cách được thực hiện bằng mắt người thay vì toán học. Giá trị 19 trở xuống dùng để tạo khoảng cách giữa văn bản và nội dung, còn 20 trở lên dùng để tạo khoảng cách giữa tiêu đề hiển thị và tiêu đề.

/* 19 or 20 */
font-variation-settings: 'opsz' 20;

GRAD

Tương tự như trọng lượng, nhưng không chạm vào khoảng cách theo chiều ngang. Phương thức này chấp nhận các giá trị từ 400 đến 1000.

/* 400-1000 */
font-variation-settings: 'GRAD' 500;

YAXS

Kéo giãn ký tự theo chiều dọc. Phương thức này chấp nhận các giá trị từ 400 đến 1000.

/* 400-1000 */
font-variation-settings: 'YAXS' 500;

Kết hợp các lựa chọn

Với một vài dòng CSS, chúng ta có thể điều chỉnh cài đặt phông chữ thành đậm theo lựa chọn của mình hoặc thử các kết hợp thú vị khác:

font-weight: 700;
font-weight: bold;
font-variation-settings: 'wght' 750, 'YAXS' 600, 'GRAD' 500, 'opsz' 20;

Và thế là người dùng Chromium trên macOS sẽ thấy phông chữ 750 tuỳ chỉnh, được nâng cấp của bạn cùng một số tinh chỉnh thú vị khác 👍

Sân chơi

Nhấp vào Phối lại để chỉnh sửa trong Glitch bên dưới để lấy một bản sao Glitch có thể chỉnh sửa, sau đó chỉnh sửa các tuỳ chọn font-variation-settings mới để xem ảnh hưởng của các tuỳ chọn đó đến phông chữ của bạn. Hãy nhớ rằng Glitch này chỉ hoạt động nếu bạn đang sử dụng thiết bị macOS Catalina.

macOS 10.15 đã thêm các tính năng mới vào phông chữ hệ thống và trong macOS 10.15, một lỗi system-ui khó xử đã được ghi lại trong trình theo dõi lỗi Chromium. Tôi tự hỏi liệu họ có liên quan gì với nhau không!?

Phụ lục: Phép hồi quy system-ui

Câu chuyện này bắt đầu bằng một lỗi khác: #1005969. Báo cáo này được báo cáo chống lại macOS 10.15 vì khoảng cách phông chữ system-ui trông hẹp và bị nhồi nhét.

Bản so sánh hai đoạn văn trên trang nhóm Facebook. Bên trái là Chrome và bên phải là Safari. Chrome có khoảng cách giữa các dòng nhỏ hơn nhưng hơi chặt hơn
Chrome ở bên trái (theo dõi chặt chẽ hơn), Safari ở bên phải (khoảng cách quang học tốt hơn)

Thông tin khái quát

Bạn có bao giờ nhận thấy trên macOS 10.14, các đoạn văn bản hoặc tiêu đề "được chụp nhanh" thành một phông chữ có giao diện khác khi kích thước tăng hoặc giảm không?

Trên Mojave (macOS 10.14), phông chữ system-ui chuyển đổi giữa hai phông chữ tuỳ thuộc vào cỡ chữ đích. Khi văn bản nằm trong 20px, macOS sử dụng "San Francisco Text". Khi văn bản từ 20px trở lên, macOS đã dùng "Màn hình San Francisco". Kích thước quang học được xây dựng theo phương thức tĩnh thành 2 phông chữ riêng biệt.

Catalina (macOS 10.15) đã xuất bản một phông chữ biến thể thống nhất mới cho San Francisco. Không còn quản lý "Văn bản" và "Màn hình" nữa. Cũng có chế độ cài đặt biến thể mới opsz như mô tả ở trên.

h1 {
  font-variation-settings: 'opsz' 20;
}

Rất tiếc, giá trị opsz mặc định bằng phông chữ Catalina mới là 20 và các kỹ sư Chromium chưa chuẩn bị áp dụng opsz cho phông chữ hệ thống. Điều này dẫn đến các kích thước nhỏ hơn hiển thị quá hẹp.

Để khắc phục vấn đề này, Chromium cần áp dụng đúng opsz cho phông chữ hệ thống. Điều này đã giúp khắc phục Vấn đề #1005969. Chiến thắng! Hay là…?

Chưa hoàn tất

Đây là phần khó khăn: Chromium đã áp dụng opsz nhưng vẫn có gì đó không ổn. Phông chữ hệ thống trên máy Mac có thêm một bảng phông chữ tên là trak, giúp điều chỉnh khoảng cách theo chiều ngang. Trong khi khắc phục lỗi, các kỹ sư Chromium nhận thấy rằng trên macOS, khi truy xuất các chỉ số theo chiều ngang từ đối tượng CTFontRef, các chỉ số trak đã được đưa vào kết quả chỉ số. Thư viện định hình HarfBuzz của Chromium cần các chỉ số mà giá trị trak chưa được tính đến.

Màn hình hiển thị giao diện người dùng hệ thống cùng tất cả độ đậm và các biến thể của phông chữ trong một danh sách. Một nửa trong số đó không áp dụng sự khác biệt về trọng số.
Trái: Độ đậm được áp dụng cho các cỡ chữ từ 19 trở xuống. Phải: Cỡ chữ từ 20 trở lên mất kiểu chữ in đậm

Trong nội bộ, Skia (thư viện đồ hoạ, không phải phông chữ cùng tên) sử dụng cả lớp CGFontRef từ CoreGraphics và lớp CTFontRef từ CoreText. Do các lượt chuyển đổi nội bộ bắt buộc giữa các đối tượng đó (dùng để duy trì khả năng tương thích ngược và truy cập vào các API cần thiết trên cả hai lớp), Skia sẽ mất thông tin về độ đậm trong một số trường hợp nhất định và phông chữ đậm sẽ ngừng hoạt động. Vấn đề này đã được theo dõi trong Vấn đề #1057654.

Skia vẫn cần hỗ trợ macOS 10.11 vì Chromium vẫn hỗ trợ. Vào ngày 10.11, phông chữ "Văn bản San Francisco" và "Hiển thị ở San Francisco" thậm chí không thể thay đổi phông chữ. Thay vào đó, mỗi phông chữ là một bộ phông chữ riêng biệt cho mỗi độ đậm có sẵn. Tại một thời điểm nào đó, mã ký tự của các ký tự này không đồng bộ với nhau. Vì vậy, nếu Skia tạo hình văn bản (chuyển đổi văn bản thành các ký tự có thể vẽ) bằng "San Francisco Text", thì văn bản đó sẽ là vô nghĩa nếu được vẽ bằng "San Francisco Display" và ngược lại. Và ngay cả khi Skia chỉ yêu cầu một kích thước khác, macOS có thể chuyển sang kích thước khác. Luôn có thể sử dụng một trong các phông chữ và chỉ điều chỉnh tỷ lệ phông chữ (sử dụng ma trận để tăng kích thước thay vì yêu cầu kích thước lớn hơn) nhưng CoreText có một vấn đề là phông chữ sẽ không tăng tỷ lệ ký tự sbix (biểu tượng cảm xúc màu) (chỉ giảm kích thước). Câu hỏi này phức tạp hơn một chút. CoreText có vẻ như giới hạn phạm vi theo chiều dọc sau khi áp dụng ma trận, điều này có vẻ liên quan đến việc không thể vẽ biểu tượng cảm xúc ở góc 45 độ. Trong mọi trường hợp, nếu muốn biểu tượng cảm xúc hiển thị lớn, bạn cần sao chép phông chữ để có phiên bản lớn.

Vì vậy, để tạo bản sao của các đối tượng CTFont ở các kích thước khác nhau trong khi vẫn đảm bảo sử dụng cùng một dữ liệu phông chữ cơ bản, Chromium đã kéo CGFont ra khỏi CTFont, sau đó tạo một CTFont mới từ CGFont (các đối tượng CGFont độc lập với kích thước, việc chuyển đổi ma thuật xảy ra ở cấp CoreText). Phương thức này hoạt động tốt cho đến phiên bản 10.154. Trong phiên bản 10.15, hành trình khứ hồi này đã mất quá nhiều thông tin, dẫn đến vấn đề về trọng lượng. Flutter nhận thấy vấn đề về trọng số và đã tạo một bản sửa lỗi thay thế để đổi kích thước nhằm tạo CTFont mới trực tiếp từ CTFont ban đầu, đồng thời kiểm soát trực tiếp kích thước quang học bằng cách sử dụng một thuộc tính cũ nhưng chưa được ghi nhận trong CoreText. Điều này giúp mọi thứ hoạt động trên 10.11 và khắc phục các vấn đề khác (chẳng hạn như đặt kích thước quang học thành giá trị mặc định một cách rõ ràng).

Tuy nhiên, cách này giúp giữ lại nhiều tính năng "thần kỳ" hơn của CoreText trong phông chữ. Một trong số đó có vẻ như vẫn điều chỉnh các tiến trình ký tự theo một cách nào đó chứ không chỉ bảng trak (ứng dụng mà Chromium đang cố gắng ngăn chặn thông qua một thuộc tính chưa được ghi nhận khác).

CGFont không thực hiện bất kỳ "phép màu" nào trong số này, vì vậy có lẽ Chromium có thể loại bỏ CGFont khỏi CTFont và chỉ sử dụng nó để tiến bộ? Rất tiếc, cách này sẽ không hiệu quả vì CoreText cũng có thể kết hợp với phông chữ theo những cách khác. Ví dụ: tính năng này làm cho biểu tượng cảm xúc nhỏ lớn hơn một chút so với kích thước bạn thực sự yêu cầu (tăng kích thước một chút). CGFont không biết về điều này, vì vậy, bạn sẽ thấy các biểu tượng cảm xúc dựa trên sbix quá gần nhau vì bạn sẽ đo ở một kích thước nhưng CoreText sẽ vẽ các biểu tượng này lớn hơn một chút. Chromium muốn có các tính năng nâng cao của CTFont, nhưng không muốn có tính năng theo dõi và tốt nhất là không có bất kỳ tính năng nào khác.

Vì bản sửa lỗi cho vấn đề khoảng cách yêu cầu một bộ bản sửa lỗi Blink và Skia liên kết với nhau, nên các kỹ sư Chromium không thể "chỉ cần quay lại" để khắc phục vấn đề. Các kỹ sư Chromium cũng đã thử sử dụng một cờ bản dựng khác để thay đổi đường dẫn mã liên quan đến phông chữ trong Skia. Cách này đã khắc phục được vấn đề phông chữ in đậm, nhưng lại làm vấn đề về khoảng cách trở lại.

Bản sửa lỗi

Cuối cùng, tất nhiên là Chromium muốn khắc phục cả hai vấn đề. Chromium hiện sử dụng các hàm đo lường phông chữ OpenType tích hợp sẵn trong phông chữ HarfBuzz để truy xuất các chỉ số theo chiều ngang trực tiếp từ dữ liệu nhị phân trong bảng phông chữ của phông chữ hệ thống. Khi sử dụng tính năng này, Chromium sẽ bỏ qua CoreText và Skia khi phông chữ có bảng trak (ngoại trừ khi đó là phông chữ biểu tượng cảm xúc).

Hiển thị giao diện người dùng hệ thống và tất cả các biến thể cũng như độ đậm phông chữ trong một danh sách. Chế độ nửa trước đó hiện không hoạt động tốt.

Trong thời gian chờ đợi, bạn vẫn có thể theo dõi Vấn đề về Skia #10123 để khắc phục hoàn toàn vấn đề này trong Skia và quay lại sử dụng Skia để truy xuất các chỉ số phông chữ hệ thống từ đó, thay vì sử dụng bản sửa lỗi hiện tại thông qua HarfBuzz.