O hirunewani blog

Q. GopdfでフォントをNoto Sans CJKに変更したら文字が細くなった

Created at

PDFを出力するツールやライブラリにはバリアブルフォントを対応していないものがあり、意図した表示にならない場合がある。

状況

GopdfでPDFを出力する際に利用するフォントをNoto Sans CJKに変更したところ、 文字自体はNoto Sans CJKで表示されるが文字が細くなったという報告を見かけ、不思議に思ったため調査を行った。

調査と原因の推測

利用されているフォントを見ると、NotoSansCJKjp-VF.ttfとありバリアブルフォントであることが分かった。

Gopdfがバリアブルフォント対応していない、正確にはフォント自体は表示されているため、フォント特性をサポートしていないことが原因と考えられる。実際コードを見ると、フォント特性をコントロールするようなAPIはなく、そもそもAPIがフォントファイルとスタイルを一対一で紐づけるようになっており静的フォントを前提としているように見える。

pdf.AddTTFFontWithOption("SomeFont", "./SomeFont-Regular.ttf", gopdf.TtfOption{
    Style: gopdf.Regular,
})

// これは内部的にRegularのSomeFontを探し、無ければエラーを吐く。
pdf.SetFont("SomeFont", "U", 16)

ただし、これはGopdfに限らず、ざっと調べただけだがGo言語のライブラリでは対応しているものがなく、JavaScriptなどのライブラリでも対応しているものは限られていた。さらにPDF出力できる有名なアプリケーションでもバリアブルフォントの対応の不十分なものがあり、報告が見られる。

バリアブルフォントについて

バリアブルフォント(Variable font、可変フォント)はOpenTypeフォント仕様を発展させたもので、単一のフォントファイルに複数のバリエーションを含めることができる。また、font-variation-settingsプロパティなどを利用して、フォントの太さや幅、傾きなどを変化させることもできる。

2010年代にサポートされた比較的新しいフォント形式だが、既にGoogle Fontsなどを始め多くのプラットフォームでバリアブルフォントが提供されている。

これ以前のフォント(標準フォント、静的フォントと呼ばれる)はバリエーション毎に作成され、個別にファイルを提供している。

対応

静的フォントを利用するしかないため、次のNoto Sans CJKの利用したいfont-weightの静的フォントを探して共有した。

https://github.com/life888888/cjk-fonts-ttf?tab=readme-ov-file#notosans-cjk-ttf