首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Cairo Surface之前创建Pango布局

在Cairo Surface之前创建Pango布局
EN

Stack Overflow用户
提问于 2015-08-03 13:26:01
回答 1查看 1.9K关注 0票数 5

在我的应用程序中,我使用Pango和Cairo创建文本纹理。这些纹理的宽度是固定的,但应该缩放它们的高度以适应文本内容。然后,参与此情况的父对象将缩放其高度以匹配文本。

问题是,我一直在初始化Pango和开罗的方式不允许这样做。目前,该系统由以下机构建立:

代码语言:javascript
复制
cairo_surface_t* cairoSurface = cairo_image_surface_create( CAIRO_FORMAT_ARGB32, sizeX, sizeY );
cairo_t* cairoContext = cairo_create( cairoSurface );
PangoLayout* pangoLayout = pango_cairo_create_layout( cairoContext );

它能固定高度,至少是表面的高度--这是我不想做的,至少不是所有时候都想做的。

我的理解是,如果没有指定布局高度,它将自动缩放高度,然后可以通过pango_layout_get_size()找到该高度。我想先创建布局,然后使用这个函数的输出来创建曲面。

但是,pango_cairo_create_layout()要求已经创建了图面,而且我一直无法找到通过开罗从pango_layout_new()呈现布局的方法。API文档之一呈现函数pango_cairo_update_layout()指定必须使用pango_cairo_create_layout()来创建布局;然而,更重要的函数pango_cairo_show_layout()注意到没有这样的要求,我不确定这是否意味着允许任何Pango布局。虽然我可以测试它是否有效,但我担心尝试和错误会导致我出现未定义的行为。

我觉得自己陷入了鸡和蛋的困境,而Pango的文档大多是API引用,对如何使用库没有什么解释。有什么办法能做到这一点吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-08-04 14:30:07

我已经想出了这个过程。希望这些信息是有帮助的--尽管我并没有宣称这是一种“正确”的方法来做这其中的任何一件事,但这是可行的。

首先,设置FontConfig。在某些系统中,这可能不是必需的--在Linux上保持它是自动的可能是可以的。然而,在Windows上,FontConfig是有问题的。处理它的最简单的方法是在内存中创建一个配置,并将它指向您希望它查找字体的位置。我把它指向我的程序的资源目录。您可以使用"C:\Windows\Fonts",但请注意,加载要花费很长时间。加载适当的font.conf文件可能是最好的方法,但我自己运气很差。

代码语言:javascript
复制
gchar* workingDir = g_get_current_dir();
gchar* resourceDir = g_strjoin( NULL, workingDir, "/Resources", (char*)0 );
FcConfigAppFontAddDir( fontConfig, (const FcChar8*)resourceDir );
g_free(workingDir);
g_free(resourceDir);
FcConfigBuildFonts( fontConfig );
FcConfigSetCurrent( fontConfig );

然后,您必须创建一个字体映射、Pango上下文和Pango布局:

代码语言:javascript
复制
PangoFontMap* fontMap = pango_cairo_font_map_new();
PangoContext* pangoContext = pango_font_map_create_context( fontMap );
PangoLayout* pangoLayout = pango_layout_new( pangoContext );

现在,使用手动创建的(不是从pango_cairo_create_layout()创建的)布局似乎不会自动加载字体。尝试使用字体地图中但没有加载的字体会导致Pango-Cairo崩溃(使用的字体没有被列出,只是默认)。因此,加载字体地图中列出的所有字体:

代码语言:javascript
复制
FcPattern *p = FcPatternCreate();
FcObjectSet *os = FcObjectSetBuild(FC_FAMILY,NULL);
FcFontSet *fs = FcFontList(fontConfig, p, os);
FcPatternDestroy( p );
FcObjectSetDestroy( os );
for( int i = 0; i < fs->nfont; ++i )
{
    guchar* fontName = FcNameUnparse( fs->fonts[i] );
    PangoFontDescription* fontDesc = pango_font_description_from_string( (gchar*)fontName );
    pango_font_map_load_font( fontMap, pangoContext, fontDesc );
    pango_font_description_free( fontDesc );
    g_free(fontName);
}

若要指定宽度:

代码语言:javascript
复制
pango_layout_set_width( pangoLayout, sizeX * PANGO_SCALE );

这也是你应该设置的理由/对齐/等等。

然后你可以插入你的文本:

代码语言:javascript
复制
pango_layout_set_markup( pangoLayout, text.c_str( ), -1 );

在此之后,您可以通过pango_layout_get_pixel_size()获得布局高度,并使用它创建Cairo对象。然后您可以通过以下方式呈现它:

代码语言:javascript
复制
cairo_move_to(cairoContext, 0, 0);
pango_cairo_update_layout( cairoContext, pangoLayout );
pango_cairo_show_layout( cairoContext, pangoLayout );
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31788577

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档