将文件中的字体加载到pango?

时间:2012-05-23 14:56:41

标签: c fonts cairo pango

我的代码使用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是非标准字体,因此需要将其安装在fonts目录中,以便我可以将它与Pango一起使用:

    desc    = pango_font_description_from_string(FONT);

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

2 个答案:

答案 0 :(得分:6)

通过将自定义字体添加到本地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 :(得分:1)

你需要Freetype才能做到这一点。

您可能需要查看以下内容(获得GPL许可)code from the fontview library

特别是,函数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);
}