GtkPixBuf は SVG 画像をもそのまま扱えて普通に描写できる。
線や図形の描写 – L’Isola di Niente
上記コードで普通に表示できると確認できます。
しかし拡大すると…
eog は綺麗に引き伸ばしされているのに対し、コッチは超ギザギザ!
MComix で試してもギザギザ、Shotwell は表示すらできない。
eog ってショボイと見せかけて実はこんなに優秀だったのかよ…
ではなく。
どうすれば綺麗に表示できるか考えて調べて色々試してみよう。
ーーーーー
自前ソースがギザギザなのは少し考えれば当然だと解る。
なにせ svg を一度 Bitmap 化して引伸す工程にしているのである。
これではベクターデータである svg での曲線が滑らかという恩恵が無い。
結果 jpeg 画像等と何も変わらないギザギザになる。
つまりベクターデータのまま拡縮して直接描写する必要がある。
メタデータを直接編集すればなんとかなる。
って、だからベクターデータの加工には面倒が付き纏うんだよ。
もしコレが特定ライブラリを使えば Easy Mode になるのだったら…
なんて誰でも考え付くよね。
いきなりそのものズバリを見つけてしまった。
RSVG Libary Reference Manual
librsvg – Wikipedia
GtkDrawingArea は GTK3 から cairo で描写している。
なので cairo から rsvg を使う方法を探す。
Cairo: A Vector Graphics Library: Cairo: A Vector Graphics Library
Fedora 21 で rsvg モジュールはデフォルトでは入っていない。
だけど gir には Rsvg が最初からあった、コレを使おう。
cairo って PostScript や PDF も扱えるのか。
面白そうだけど今回は細かいことは置いておいて。
Python 用 cairo ライブラリから SVG を描写する方法を。
Surfaces ? Pycairo v1.10.0 documentation
サーフェス(面)のサイズを変更するには Matrix を使うのか。
1,4 番目引数で x,y のサイズということみたい。
ということで、サーフェスなので paint でなくレンダリングする。
#!/usr/bin/env python3 from gi.repository import Gtk, Gdk, Gio, Rsvg import cairo, sys class Win(Gtk.ApplicationWindow): def __init__(self, app): """ DnD SVG Viewer """ Gtk.Window.__init__(self, application=app) # svg self.svg = None # DrawingArea self.da = Gtk.DrawingArea() self.da.connect("draw", self.on_draw) self.add(self.da) # DnD dnd_list = Gtk.TargetEntry.new("text/uri-list", 0, 0) self.drag_dest_set( Gtk.DestDefaults.MOTION | Gtk.DestDefaults.HIGHLIGHT | Gtk.DestDefaults.DROP, [dnd_list], Gdk.DragAction.MOVE ) self.drag_dest_add_uri_targets() # self self.set_title("DnD SVG Viewer") self.resize(200, 200) self.show_all() def do_drag_data_received(self, drag_context, x, y, data, info, time): """ On Drop """ uris = data.get_uris() f = Gio.File.new_for_uri(uris[0]) path = f.get_path() # Recreate svg self.svg = Rsvg.Handle.new_from_file(path) # invalidate self.da.queue_draw() def on_draw(self, widget, cr): """ Draw x5 SVG """ if self.svg: # x5 size matrix = cairo.Matrix(5, 0, 0, 5, 0, 0) cr.transform (matrix) # Render self.svg.render_cairo(cr) class App(Gtk.Application): def __init__(self): Gtk.Application.__init__(self, application_id="apps.test.dnd", flags=Gio.ApplicationFlags.FLAGS_NONE) def do_activate(self): Win(app) app = App() app.run(sys.argv)
これならギザギザにならずに拡大することができる。
別途でインストールするものは何もないのに、Linux 恐るべし。
いやまあ全部 GNOME プロジェクトのおかげなんですけど。
結論、cairo って実はこんなに面白いんだyo!