MacOS下cairo_show_text返回无效表面错误如何解决?
macOS下Cairo调用cairo_show_text出现“表面类型不适合操作”错误的解决方法
问题背景
在macOS环境中调用自定义的cairo_text_outline函数时,cairo_show_text返回错误状态码13,提示the surface type is not appropriate for the operation,但相同代码在Linux和Windows平台可正常运行。
自定义函数代码
void cairo_text_outline (cairo_t *cr, double x, double y, const char *p) { cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); cairo_move_to(cr, x - 1.0, y - 1.0); printf("3 %s\n", cairo_status_to_string(cairo_status(cr))); if (cairo_status(cr)) abort(); cairo_show_text(cr, p); printf("4 %d %s\n", cairo_status(cr), cairo_status_to_string(cairo_status(cr))); if (cairo_status(cr)) abort(); }
调用位置代码
[...] /* text */ cairo_identity_matrix(cr); cairo_set_font(cr, &g_font_courier_new); cairo_set_font_size(cr, 20); cairo_text_extents(cr, seq->title, &te); cairo_text_outline(cr, 20.0, window->h - te.height - te.y_bearing - 20, seq->title); [...]
错误输出
3 no error has occurred 4 13 the surface type is not appropriate for the operation
解决方法
1. 改用路径渲染文本替换cairo_show_text
macOS的Quartz后端对cairo_show_text的支持存在限制,可通过将文本转换为路径再填充的方式绕过该问题,修改自定义函数如下:
void cairo_text_outline (cairo_t *cr, double x, double y, const char *p) { cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); cairo_move_to(cr, x - 1.0, y - 1.0); // 替换cairo_show_text为路径渲染 cairo_text_path(cr, p); cairo_fill(cr); printf("4 %d %s\n", cairo_status(cr), cairo_status_to_string(cairo_status(cr))); if (cairo_status(cr)) abort(); }
2. 调整字体加载方式
macOS上Cairo依赖Quartz字体系统,直接使用cairo_set_font传入自定义字体结构易出现兼容性问题,改用系统原生字体加载方式:
// 替换原有的cairo_set_font调用 cairo_select_font_face(cr, "Courier New", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size(cr, 20);
3. 检查并确认Cairo表面类型
通过cairo_surface_get_type(cairo_get_target(cr))确认当前使用的表面类型,如果是CAIRO_SURFACE_TYPE_QUARTZ,确保创建表面时使用cairo_quartz_surface_create而非通用创建函数,避免配置错误。
4. 更新Cairo版本
旧版Cairo的Quartz后端存在已知Bug,升级到最新稳定版可修复多数平台兼容性问题。
内容的提问来源于stack exchange,提问作者thodg
相关产品推荐
相关产品推荐

