From 40b7a27bad8b8b35cb215bf4f4cba02a00d6f9e2 Mon Sep 17 00:00:00 2001 From: Nicolas George Date: Sat, 7 Apr 2012 15:09:16 +0200 Subject: vf_drawtext: fontconfig support. --- libavfilter/vf_drawtext.c | 103 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 95 insertions(+), 8 deletions(-) (limited to 'libavfilter/vf_drawtext.c') diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c index 43b04e01e6..5cfe6bf262 100644 --- a/libavfilter/vf_drawtext.c +++ b/libavfilter/vf_drawtext.c @@ -48,6 +48,9 @@ #include #include FT_FREETYPE_H #include FT_GLYPH_H +#if CONFIG_FONTCONFIG +#include +#endif static const char *const var_names[] = { "main_w", "w", "W", ///< width of the input video @@ -167,7 +170,7 @@ static const AVOption drawtext_options[]= { {"boxcolor", "set box color", OFFSET(boxcolor_string), AV_OPT_TYPE_STRING, {.str="white"}, CHAR_MIN, CHAR_MAX }, {"shadowcolor", "set shadow color", OFFSET(shadowcolor_string), AV_OPT_TYPE_STRING, {.str="black"}, CHAR_MIN, CHAR_MAX }, {"box", "set box", OFFSET(draw_box), AV_OPT_TYPE_INT, {.dbl=0}, 0, 1 }, -{"fontsize", "set font size", OFFSET(fontsize), AV_OPT_TYPE_INT, {.dbl=16}, 1, INT_MAX }, +{"fontsize", "set font size", OFFSET(fontsize), AV_OPT_TYPE_INT, {.dbl=0}, 0, INT_MAX }, {"x", "set x expression", OFFSET(x_expr), AV_OPT_TYPE_STRING, {.str="0"}, CHAR_MIN, CHAR_MAX }, {"y", "set y expression", OFFSET(y_expr), AV_OPT_TYPE_STRING, {.str="0"}, CHAR_MIN, CHAR_MAX }, {"shadowx", "set x", OFFSET(shadowx), AV_OPT_TYPE_INT, {.dbl=0}, INT_MIN, INT_MAX }, @@ -298,6 +301,91 @@ error: return ret; } +static int load_font_file(AVFilterContext *ctx, const char *path, int index, + const char **error) +{ + DrawTextContext *dtext = ctx->priv; + int err; + + err = FT_New_Face(dtext->library, path, index, &dtext->face); + if (err) { + *error = FT_ERRMSG(err); + return AVERROR(EINVAL); + } + return 0; +} + +#if CONFIG_FONTCONFIG +static int load_font_fontconfig(AVFilterContext *ctx, const char **error) +{ + DrawTextContext *dtext = ctx->priv; + FcConfig *fontconfig; + FcPattern *pattern, *fpat; + FcResult result = FcResultMatch; + FcChar8 *filename; + int err, index; + double size; + + fontconfig = FcInitLoadConfigAndFonts(); + if (!fontconfig) { + *error = "impossible to init fontconfig\n"; + return AVERROR(EINVAL); + } + pattern = FcNameParse(dtext->fontfile ? dtext->fontfile : + (uint8_t *)(intptr_t)"default"); + if (!pattern) { + *error = "could not parse fontconfig pattern"; + return AVERROR(EINVAL); + } + if (!FcConfigSubstitute(fontconfig, pattern, FcMatchPattern)) { + *error = "could not substitue fontconfig options"; /* very unlikely */ + return AVERROR(EINVAL); + } + FcDefaultSubstitute(pattern); + fpat = FcFontMatch(fontconfig, pattern, &result); + if (!fpat || result != FcResultMatch) { + *error = "impossible to find a matching font"; + return AVERROR(EINVAL); + } + if (FcPatternGetString (fpat, FC_FILE, 0, &filename) != FcResultMatch || + FcPatternGetInteger(fpat, FC_INDEX, 0, &index ) != FcResultMatch || + FcPatternGetDouble (fpat, FC_SIZE, 0, &size ) != FcResultMatch) { + *error = "impossible to find font information"; + return AVERROR(EINVAL); + } + av_log(ctx, AV_LOG_INFO, "Using \"%s\"\n", filename); + if (!dtext->fontsize) + dtext->fontsize = size + 0.5; + err = load_font_file(ctx, filename, index, error); + if (err) + return err; + FcPatternDestroy(fpat); + FcPatternDestroy(pattern); + FcConfigDestroy(fontconfig); + return 0; +} +#endif + +static int load_font(AVFilterContext *ctx) +{ + DrawTextContext *dtext = ctx->priv; + int err; + const char *error = "unknown error\n"; + + /* load the face, and set up the encoding, which is by default UTF-8 */ + err = load_font_file(ctx, dtext->fontfile, 0, &error); + if (!err) + return 0; +#if CONFIG_FONTCONFIG + err = load_font_fontconfig(ctx, &error); + if (!err) + return 0; +#endif + av_log(ctx, AV_LOG_ERROR, "Could not load font \"%s\": %s\n", + dtext->fontfile, error); + return err; +} + static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) { int err; @@ -312,7 +400,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) return err; } - if (!dtext->fontfile) { + if (!dtext->fontfile && !CONFIG_FONTCONFIG) { av_log(ctx, AV_LOG_ERROR, "No font filename provided\n"); return AVERROR(EINVAL); } @@ -381,12 +469,11 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) return AVERROR(EINVAL); } - /* load the face, and set up the encoding, which is by default UTF-8 */ - if ((err = FT_New_Face(dtext->library, dtext->fontfile, 0, &dtext->face))) { - av_log(ctx, AV_LOG_ERROR, "Could not load fontface from file '%s': %s\n", - dtext->fontfile, FT_ERRMSG(err)); - return AVERROR(EINVAL); - } + err = load_font(ctx); + if (err) + return err; + if (!dtext->fontsize) + dtext->fontsize = 16; if ((err = FT_Set_Pixel_Sizes(dtext->face, 0, dtext->fontsize))) { av_log(ctx, AV_LOG_ERROR, "Could not set font size to %d pixels: %s\n", dtext->fontsize, FT_ERRMSG(err)); -- cgit v1.2.3