やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

fonttoolsでSVGのuseからglyphが作れないか試すが失敗(fonttools, svg2glif.py)

 残念。

前回まで

 上記の準備を完了させたものとして今回の話を進める。

今回

ヘルプ

 まずは前回起動確認したsvg2glif.pyのコマンドについてヘルプ表示する。

$ python svg2glif.py --help
usage: svg2glif.py [-h] [-n NAME] [-w WIDTH] [-H HEIGHT] [-u UNICODES] [-t TRANSFORM] [-f {1,2}] INPUT.svg [OUTPUT.glif]

Convert SVG outlines to UFO glyphs (.glif)

positional arguments:
  INPUT.svg             Input SVG file containing <path> elements with "d" attributes.
  OUTPUT.glif           Output GLIF file (default: print to stdout)

options:
  -h, --help            show this help message and exit
  -n NAME, --name NAME  The glyph name (default: input SVG file basename, without the .svg extension)
  -w WIDTH, --width WIDTH
                        The glyph advance width (default: 0)
  -H HEIGHT, --height HEIGHT
                        The glyph vertical advance (optional if "width" is defined)
  -u UNICODES, --unicodes UNICODES
                        List of Unicode code points as hexadecimal numbers (e.g. -u "0041 0042")
  -t TRANSFORM, --transform TRANSFORM
                        Transformation matrix as a list of six float values (e.g. -t "0.1 0 0 -0.1 -50 200")
  -f {1,2}, --format {1,2}
                        UFO GLIF format version (default: 2)

 -tを使って変形したい。

成果物

 上向きの矢印SVG画像を180度回転させて下向きの矢印にしたい。

  • arrow-top.svg

arrow-top.svg

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256"><path style="opacity:1;fill:none;fill-opacity:0;stroke:#000003;stroke-width:16;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="M128 7.781 7.781 120.22H64V248h128V120.219h56.219L128 7.78z"/></svg>

run.sh

#!/usr/bin/env bash
cd `dirname $0`
python svg2glif.py -t "rotate(180,128,128)" arrow-top.svg arrow-bottom.svg

 実行すると以下エラーになった。

svg2glif.py: error: argument -t/--transform: Invalid transformation matrix: 'rotate(180,128,128)'

 無効な値らしい。前回svg2glif.py内にあるコメントで察してはいたが、どうやら6桁のmatrix(行列)値をセットすべきらしい。以下の情報源にも書いてあった。

行列により上下反転させる

 6桁の行列値は次のような意味だと思われる。

a b c d e f
要素 意味
a 拡大縮小X
b 拡大縮小Y
c 回転X
d 回転Y
e 移動X
f 移動Y
python svg2glif.py -t "0 -1 0 0 0 0" arrow-top.svg arrow-bottom.svg

 実行したらarrow-bottom.svgファイルが生成される。その中身が以下。

<?xml version='1.0' encoding='UTF-8'?>
<glyph name="arrow-top" format="2">
  <outline>
    <contour>
      <point x="0.0" y="-128.0" type="line"/>
      <point x="0.0" y="-7.781" type="line"/>
      <point x="0.0" y="-64.0" type="line"/>
      <point x="0.0" y="-64.0" type="line"/>
      <point x="0.0" y="-192.0" type="line"/>
      <point x="0.0" y="-192.0" type="line"/>
      <point x="0.0" y="-248.219" type="line"/>
      <point x="0.0" y="-128.0" type="line"/>
    </contour>
  </outline>
</glyph>

 これが意味不明。そもそもSVG規格の要素に<outline>,<contour>,<point>などという要素は存在しない。

 最初から気になっていたのだが、glifって何? svg2glif.pyというファイル名だが、その中にあるglifって何? glyphではないの? 誤字ではないの?

 情報源のSVG ⇄ グリフ をするときの座標変換ではTeXの数式って書いてある。たぶん以下コードがそれ。ならglifというのはTeX固有の文脈や機能なのかな?

\begin{pmatrix}
 1 & 0 \\ 0 & -1
 \end{pmatrix}
 \begin{pmatrix}
 x \\ y
 \end{pmatrix}
+
\begin{pmatrix}
 0 \\ 0
 \end{pmatrix}

 SVGじゃなかったのか……。情報源にはSVGPathも紹介されていたが、これクラスだし、どう使うの? SVGファイル出力されるの? サッパリわからない。

所感

 SVGスプライトからフォントを作るため、<symbol>,<glyph><use transform="rotate(180,128,128)">みたいなことをしたかったのだが、情報が一切見つからない。たぶん、できないのだろう。

 でも、単に元の図形をコピーして変形するだけだから論理的には可能なはず。それを実現するアフィン変換や、それに基づき最終的なd属性値を作るのが大変そうだけど。

 そんなの誰かがとっくに作ってると思っていたのだが。誰も作ってないなら、私に作れるとも思えないし、諦めるか。

 思いつく代案は以下。

  • Inkscapeで変形させた図形のパスデータを生成する

 できればプログラマブルに定義したり、自動化スクリプトを作れるのが望ましかったのだが、難しそうだ。