drawtext: Add fontconfig support

Introduce the `font` option and make it optional to pass a fontfile.

Signed-off-by: Luca Barbato <lu_zero@gentoo.org>
This commit is contained in:
Luca Barbato
2014-04-12 16:02:50 +02:00
parent a6ac4fcce4
commit f1b239ec8b
3 changed files with 104 additions and 5 deletions

2
configure vendored
View File

@@ -1128,6 +1128,7 @@ EXTERNAL_LIBRARY_LIST="
libdc1394 libdc1394
libfaac libfaac
libfdk_aac libfdk_aac
libfontconfig
libfreetype libfreetype
libgsm libgsm
libilbc libilbc
@@ -4024,6 +4025,7 @@ enabled frei0r && { check_header frei0r.h || die "ERROR: frei0r.h hea
enabled gnutls && require_pkg_config gnutls gnutls/gnutls.h gnutls_global_init enabled gnutls && require_pkg_config gnutls gnutls/gnutls.h gnutls_global_init
enabled libfaac && require2 libfaac "stdint.h faac.h" faacEncGetVersion -lfaac enabled libfaac && require2 libfaac "stdint.h faac.h" faacEncGetVersion -lfaac
enabled libfdk_aac && require libfdk_aac fdk-aac/aacenc_lib.h aacEncOpen -lfdk-aac enabled libfdk_aac && require libfdk_aac fdk-aac/aacenc_lib.h aacEncOpen -lfdk-aac
enabled libfontconfig && require_pkg_config fontconfig "fontconfig/fontconfig.h" FcInit
enabled libfreetype && require_pkg_config freetype2 "ft2build.h FT_FREETYPE_H" FT_Init_FreeType enabled libfreetype && require_pkg_config freetype2 "ft2build.h FT_FREETYPE_H" FT_Init_FreeType
enabled libgsm && { for gsm_hdr in "gsm.h" "gsm/gsm.h"; do enabled libgsm && { for gsm_hdr in "gsm.h" "gsm/gsm.h"; do
check_lib "${gsm_hdr}" gsm_create -lgsm && break; check_lib "${gsm_hdr}" gsm_create -lgsm && break;

View File

@@ -1115,6 +1115,8 @@ libfreetype library.
To enable compilation of this filter, you need to configure Libav with To enable compilation of this filter, you need to configure Libav with
@code{--enable-libfreetype}. @code{--enable-libfreetype}.
To enable default font fallback and the @var{font} option you need to
configure Libav with @code{--enable-libfontconfig}.
The filter also recognizes strftime() sequences in the provided text The filter also recognizes strftime() sequences in the provided text
and expands them accordingly. Check the documentation of strftime(). and expands them accordingly. Check the documentation of strftime().
@@ -1123,9 +1125,12 @@ It accepts the following parameters:
@table @option @table @option
@item font
The font family to be used for drawing text. By default Sans.
@item fontfile @item fontfile
The font file to be used for drawing text. The path must be included. The font file to be used for drawing text. The path must be included.
This parameter is mandatory. This parameter is mandatory if the fontconfig support is disabled.
@item text @item text
The text string to be drawn. The text must be a sequence of UTF-8 The text string to be drawn. The text must be a sequence of UTF-8

View File

@@ -26,8 +26,17 @@
* filter by Gustavo Sverzut Barbieri * filter by Gustavo Sverzut Barbieri
*/ */
#include "config.h"
#include <sys/types.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/stat.h>
#include <time.h> #include <time.h>
#include <unistd.h>
#if CONFIG_LIBFONTCONFIG
#include <fontconfig/fontconfig.h>
#endif
#include "libavutil/colorspace.h" #include "libavutil/colorspace.h"
#include "libavutil/common.h" #include "libavutil/common.h"
@@ -98,6 +107,9 @@ enum var_name {
typedef struct { typedef struct {
const AVClass *class; const AVClass *class;
#if CONFIG_LIBFONTCONFIG
uint8_t *font; ///< font to be used
#endif
uint8_t *fontfile; ///< font to be used uint8_t *fontfile; ///< font to be used
uint8_t *text; ///< text to be drawn uint8_t *text; ///< text to be drawn
uint8_t *expanded_text; ///< used to contain the strftime()-expanded text uint8_t *expanded_text; ///< used to contain the strftime()-expanded text
@@ -146,6 +158,9 @@ typedef struct {
#define FLAGS AV_OPT_FLAG_VIDEO_PARAM #define FLAGS AV_OPT_FLAG_VIDEO_PARAM
static const AVOption drawtext_options[]= { static const AVOption drawtext_options[]= {
#if CONFIG_LIBFONTCONFIG
{ "font", "Font name", OFFSET(font), AV_OPT_TYPE_STRING, { .str = "Sans" }, .flags = FLAGS },
#endif
{ "fontfile", NULL, OFFSET(fontfile), AV_OPT_TYPE_STRING, .flags = FLAGS }, { "fontfile", NULL, OFFSET(fontfile), AV_OPT_TYPE_STRING, .flags = FLAGS },
{ "text", NULL, OFFSET(text), AV_OPT_TYPE_STRING, .flags = FLAGS }, { "text", NULL, OFFSET(text), AV_OPT_TYPE_STRING, .flags = FLAGS },
{ "textfile", NULL, OFFSET(textfile), AV_OPT_TYPE_STRING, .flags = FLAGS }, { "textfile", NULL, OFFSET(textfile), AV_OPT_TYPE_STRING, .flags = FLAGS },
@@ -279,16 +294,93 @@ error:
return ret; return ret;
} }
static int parse_font(AVFilterContext *ctx)
{
DrawTextContext *s = ctx->priv;
#if !CONFIG_LIBFONTCONFIG
if (!s->fontfile) {
av_log(ctx, AV_LOG_ERROR, "No font filename provided\n");
return AVERROR(EINVAL);
}
return 0;
#else
FcPattern *pat, *best;
FcResult result = FcResultMatch;
FcBool fc_bool;
FcChar8* fc_string;
int err = AVERROR(ENOENT);
if (s->fontfile)
return 0;
if (!FcInit())
return AVERROR_UNKNOWN;
if (!(pat = FcPatternCreate()))
return AVERROR(ENOMEM);
FcPatternAddString(pat, FC_FAMILY, s->font);
FcPatternAddBool(pat, FC_OUTLINE, FcTrue);
FcPatternAddDouble(pat, FC_SIZE, (double)s->fontsize);
FcDefaultSubstitute(pat);
if (!FcConfigSubstitute(NULL, pat, FcMatchPattern)) {
FcPatternDestroy(pat);
return AVERROR(ENOMEM);
}
best = FcFontMatch(NULL, pat, &result);
FcPatternDestroy(pat);
if (!best || result == FcResultNoMatch) {
av_log(ctx, AV_LOG_ERROR,
"Cannot find a valid font for the family %s\n",
s->font);
goto fail;
}
if (FcPatternGetBool(best, FC_OUTLINE, 0, &fc_bool) != FcResultMatch ||
!fc_bool) {
av_log(ctx, AV_LOG_ERROR, "Outline not available for %s\n",
s->font);
goto fail;
}
if (FcPatternGetString(best, FC_FAMILY, 0, &fc_string) != FcResultMatch) {
av_log(ctx, AV_LOG_ERROR, "No matches for %s\n",
s->font);
goto fail;
}
if (FcPatternGetString(best, FC_FILE, 0, &fc_string) != FcResultMatch) {
av_log(ctx, AV_LOG_ERROR, "No file path for %s\n",
s->font);
goto fail;
}
s->fontfile = av_strdup(fc_string);
if (!s->fontfile)
err = AVERROR(ENOMEM);
else
err = 0;
fail:
FcPatternDestroy(best);
return err;
#endif
}
static av_cold int init(AVFilterContext *ctx) static av_cold int init(AVFilterContext *ctx)
{ {
int err; int err;
DrawTextContext *s = ctx->priv; DrawTextContext *s = ctx->priv;
Glyph *glyph; Glyph *glyph;
if (!s->fontfile) { if ((err = parse_font(ctx)) < 0)
av_log(ctx, AV_LOG_ERROR, "No font filename provided\n"); return err;
return AVERROR(EINVAL);
}
if (s->textfile) { if (s->textfile) {
uint8_t *textbuf; uint8_t *textbuf;