问题
I have a code uses Cairo and Pango to create an image :
#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);
}
The font I use , MizuFontAlphabet
, is a none-standard font so it is needed to be installed in the fonts directory so I can use it with Pango :
desc = pango_font_description_from_string(FONT);
How could I load the font from a file in case that font wasn't installed?
回答1:
This problem can be solved fairly easily by adding a custom font to the local fontconfig state:
#include <fontconfig/fontconfig.h>
std::string yourFontFilePath = "/home/testUser/bla.ttf";
const FcChar8 * file = (const FcChar8 *)yourFontFilePath.c_str();
FcBool fontAddStatus = FcConfigAppFontAddFile(FcConfigGetCurrent(), file);
Now the pango rendering engine will use your custom font just by using the PangoFontDescription.
回答2:
You'll need Freetype to do that.
You may want to have a look at the following (GPL licensed) code from the fontview library.
Especially, the function 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);
}
来源:https://stackoverflow.com/questions/10722577/loading-a-font-from-a-file-to-pango