Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5609908
  • 博文数量: 922
  • 博客积分: 19333
  • 博客等级: 上将
  • 技术积分: 11226
  • 用 户 组: 普通用户
  • 注册时间: 2007-03-27 14:33
文章分类

全部博文(922)

文章存档

2023年(1)

2020年(2)

2019年(1)

2017年(1)

2016年(3)

2015年(10)

2014年(17)

2013年(49)

2012年(291)

2011年(266)

2010年(95)

2009年(54)

2008年(132)

分类:

2010-01-16 20:56:29

Cairo将成为Linux 2D 绘图的未来

内容:

1,什么是Cairo

2.理解cairo

3.常用函数

4.常用代码片断举例



注意:目前"有理论没有实践"^_^

=======================

1,什么是Cairo

=======================

cairo是一个支持多种输出的向量图形库。也就是说,cairo是种画图的工具库,他可以向多种设备上画图,比如: cairo可以输出到png,可以输出到pdf,可以输出到ps,可以输出到xlib,可以输出到XCB,可以输出到win32,以后还要输出到svg 


=======================

2.理解cairo

=======================

如果单纯的从代码上理解cairo,可能容易让人迷惑,所以,我们需要这么去理解cairo: 

cairo是一个画笔,你可以为这个画笔设置颜色、设置字体、设置alpha,也可以用这个画笔去画出任何图形。 就像画家作画一样,你可以用画布,也可以用宣纸,也可以用其他的材料。cairo这支画笔,可以在png,ps,pdf或者Xlib上画东西。 


例子如下: 

/*利用cairo绘制一个png图形*/

#include  

#include  

#include 

#include 

int main() 

{

FILE *file; 

file=fopen("a.png","w");//打开一个文件,写入,文件名为a.png 


cairo_t *cr; //声明一支画笔 

cr=cairo_create();//创建画笔 

cairo_set_target_png(cr,file,CAIRO_FORMAT_ARGB32,400,400);//设置画布,就是文件,a.png 


cairo_set_rgb_color(cr,0,1,0);//设置画笔颜色,也就是红,绿,蓝,这里设置成绿色。 

cairo_rectangle(cr,10,10,200,200);//画一个方块,位置从坐标(10,10)开始,宽200,高200 

cairo_fill(cr);//填充,使用的颜色当然是上面设置的颜色。 

cairo_move_to(cr,250,200);//将画笔移动到(250,200) 

cairo_select_font (cr, "DongWen--Song", 

CAIRO_FONT_SLANT_NORMAL, 

CAIRO_FONT_WEIGHT_NORMAL);//为cairo设置一个字体,字体名DongWen--Song,非斜体,非粗体。 

cairo_scale_font(cr,60);//缩放字体到60倍 

cairo_show_text(cr,"hello world");//画出一个串 

cairo_destroy(cr);//销毁画笔 

fclose(file);//关闭文件 


存成t1.c,然后使用下面的命令编译 

gcc -o t1 t1.c -lcairo -I/usr/include/cairo 


运行./t1,就生成了一个png图片文件,自己用工具打开看就可以了。


=======================

3.常用函数

=======================

操作画笔: 

创建画笔。

cairo_create();


增加引用计数1。 

cairo_reference();


减少引用计数1,如果返回0,所有的资源均被释放。

cairo_destroy();


保存当前cairo画笔。 

cairo_save();


恢复上一次保存的cairo画笔,也就是说必须跟cairo_save()配对。

cairo_restore();

------------

描绘函数:

将一个path用线把轮廓描出来(这个函数绘制的是“空心”的图)。

cairo_stoke(cr); 


将你前面画的东西(一个path)用指定颜色填充起来(这个函数绘制的是“实心”的图)。

cairo_fill(cr); 

--------------

绘制图形:

方块:

cairo_rectangle(cr,10,10,100,100); 


通过三点定义一道弧线:

cairo_curve_to(cr,x1,y1,x2,y2,x3,y3) 


顺时针画一个圆弧,圆心x,y,半径radius,起始弧度from,终止弧度to.

比如从0,M_PI(在math.h里),就可以是一个半圆(开口的不会补上直线)。从0到2*M_PI就是一个整圆。

cairo_arc(cr,x,y,radius,from,to); 


逆时针画一个圆弧.

cairo_arc_negative(cr,x,y,radius,from,to); 

----------------

字体相关:

/*暂时不用,所以具体略过*/

创建字体,返回cairo_font_t * 。

cairo_ft_font_create();

设置字体,接受参数cairo_t *和cairo_font_t * 。

cairo_set_font();

选择正体Nimbus Sans L,请根据你系统的fc-list自己选择一个字体.

cairo_select_font(cr,"Nimbus Sans L", 0,0); 

缩放字体,设置为60,虽然是scale,但是cairo内部实际上用的是字号

cairo_scale_font(cr,60); 

显示hehe,蓝色,60号,Nimbus Sans L字体

cairo_show_text(cr,"hehe"); 

----------------

绘制路径相关:

好像是用了path就不用使用restore防止画笔移动的时候绘制额外直线了,见例子。

cairo_new_path(cr); 

cairo_close_path(cr);


显示字体,类似cairo_show_text但可把字体当成path处理,所以,可以作出任何特效和变换。 

cairo_text_path(char * utf8); 

---------------

特殊图形绘制:

旋转函数,接受弧度做参数(用M_PI去除)

注意,使用时,它是影响全局的,也就是旋转了之后,后面画的一切都是旋转的.

所以旋转之前,做一下cairo_save,完成需要的旋转之后做一下cairo_restore能方便一点。

cairo_rotate(cr,angle); 


缩放图形,谨慎使用,注意使用cairo_save和cairo_restore,这个函数可以在不同的surface上使用。 

x指宽度缩放倍数,y指高度缩放的倍数。

cairo_scale(cr,x,y); 


相对坐标,就是以你当前的点为坐标的原点,然后在移动或者画到制定的位置。

cairo_rel_move_to(); 

cairo_rel_line_to(); 

cairo_rel_curve_to(); 


=======================

4.常用代码片断举例

=======================

绘制:

 

画一个方块(stroke):

cairo_rectangle(cr,10,10,100,100); 

cairo_set_line_width(cr,10) 

cairo_set_rgb_color(cr,0,0,1); 

cairo_stroke(cr); 


画一条斜线(从0,0到100,100)(stroke):

cairo_move_to(cr,0,0); 

cairo_line_to(cr,100,100); 

cairo_set_rgb_color(cr,1,0,0); 

cairo_stroke(cr); 


画一个空心圆圈(stroke):

cairo_arc(cr,100,100,40,0,2*M_PI); 

cairo_set_line_width(cr,3); 

cairo_set_rgb_color(cr,1,0,0); 

cairo_stroke(cr); 

 

一个红色的实心圆(fill): 

cairo_arc(cr,100,100,40,0,2*M_PI);//以100,100坐标为圆心画一个半径为40的圆(整圆)。 

cairo_set_rgb_color(cr,1,0,0);//红色 

cairo_fill(cr);//这时候得到的就是一个红色的实心圆。

----------------

写字:

/*将画笔移动到 60x60坐标。

注意:画文字的时候,这个坐标是文字左下角坐标,

如果你这时候移动到0,0坐标,其实你的文字将被画到400x400的画布之外。*/

cairo_move_to(cr,60,60);

//选择正体Nimbus Sans L,请根据你系统的fc-list自己选择一个字体 

cairo_select_font(cr,"Nimbus Sans L", 0,0); 

//设置为60,虽然是scale,但是cairo内部实际上用的是字号

cairo_scale_font(cr,60); 

//显示hehe,蓝色,60号,Nimbus Sans L字体 

cairo_show_text(cr,"hehe");


作一个空心字: 

//使用了textpath这是通过cairo_show_text()做不到的。

cairo_text_path("Hello"); 

cairo_set_line_width(cr,1); 

cairo_stroke(cr); 

 


----------------

相对坐标:

cairo_move_to(cr,10,10); 

//这时候点就在20,20上

cairo_rel_move_to(cr,10,10); 


----------------

保存画笔:

/*大体过程:

1)保存画笔cairo_save(cr);

2)使用画笔...导致画笔发生变化...

3)恢复画笔cairo_restore(cr); 

为保持完整性,代码有点多但不影响实质

*/

cairo_t * cr; 

cr = cairo_create(); //声明画笔并创建 

FILE *file; 

file=fopen("c.png","w"); 

//设置目标为一个png文件,大小为400x400,色彩32位。 

cairo_set_target_png(cr,file,CAIRO_FORMAT_ARGB32,400,400);


//$$$SAVE_1 保存画笔,这时候,画笔是干干净净的,没有任何操作。 

cairo_save(cr);


//画一个矩形框,蓝色 

cairo_rectangle(cr,10,10,200,200); 

cairo_set_rgb_color(cr,0,0,1); 

cairo_set_line_width(cr,4); 

cairo_stroke(cr); 


//写字 

cairo_move_to(cr,60,60);

cairo_select_font(cr,"Nimbus Sans L", 0,0); 

cairo_scale_font(cr,60); 

cairo_show_text(cr,"hehe"); 


//$$$恢复到 SAVE_1,这时候的画笔又是干干净净的了。

cairo_restore(cr); 

//SAVE_2 再保存一下,没准以后还会用到这个干净的画笔

cairo_save(cr);。 


//写字

cairo_move_to(cr,70,70);

cairo_set_rgb_color(cr,1,0,0); 

cairo_scale_font(cr,60); 

//如果上面不作restore,而又进行了scale_font,这时候,字体就是60x60倍了 

cairo_show_text(cr,"hehe");


//恢复到SAVE_2,这时候画笔仍然是初始状态。 

cairo_restore(cr); 



/*画了一个大半圆曲线。

如果,上面你没有恢复到画笔的初始状态,那么,这时候cairo画笔位于70,70,将画一条直线,捎带一个大半圆曲线,画线的方向是这样的,从当前坐标(70,70)到大半圆的开头,然后到大半圆结尾, 也就是顺时针方向。 

*/ 

cairo_set_rgb_color(cr,0,1,0); 

cairo_arc(cr,100,100,60,0, 1.5*M_PI); 

cairo_set_line_width(cr,3); 

cairo_set_line_cap(cr,CAIRO_LINE_CAP_ROUND); 

cairo_stroke(cr); 


cairo_destroy(cr); 

cairo_destroy(cr); 

fclose(file); 

--------------------

使用路径:

/*当前点在(70,70)那么在(100,100)处画圆会首先移动到该圆点,导致一条直线

*所以path可以解决这个问题见下面:

*/

cairo_move_to(70,70); 

cairo_new_path(cr); 

cairo_set_rgb_color(cr,0,1,0); 

cairo_arc(cr,100,100,60,0, 1.5*M_PI); 

cairo_set_line_width(cr,3); 

cairo_set_line_cap(cr,CAIRO_LINE_CAP_ROUND); 

cairo_stroke(cr); 

cairo_close_path(cr); 

----------------

旋转:

cairo_t *cr; 

cr = cairo_create(); 

cairo_set_target_.....; 

//顺时针旋转30度。如果是-M_PI/6,也就是逆时针旋转30度了。 

cairo_rotate(cr,M_PI/6);

cairo_rectangle(cr,10,10,100,100);//正方形 

cairo_set_rgb_color(cr,1,0,0); 

cairo_set_line_width(cr,10); 

cairo_stroke(cr); 


缩放:绘制一个平行四边形

cairo_t *cr; 

cr = cairo_create(); 

cairo_set_target_.....; 

//水平方向不变,垂直方向缩小为一半。 

cairo_scale(cr,1,0.5);

//顺时针旋转30度。如果是-M_PI/6,也就是逆时针旋转30度了。 

cairo_rotate(cr,M_PI/6);

cairo_rectangle(cr,10,10,100,100);//正方形,经过了scale之后,变成了长方形。 

cairo_set_rgb_color(cr,1,0,0); 

cairo_set_line_width(cr,10); 

/*首先,上下两条边的粗细变成了原来的一半,同时这个图形不是一个直角矩形,而是一个平行四边形。

因为: 

进行了scale之后,影响垂直方向的所有变换,都变成了原来的一半。所以,本来应该是每条边都旋转30度,现在 上下两条边都变成了旋转一半的度数,也就是15度。 

当然,如果你要旋转一个长方形,只要直接用cairo_rectangle画一个长方形就OK了 

注意,cairo_rotate只影响其后的内容,所以,不能在画完了在rotate。

*/

cairo_stroke(cr); 

=======================

参考:

http://hi.baidu.com/litaosmile/blog/item/68a89a8b092f4f1ac9fc7a66.html


阅读(10043) | 评论(2) | 转发(1) |
给主人留下些什么吧!~~

vaqeteart2010-04-09 21:11:17

我的邮箱quiet_heart000@126.com 可以给我发邮件。QQ我不经常上的。

chinaunix网友2010-04-09 13:52:39

您好,有几个问题想请教一下,能否加我qq178188336