PlantUML Server で生成した SVG が中華フォントになるときの日本語フォント指定

テキストで UML が記述できる PlantUML は同じくテキストでドキュメントが作成できる Markdown と非常に相性がいいです。

Markdown の文中に PlantUML の記述を埋め込んでおけば、画像として管理が別になることもないですし、 Git での差分管理も容易です。

ただし PlantUML はテキストなので当然、画像に変換してやる必要があります。 VSCode では PlantUML 拡張機能を入れるだけで自動的に変換してプレビューに表示してくれます。

PlantUML で UML 図を生成する方法はいろいろありますが、拡張機能などで生成される場合、公式の PlantUML Server を使って動的生成する例が多いです。

今回は SVG (Scalable Vector Graphics) 形式で画像を取得するときに日本語フォントが中華フォントになってしまうことがあるので、それの回避方法を紹介します。

PlantUML Server について

公式の PlantUML Serverhttp://www.plantuml.com/plantuml という URL で利用できるようになっています。

@startuml

hide footbox

actor お客様 as student
actor 係員 as teacher

student -> teacher : リクエスト

@enduml

たとえば上記のような PlantUML は

https://www.plantuml.com/plantuml/svg/SoWkIImgAStDuNA0ip8oKr8LqlBpIvBoAxYu4fDByeiK7ZTsFLstwDdo6Gg9nGh59QKfgNabKAad-vkUJbu84Yz9JKpEI2tYue8gKD2rWuafM2ayRbxrk6dzuwOLZvjsFcxkuE9oICrB0TiCeG40

のような URL で下記のような UML 画像に変換できます。

このパラメーターには PlantUML の記述が圧縮・エンコードされているので、復元も可能です。

URL に svg と含まれていることからもわかるように、この URL は SVG (ベクター) 形式の画像を返します。ちなみに svg を png に変えると PNG 画像が取得できます。

PlantUML Server で生成した SVG での日本語フォント指定

仕組み

前掲の URL をブラウザで開き、中身の SVG タグを見てみると下記のような構造になっていることがわかります。

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="application/ecmascript" contentStyleType="text/css" height="147px" preserveAspectRatio="none" style="width:146px;height:147px;" version="1.1" viewBox="0 0 146 147" width="146px" zoomAndPan="magnify">
  <defs>~省略~</defs>
  <g>
    <line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="32" x2="32" y1="86.2969" y2="135.4297"/>
    <line style="stroke: #A80036; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="121" x2="121" y1="86.2969" y2="135.4297"/>
    <text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="42" x="8" y="82.9951">お客様  </text>
    ~省略~
  </g>
</svg>

文字列の部分は <text> タグで、フォントは font-family 属性で指定されています。

この font-family を変更するには skinparam defaultFontName フォント名 を指定します。

使用できるフォントは listfonts という PlantUML の関数 (?) で取得できます。

@startuml
listfonts お客様からのリクエスト
@enduml

実際に PlantUML Server で listfonts を表示したものが下記です (リアルタイムです)

前述の例では下記のようになります。 VL PGothic が利用できるようなので指定してみましょう。

@startuml

skinparam defaultFontName VL PGothic
hide footbox

actor お客様 as student
actor 係員 as teacher

student -> teacher : リクエスト

@enduml

下記のようになります。

たしかに VL PGothic が適用されています。

問題点

ただし、上記のように指定したフォントがきれいに適用されるのは画像フォーマットが PNG などのラスター画像の場合のみです。

SVG では前掲のとおり、 <text> タグの font-familyVL PGothic という指定がハマるだけなので、下記のようになります。

<text fill="#000000" font-family="VL PGothic" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="42" x="8" y="82.9951">お客様  </text>

この指定は当然ながら環境依存になので、 PC に VL ゴシック がインストールされていなければ代替のフォントが使われます。おそらく一般的なユーザーではインストールされていないでしょう。

おそらく Windows の Chrome や Edge で開くとメイリオが代替フォントに使われるはずです。ただ環境によってはよくわからない中華フォントが優先されてしまい下記のようになってしまうことがあります。

plantuml server svg japanese font issue 4

これはさすがにドキュメントに使えないので、さてどうするか思案しました。結局のところ defaultFontName に「だいたいどの PC でも入ってそうなフォント」を指定するしかないという結論にいたりました。

SVG の場合、サーバー側でフォントを使用しないので、 listfonts にあるフォントを使う必要がないのです。

ということでたとえば下記のように明示的にメイリオを指定します。

@startuml

skinparam defaultFontName メイリオ
hide footbox

actor お客様 as student
actor 係員 as teacher

student -> teacher : リクエスト

@enduml

ダサいですね。しかし、結果はきれいに描画されます。

plantuml server svg japanese font issue 5

ダサいですが、これで我慢しましょう。

結論

PlantUML Server を使って、 SVG 形式の画像で日本語フォントを指定するときは、ローカルの環境にあるフォントを指定しましょう。

kenzauros