Triển khai phông chữ tuỳ chỉnh

Kể từ Android 15, các phông chữ có thể thay đổi sẽ được kết xuất trong thời gian chạy với hiệu suất và độ chi tiết cao hơn. Với bản cập nhật này, các nhà cung cấp phải thêm chế độ cấu hình phông chữ biến đổi mới vào font_fallback.xml thay vì fonts.xml, vì fonts.xml không còn được dùng nữa. Hãy xem bài viết Hỗ trợ phông chữ có thể thay đổi để biết thêm thông tin.

Trong Android 11 trở xuống, việc cập nhật các tệp phông chữ đã cài đặt trên thiết bị trong AOSP (trong phân vùng /system/fonts) hoặc các phân vùng của nhà cung cấp (trong phân vùng /product/fonts hoặc /system/fonts) đòi hỏi phải có bản cập nhật hệ thống từ OEM. Yêu cầu này có tác động đáng kể đến khả năng tương thích của biểu tượng cảm xúc. Trong Android 12, bạn có thể sử dụng dịch vụ hệ thống FontManager để quản lý các tệp phông chữ đã cài đặt và cập nhật các tệp phông chữ đã cài đặt trên thiết bị mà không cần cập nhật hệ thống.

Android 12 có 3 hoạt động tương tác giữa các quy trình: FontManagerService, Font UpdaterApplication.

FontManagerService là hệ thống quản lý trung tâm trong máy chủ hệ thống. FontManagerService lưu trữ chế độ cài đặt phông chữ hệ thống mới nhất cho mỗi người dùng.

FontUpdater là một trình cập nhật phông chữ có thể cắm được và được kiểm tra quyền signature|privileged tin cậy. FontUpdater giao tiếp với FontManagerService để nhận, cài đặt, xoá hoặc cập nhật chế độ cài đặt phông chữ hệ thống hiện tại. FontUpdater có thể truyền nội dung tệp phông chữ mới bằng cơ chế giao tiếp giữa các quy trình (IPC). FontManagerService sẽ lưu nội dung vào một vị trí lưu trữ mà mọi người đều có thể đọc, chẳng hạn như trong các tệp /data/fonts. Bộ nhớ này được bảo vệ. Chỉ FontManagerService mới có thể ghi tệp này theo chính sách SELinux.

Khi lớp Application khởi chạy, lớp này sẽ truyền các chế độ cài đặt phông chữ của hệ thống dưới dạng đối số của phương thức bindApplication; sau đó, lớp này sẽ khởi tạo các chế độ cài đặt phông chữ để quy trình ứng dụng sử dụng.

Hỗ trợ phông chữ biến đổi

Kể từ Android 15, các cấu hình phông chữ biến đổi được chỉ định trong font_fallback.xml bằng định dạng sau:

<family lang="und-Ethi" supportedAxes="wght,ital">
    <font>NotoSansEthiopic-VF.ttf</font>
</family>

Ở định dạng này, một phông chữ có thể thay đổi sẽ có tất cả các thuộc tính của một phông chữ tĩnh với thuộc tính supportedAxes bổ sung. Thuộc tính supportedAxes là danh sách được phân tách bằng dấu phẩy gồm các thẻ trục được hỗ trợ. Với Android 15, bạn chỉ có thể chỉ định các trục wghtital.

Nếu bạn không chỉ định thuộc tính supportedAxes, thì nút font sẽ hoạt động như một phông chữ tĩnh của một phiên bản duy nhất của phông chữ có thể thay đổi được chỉ định bằng các phần tử con axis.

Nếu bạn chỉ định thuộc tính supportedAxes, hệ thống sẽ tự động tạo một phiên bản phông chữ cho giá trị trọng lượng và kiểu đã cho trong thời gian chạy.

Nhà phát triển có thể sử dụng API Java android.graphics.fonts.SystemFonts#getAvailableFonts hoặc API NDK ASystemFontIterator_open để lấy danh sách các tệp phông chữ được cài đặt trên hệ thống. Để biết thông tin về các API dành cho nhà phát triển hỗ trợ bản cập nhật này, hãy xem API Phông chữ biến đổi OpenType được cải tiếnbuildVariableFamily.

Tuỳ chỉnh phông chữ

Một số nhà sản xuất thiết bị gốc (OEM) cài đặt hoặc thay thế các tệp phông chữ trong AOSP để thể hiện thương hiệu của họ. Android 12 hỗ trợ chức năng này, nhưng có thêm các yêu cầu để luôn cập nhật phông chữ biểu tượng cảm xúc trên thiết bị. Các OEM không sửa đổi hoặc cập nhật tệp phông chữ biểu tượng cảm xúc không cần sử dụng tính năng này.

Google cập nhật các tệp phông chữ, đặc biệt là các tệp NotoColorEmoji thông qua GMS Core, vì vậy, đừng sửa đổi hoặc xoá tệp NotoColorEmoji.ttf khỏi phân vùng /system và đừng xoá tệp này khỏi /frameworks/base/data/fonts/fonts.xml. Xin lưu ý 3 cách sau đây mà bạn có thể tuỳ chỉnh phông chữ:

  1. Thay thế tệp NotoColorEmoji.ttf bằng một phông chữ biểu tượng cảm xúc có thương hiệu của OEM.
  2. Sửa đổi tệp NotoColorEmoji.ttf cho phù hợp với nhu cầu của thị trường địa phương.
  3. Thay thế hoặc sửa đổi các tệp phông chữ khác.

Nếu không sửa đổi phông chữ biểu tượng cảm xúc trong AOSP, bạn không cần làm gì cả. Nếu bạn muốn tuỳ chỉnh phông chữ biểu tượng cảm xúc, hãy làm theo hướng dẫn trong các phần sau.

Thay thế NotoColorEmoji.ttf bằng phông chữ biểu tượng cảm xúc có thương hiệu của OEM

Để thay thế tệp NotoColorEmoji.ttf bằng tệp phông chữ biểu tượng cảm xúc có thương hiệu của OEM, hãy đặt phông chữ biểu tượng cảm xúc ngay trước chuỗi dự phòng phông chữ:

  1. Đặt phông chữ của riêng bạn (gọi là OEMCustomEmoji.ttf) vào phân vùng /system.
  2. Sửa đổi /frameworks/base/data/fonts/fonts.xml (và /frameworks/base/data/fonts/font-fallback.xml trong Android 15 trở lên) như trong mã sau:

    <family lang="ko">
    <font weight="400" style="normal" index="1">NotoSansCJK-Regular.ttc</font>
    </family>
    <!-- ADD FOLLOWING LINE -->
    <family lang="und-Zsye">
       <font weight="400" style="normal">OEMCustomEmoji.ttf</font>
    </family>
    <!-- END OF MODIFICATION -->
    <family lang="und-Zsye">
       <font weight="400" style="normal">NotoColorEmoji.ttf</font>
    </family>
    <family lang="und-Zsym">
       <font weight="400" style="normal">NotoSansSymbols-Regular-Subsetted2.ttf</font>
    </family>
    

Sửa đổi NotoColorEmoji.ttf cho phù hợp với nhu cầu của thị trường địa phương

Hãy làm theo các bước sau để tuỳ chỉnh cho phù hợp với nhu cầu của thị trường địa phương:

  1. Tạo tệp NotoColorEmoji của riêng bạn bằng một tên khác; ví dụ: đặt tên là Modified\_NotoColorEmoji.ttf.
  2. Đặt tệp này trước tệp NotoColorEmoji.ttf gốc.

Sau khi bạn thực hiện bước 2, biểu tượng đã sửa đổi do Modified\NotoColorEmoji.ttf hỗ trợ sẽ xuất hiện thay vì biểu tượng NotoColorEmoji.ttf ban đầu. Google khuyên bạn nên làm như sau:

  • Chỉ có glyph cần thiết trong phông chữ này.
  • Uỷ quyền các glyph chưa sửa đổi cho tệp NotoColorEmoji.ttf ban đầu để thiết bị của bạn nhận được mọi bản sửa lỗi thiết kế trong các bản phát hành biểu tượng cảm xúc trong tương lai.

Xoá glyph: Để xoá glyph khỏi tệp NotoColorEmoji.ttf, hãy làm theo các bước 1 và 2, đồng thời chỉ định glyph ID = 0 trong cmap.

Sử dụng cờ khu vực: Nếu biểu tượng mục tiêu là cờ khu vực, hãy chỉ định mã nhận dạng biểu tượng là mã quốc gia không xác định. (Sử dụng country code = "ZZ".)

Tạo một glyph tofu: Bạn có thể chỉ định rõ mã glyph tofu nếu muốn sử dụng một mã. Khi bạn chỉ định glyphID = 0, ứng dụng liên quan sẽ diễn giải đó là "không có ký tự tượng hình". Ví dụ: khi bạn sử dụng thuộc tính này, ứng dụng Paint#hasGlyph sẽ trả về false.

Thay thế hoặc sửa đổi các tệp phông chữ khác

Để thay thế hoặc sửa đổi các phông chữ khác, bạn có thể tuỳ chỉnh tương tự như khi sửa đổi tệp TTF cho nhu cầu của thị trường địa phương. Các tệp phông chữ không xác định được cập nhật trong AOSP trong thời gian chạy sẽ bị bỏ qua và không được cập nhật. Google bỏ qua các phông chữ không xác định trên thiết bị của bạn. Trong đó có các tệp phông chữ đã được sửa đổi từ phông chữ gốc trong AOSP.

Mặc dù Google thực hiện các bản cập nhật phông chữ trong GMS Core, nhưng cơ chế cập nhật phông chữ chung vẫn được mở cho tất cả các OEM. Các OEM có thể cài đặt trình cập nhật phông chữ bổ sung bằng cách làm theo các bước trong phần Đáp ứng các điều kiện tiên quyết, Ký tệp phông chữThực hiện các bản cập nhật phông chữ trong thời gian chạy.

Đáp ứng các điều kiện tiên quyết

Cơ chế cập nhật phông chữ sử dụng tính năng fs-verity của nhân Linux. Xác minh rằng thiết bị của bạn tuân thủ fs-verity và đưa chứng chỉ vào thiết bị.

Ký tệp phông chữ

Vì tệp phông chữ là tài nguyên có rủi ro, nên chúng phải được xác minh bằng các khoá đáng tin cậy. Xem xét kỹ tất cả các tệp phông chữ cần cập nhật và ký bằng khoá riêng tư của bạn. Chữ ký phải tương thích với fs-verity.

Cập nhật phông chữ trong thời gian chạy

Ứng dụng hệ thống FontManager thực hiện các bản cập nhật phông chữ. Ứng dụng FontManager cung cấp trạng thái phông chữ hệ thống đã cài đặt mới nhất và khả năng cập nhật tệp phông chữ bằng chữ ký. Để gọi các ứng dụng cập nhật, hãy thêm quyền UPDATE_FONT signature|privileged vào danh sách ứng dụng được phépvào tệp kê khai.

Cung cấp quyền UPDATE_FONT signature|privileged cho hàm trình cập nhật của ứng dụng.