为何pango_layout_get_pixel_extents返回0×2尺寸的矩形?
PangoCairo布局返回0×2尺寸的原因与修复
问题描述
我几乎完全按照PangoCairo官方教程流程实现代码,仅在构造函数外设置字体大小(为了支持任意字体大小),但最终布局被判定为0×2的尺寸。代码如下:
#include <stdio.h> #include <cairo/cairo.h> #include <pango/pangocairo.h> int main() { cairo_surface_t *const surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 400, 400); cairo_t *const cairo = cairo_create(surface); PangoContext *const pango = pango_cairo_create_context(cairo); PangoFontDescription *desc = pango_font_description_from_string("Noto Sans Regular"); PangoLayout *layout = pango_layout_new(pango); pango_layout_set_text(layout, "Hello, world!", 13); pango_font_description_set_size(desc, 16); pango_layout_set_font_description(layout, desc); PangoRectangle lay_rect, px_rect; pango_layout_get_extents(layout, nullptr, &lay_rect); pango_layout_get_pixel_extents(layout, nullptr, &px_rect); printf( "{\n" "\t\"lw\": %i,\n" "\t\"lh\": %i,\n" "\t\"pw\": %i,\n" "\t\"ph\": %i\n" "}\n", lay_rect.width, lay_rect.height, px_rect.width, px_rect.height ); return 0; }
原因分析
问题核心是字体大小的单位错误:pango_font_description_set_size接收的参数是Pango单位(1个Pango单位 = 1/1024点),你直接传入数值16,相当于设置了16/1024 = 0.015625点的字体——这个尺寸极小,几乎不可见,所以布局宽度被计算为0,高度仅保留了字体的最小基线高度(2像素)。
修复方案
有两种正确的字体大小设置方式:
使用
PANGO_SCALE转换单位(推荐,符合Pango的默认单位逻辑):
将像素/点数乘以PANGO_SCALE,转换为Pango单位:pango_font_description_set_size(desc, 16 * PANGO_SCALE);使用绝对尺寸设置:
调用pango_font_description_set_absolute_size直接设置以像素为单位的大小(需注意屏幕DPI适配):pango_font_description_set_absolute_size(desc, 16 * PANGO_SCALE);
另外,别忘了在代码末尾释放资源,避免内存泄漏:
- 调用
pango_font_description_free(desc)释放字体描述符 - 调用
g_object_unref释放PangoLayout和PangoContext - 销毁Cairo的上下文和表面
修改后的完整代码
#include <stdio.h> #include <cairo/cairo.h> #include <pango/pangocairo.h> int main() { cairo_surface_t *const surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 400, 400); cairo_t *const cairo = cairo_create(surface); PangoContext *const pango = pango_cairo_create_context(cairo); PangoFontDescription *desc = pango_font_description_from_string("Noto Sans Regular"); PangoLayout *layout = pango_layout_new(pango); pango_layout_set_text(layout, "Hello, world!", 13); // 修复:转换为正确的Pango单位 pango_font_description_set_size(desc, 16 * PANGO_SCALE); pango_layout_set_font_description(layout, desc); PangoRectangle lay_rect, px_rect; pango_layout_get_extents(layout, nullptr, &lay_rect); pango_layout_get_pixel_extents(layout, nullptr, &px_rect); printf( "{\n" "\t\"lw\": %i,\n" "\t\"lh\": %i,\n" "\t\"pw\": %i,\n" "\t\"ph\": %i\n" "}\n", lay_rect.width, lay_rect.height, px_rect.width, px_rect.height ); // 释放资源 pango_font_description_free(desc); g_object_unref(layout); g_object_unref(pango); cairo_destroy(cairo); cairo_surface_destroy(surface); return 0; }
内容的提问来源于stack exchange,提问作者Coarse Rosinflower
相关产品推荐
相关产品推荐

