You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 13:23:11