Inkscapeでエクステンションを自作する方法を試してみました。
ここでは位置や幅を指定するときの単位(mmやpx)を指定してオブジェクトを描くサンプルを作ってみました。エクステンションのPythonプログラムの中で単位を指定するための専用の変数や関数は存在しないようで、数字と単位の表記文字を使って指定することになるようです。
(参考:「長さ」の単位について)
以下のサンプルでは、ストロークの幅を異なる単位で指定した矩形(Rectangleオブジェクト)を描いています。4つのRectangleオブジェクトを生成して、stroke-widthというスタイル属性に「2.0」や「2.0mm」のような値を指定しています。
import inkex
from inkex import units
import sys
class UnitExtension(inkex.extensions.EffectExtension):
def effect(self):
rect1 = inkex.elements._polygons.Rectangle(x='50', y='10', width='100', height='10')
rect1.style = {'stroke': '#0F0', 'stroke-width': '2.0', 'fill': 'none'}
text1 = inkex.elements._text.TextElement()
text1.style = {'font-size': str(units.convert_unit('28.3pt', 'mm'))}
text1.set('x','50')
text1.set('y','30')
text1.text = 'width=2.0'
rect2 = inkex.elements._polygons.Rectangle(x='50', y='40', width='100', height='10')
rect2.style = {'stroke': '#00F',
'stroke-width': str(units.convert_unit('2.0mm', 'mm')) , 'fill': 'none'}
text2 = text1.copy()
text2.set('y','60')
text2.text = 'width=2.0mm'
rect3 = inkex.elements._polygons.Rectangle(x='50', y='70', width='100', height='10')
rect3.style = {'stroke': '#0FF',
'stroke-width': str(units.convert_unit('2.0px', 'mm')) , 'fill': 'none'}
text3 = text1.copy()
text3.set('y','90')
text3.text = 'width=2.0px'
rect4 = inkex.elements._polygons.Rectangle(x='50', y='100', width='100', height='10')
rect4.style = {'stroke': '#FF0',
'stroke-width': str(units.convert_unit('2.0pt', 'mm')) , 'fill': 'none'}
text4 = text1.copy()
text4.set('y','120')
text4.text = 'width=2.0pt'
# レイヤ上にオブジェクトを並べる
self.svg.get_current_layer().add(rect1, text1,
rect2, text2,
rect3, text3,
rect4, text4)
if __name__ == '__main__':
UnitExtension().run()
ストロークの幅をラベル表示するためのTextオブジェクトは、copyメソッドを使って複製して使っています。
ポイントは、「20mm」や「30px」のように、数値と単位文字を連結したものをプログラム中で直接使うことができないことです。やってみると一応動きますが、SVM形式ファイルの中を調べてみると変な値になっています。
そこで、Inkscapeが長さの値を「mm」で格納していることに注意して、unitsクラスのconvert_unit()というメソッドで「mm」の値に変換してからスタイルにセットしてみました。これならInkscape内部では「単位なし(すなわちmm)」の長さが記憶されるので、指定したとおりの長さ(この例ではストロークの幅)で表示されます。
実行すると次のように矩形オブジェクトが追加されます。
