cornsea

在nanox中使用cairo来渲染字体

nanox的字体处理功能用起来不是很方便,而cairo有比较强大的字体渲染和画图功能,因此这次尝试将两者结合。

将两者结合时,唯一需要注意的问题是像素的格式区别:
nanox的各颜色通道顺序是: RGBA  R是低地址
cairo的顺序是:BGRA     B是低地址

示例代码如下:
使用时,先调用prepare函数,创建cairo的surface,然后调用render函数,获取渲染后的图像,图像的地址
通过buf指针传回.这个buf可以通过nanox的GrArea直接显示,比如:
GrArea (win_id, gc_id, 0, 0, width, height, buf_from_cairo, MWPF_RGB);


static cairo_surface_t *prepare_text(int width, int height)
{
        cairo_surface_t * surface;
        surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, height);
        fprintf(stderr, "prepare text finished\n");
        return surface;
}

static void render_text(cairo_surface_t *surface, unsigned char **buf, unsigned int *width, unsigned int *height)
{
        unsigned char *databuf;
        unsigned int dw, dh , ds;
        unsigned char *pixbuf;
        unsigned int i, j;
        cairo_t *cr = cairo_create(surface);
        cairo_select_font_face(cr, "Sazanami Gothic", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
        cairo_set_font_size(cr, 30.0);
        cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
        cairo_move_to(cr, 0.0, 35.0);
        cairo_show_text(cr, "R u 学生.");
        cairo_move_to(cr, 0.0, 0.0);
        cairo_set_source_rgb(cr, 1.0, 0.0, 0.0);
        cairo_line_to(cr, 100.0, 15.0);
        cairo_arc(cr, 200, 30, 15, 0.0, 2 * 3.1415926);
        cairo_stroke(cr);
        cairo_destroy(cr);

        databuf = cairo_image_surface_get_data(surface);
        if (!databuf) {
                fprintf(stderr, "get cairo image data failed\n");
                return;
        }

        dw = cairo_image_surface_get_width(surface);
        dh = cairo_image_surface_get_height(surface);
        ds = cairo_image_surface_get_stride(surface);

        fprintf(stderr, " w: %d, h: %d, s: %d\n", dw, dh ,ds);
        pixbuf = (unsigned char *)malloc(dh * ds);

        /* Name :  Low               High */
        /* Cairo:  B      G      R     A  */ /* src */
        /* Nanox:  R      G      B     A */ /* dst */
        /* only for little endian ? */
        for (i = 0; i < dh; i++) {
                unsigned char *row = databuf + i * ds;
                unsigned char *dst = pixbuf + i * ds;

                for (j = 0; j < ds; j += 4) {
                        unsigned char *data = &row[j];
                        unsigned char *b = &dst[j];
                        unsigned int pixel;
                        /* wait for optimization */
                        memcpy(&pixel, data, sizeof(unsigned int));

                        b[0] = (pixel & 0xff0000) >> 16;
                        b[1] = (pixel & 0x00ff00) >> 8;
                        b[2] = (pixel & 0x0000ff) >> 0;
                        b[3] = 0;
                }
        }
        fprintf(stderr, " render text finished\n");
#if 0
        cairo_surface_write_to_png(surface, "hello.png");
#endif
        cairo_surface_destroy(surface);
        *buf = pixbuf;
        *width = dw;
        *height = dh;
}

posted on 2009-11-25 20:41  cornsea  阅读(1888)  评论(0编辑  收藏  举报

导航