Cairo 图形指南 (11) —— 图像

在这一篇里,要讲述图像的处理。先是演示如何在 GTK+ 窗口中显示一幅图像,然后再制造一些特效。

Posted by LiYanrui Apr 09, 2010 04:39:06 AM


Cairo 图形指南 (10) —— 文本

本篇讲述如何处理文本。

Posted by LiYanrui Apr 07, 2010 10:24:04 PM


Cairo 图形指南 (9) —— 变换

这一篇讲述变换(Transformation) 仿射变换是由一些线性变换与平移构成的。线性变换可以写为单个矩阵的形式。旋转是让一个刚体绕一点运动的变换。缩放变换是让物体的形状扩大与减小,并且在各个方向上的缩放因子都相同。平移变换将每个点沿着指定的方向移动常量距离。错切对于给定轴线,沿垂直于它的方向对物体进行移动的变换,并且在轴线的一侧的移动距离大于另一侧。

——上述内容来自维基百科全书

Posted by LiYanrui Apr 06, 2010 11:12:45 PM


Cairo 图形指南 (8) —— 裁剪与遮蔽

在这一篇中讲述裁剪(Clipping)与遮蔽(Masking)。

Posted by LiYanrui Apr 05, 2010 10:52:21 PM


vala, vala!

这 1 年多以来,玩 ConTeXt 把我的业余甚至部分主要时间都变成了“暗时间”。昨晚看到 gedit 小版本号更新,有点奇怪这个东西每次都更新了啥,然后就去 http://projects.gnome.org/ 去查看它的更新记录,发现很多次版本升级只是做了一些微小的 bug 修正以及界面本地化,心里对此很不以为然。正在对 gnome 每次都打太极拳感到郁闷时,在那个页面上发现了 vala。

Posted by LiYanrui Dec 24, 2009 05:06:00 PM


Emacs 与 C/C++ 代码自动补全

基于 Emacs 的 company 模式并配合 semantic 文法分析器,实现 Emacs 的 C/C++ 代码自动补全。

Posted by LiYanrui Aug 29, 2009 10:05:19 AM


创建临时文件

经常在 /tmp 目录下看到许多带有奇怪编号的文件名,比如 XXX_2znzjy、XXX__6yQ1id 之类,却从未想过它们是怎么来的。

近来我一直在搞投机取巧的事情,就是用自己写的 C 程序直接调用 qhull 程序去生成三维点集的凸包。要达到这一目的,我首先需要解决我的程序与 qhull 程序之间的数据交换问题。在不触及 qhull 源代码的条件下,采用文件进行数据传递是我能找到的最好的方法(如果你有更好的,告诉我吧)。

选择使用文件进行数据交换之后,我想做的更加稳妥和专业一些,这时 /tmp 目录冲我暧昧地笑了一下。打开 APUE(版本号的默认值是“第 2 版”),在 5.13 节可以找到有关 ISO C 和 SUS 标准中用于生成临时文件的函数的详细阐述。话说,这本 APUE 自打我从图书馆借过来后,翻看了前两章之后,它就一直做充当我的枕头的工作,现在它总算又重新找回我的宠幸。

我比较喜欢 ISO C 定义的 tmpnam ( ) 函数,因为它可以生成一个唯一的文件名,我可以利用这个文件名打开文件进行各种操作。但是 "man -S 3 tmpnam",却看到:

BUGS
       Never use this function.  Use mkstemp(3) or tmpfile(3) instead.

tmpfile ( ) 这个函数也很不错,不过不知道怎么获取它所创建的文件名。于是,我只能将希望寄托给 mkstemp () 了。

mkstemp ( ) 的确不辱使命,它可以创建临时文件,并且还能告诉我文件名。但是,它也不完美,因为它的容貌不讨人喜欢。首先,要使用它,需 #include <stdlib.h>,并且它不算是 c99 标准定义的函数,所以当你采用 c99 标准去调用 gcc 编译那些使用了 mkstemp ( ) 函数的 C 文件时,就会遇到“未找到 mkstemp ( ) 函数声明”的警告:

warning: implicit declaration of function ‘mkstemp‘

要消除这个警告,需要在 C 文件的头部添加:

#define _XOPEN_SOURCE 500

如果是比较新的 glibc 版本,那么讲 _XOPEN_SOURCE 的值定义成 600 或 700 都可以。这些事情,都是 APUE 和 man 告诉我的。如果不想把代码搞的太难看,也可以在 gcc 的编译命令中添加 "-D_XOPEN_SOURCE" 宏选项来实现。

mkstemp () 函数接受一个字符串变量,返回文件描述符,如果返回值为 -1 表明创建文件失败。调用它的简单示例代码如下:

        char fn[128] = "/tmp/testXXXXXX";
        int fd;

        if ((fd = mkstemp (fn)) == -1)
                exit (-1);

注意,mkstemp ( ) 函数所接受的参数是字符串变量,而非字符串常量,并且该字符串变量的最后 6 位必须是 “XXXXXX”,也就是说这个字符串变量实际上是一个字符串模板,mkstemp ( ) 函数内部会将这个字符串的 "XXXXXX" 部分进行替换,并将替换后字符串作为临时文件名。

还要注意,mkstemp ( ) 函数返回的不是文件指针,而是文件描述符(参考 APUE 3.2 节)。如果想将文件描述符转换为我们熟悉的 C 语言文件指针类型,可以使用 fdopen ( ) 函数,例如:

        FILE *fp;
        char fn[128] = "/tmp/testXXXXXX";
        int fd;

        if ((fd = mkstemp (fn)) == -1)
                exit (-1);
        if ((fp = fdopen (fd)) == NULL)
                exit (-1);

在拥有文件指针的情况下,我们就可以“很自由地”(相对于动态语言,一点都不自由)利用 ISO C 定义的文件操作函数进行文件读写操作了。

最后要注意的就是,mkstemp ( ) 不会对创建的临时文件进行删除。如果临时文件位于 /tmp 目录,那么系统重新启动时一般会自动清理。如果想在程序中删除不再使用的临时文件,可以使用 Unix 系统调用 unlink ( ) 函数来实现。unlink ( ) 函数的用法可以查阅 man 的第 2 节,即 "man -S 2 unlink"。

Posted by LiYanrui Aug 22, 2009 04:02:45 PM


开始全面接触 GTK+

说来也惭愧,2 年前我就打算好好学习 GTK+,期间断断续续的进行了几次,每次都是浅尝辄止。这主要是因为在我们的项目里,我不负责界面设计,因此也没有足够的动力。另外,我将大把的时间都用来折腾 TeX 上了,从 PDFTeX、XeTeX 到 LuaTeX,从 LaTeX 到 ConTeXt,又从 ConTeXt MkII 到 ConTeXt MkIV。现在之所以决定认真的搞定 GTK+,是因为有些鲠骨在咽般的因素在刺激我。

Posted by LiYanrui Apr 30, 2009 01:29:19 AM