fresh digitable

めんどくさかったなってことを振り返ったり振り返らなかったりするための記録

実行環境でうまく表示できないVectorDrawableについてのメモ

レイアウトエディタのプレビューだと何ともないのに実行環境だと表示が崩れてしまうVectorDrawableのファイルがあったので状況整理のためにメモしておく。

もとのSVGはデザイナさんが作成したものを受け取ったあとSvgToVectorDrawableConverterというツールで変換した。

github.com

 

件のSVGのデータは平たくいうと目のアイコンなんだけど、ノードがものすごく近い間隔でいっぱい置いてあって、「パスが長すぎる」という旨の警告がAndroidstudioに出ていた。ただ、VectorDrawableのプレビューでもレイアウトエディタのプレビューでも問題なく表示できていたので大丈夫かと思ってエミュレータで動かしてみたところ、塗りつぶしの領域を決めそこなった感じの目のアイコンが表示された。

参考: VectorDrawableの穴を塞がないようにする

最初はfillTypeの問題かなと思ってパスをざっくりと読んでみたが、回転の方向はあっているように見えた。また、そのようなツールが公開されていたので確かめてみたが、特に問題はなさそうであった。

 

次に、VectorDrawableが読み込まれてPathオブジェクトに変換されるあたりの処理を眺めることにした。

http://tools.oesf.biz/android-7.1.1_r1.0/xref/frameworks/support/graphics/drawable/static/src/android/support/graphics/drawable/PathParser.java

 

AndroidのPathParserではA命令をいくつかのC命令に変換・分割している様子。A命令をベジエ曲線で近似した時の誤差については次のページが詳しい。

zellij.hatenablog.com

 

いくらか調べて、ノードの間隔が詰まりすぎていると近似したときの誤差でパスが重なってしまい、塗りつぶしの領域が意図しないものに変わってしまうのではないかという仮説を立てた。ちゃんと検証するかどうかは未定。

 

いずれにせよ、近い間隔でノードを置かない、ツールなどでクリンナップする、A命令を予めCやSなどのベジエ曲線の命令に置き換えておくなどしてみると安心かもしれない。