第 6 章 cairo による図形の描画 81
6.6 線分の属性と描画サンプル
cairoでは,線分のパスに対して次の属性を設定できます.
• 線分の太さ
• 線端の種類
• 接続の種類
• 線分の種類
以下では,線分の属性を変えて描画したプログラム例と合わせて説明します.
6.6.1 線分の太さ
線分の太さは,関数cairo set line widthで変更できます.
v o i d c a i r o _ s e t _ l i n e _ w i d t h (c a i r o _ t * cr , d o u b l e w i d t h ) ; 線分の太さは,標準では2.0画素に設定されています.
6.6.2 線端の種類
線端の種類には,表6.2に示したcairo line cap t列挙体で定義された3種類があります.描画される線端は図6.2のように なります.
表6.2 線端の種類
値 説明
CAIRO LINE CAP BUTT 始点と終点をそのまま描画する.
CAIRO LINE CAP ROUND 線端を丸く描画する.
CAIRO LINE CAP SQUARE 線端を線幅の半分だけはみだして描画する.
図6.2に示したように,CAIRO LINE CAP ROUNDとCAIRO LINE CAP SQUAREを設定した場合は,線分の両端は 指定した座標よりも線の太さの半分のサイズだけはみ出します.これらの値を設定するためには,関数cairo set line capを使 用します.
v o i d c a i r o _ s e t _ l i n e _ c a p (c a i r o _ t * cr , c a i r o _ l i n e _ c a p _ t l i n e _ c a p ) ;
ソース6–1に,図6.2のソースコードを示します.このソース6–1では描画する線分の色を,関数cairo set source rgbを 使って設定しています.線分の色も線分の属性だと思われるかもしれませんが,色情報はソースの属性です.ソースは標準では
図6.2 線端の種類
RGBの単色(初期状態では黒)に設定されています.cairoではソースとして,単色だけでなく,グラデーション等のパター ンや画像等も設定することができます.このためcairoでは,GDKではできないような柔軟な描画を簡単に実現できるように なっています.
ソース6–1 線端の種類: cairo-line-cap.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 d o u b l e l i n e _ w i d t h = 3 0 . 0 ;
11
12 c r = g d k _ c a i r o _ c r e a t e ( d r a w a b l e ) ;
13
14 c a i r o _ s e t _ l i n e _ w i d t h ( cr , l i n e _ w i d t h ) ;
15
16 c a i r o _ s e t _ s o u r c e _ r g b ( cr , 1 . 0 , 0 . 0 , 0 . 0 ) ;
17 c a i r o _ s e t _ l i n e _ c a p ( cr , C A I R O _ L I N E _ C A P _ B U T T ) ;
18 c a i r o _ m o v e _ t o ( cr , 5 0 . 0 , 5 0 . 0 ) ;
19 c a i r o _ l i n e _ t o ( cr , 3 5 0 . 0 , 5 0 . 0 ) ;
20 c a i r o _ s t r o k e ( c r ) ;
21
22 c a i r o _ s e t _ s o u r c e _ r g b ( cr , 0 . 0 , 1 . 0 , 0 . 0 ) ;
23 c a i r o _ s e t _ l i n e _ c a p ( cr , C A I R O _ L I N E _ C A P _ R O U N D ) ;
24 c a i r o _ m o v e _ t o ( cr , 5 0 . 0 , 1 0 0 . 0 ) ;
25 c a i r o _ l i n e _ t o ( cr , 3 5 0 . 0 , 1 0 0 . 0 ) ;
26 c a i r o _ s t r o k e ( c r ) ;
27
28 c a i r o _ s e t _ s o u r c e _ r g b ( cr , 0 . 0 , 0 . 0 , 1 . 0 ) ;
29 c a i r o _ s e t _ l i n e _ c a p ( cr , C A I R O _ L I N E _ C A P _ S Q U A R E ) ;
30 c a i r o _ m o v e _ t o ( cr , 5 0 . 0 , 1 5 0 . 0 ) ;
31 c a i r o _ l i n e _ t o ( cr , 3 5 0 . 0 , 1 5 0 . 0 ) ;
32 c a i r o _ s t r o k e ( c r ) ;
33
34 c a i r o _ s e t _ l i n e _ w i d t h ( cr , 1 ) ;
35 c a i r o _ s e t _ s o u r c e _ r g b ( cr , 0 . 0 , 0 . 0 , 0 . 0 ) ;
36
37 c a i r o _ m o v e _ t o ( cr , 5 0 . 0 , 1 5 . 0 ) ;
38 c a i r o _ l i n e _ t o ( cr , 5 0 . 0 , 1 8 5 . 0 ) ;
39 c a i r o _ s t r o k e ( c r ) ;
40
41 c a i r o _ m o v e _ t o ( cr , 5 0 . 0 - l i n e _ w i d t h / 2 . 0 , 1 5 . 0 ) ;
42 c a i r o _ l i n e _ t o ( cr , 5 0 . 0 - l i n e _ w i d t h / 2 . 0 , 1 8 5 . 0 ) ;
43 c a i r o _ s t r o k e ( c r ) ;
44
45 c a i r o _ d e s t r o y ( c r ) ;
46
47 r e t u r n F A L S E ;
48 }
49 50 i n t
51 m a i n (i n t ar g c , c h a r * a r g v [ ] )
52 {
54 G t k W i d g e t * c a n v a s ;
55
56 g t k _ i n i t ( & a r g c , & a r g v ) ;
57
58 w i n d o w = g t k _ w i n d o w _ n e w ( G T K _ W I N D O W _ T O P L E V E L ) ;
59 g t k _ w i n d o w _ s e t _ t i t l e ( G T K _ W I N D O W ( w i n d o w ) , " c a i r o _ l i n e _ c a p S a m p l e " ) ;
60 g t k _ w i d g e t _ s e t _ s i z e _ r e q u e s t ( w i n d o w , 4 0 0 , 2 0 0 ) ;
61 g _ s i g n a l _ c o n n e c t ( G _ O B J E C T ( w i n d o w ) , " d e s t r o y " ,
62 G _ C A L L B A C K ( g t k _ m a i n _ q u i t ) , N U L L ) ;
63
64 c a n v a s = g t k _ d r a w i n g _ a r e a _ n e w ( ) ;
65 g t k _ c o n t a i n e r _ a d d ( G T K _ C O N T A I N E R ( w i n d o w ) , c a n v a s ) ;
66 g _ s i g n a l _ c o n n e c t ( G _ O B J E C T ( c a n v a s ) , " e x p o s e - e v e n t " ,
67 G _ C A L L B A C K ( c b _ e x p o s e _ e v e n t ) , N U L L ) ;
68
69 g t k _ w i d g e t _ s h o w _ a l l ( w i n d o w ) ;
70 g t k _ m a i n ( ) ;
71
72 r e t u r n 0 ;
73 }
6.6.3 接続の種類
線分と線分をつなぐ接続の種類には,表6.3に示したcairo line join t列挙体で定義された3種類があります.実際に描画し た例は図6.3のようになります.
表6.3 接続の種類
値 説明
CAIRO LINE JOIN MITER 接続部分をとがらせる.
CAIRO LINE JOIN ROUND 接続部分を丸くする.
CAIRO LINE JOIN BEVEL 接続部分のとがった部分をカットしたような形にする.
図6.3 接続の種類
これらの値を設定するためには関数cairo set line joinを使用します.
v o i d c a i r o _ s e t _ l i n e _ j o i n (c a i r o _ t * cr , c a i r o _ l i n e _ j o i n _ t l i n e _ j o i n ) ;
ソース6–2に,図6.3のソースコードを示します.関数cairo set line joinの使い方に関しては説明する必要はないでしょう.
このソースコード中では,6.12節(p.103)で説明する関数cairo translateを使用しています.この関数は,パスを作成する 際の座標系原点を,この関数で指定した値だけ平行移動させます.22行目から始まるforループ中で同じ座標を指定して3つ の折れ線を描画していますが,ループの最後の行で関数cairo translateを呼び出しているので,横方向に平行移動した位置に それぞれ折れ線が描画されています.
ソース6–2 接続の種類: cairo line join.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 _ l i n e _ j o i n _ t j o i n _ t y p e [ ] = { C A I R O _ L I N E _ J O I N _ M I T E R ,
11 C A I R O _ L I N E _ J O I N _ R O U N D ,
12 C A I R O _ L I N E _ J O I N _ B E V E L } ;
13 d o u b l e c o l o r [ 3 ] [ 3 ] = { { 1 . 0 , 0 . 0 , 0 . 0 } ,
14 { 0 . 0 , 1 . 0 , 0 . 0 } ,
15 { 0 . 0 , 0 . 0 , 1 . 0 } } ;
16 i n t n ;
17
18 c r = g d k _ c a i r o _ c r e a t e ( d r a w a b l e ) ;
19
20 c a i r o _ s e t _ l i n e _ w i d t h ( cr , 3 0 . 0 ) ;
21
22 f o r ( n = 0 ; n < 3 ; n + + )
23 {
24 c a i r o _ s e t _ s o u r c e _ r g b ( cr , c o l o r [ n ] [ 0 ] , c o l o r [ n ] [ 1 ] , c o l o r [ n ] [ 2 ] ) ;
25 c a i r o _ s e t _ l i n e _ j o i n ( cr , j o i n _ t y p e [ n ] ) ;
26 c a i r o _ m o v e _ t o ( cr , 2 5 . 0 , 1 5 0 . 0 ) ;
27 c a i r o _ l i n e _ t o ( cr , 2 5 . 0 , 5 0 . 0 ) ;
28 c a i r o _ l i n e _ t o ( cr , 1 2 5 . 0 , 1 2 5 . 0 ) ;
29 c a i r o _ s t r o k e ( c r ) ;
30 c a i r o _ t r a n s l a t e ( cr , 1 3 0 . 0 , 0 . 0 ) ;
31 }
32 c a i r o _ d e s t r o y ( c r ) ;
33
34 r e t u r n F A L S E ;
35 }
6.6.4 線分の種類
線分は,関数cairo set dashを使用してそのパターンを設定することで,破線や点線等として描画することができます.
v o i d c a i r o _ s e t _ d a s h (c a i r o _ t * cr , c o n s t d o u b l e * d a s h e s ,
i n t n u m _ d a s h e s ,
d o u b l e o f f s e t ) ;
この関数を使用して破線と鎖線を描画した例を図6.4に示します.ソースコードはソース6–3です.
図6.4 線分の種類
関数cairo set dashの使い方
図6.4の例を用いて,関数cairo set dashの引数の意味と,設定方法を説明します.
まず,破線のパターンを設定するのが第2引数です.第2引数はdouble型の配列で,この配列には,前景の長さと背景の長 さを交互に格納します.
図6.4の一番上の破線では,ソース6–3の10行目でパターンを設定しており,前景を40,背景を5の間隔で繰り返す破線と なっています.また真ん中の鎖線では,前景40,背景5,前景5,背景5というパターンの鎖線を設定しています.
第3引数は,第2引数で与える配列の要素数です.
第4引数では,パターンの開始位置を設定します.つまり,正の値を与えると,線分のパターンを左にシフトし,負の値を与 えると,反対に線分のパターンを右にシフトしたような結果が得られます.図6.4の一番下の鎖線では真ん中の鎖線と同じパ ターンを描画していますが,第4引数を−5としているので,真ん中の鎖線を右にシフトしたように描画されていることがわか
ると思います.
ソース6–3 線分の種類: cairo line dash.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 d o u b l e d a s h _ p a t t e r n 1 [ ] = { 4 0 . 0 , 5 . 0 } ;
11 d o u b l e d a s h _ p a t t e r n 2 [ ] = { 4 0 . 0 , 5 . 0 , 5 . 0 , 5 . 0 } ;
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 c a i r o _ s e t _ l i n e _ w i d t h ( cr , 5 . 0 ) ;
16
17 c a i r o _ s e t _ s o u r c e _ r g b ( cr , 1 . 0 , 0 . 0 , 0 . 0 ) ;
18 c a i r o _ s e t _ d a s h ( cr , d a s h _ p a t t e r n 1 ,
19 s i z e o f ( d a s h _ p a t t e r n 1 ) / s i z e o f ( d a s h _ p a t t e r n 1 [ 0 ] ) ,
20 0 ) ;
21 c a i r o _ m o v e _ t o ( cr , 5 0 . 0 , 5 0 . 0 ) ;
22 c a i r o _ l i n e _ t o ( cr , 3 5 0 . 0 , 5 0 . 0 ) ;
23 c a i r o _ s t r o k e ( c r ) ;
24
25 c a i r o _ s e t _ s o u r c e _ r g b ( cr , 0 . 0 , 1 . 0 , 0 . 0 ) ;
26 c a i r o _ s e t _ d a s h ( cr , d a s h _ p a t t e r n 2 ,
27 s i z e o f ( d a s h _ p a t t e r n 2 ) / s i z e o f ( d a s h _ p a t t e r n 2 [ 0 ] ) ,
28 0 ) ;
29 c a i r o _ m o v e _ t o ( cr , 5 0 . 0 , 1 0 0 . 0 ) ;
30 c a i r o _ l i n e _ t o ( cr , 3 5 0 . 0 , 1 0 0 . 0 ) ;
31 c a i r o _ s t r o k e ( c r ) ;
32
33 c a i r o _ s e t _ s o u r c e _ r g b ( cr , 0 . 0 , 0 . 0 , 1 . 0 ) ;
34 c a i r o _ s e t _ d a s h ( cr , d a s h _ p a t t e r n 2 ,
35 s i z e o f ( d a s h _ p a t t e r n 2 ) / s i z e o f ( d a s h _ p a t t e r n 2 [ 0 ] ) ,
36 -5);
37 c a i r o _ m o v e _ t o ( cr , 5 0 . 0 , 1 5 0 . 0 ) ;
38 c a i r o _ l i n e _ t o ( cr , 3 5 0 . 0 , 1 5 0 . 0 ) ;
39 c a i r o _ s t r o k e ( c r ) ;
40
41 c a i r o _ d e s t r o y ( c r ) ;
42
43 r e t u r n F A L S E ;
44 }