【发布时间】:2016-03-31 16:31:27
【问题描述】:
我正在尝试编写一个以 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 位,不能期望扩展到我尝试渲染的特殊字符集,所以要让它工作,我需要以不同的方式表示特殊字符吗?
那么如何在 Cairo 中渲染特殊字符呢?我需要改用 Pango,还是我在 C++ 中的表示根本不正确?
“a”和“á”等普通字符正确呈现
我已经设法让一些字符使用 Pango 在 GtkDrawingArea 小部件上呈现,所以这似乎是 Cairo 的问题。
【问题讨论】:
-
这是 C 代码的直接链接。我正在更新它以显示网站
-
您是否安装了正确的字体?
-
在终端、firefox 和我的所有其他应用程序中呈现
-
你的 C++ 是正确的,只要你能渲染其他字符。尝试以
u8"a"开头。 -
您使用的是 cairo toy text API 字体渲染。对于严重的(即不是基本的拉丁文本)字体渲染,您应该使用PangoCairo。