第 6 章 cairo による図形の描画 81
6.11 ソースの設定
6.11.2 グラデーションパターンのソース
cairoで作成できるグラデーションパターンには次の2通りがあります.
• 線形のグラデーションパターン
• 放射状のグラデーションパターン
グラデーションパターンの作成とグラデーションパターンの描画は次の手順で行います.
1. パターンの大きさの設定 2. グラデーションパターンの設定 3. パターンをソースに設定 4. パスを描画
手順1,2によって作成したパターンをソースとして設定するには,関数cairo set sourceを使用します.
v o i d c a i r o _ s e t _ s o u r c e (c a i r o _ t * cr , c a i r o _ p a t t e r n _ t * s o u r c e ) ; 手順1,2については,このあとグラデーションパターンごとに説明していきます.
線形のグラデーションパターン
線形のグラデーションパターンを作成するには,まず関数cairo pattern create linearによって,グラデーションパターンを 作成する矩形の左上と右下の座標を指定します.
c a i r o _ p a t t e r n _ t* c a i r o _ p a t t e r n _ c r e a t e _ l i n e a r (d o u b l e x0 , d o u b l e y0 , d o u b l e x1 , d o u b l e y 1 ) ;
パターン領域を作成する際の座標と,パスを作成する際の座標は,同じ座標系となっています.したがって,パターンを作成 した位置と描画する位置がずれている場合には,意図したように正しく描画されません.そのため,パターンを作成する際に は,描画する領域や描画の仕方を考慮して,パターンを作成する位置と大きさを指定しなければいけません.ただし,6.12節
(p.103)で紹介するcairo matrix t型の変換行列を用いて,作成したパターンを変換(実際には描画領域を変換)することに よって,作成したパターンの位置や大きさにとらわれず,パターンを描画することが可能です.
パターン領域を作成したら,次は具体的にどのようなグラデーションにするのかを,次の関数を使用して設定します.
v o i d c a i r o _ p a t t e r n _ a d d _ c o l o r _ s t o p _ r g b (c a i r o _ p a t t e r n _ t * p a t t e r n ,
d o u b l e o f f s e t ,
d o u b l e red ,
d o u b l e g r e e n ,
d o u b l e b l u e ) ;
v o i d c a i r o _ p a t t e r n _ a d d _ c o l o r _ s t o p _ r g b a (c a i r o _ p a t t e r n _ t * p a t t e r n ,
d o u b l e o f f s e t ,
d o u b l e red ,
d o u b l e g r e e n ,
d o u b l e b l u e ,
d o u b l e a l p h a ) ;
それぞれの関数の第3から第5引数には,グラデーションパターンに使用するRGB情報を0から1の範囲で指定します.第 2引数は,その色を作成したパターン領域のどの位置に配置するかを指定する値で,0から1までの範囲で指定します.
図6.11を例に,線形グラデーションパターンの作成方法について具体的に説明していきます.ソースコードは,ソース6–9 になります.この例では,次に示す3種類のグラデーションパターンを作成しています.
• 水平方向のグラデーション(2つの色の混合)
• 垂直方向のグラデーション(アルファ値を線形に変化)
• 斜め方向のグラデーション
水平方向のグラデーション グラデーションの方向は,関数cairo pattern create linearに与える座標パラメータで決定しま す.水平方向のグラデーションを作成したい場合には,水平方向の座標をパターンの大きさだけ変化させます.一方,垂直方向 の座標は変化量を0に,すなわち同じ値を与えます.
ソース6–9のpattern1では16行目でパターン領域を決定していますが,水平方向は50.0から350.0まで増加し,垂直方向
の座標は同じ値(50.0)になっています.
次に17–18行目で、RGB値を変化させたグラデーションパターンを設定しています.そして作成したパターンを,19行目で
ソースに設定して,20行目で同じ幅の矩形パスを作成して,21行目で描画しています.
垂直方向のグラデーション 次に、垂直方向のグラデーション(pattern2)を作成する場合には,水平方向のグラデーションの 場合とは反対に,垂直方向の座標を変化させ(120.0から170.0),水平方向の座標に同じ値(50.0)を与えます(23行目).
さ ら に ,こ の 例 で は RGB 値 は 変 化 さ せ ず ,ア ル フ ァ 値 を 1 か ら 0 に グ ラ デ ー シ ョ ン さ せ た パ タ ー ン を ,関 数 cairo pattern add color stop rgbaで作成して(24–25行目),描画しています(26–28行目).
斜 め 方 向 の グ ラ デ ー シ ョ ン 最 後 に 斜 め 方 向 の グ ラ デ ー シ ョ ン パ タ ー ン(pattern3)に つ い て 説 明 し ま す .関 数 cairo pattern create linear に与えるパラメータを垂直方向も水平方向も変化させることで(30行目),2つの座標(x0,
y0)–(x1,y1)を結んだ方向に,グラデーションが生成されます.さらにpattern3では,パターンの位置と大きさが上記の2つ
のグラデーションの場合と異なっています。pattern1とpattern2では,作成されたパターンと描画されるパスが一致していま
した。pattern3では,グラデーションパターンを(0,0)–(50,50)の領域で作成して,実際に描画する領域は位置も大きさも変
化させています.
パターンを異なる位置に描画したい 関数cairo translateを使用して,パスを作成する座標がパターンを作成した位置と一致 するように,座標系を平行移動します(36行目).37行目でパスを作成する際には,パターンを作成した位置とパスの始点が一 致していることがわかると思います.
パターンより大きな描画領域 描画領域がパターンよりも大きい場合に,パターン外の領域をどう描画するかは,関数 cairo pattern set extendで設定します.
v o i d c a i r o _ p a t t e r n _ s e t _ e x t e n d (c a i r o _ p a t t e r n _ t * p a t t e r n , c a i r o _ e x t e n d _ t e x t e n d ) ;
描画の方法には,表6.4に示すcairo extend t列挙体で定義された4種類の方法があり,初期状態ではCAIRO EXTEND NONE が設定されています.この例では,35行目でCAIRO EXTEND REPEATが設定されているため,パターンが繰り返し描画 されます.
表6.4 パターン外の領域の描画設定
値 説明
CAIRO EXTEND NONE 何も描画しない.
CAIRO EXTEND REPEAT パターンをタイル状に繰り返し描画する.
CAIRO EXTEND REFLECT パターンを折り返してタイル状に描画する.
CAIRO EXTEND PAD パターンの端の値で描画する.
図6.11 線形グラデーションパターン
ソース6–9 線形グラデーションパターン: cairo pattern linear.c(一部を抜粋)
1 # i n c l u d e <g t k / g t k . h >
2
3 g b o o l e a n
4 c b _ e x p o s e _ e v e n t (G t k W i d g e t * w i d g e t ,
5 G d k E v e n t E x p o s e * e v e n t ,
6 g p o i n t e r u s e r _ d a t a )
7 {
8 G d k W i n d o w * d r a w a b l e = w i d g e t - >w i n d o w ;
9 c a i r o _ t * c r ;
10 c a i r o _ p a t t e r n _ t * p a t t e r n 1 ;
11 c a i r o _ p a t t e r n _ t * p a t t e r n 2 ;
12 c a i r o _ p a t t e r n _ t * p a t t e r n 3 ;
13
14 c r = g d k _ c a i r o _ c r e a t e ( d r a w a b l e ) ;
15
16 p a t t e r n 1 = c a i r o _ p a t t e r n _ c r e a t e _ l i n e a r ( 5 0 . 0 , 5 0 . 0 , 3 5 0 . 0 , 5 0 . 0 ) ;
17 c a i r o _ p a t t e r n _ a d d _ c o l o r _ s t o p _ r g b ( p a t t e r n 1 , 0 . 0 , 1 . 0 , 0 . 0 , 0 . 0 ) ;
18 c a i r o _ p a t t e r n _ a d d _ c o l o r _ s t o p _ r g b ( p a t t e r n 1 , 1 . 0 , 1 . 0 , 1 . 0 , 1 . 0 ) ;
19 c a i r o _ s e t _ s o u r c e ( cr , p a t t e r n 1 ) ;
20 c a i r o _ r e c t a n g l e ( cr , 5 0 . 0 , 5 0 . 0 , 3 0 0 . 0 , 5 0 . 0 ) ;
21 c a i r o _ f i l l ( c r ) ;
22
23 p a t t e r n 2 = c a i r o _ p a t t e r n _ c r e a t e _ l i n e a r ( 5 0 . 0 , 1 2 0 . 0 , 5 0 . 0 , 1 7 0 . 0 ) ;
24 c a i r o _ p a t t e r n _ a d d _ c o l o r _ s t o p _ r g b a ( p a t t e r n 2 , 0 . 0 , 0 . 0 , 1 . 0 , 0 . 0 , 1 . 0 ) ;
25 c a i r o _ p a t t e r n _ a d d _ c o l o r _ s t o p _ r g b a ( p a t t e r n 2 , 1 . 0 , 0 . 0 , 1 . 0 , 0 . 0 , 0 . 0 ) ;
26 c a i r o _ s e t _ s o u r c e ( cr , p a t t e r n 2 ) ;
27 c a i r o _ r e c t a n g l e ( cr , 5 0 . 0 , 1 2 0 . 0 , 3 0 0 . 0 , 5 0 . 0 ) ;
28 c a i r o _ f i l l ( c r ) ;
29
30 p a t t e r n 3 = c a i r o _ p a t t e r n _ c r e a t e _ l i n e a r (0 , 0 . 0 , 5 0 . 0 , 5 0 . 0 ) ;
31 c a i r o _ p a t t e r n _ a d d _ c o l o r _ s t o p _ r g b ( p a t t e r n 3 , 0 . 0 , 0 . 0 , 0 . 0 , 0 . 0 ) ;
32 c a i r o _ p a t t e r n _ a d d _ c o l o r _ s t o p _ r g b ( p a t t e r n 3 , 0 . 5 , 1 . 0 , 1 . 0 , 0 . 0 ) ;
33 c a i r o _ p a t t e r n _ a d d _ c o l o r _ s t o p _ r g b ( p a t t e r n 3 , 1 . 0 , 0 . 0 , 0 . 0 , 0 . 0 ) ;
34 c a i r o _ p a t t e r n _ s e t _ e x t e n d ( p a t t e r n 3 , C A I R O _ E X T E N D _ R E P E A T ) ;
35 c a i r o _ s e t _ s o u r c e ( cr , p a t t e r n 3 ) ;
36 c a i r o _ t r a n s l a t e ( cr , 5 0 . 0 , 1 9 0 . 0 ) ;
37 c a i r o _ r e c t a n g l e ( cr , 0 . 0 , 0 . 0 , 3 0 0 . 0 , 7 0 . 0 ) ;
38 c a i r o _ f i l l ( c r ) ;
39
40 c a i r o _ p a t t e r n _ d e s t r o y ( p a t t e r n 1 ) ;
41 c a i r o _ p a t t e r n _ d e s t r o y ( p a t t e r n 2 ) ;
42 c a i r o _ p a t t e r n _ d e s t r o y ( p a t t e r n 3 ) ;
43 c a i r o _ d e s t r o y ( c r ) ;
44
45 r e t u r n F A L S E ;
46 }
放射状のグラデーションパターン
放射状のグラデーションパターンを作成するには,まず関数cairo pattern create radialによって,グラデーションパターン を作成する2つの円領域を指定します.
c a i r o _ p a t t e r n _ t* c a i r o _ p a t t e r n _ c r e a t e _ r a d i a l (d o u b l e cx0 , d o u b l e cy0 , d o u b l e r a d i u s 0 ,
d o u b l e cx1 , d o u b l e cy1 , d o u b l e r a d i u s 1 ) ;
第1引数から第3引数で指定する円はパターンの内側の円を表し,第4引数から第6引数で指定する円は外側の円を表しま す.そして,内側の円の円弧から外側の円の円弧に向かって,放射状にグラデーションが生成されます.内側の円の内部は,関 数cairo pattern add color stop rgbで設定された内側の円に一番近い色で描画されます.
図6.12に放射状のグラデーションパターンで円を描画した例を,そのソースコードをソース6–10に示します.
ソース6–10 放射状グラデーションパターン: cairo pattern radial.c(一部を抜粋)
1 # i n c l u d e <g t k / g t k . h >
2 # i n c l u d e <m a t h . h >
3
4 g b o o l e a n
5 c b _ e x p o s e _ e v e n t (G t k W i d g e t * w i d g e t ,
6 G d k E v e n t E x p o s e * e v e n t ,
7 g p o i n t e r u s e r _ d a t a )
8 {
9 G d k W i n d o w * d r a w a b l e = w i d g e t - >w i n d o w ;
10 c a i r o _ t * c r ;
11 c a i r o _ p a t t e r n _ t * p a t t e r n ;
12
13 c r = g d k _ c a i r o _ c r e a t e ( d r a w a b l e ) ;
14
15 p a t t e r n = c a i r o _ p a t t e r n _ c r e a t e _ r a d i a l ( 1 6 0 . 0 , 1 6 0 . 0 , 3 0 . 0 ,
16 2 0 0 . 0 , 2 0 0 . 0 , 2 0 0 . 0 ) ;
図6.12 放射状グラデーションパターン
17 c a i r o _ p a t t e r n _ a d d _ c o l o r _ s t o p _ r g b ( p a t t e r n , 0 . 5 , 1 . 0 , 0 . 0 , 0 . 0 ) ;
18 c a i r o _ p a t t e r n _ a d d _ c o l o r _ s t o p _ r g b ( p a t t e r n , 1 . 0 , 1 . 0 , 1 . 0 , 1 . 0 ) ;
19 c a i r o _ s e t _ s o u r c e ( cr , p a t t e r n ) ;
20 c a i r o _ a r c ( cr , 2 0 0 . 0 , 2 0 0 . 0 , 1 6 0 . 0 , 0 . 0 , 2 . 0 * M _ P I ) ;
21 c a i r o _ f i l l ( c r ) ;
22
23 c a i r o _ p a t t e r n _ d e s t r o y ( p a t t e r n ) ;
24 c a i r o _ d e s t r o y ( c r ) ;
25
26 r e t u r n F A L S E ;
27 }