Commit f1b239ec authored by Luca Barbato's avatar Luca Barbato

drawtext: Add fontconfig support

Introduce the `font` option and make it optional to pass a fontfile.
Signed-off-by: 's avatarLuca Barbato <lu_zero@gentoo.org>
parent a6ac4fcc
...@@ -1128,6 +1128,7 @@ EXTERNAL_LIBRARY_LIST=" ...@@ -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 ...@@ -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;
......
...@@ -1115,6 +1115,8 @@ libfreetype library. ...@@ -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: ...@@ -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
......
...@@ -26,8 +26,17 @@ ...@@ -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 { ...@@ -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 { ...@@ -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,17 +294,94 @@ error: ...@@ -279,17 +294,94 @@ error:
return ret; return ret;
} }
static av_cold int init(AVFilterContext *ctx) static int parse_font(AVFilterContext *ctx)
{ {
int err;
DrawTextContext *s = ctx->priv; DrawTextContext *s = ctx->priv;
Glyph *glyph; #if !CONFIG_LIBFONTCONFIG
if (!s->fontfile) { if (!s->fontfile) {
av_log(ctx, AV_LOG_ERROR, "No font filename provided\n"); av_log(ctx, AV_LOG_ERROR, "No font filename provided\n");
return AVERROR(EINVAL); 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)
{
int err;
DrawTextContext *s = ctx->priv;
Glyph *glyph;
if ((err = parse_font(ctx)) < 0)
return err;
if (s->textfile) { if (s->textfile) {
uint8_t *textbuf; uint8_t *textbuf;
size_t textbuf_size; size_t textbuf_size;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment