暮らしの技術

暮らしを豊かにする技術や、特に暮らしを豊かにしない技術があります

3点リーダ偏り問題、あるいは「そしてまた。 次の縦書きがはじまるのです。 」

f:id:side_tana:20161020233436p:plain*1

ポプテピピックよくて,とくに「竹書房⁉︎ 破壊したはずでは……」が好きで,潰したはずのバグが発見されたときのissueなんかで貼っつけて遊んだりしてます.破壊したはずなのは竹書房ではないので,吹き出しの中身を適当に変更したりします.とはいえ業務中にそういったことをするわけにはいきませんから,昼休みなんかにやります.すると昼ご飯を食べる時間がなくなってしまいます.困りました.由々しき事態です.というわけで最初のスクリーンショットのようなツールを作りました.公開の予定はありません.

さて本題.

SVGにおける縦書きサポート

writing-mode: tb; でいけます.tb 古い記法でしょ vertical-rl では? とお思いになられるかと思いますが SVG1 では tb みたいです.
developer.mozilla.org

SVGにおける縦書きサポートの課題

縦書き界隈でしばしばあるのが,「この記号ちょっとずらしたい」みたいな需要で,具体的には上のスクリーンショットでいう三点リーダとか.

伝統的な縦書き技法に「一文字一文字を真心込めて SPAN でくるみ配置していく」みたいなのがあるんですが,それに近いことを部分的にしたくなるわけです.SVG の TEXT には 部分テキストを表す TSPAN が定義されていますが,変形するための transform 属性は定義されていません.実際にAdobe Illustrator なんかでひと文字だけ回転させたアートボードをSVGとして吐き出すとこんな具合です.

f:id:side_tana:20161021013203p:plain
これを書き出しました.獰悪の獰の字だけ時計回りに90度回転しています.なぜこんな分かりにくい文字を選んだのか.

f:id:side_tana:20161021013338p:plain
「という人間中で一番」のところで TSPAN が一度閉じられ,さらに TEXT も閉じられ,あたらしい TEXT では transform にrotateが指定されていて,そのあとに最後の「悪な種族であったそうだ」だけが入った TEXT 要素があるのがわかると思います.どんな文章が来るかわからず,動的に制御したい場合,このような仕様だとなかなかやっかいです.

つらいですね.なんとかなりたい.なんとかなりませんか? 似た問題に「2桁数字横並び配置問題」というのがあります.

f:id:side_tana:20161020233830p:plain
*2

縦書きだ,漢数字を使えといった声もあるかと思います.私もそう思う.ちなみにここからの派生コンボで「一桁の数字も縦にしたいしその場合はセンタリングで」に繋げることができます.

あ,あと普通に忘れてたんですけど TEXT 自動改行(?) 表示スペース似合わせていい感じに表示するみたいなのないっぽくて,今回は気合いでTSPAN並べていきました.ましな方法知りたい.

書き出し時の問題

こういったツールの場合画像をダウンロードしたくなります.戦略を考えてみますと

1. SVG を HTML の IMG で読み込む
2. canvas 要素を作り drawImage で上記の IMG を読み込む
3. a 要素を作り, href 属性に canvas.toDataURL() で吐いた文字列を指定する
4. a 要素に加工した上でクリックイベントを送る

みたいな感じになります.簡単そうですね.でも実際にやるとハマる.

ハマりどころ

imageエレメントで外部リソースを指定しているとimgタグに食わせた場合に表示されない

なんかどうせCORSまわりでcanvasが汚染されたんでしょとかいって雑にdata URI schemaでデータを埋め込んだら回避できた.今回,オリジンは同じだったので冷静に考えるとおかしい.imgのsrcにsvgを指定した場合はimageエレメントのロードやってくれないんだったっけ*3
f:id:side_tana:20161021005745p:plain
SVGの xlinkHref に外部のリソースを指定した場合
f:id:side_tana:20161021005715p:plain 
SVGの xlinkHref にdata URI を指定した場合

font が反映されない

imgがフォントの反映してくれない問題.今回それっぽさを出すためにちゃんとアンチック体を使っているのですが*4,上記の方法で吐き出した画像だとフォント指定が無視されている.画像の時と同じパターン? SVGにフォント埋め込む方法あるのかな,あったら解決できそう.

戦略を変える

canvgによる回避

canvgってのはsvgをパースしてcanvasゴリゴリ書けばええやんけっていう男気溢れるプロジェクト.
f:id:side_tana:20161021010147p:plain
フォントはちゃんと反映されてるっぽいですが縦書きまわりが破滅してますね,これどうなってるんだろ,ちょっと興味出てきた.

大変ですね

大変ですね.ダウンロードの件はスクリーンショットでいいと思います.はやいしノーコスト.

*1:破壊してません

*2:10 を水平に並べたいという自然な欲求が沸き立ちます

*3:この文章普通に意味わかんないですね.SVGには外部画像を読み込む IMAGE 要素が用意されていて,HTML で画像表示に使われる IMG 要素とは名前が違います

*4:漢字がゴシックでかなが明朝体のやつ.一番最初のスクリーンショットをみてくれ!