このページでは、Inkscapeでオブジェクトの塗りつぶしに用いる「パターン」の位置がズレるという現象について、分かっていることをまとめていきたいと思います。

- Contents
- (動作1)ハンドルが表示されないことについて
- (動作2)オリジナルのパターンが勝手に大きくなる
(参考:パターンを使って塗りつぶす)
(参考:オリジナルのパターンをメニューに登録する)
パターンを使って塗りつぶす機能自体はSVG形式として標準化されていますが、Inkscapeがそのパターン塗りつぶしをサポートするにあたってちょっとクセのある不思議な動作をするように作られているようで、時々混乱します。
この不思議な動作に出くわしても簡単に対処できることはわかっているので何も慌てることはないのですが、その動作の裏に何があるのかを分かっているともう少し安心してInkscapeを使えるように思うので、自分なりに調べてみました。
その不思議な動作というのは他のページでも書いていますが次の2点です。
(動作1)選んだパターンでオブジェクトを塗りつぶした上で、パターンを拡大縮小したり回転したりしようとしてノードツールを選ぶか、またはダイアログ上で「キャンバス上で編集」というボタンをクリックしても編集用のハンドルが表示されないことがある。
(動作2)「オブジェクトをパターンに」というメニューでオリジナルのパターンを登録して、その登録したパターンをフィル/ストロークダイアログ上で選ぶことで別のオブジェクトの塗りつぶしに設定すると、パターンとして登録したオブジェクトよりも拡大されたパターンが設定される。
以下、この2つの動作のそれぞれについて順番に書いてみたいと思います。
(動作1)ハンドルが表示されないことについて
オブジェクトにパターンを設定し、さらにノードツールを選ぶか、またはフィル/ストロークダイアログ上で「キャンバス上で編集」というボタンをクリックすると、次のように設定済みのパターンの拡縮、移動、回転を行うための専用のハンドルが表示されます。

このことについては「パターンを使って塗りつぶす」のほうに書いてあります。
ところがどういう条件で起こるのか分かっていないのですが、時々このパターン用ハンドルが表示されないことがあります。何が起こっているかというと、次のようにパターンを設定してあるオブジェクトとは関係なさそうなところに表示されるのです。

このことを知らないと、パターン用ハンドルは当然パターンが表示されているところの上に現れるものと思っているので、パターン用ハンドルを見失ってしまい、何が起こっているのか分からなくて困ってしまいます。
極端なケースでは次のようにキャンバスからも遠く離れた位置に表示されていたりします。

キャンバス全体を大きくズームアウトすれば見つけることはできますが、こういう状況になっているかもしれないことを知らないとそんな操作はなかなかできません。
対処方法から先に書いておくと、表示されているパターン(そのパターンで塗りつぶされているところ)の上を1回クリックするという方法が簡単です。そうすると、遠くに存在するパターン用ハンドルがクリックした位置に移動してきます。

いろいろ調べてみましたがなぜこのようなことになるのかは分からなかったので、パターン用ハンドルが見えなくなったらクリックするという対症療法だと考えればいいかなと思います。
ここでパターンを使った塗りつぶしの様子を模式的に表してみると次のようになります。

パターンによる塗りつぶしというのは、パターン化したオブジェクト群を1つの単位として縦横に並べ、それを設定対象のオブジェクトのアウトラインで切り取っているようなイメージになります。
このとき切り取られてしまった外側にも無限にパターンが並んでいるところが想像できます。
そしてパターン用ハンドルはこの縦横に並んだパターンのうちの1つの周囲に表示されているようです。その「パターンのうちの1つ」がどういう処理で選ばれているのかが分からないのですが、その選ぶ処理は簡単に想像できるようなものではなさそうで、オブジェクトから離れた位置のパターンを何らかの理由で選んでいるのじゃないかと思われます。
例えば次のような感じです。

オブジェクトで切り取ったところに含まれない、離れた位置のパターンを1つ選んでその周囲にパターン用ハンドルを表示しているのではないか、ということです。
もしこの状態になってしまっても、切り取ったところに含まれるパターンの1単位をクリックによって選び直せばそちらにハンドルが移動してきてくれるということです。
(動作2)オリジナルのパターンが自動的に大きくなる
この動作についても「パターンを使って塗りつぶす」のページで「謎の拡大」と呼んで説明してあります。
今回はこの「謎の拡大」の原因について調べてみた結果をメモしておこうと思います。
ことはどうやらSVG形式データの中に記述される座標値の扱いの問題につながっているようです。
SVG形式データの中にはいろんなところに座標値が記述されていて、その座標値がInkscapeの中でどのように処理されるかという点に関連することなので、塗りつぶしパターンの座標値に限った話ではないSVG形式データ一般の話題だと思うのですが、Inkscapeを使っているとこのことに影響されるのは塗りつぶしパターンの「謎の拡大」のときぐらいなので、ここにまとめておきます。
まずSVG形式データの中に記述される座標値ですが、「mm」や「px」のように単位と一緒に記述することも可能ですが、そうするとどんな解像度でも同じように表示できるベクトルデータとしての特徴を生かせないので、通常は単位なしで数値だけの座標値を記述するようです。
そして単位なし座標値はCSS(スタイルシート)でいうところの「px」(ピクセル)を省略した書き方なのだそうですが、一方でSVGでは「width」と「height」と「viewBox」という属性を指定することで、画面に表示したときのSVGドキュメント(<svg>要素)の幅と高さに対して座標値の最大値と最小値(つまり座標値のレンジ)を指定することができるので、単位なし座標値は解像度の単位である「DPI」でいうところのピクセル数ではなく、そのSVGドキュメントの幅と高さの何分の1を座標値「1」の大きさとするかをSVGドキュメント内に定義することができるようになっているそうです。
例えば、「width=100mm height=100mm viewBox="0, 0, 100, 100"」と記述したSVGドキュメントの場合、「width=10 height=10」という属性の矩形を表示すると、100mmを長さ「100」として(つまり1mmを「1」として)表示されます。この矩形は10px x 10pxの大きさで表示されるのではなく、10mm x 10mmの大きさで表示されることになります。
これはいわゆる「ピクセル」という言葉の意味とは少し違った扱いになっていると感じます。
このように、SVGの場合、CSSで記述される座標値とはちょっと違って、viewBoxの値として自分で定義する相対的な座標系での座標値を記述しているのだと理解したほうが良さそうです。
さて、そうするとInkscapeを使って作成したSVGデータの中に記述されている座標値が表示の際にどんな長さとして扱われるのかは、InkscapeがviewBoxにどんな値を記述しているのかによる、ということになります。
そしてそれは「ドキュメントのプロパティ」というダイアログの次の画面の設定で決まります。

上のほうでは1ページ目(フロントページ)の大きさを指定します。
下のほうではviewBoxに記述する値を指定します。直接数値を入力することもできますが、真ん中ほどにある「尺度」という欄の値を調整すると、フロントページの大きさに対してviewBoxの値を自動的に計算してくれます。
デフォルトではこの「尺度」は「1.0」になっているので、フロントページの幅と高さはそのままviewBoxの幅と高さ(水平方向の最大座標と垂直方向の最大座標)になります。
そして、キャンバス上でオブジェクトを入力すると、そのSVGデータ内の座標値はこのviewBoxの値を使って変換された座標値になります。
例えばキャンバス上で10mm x 10mmの矩形を描いてSVGデータとして保存すると、その矩形の座標値としては「width=10.0 height=10.0」が記述されることになります。
もちろん「尺度」を変更することで画面上で10mmで描いたものもSVGの中に異なる座標値で保存することもできます。
ところでInkscapeの画面には次のようにオブジェクトの座標値(例えば幅と高さ)を設定する入力欄があります。

キャンバス上のオブジェクトはここで指定した座標値で位置と大きさが決まります。
とくに単位として「px」を指定した場合は「96dpi」という解像度のピクセル数を指定することになる(参考:ディスプレイ解像度の話)のですが、ここに指定した値もSVGとして保存する際はviewBoxの値に応じて変換された座標値が格納されます。
ここでやっとパターンの話になります。
パターンとして登録しようと思うオブジェクトをキャンバス上の座標値(例えば「px」)で示される大きさで描き、メニューで「オブジェクトをパターンに」を操作してパターンとして登録します。登録したパターンはフィル/ストロークダイアログに設定可能なパターンの1つとして表示されます。詳しくは「パターンを使って塗りつぶす」に書いてあります。
この状態でドキュメントをSVG形式ファイルとして保存します。
すると、パターンとして登録したオブジェクトがその座標値とともにそのSVG形式ファイルの中に記述されていますが、その座標値はviewBoxに従って変換された値ではなく、再び画面上の長さを表す値に戻されたものが使われます。どうしてそんなことになるのかは分かっていません。
これも例でみてみます。
「尺度」をデフォルトの「1.0」のままにして、キャンバスに矩形を描き、幅も高さも「10.0px」を設定します。
そして例としてこの矩形にグラデーションを設定した上で(これは実例をわかりやすくするため)、パターンに登録します。
比較のため、パターンの元に使った矩形と、それをパターン化して円の塗りつぶしに使ったものを並べた状態を示します。

パターン化すると、パターン1個あたりの大きさはパターンの元に使った矩形よりもだいぶ大きいことが分かります。
このときSVGデータ内がどうなっているかを見てみます。
まずパターンの元に使った矩形を記述した部分は次のようになっています。

幅も高さも「2.64」という不思議な値になっています。画面上で設定した幅と高さ「10.0px」を解像度「96dpi」と「1inch=25.4mm」であることを考慮して「mm」に変換すると「2.64mm」ですが、尺度が「1.0」なので、SVG内には「2.64」という値が格納されるわけです。
一方、パターン化によってSVG内に格納された矩形は次のようになっています。

幅も高さも「10」が記述されています。viewBoxの値を使って画面上の座標値に戻された結果「10」となっているわけです。なぜ「座標値を戻す」必要があるのかは分かっていません。
ところがこのパターンを何かのオブジェクトの塗りつぶしに設定すると、Inkscapeはこの「10」という座標値を当然のようにキャンバス上の座標値に変換してから表示するので、もう一度viewBoxの値にしたがった変換が行われます。そうすると画面上の座標値は、解像度「96dpi」、「1inch=25.4mm」、尺度「1.0」であることから「37.795px」ということになります。
要するにキャンバス上で「10px」の大きさで描いたオブジェクトをパターン化し、そのパターンを別のオブジェクトの塗りつぶしに使うと、パターン1個の大きさは「37px」になるので、3倍ちょっとの大きさに自動的に拡大されたかのように見えるというわけです。
これが正しい動作なのかどうかはわからないのですが、自作のパターンを登録して塗りつぶしに使ったときに拡大されてしまった場合は、「キャンバス上で編集」ボタンをクリックして編集可能にした上で、小さくなるように手で調整すればよいことになります。
なお、「尺度」が「1.0」だからこういうことになるので、画面上の「px」の値とSVGデータ内の座標値が一致するように「尺度」として「0.2645」などという値を設定すれば、このように拡大されるようなことはなくなりますが、そこまでしなくてもいいかなと思います。