💩
Flutter Web (CanvasKit) で日本語や絵文字の描画問題を回避する
問題
CanvasKitでの描画はhtmlに比べてパフォーマンスが高く、環境による描画の差がない利点があリますが、2バイト文字や絵文字が一時的にいわゆる "Tofu" になってしまうことがissueとして上げられています。
(例)
↓ 数秒後...
現在、Flutter WebはCanvasKitがデフォルトのレンダラーです(デスクトップ向けの場合)。--web-renderer でhtmlを指定するかモバイルで閲覧すればこの問題は回避できるのですが、デスクトップでCanvasKitレンダラーを使う場合でも回避できる方法を紹介します。
回避方法
Tofuになってしまう文字が含まれるフォントをプロジェクトに組み込んで、MaterialAppの {theme: } などでフォント指定するだけです。
(例)pubspec.yaml
fonts:
- family: Hiragino Maru
fonts:
- asset: fonts/Hiragino_Maru.ttc
- family: Color Emoji
fonts:
- asset: fonts/Apple Color Emoji.ttc
(例)日本語フォントを全体のテーマに指定
MaterialApp(
theme: ThemeData(
fontFamily: 'Hiragino Maru', // ←
primaryColor: Colors.cyan,
accentColor: Colors.yellow,
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
primary: Colors.cyan[700],
onPrimary: Colors.white,
),
),
),
);
(例)絵文字フォントを個別指定(Apple Color Emoji 使用)
Text(
'あいうえお💩',
style: TextStyle(
fontFamilyFallback: ['Color Emoji'], // ←
),
),
結果
描画直後にきちんと表示されることがわかるように Future.delayed() でTextの読み込みを遅らせています。
CanvasKitでの日本語と絵文字の描画
{style: } プロパティがあるWidgetであれば、Text Widget だけでなく TextField Widget などにも応用が可能です。
Discussion