在C ++中使用Cairo渲染亚洲字符?

时间:2016-03-31 16:31:27

标签: c++ utf-8 cairo

我正在尝试编写一个用UTF-8渲染亚洲字符的程序。当我尝试在终端或文本编辑器环境中呈现字符时,它会正确呈现。当我尝试在cairo中渲染时,我会在输出中呈现矩形(而不是我期望的UTF8字符)。

下面是我正在运行的示例代码,它使用呈现的文本生成PNG文件输出。当我在gcc中编译并运行代码时,我没有得到预期的字符と,而是得到一个矩形。我目前正在运行http://cairographics.org/tutorial/中的示例并向其提供我想要呈现的特殊字符。

#include <math.h>
#include <stdio.h>
#include <cairo.h>

int
main (int argc, char *argv[])
{
//CODE FROM http://cairographics.org/tutorial/textextents.c
    /* Variable declarations */
    cairo_surface_t *surface;
    cairo_t *cr;
    double x, y, px, ux=1, uy=1, dashlength;
    char text[]= u8"と";
    cairo_font_extents_t fe;
    cairo_text_extents_t te;

    /* Prepare drawing area */
    surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 240, 240);
    cr = cairo_create (surface);
    /* Example is in 26.0 x 1.0 coordinate space */
    cairo_scale (cr, 240, 240);
    cairo_set_font_size (cr, 0.5);

    /* Drawing code goes here */
    cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
    cairo_select_font_face (cr, "Sans",
            CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
    cairo_font_extents (cr, &fe);

    cairo_device_to_user_distance (cr, &ux, &uy);
    if (ux > uy)
        px = ux;
    else
        px = uy;
    cairo_font_extents (cr, &fe);
    cairo_text_extents (cr, text, &te);
    x = 0.5 - te.x_bearing - te.width / 2;
    y = 0.5 - fe.descent + fe.height / 2;

    /* baseline, descent, ascent, height */
    cairo_set_line_width (cr, 4*px);
    dashlength = 9*px;
    cairo_set_dash (cr, &dashlength, 1, 0);
    cairo_set_source_rgba (cr, 0, 0.6, 0, 0.5);
    cairo_move_to (cr, x + te.x_bearing, y);
    cairo_rel_line_to (cr, te.width, 0);
    cairo_move_to (cr, x + te.x_bearing, y + fe.descent);
    cairo_rel_line_to (cr, te.width, 0);
    cairo_move_to (cr, x + te.x_bearing, y - fe.ascent);
    cairo_rel_line_to (cr, te.width, 0);
    cairo_move_to (cr, x + te.x_bearing, y - fe.height);
    cairo_rel_line_to (cr, te.width, 0);
    cairo_stroke (cr);

    /* extents: width & height */
    cairo_set_source_rgba (cr, 0, 0, 0.75, 0.5);
    cairo_set_line_width (cr, px);
    dashlength = 3*px;
    cairo_set_dash (cr, &dashlength, 1, 0);
    cairo_rectangle (cr, x + te.x_bearing, y + te.y_bearing, te.width, te.height);
    cairo_stroke (cr);

    /* text */
    cairo_move_to (cr, x, y);
    cairo_set_source_rgb (cr, 0, 0, 0);
    cairo_show_text (cr, text);

    /* bearing */
    cairo_set_dash (cr, NULL, 0, 0);
    cairo_set_line_width (cr, 2 * px);
    cairo_set_source_rgba (cr, 0, 0, 0.75, 0.5);
    cairo_move_to (cr, x, y);
    cairo_rel_line_to (cr, te.x_bearing, te.y_bearing);
    cairo_stroke (cr);

    /* text's advance */
    cairo_set_source_rgba (cr, 0, 0, 0.75, 0.5);
    cairo_arc (cr, x + te.x_advance, y + te.y_advance, 5 * px, 0, 2 * M_PI);
    cairo_fill (cr);

    /* reference point */
    cairo_arc (cr, x, y, 5 * px, 0, 2 * M_PI);
    cairo_set_source_rgba (cr, 0.75, 0, 0, 0.5);
    cairo_fill (cr);

    /* Write output and clean up */
    cairo_surface_write_to_png (surface, "textextents.png");
    cairo_destroy (cr);
    cairo_surface_destroy (surface);

    return 0;
}

我意识到C ++中的字符只有8位,不能指望扩展到我试图渲染的特殊字符集,所以为了让它工作,我需要以不同的方式表示特殊字符吗? / p>

以下是运行代码时获得的图像:Rendition of と

那么如何在开罗渲染特殊角色?我是否需要使用Pango,或者我在C ++中的表示从根本上是不正确的?

普通字符如“a”和“á”正确呈现

我设法使用Pango在GtkDrawingArea小部件上渲染一些角色,所以这似乎是开罗的一个问题。

1 个答案:

答案 0 :(得分:1)

根据the Cairo documentation,不建议使用Cairo进行文本操作。他们将其描述为玩具文本API,并建议使用Pango作为文本,正如您已经提到过的可能性。我不能肯定地说这是你的问题,但在链接页面的描述中,它说开罗不能很好地处理字体问题。您选择的字体可能不支持此字符。