从文件加载字体到Pango?

6

我有一段代码使用CairoPango来创建一张图片:

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

#define IMAGE_WIDTH  650
#define IMAGE_HEIGHT 150

#define TEXT "HELLO WORLD"
#define FONT "MizuFontAlphabet Normal 40"

/*
 * $ gcc $(pkg-config pangocairo cairo --cflags --libs) file.c
 */


int main(int argc , char** argv) {

    cairo_surface_t *surface;
    cairo_t *cr;

    PangoLayout *layout;
    PangoFontDescription *desc;
    PangoRectangle extents;

    surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, IMAGE_WIDTH, IMAGE_HEIGHT);
    cr      = cairo_create(surface);

    cairo_rectangle(cr, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);
    cairo_set_source_rgb(cr, 0, 0, 0);
    cairo_fill(cr);
    cairo_stroke(cr);

    /* the font is needed to be installed in fonts directory */
    layout  = pango_cairo_create_layout(cr);
    pango_layout_set_text(layout, TEXT, -1);
    desc    = pango_font_description_from_string(FONT);
    pango_layout_set_font_description(layout, desc);
    pango_font_description_free (desc);

    pango_layout_get_pixel_extents(layout, NULL, &extents);
    int x   = (int) (IMAGE_WIDTH - extents.width) / 2;
    int y   = (int) (IMAGE_HEIGHT - extents.height) / 2;

    cairo_set_source_rgb(cr, 0.33, 0.55, 0.88);
    cairo_move_to(cr, x, y);
    pango_cairo_show_layout(cr, layout);

    g_object_unref(layout);

    cairo_surface_write_to_png(surface, "image.png");

    cairo_destroy(cr);
    cairo_surface_destroy(surface);

    return(0);
}

我使用的字体是MizuFontAlphabet,它不是标准字体,因此需要将其安装在字体目录中,这样我才能与Pango一起使用:

    desc    = pango_font_description_from_string(FONT);

如果没有安装字体,我该如何从文件中加载字体?

2个回答

7
这个问题可以通过向本地fontconfig状态添加自定义字体来相对容易地解决:
#include <fontconfig/fontconfig.h>


std::string yourFontFilePath = "/home/testUser/bla.ttf";
const FcChar8 * file = (const FcChar8 *)yourFontFilePath.c_str();
FcBool fontAddStatus = FcConfigAppFontAddFile(FcConfigGetCurrent(), file);

现在,Pango渲染引擎将通过使用PangoFontDescription来使用您的自定义字体。

1
将 FcConfigAppFOntAddFile 更改为 FcConfigAppFontAddFile。 - 骑天大圣
1
此答案假定pango正在使用fontconfig后端。您是否知道一个跨平台的解决方案,可以在pango级别上工作? - Isaac Hanson
1
如何创建一个PangoFontDescription,以引用给定的bla.ttf字体? - avl_sweden

1
你需要安装Freetype才能做到。
你可能需要查看以下(GPL许可的)来自fontview库的代码
特别是font_model_new函数:
GObject *font_model_new (gchar *fontfile) {
    FontModel *model;
    FT_Library library;
    FT_Face face;
    FcConfig *config;
    TT_OS2* os2;

    g_return_val_if_fail (fontfile, NULL);

    if (FT_Init_FreeType(&library)) {
        g_error ("FT_Init_FreeType failed");
        return NULL;
    }

    if (FT_New_Face (library, fontfile, 0, &face)) {
        g_error ("FT_New_Face failed");
        return NULL;
    }

    if (!FT_IS_SFNT(face)) {
        g_error ("Not an SFNT font!");
        return NULL;
    }

    config = FcConfigCreate ();
    if (!FcConfigAppFontAddFile (config, (FcChar8*)fontfile)) {
        g_error ("FcConfigAppFontAddFile failed");
        return NULL;
    }

    model = g_object_new (FONT_MODEL_TYPE, NULL);
    model->file = g_strdup (fontfile);
    model->ft_face = face;
    model->config = config;
    model->family = face->family_name;
    model->style = face->style_name;
    model->units_per_em = face->units_per_EM;

    model->xheight = 0;
    model->ascender = 0;
    model->descender = 0;

    model->sample = NULL;

    memset(&model->color, 0, sizeof (ColorTable));

    /* Get font metadata if available/applicable */
    os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2);
    if (os2) {
        model->xheight = os2->sxHeight;
        model->ascender = os2->sTypoAscender;
        model->descender = os2->sTypoDescender;
    }

    model->family = get_font_name (face, TT_NAME_ID_PREFERRED_FAMILY);
    if (!model->family)
        model->family = get_font_name (face, TT_NAME_ID_FONT_FAMILY);

    model->style = get_font_name (face, TT_NAME_ID_PREFERRED_SUBFAMILY);
    if (!model->style)
        model->style = get_font_name (face, TT_NAME_ID_FONT_SUBFAMILY);

    model->copyright = get_font_name (face, TT_NAME_ID_COPYRIGHT);
    model->version = get_font_name (face, TT_NAME_ID_VERSION_STRING);
    model->description = get_font_name (face, TT_NAME_ID_DESCRIPTION);
    model->sample = get_font_name (face, TT_NAME_ID_SAMPLE_TEXT);

    model->mmvar = NULL;
    model->mmcoords = NULL;
    if (FT_HAS_MULTIPLE_MASTERS (face)) {
        if (FT_Get_MM_Var (face, &model->mmvar) != 0) {
            model->mmvar = NULL;
        }
    }

    load_color_table (model);

    return G_OBJECT (model);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接