pangocairo:透明记录表面上的变色

时间:2018-03-16 11:03:29

标签: cairo pango pangocairo

当我使用Pango在透明的Cairo记录表面上绘制文本时,文本变得非常褪色,特别是在半透明的抗锯齿区域。例如,this image has the correct (top) and incorrect (bottom) rendition of some text。 (Segment of previous image zoomed in)。

显然,我的问题是如何在使用透明记录表面时获得正确的色彩再现。至少,我假设这个问题与我没有很好地理解pangocairo管道有关。如果它是Pango或Cairo中的错误,请告诉我。

用于生成上图的代码:

#include <cairo/cairo.h>
#include <pango/pangocairo.h>

int main(int argc, char **argv)
{
    cairo_surface_t *canvas = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
        320, 60);
    cairo_t *cctx = cairo_create(canvas);

    cairo_surface_t *surf = cairo_recording_surface_create(
        CAIRO_CONTENT_COLOR_ALPHA, NULL);
    cairo_t *ctx = cairo_create(surf);
    PangoFontDescription *fd = pango_font_description_new();
    PangoLayout *layout = pango_cairo_create_layout(ctx);
    PangoAttrList *attrs = pango_attr_list_new();
    PangoAttribute *at;

    cairo_set_source_rgba(cctx, 1, 1, 1, 1);
    cairo_paint(cctx);
    cairo_translate(cctx, 16, 8);

    pango_font_description_set_family(fd, "DejaVu Sans Mono");
    pango_layout_set_font_description(layout, fd);

    pango_layout_set_text(layout, "Bless the Maker and His water", -1);
    pango_layout_set_attributes(layout, attrs);

    at = pango_attr_foreground_new(0, 0xffff, 0xffff);
    pango_attr_list_change(attrs, at);
    at = pango_attr_foreground_alpha_new(0xffff);
    pango_attr_list_change(attrs, at);

    cairo_save(ctx);
    cairo_set_source_rgba(ctx, 1, 1, 1, 1);
    cairo_set_operator(ctx, CAIRO_OPERATOR_SOURCE);
    cairo_paint(ctx);
    cairo_restore(ctx);

    pango_cairo_update_layout(ctx, layout);
    pango_cairo_show_layout(ctx, layout);

    cairo_set_source_surface(cctx, surf, 0, 0);
    cairo_paint(cctx);

    cairo_save(ctx);
    cairo_set_source_rgba(ctx, 0, 0, 0, 0);
    cairo_set_operator(ctx, CAIRO_OPERATOR_SOURCE);
    cairo_paint(ctx);
    cairo_restore(ctx);

    pango_cairo_update_layout(ctx, layout);
    pango_cairo_show_layout(ctx, layout);

    cairo_translate(cctx, 0, 24);
    cairo_set_source_surface(cctx, surf, 0, 0);
    cairo_paint(cctx);

    cairo_surface_write_to_png(canvas, "test.png");

    g_object_unref(layout);
    pango_attr_list_unref(attrs);
    pango_font_description_free(fd);
    cairo_destroy(ctx);
    cairo_destroy(cctx);
    cairo_surface_destroy(surf);
    cairo_surface_destroy(canvas);

    return 0;
}


更新:这似乎是由视频管道中的某些内容引起的,可能是一个错误。我可以使用AMD显卡在两个盒子上重现这个,但不能在使用nVidia卡的盒子上重现。如果有人知道解决方法的话,我会把它打开。

2 个答案:

答案 0 :(得分:1)

原来@ uli-schlachter 几乎正确:您必须在Pango布局对象上设置抗锯齿选项:

PangoContext *pctx = pango_layout_get_context(layout);
cairo_font_options_t *opts = cairo_font_options_create();
cairo_font_options_set_antialias(opts, CAIRO_ANTIALIAS_GRAY);
pango_cairo_context_set_font_options(pctx, opts);
cairo_font_options_destroy(opts);

答案 1 :(得分:0)

首先:您的示例代码不会在此处重现问题。结果图像中没有“彩色条纹”。

如果你允许我猜测:开罗假设你的子像素为RGB。根据{{​​1}}的文档,这仅适用于cairo_subpixel_order_t。因此,我建议你这样做:

CAIRO_ANTIALIAS_SUBPIXEL