2009年04月08日

rsvg2とcairoでsvgをSDLに描画したり保存したり

cairoで一般的なビットマップを扱う場合は代替手段も多いだろうが
同一描画命令でps2,pdf,svgもサポートしている点が大きい。
今回はrsvg2も使い、svgファイルをimageとsvgそれぞれに取り込み
文字を描画してimageをsvgに描画し、それをsvgとpngに出力をしつつ画面をだすということをやってみた。
rsvg2の使用はglib2,gobject依存必須になる。cairoがglibすら使っていないことを考えると
なかなか微妙な存在ではあるが
シンプルな内容とはいえいろいろな要素をもった今回の内容でも
実行ファイルサイズはstrip前でも9.9kbyte、strip -sで6.6kbyteで使用メモリ9Mbyte強と多いめ
と主目的がSVGでないならば微妙な位置だが
firefoxでもwebkitでも読めないsvgz(gz圧縮したsvg)を読み込める点だけでも評価に値する。

SVGファイルでテーマファイルを適当に指定して使った。
今回の結果物がこちら
cairo-svg
svgを読込みsvgサーフィスとイメージサーフィスに描画し
さらにそれぞれにテキストを描画してsdlサーフィスに取り込んだものをsvgとpngで出力してから
SDLの画面に描画した。

ライブラリーとして使うのはrsvg2だがglib系なのでpkg-configでオプションを取得した。


pkg-config librsvg-2.0 --cflags --libs


これでもれなくcairoのライブラリとパスもついてくる。
あと必要なのはsdlの分だけ

includeも

#include <librsvg/rsvg.h>
#include <librsvg/rsvg-cairo.h>
//#include <cairo.h>
#include <cairo-svg.h>

とcairo.hはコメントアウトできた。
cairo-svg.hはsvg出力に必要。

rsvg2による読み込みは
http://library.gnome.org/devel/rsvg/stable/index.html
あたりのリファレンスを読むと分かる。

基本的なファイルの読み込みの流れはSRCSVGをファイル名として

//var
cairo_t *cr3;
cairo_surface_t *image;
SDL_Surface *img1;
RsvgHandle *r_svg;
RsvgError rs_err;
RsvgDimensionData svgdim;

//begen

rsvg_init();
r_svg = rsvg_handle_new_from_file(SRCSVG, NULL);
//r_svg = rsvg_handle_new_from_file(SRCSVG, &rs_err);
rsvg_handle_get_dimensions(r_svg,&svgdim);

img1=SDL_CreateRGBSurface(SDL_SWSURFACE,svgdim.width,svgdim.height
, 32, rmask, gmask, bmask,amask);//rGbA

image = cairo_image_surface_create_for_data (
img1->pixels,
CAIRO_FORMAT_ARGB32,
img1->w,
img1->h,
img1->pitch);
cr3 = cairo_create (image);

rsvg_handle_render_cairo(r_svg, cr3);
cairo_surface_write_to_png (image, DSTPNG2);
rsvg_handle_free(r_svg);
rsvg_term();

cairo_destroy (cr3);
cairo_surface_destroy (image);
SDL_FreeSurface( img1 );


という感じになる。
最初rsvg_initの存在に気づかずエラーばかりでていた。
実際はファイルエラーも考慮してr_svgのNULLチェック後に処理をするのが良いだろう。

ファイル読み込みの他rsvg_handle_new_from_data もありシンプルにポインタ渡しで使えるので
自由度も高いがファイルからよめれば充分な気はする。

高さと幅はメンバーとかではなくてrsvg_handle_get_dimensionsで得る。
ブラックボックスとして読み込むのには良いのだが
「svgエディター」を考えた場合はこのrsvgだと解析が出来ないので若干不便ではある。


svg_sf = cairo_svg_surface_create(DSTSVG, svgdim.width, svgdim.height);
cr2 = cairo_create(svg_sf);
rsvg_handle_render_cairo(r_svg, cr2);
cairo_surface_write_to_png (r_svg, DSTPNG);
.
.
.

とすればSVGとして読み込める。
また上記の様にSVGサーフィスもPNGとして出力出来る。

ここで

cairo_set_source_surface (cr2, image, 100,50);
cairo_paint (cr2);

としたところSVGファイルに「画像」としてのデータも上乗せできた。

実験実験しいけれど「画像」かつ「描画スクリプト」としてうまく扱えると同時に
rsvg_handle_render_cairoはcairo描画の一部として使えるものの
イメージ化するタイミングを間違えると画質が低下する可能性を感じた。

当然今回の結果はpdfやpsにも反映できるのでアプリケーションに印刷能力を追加できる。
またこの段階のコードでは既存のSVGは編集できないがパーツとして利用したり
任意のスケールでイメージ化してテクスチャーとして使える。
ビットマップを回転させるよりSVGを回転してからイメージ化する方が画質も良いわけで
必要に応じて展開するなどゲーム用としても悪くない。


ラベル:cairo SVG SDL
posted by Xo_ox at 15:51| Comment(0) | クロスプラットフォーム | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
×

この広告は180日以上新しい記事の投稿がないブログに表示されております。