So-net無料ブログ作成
検索選択

SVGから内部形式のデータへの変換2 [Qt]

実装に取り掛かりたいと思いますが、データの変換の部分は下記の様な構造で実装を行おうと考えています。

10092800.png
この2つのクラスはまとめられますかね?


一応、Qtの考え方(と私が理解している・・)に合わせて、QPaintDeviceのサブクラスとQPaintEngineのサブクラスに分けていますが、データの変換という目的のためなら、何となく一つにした方がいい様な気がしてますが、まあ最初はこのままで行きます。このクラスをQtlDrawDataから利用する形にしようと思っています。

データ変換のシーケンスは下記の様な感じでしょうか。

10092802.png


さて、肝心の「描画の処理」の所をブラックボックスにしていますが、処理を考えて行きましょう。呼び出される関数と必要そうな処理は前回の表の通りなので、実際に実装して行こうと思います。

シーケンス中、QtlSvgConvertor::setDevice()と言う関数がQtlSvgConvertorから呼び出されています。これは、下記の通り、データの書き込み先のデバイス(今のところ、QtlDrawData内で保持しているQPixmapを想定)を登録する関数となっています。書き込み先のパラメータが必要な時は、全てこの関数で登録されたデバイスから引き出す事にします。コンストラクタで指定できた方がいいですかね・・。まあ、ええか。

QtlSvgConvertor::setDevice()
引数QPaintDeviceデータの描画先
戻り値void
処理引数のQPaintDeviceを記憶する


metric()は、要求されたものを返しますが、このデータの元が、先程の関数で設定されたQPaintDeviceから値を引き出す事になります。

で、updateState()ですね。前回の記事では、パラメータを保存する旨を書いていましたが、よく考えてみると、今のところは書き込む時にペンの設定を変えたりしていないので、必要ないんですよね・・。今は無視する事にします。

次はdrawPath()ですが、今のところ、終点の処理をデータとして保存する必要は無いので、前回記載のとおり、何もしません。

そして、drawPolygon()です。これは、線の描画として処理が必要です。が、だいぶ前に書いたとおり、ターゲットのサイズが違う場合が気になります。一応、アプリの動作としては、書いたものをウィンドウのサイズに合わせて、拡大・縮小させたいと考えています。もう、いつ始めたのかも分からないくらいになってますが、作ろうとしてるのはメモですからね。どのようなウィンドウサイズでもメモが読めるようにしたいと思います。

・・・データの精度が気になりますね。現状は、最初にメモを取った時の画面のサイズが元になってしまっていますが、最初に小さいサイズのウィンドウで書いたデータに大きい画面で書き足した時に点が荒くなってしまうのは避けたいですね・・。データの元サイズは標準のサイズとして決め打ちしとく必要がありそうですが、その場合は、最初にデータを書き込むときから、座標変換をかます必要がありますねぇ・・・。


ちょっと悩むので続く。





SVGから内部形式のデータへの変換 [Qt]

さて、SVGの要素の大体の意味がわかったところで、呼び出された関数の処理を考えていきたいと思います。「metric()」以外は、QPaintEngineのメンバ関数となっています。

begin()
引数QPaintDevice *データ変換用のクラス(QPaintDeviceのサブクラス)が来る予定
戻り値bool成功時true、失敗時false。
処理 書き込み先のサイズなど、後の処理に必要なデータを取得。


metric()
引数PaintDeviceMetric要求パラメータ
戻り値int要求されたパラメータの値
処理 QPaintDeviceの仮想関数。要求されているパラメータの値をbegin()で登録されたQPaintDeviceから引きだして返す。


updateState()
引数QPaintEngineState変更のあったパラメータ
戻り値void
処理 描画に使うパラメータをQPaintEngineStateから取得し、保存しておく。それぞれのパラメータに対する呼び出し関数は、詳細説明に記載されている。現状で保存が必要と思われるパラメータは、QPainter::RenderHintsQBrushQPenQFont。QPainter::RenderHintsはenum型、QBrushは、通常用と背景用の2種類のインスタンスが必要な様子。


drawPath()
引数QPainterPath描画終了位置周辺の座標が入っている様子
戻り値void
処理 終点周辺の点が含まれているため、線の終端の描画を行っている様子。現状、内部データには不要と思われる。ただし、終端のみかどうか注意しておく必要はあると思われる。


drawPolygon()
引数QPointF *線を描画するための点の配列。
int上記に含まれている点の数
PolygonDrawMode描画モード。線の書き方、今、実装している範囲では、気にする必要は無さげ。
戻り値void
処理 含まれている点を取り出して、線を引いて行く。


end()
引数なし
戻り値bool終了の成否(true/false)を返す。
処理 保存していたデータを破棄して終了。正常な場合はtrueを返す。異常な場合はfalseを返す。


これを参考に、起動時にデータを読み込む実装をしたいと思います。


細切れでなんなんですが、つづく。





SVGの要素 [SVG]

何があるのかが分かってきましたが、まだまだもやもやしていているので、出てきたSVGの要素についてどういう意味があるのかまとめておきます。

svgSVG文書はこの要素の中に書かれる。svg要素は他のXML文書の中に書き込めるらしい。ただし、svg要素の中にsvg要素をネストすることはできないとのこと。
xmlns名前空間の定義。「http://www.w3.org/2000/svg」固定?
xmlns:xlink
widthSVG文書の幅を示す。負の値は取れない。数値と単位で示す。単位は、in、cm、mm、pt、pc、px、%のいずれか。%はviewportの幅に対する割合となる。
heightSVG文書の高さを示す。負の値は取れない。数値と単位で示す。単位は、in、cm、mm、pt、pc、px、%のいずれか。%はviewportの高さに対する割合となる。
viewBox内包するグラフィック要素が収まるべきviewportの指定を行う。値はmin-x、min-y、width、heightの順にスペースかコンマで区切って指定するか、もしくはnoneとするとのこと。
versionSVGのバージョン。1.0、1.1、1.2のいずれかを指定。
baseProfileSVGのプロファイル。none、full、basic、tinyのいずれかを指定。
titleSVG文書のタイトル。プレインテキストで、SVG文書内に1つ以上含むことができる様子。
descSVG文書の説明。プレインテキストで、より詳細に記述するとのこと。こちらもSVG文書内に1つ以上含むことができる様子。
defs参照される要素を定義するためのコンテナ要素(?)。マクロ定義的な要素でしょうか?詳細不明(と言うか、必要になったら見ます)。
ggraphics elements」関連をグルーピングするためのコンテナ要素。
fillグラフィック要素の内部が塗りつぶされるべきかどうかを指定する。値は、none、currentColor、sRGBによる表記(?)、Functional IRIでの表記(?)、System paintによる表記(?)、inheritがある様子。HTMLで行われている表記も利用できる様子。
stroke線を描画する際のペン先を決める。値は、こちらの表記か、inherit。色などでいい様子。
fill-opacity現在のオブジェクトの内部を描画する際の透過度を指定する様子。0-1の間の任意の値かinheritを設定
vector-effectオブジェクトのアウトラインの幅を制御するためのものの様子。例えば、2pxの幅の線があった時、拡大表示されてもその線の幅を2pxに維持したい時などに使用するとか。値は、non-scaling-stroke、none、inherit。non-scaling-strokeで、幅を維持する設定になる様子。
stroke-width詳しい説明が見当たらないんですが、名前から線の幅でしょうね。値は数値もしくは、inheritで、値は現在のユーザー座標系に従うらしいです。
fill-rule描画された「形」の「内部」の決め方を指定。値はnonzero、evenodd、inherit」の3種。が、外か内かの決定のアルゴリズムがちゃんと理解できません・・。
stroke-linecap線分の終端の形を指定する様子。値は、butt、round、squareで、buttは終端を描かない、roundは丸く、squareは四角く描画するとのこと。
stroke-linejoin線分の接合点の形を指定する様子。値はmiter、round、bevelで、miterはきれいな角を、roundは丸まった角を、bevelは平坦な角を描く様子。
stroke-opacity描画する線の透過度を指定する様子。0-1の間の任意の値かinheritを指定するとのこと。
transform座標系の方法の指定の様子。値は<transform-list><transform-ref>、noneのいずれかを取るとのこと。今回のデータで設定されているmatrix(1,0,0,1,0,0) は特に変換しないことを示している様子
font-familyfont関連の様ですが、今回は文字は扱っていないので、とりあえず無視しておきます。
font-size
font-weight
font-style
pathmoveto、lineto、curveto、closepathで複数の点を指定することにより、形の輪郭を描画するとのこと。
fill-ruleg要素の項目を参照。
d形のアウトラインを定義する。「moveto」「lineto」「curveto」「closepath」で指定。データに出てきている「M」「L」はそれぞれ、「moveto」「lineto」を意味する。
【参考】8.3 Path data - SVG Tiny 1.2
polylinebasic shape」として分類される要素の一つ。線分の組み合わせで閉じていない線の定義に使用。
fillg要素の項目を参照。
points線を構成する点の集合。座標はユーザー定義の座標系上の値。svg要素のviewBoxで定義するもののようです。X座標、Y座標を「,」で並べ、各点をスペースで区切る様子。


を見ていると、svg要素のviewBoxアトリビュートで指定した値が各グラフィック要素で指定する点の座標系になるように思えます。で、実際の表示についてはwidthアトリビュートなどと合わせて変換することになるのか・・?と言うのが、今の理解です。座標系については、もっとちゃんと読んで理解しないとだめな感じですね・・・。


ま、とりあえず次回から、ここまでの知識でSVGから内部データの変換を試みてみます。つづく。

【参考】
Scalable Vector Graphics (SVG) Tiny 1.2 Specification - W3C
Scalable Vector Graphics - Wikipedia






デル株式会社

QPaintEngineの呼ばれ方の詳細の確認 [Qt]

前回で大体何が来ているのかが見えてきたので、今回はちゃんとSVGのデータと呼ばれた関数を精査していきます。回りくどい気がしますが・・。

さて、テストに使うのは次のデータ。

10090700.png
ま、何でもいいんですが・・。


で、SVGファイルの中身を見ていきます。・・・ソースをそのまま見ると見にくいので、XMLのデータとして、ツリー上に表示させたいんですが、なんか、いいツールはないんですかね・・。そのままFirefoxで表示させると画像として解釈してくれるので、拡張子を「.xml」に変更してみましたが、ちゃんとSVGと判断してくれてしまったりします・・。

仕方が無いので、Mac上で表示できないものか探してみましたところ、たくさんある様ですが、どれがいいのか探すのが面倒ですね・・。他のサイトで調べてみたところ、AquaPathと言うソフトが良さげですので、試してみました。最初は使い方が良くわかりませんでしたが、何とかツリー表示できました。

*
さて、どういうふうにまとめましょうかね・・。SVG自体をよく(と言うか全然)知らないので、入っているものを全部挙げて行ってみます。

svgアトリビュートとして、width, height, vieBox, version, baseProfile等が設定されている。
tilteタイトル?
desc説明?
defs何か定義がある場合に記述?データには何も記載なし。
gアトリビュートとして、fill(none), stroke(black), vector-effect(non-scaling-stroke), stroke-width(1), fill-rule(evenodd), stroke-linecap(square), stroke-linejoin(bevel)が設定されている。
gアトリビュートとしてfill(#000000), fill-opacity(1), stroke(none), transform(matrix(1,0,0,1,0,0)), font-famiy, font-size(10), font-weight(400), font-style(normal)が設定されている。
pathアトリビュートとしてfill-rule(evenodd), d(M56.5,100.5 L57.5,100.5 L57.5,101.5 L56.5,101.5 L56.5,100.5)が設定されている。
gアトリビュートとして、fill(none), stroke(#000000), stroke-opacity(1), vector-effect(non-scaling-stroke), stroke-width(1), stroke-linecap(square), stroke-linejoin(bevel), transform(matrix(1,0,0,1,0,0), font-family, font-size(10), font-weight(400), font-style(normal)が設定されている。
gアトリビュートとしてfill, fill-opacity, stroke, transform, font-famiy, font-size, font-weight, font-styleが設定されている。
pathアトリビュートとしてfill-rule, dが設定されている。
gアトリビュートとして、fill(none), stroke(#000000), stroke-opacity(1), vector-effect(non-scaling-stroke), stroke-width(1), stroke-linecap(square), stroke-linejoin(bevel), transform(matrix(1,0,0,1,0,0), font-family, font-size(10), font-weight(400), font-style(normal)が設定されている。
polylineアトリビュートとしてfill, pointsが設定されている。pointsは2点を設定しているように見える。これが、後5個つづいている
gアトリビュートとしてfill, fill-opacity, stroke, transform, font-famiy, font-size, font-weight, font-styleが設定されている。
pathアトリビュートとしてfill-rule, dが設定されている。
gアトリビュートとして、fill, stroke, stroke-opacity, vector-effect, stroke-width, stroke-width, stroke-linecap, stroke-linejoin, transform, font-family, font-size, font-weight, font-styleが設定されている。
polylineアトリビュートとしてfill, pointsが設定されている。pointsは2点を設定しているように見える。これが後11個つづいている。
gアトリビュートとしてfill, fill-opacity, stroke, transform, font-famiy, font-size, font-weight, font-styleが設定されている。
pathアトリビュートとしてfill-rule, dが設定されている。
gアトリビュートとしてfill, fill-opacity, stroke, transform, font-famiy, font-size, font-weight, font-styleが設定されている。中身は空。
gアトリビュートとしてfill, fill-opacity, stroke, transform, font-famiy, font-size, font-weight, font-styleが設定されている。
pathアトリビュートとしてfill-rule, dが設定されている。
gアトリビュートとして、fill, stroke, stroke-opacity, vector-effect, stroke-width, stroke-width, stroke-linecap, stroke-linejoin, transform, font-family, font-size, font-weight, font-styleが設定されている。
polylineアトリビュートとしてfill, pointsが設定されている。pointsは2点を設定しているように見える。これが後3個つづいている。


以下、pathがあるパターンと、polylineがあるパターンと、何も無いパターンの繰り返しですね。「path」→「空」→「path」→「polyline」→「path」と言う感じでしょうか。

ログと見比べてみると、gに入るところで、metric()、updateState()が呼ばれ、pathでdrawPath()、polylineでdrawPolygon()が呼ばれてる感じですかね・・。metric()、updateState()の呼ばれ方がもう少し知りたい気がしますね・・。

drawPath()とdrawPolygon()の違いもよくわかりませんしねぇ・・。

う~ん、つづく。







ブログを作る(無料) powered by So-netブログ

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。