summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xconfigure2
-rw-r--r--doc/filters.texi7
-rw-r--r--libavfilter/vf_drawtext.c100
3 files changed, 104 insertions, 5 deletions
diff --git a/configure b/configure
index 3c49d9c8b6..63a9e723bd 100755
--- a/configure
+++ b/configure
@@ -1128,6 +1128,7 @@ EXTERNAL_LIBRARY_LIST="
libdc1394
libfaac
libfdk_aac
+ libfontconfig
libfreetype
libgsm
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 libfaac && require2 libfaac "stdint.h faac.h" faacEncGetVersion -lfaac
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 libgsm && { for gsm_hdr in "gsm.h" "gsm/gsm.h"; do
check_lib "${gsm_hdr}" gsm_create -lgsm && break;
diff --git a/doc/filters.texi b/doc/filters.texi
index 18531de295..d10a107b64 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -1115,6 +1115,8 @@ libfreetype library.
To enable compilation of this filter, you need to configure Libav with
@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
and expands them accordingly. Check the documentation of strftime().
@@ -1123,9 +1125,12 @@ It accepts the following parameters:
@table @option
+@item font
+The font family to be used for drawing text. By default Sans.
+
@item fontfile
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
The text string to be drawn. The text must be a sequence of UTF-8
diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c
index 314e0fc808..2338b03229 100644
--- a/libavfilter/vf_drawtext.c
+++ b/libavfilter/vf_drawtext.c
@@ -26,8 +26,17 @@
* filter by Gustavo Sverzut Barbieri
*/
+#include "config.h"
+
+#include <sys/types.h>
#include <sys/time.h>
+#include <sys/stat.h>
#include <time.h>
+#include <unistd.h>
+
+#if CONFIG_LIBFONTCONFIG
+#include <fontconfig/fontconfig.h>
+#endif
#include "libavutil/colorspace.h"
#include "libavutil/common.h"
@@ -98,6 +107,9 @@ enum var_name {
typedef struct {
const AVClass *class;
+#if CONFIG_LIBFONTCONFIG
+ uint8_t *font; ///< font to be used
+#endif
uint8_t *fontfile; ///< font to be used
uint8_t *text; ///< text to be drawn
uint8_t *expanded_text; ///< used to contain the strftime()-expanded text
@@ -146,6 +158,9 @@ typedef struct {
#define FLAGS AV_OPT_FLAG_VIDEO_PARAM
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 },
{ "text", NULL, OFFSET(text), AV_OPT_TYPE_STRING, .flags = FLAGS },
{ "textfile", NULL, OFFSET(textfile), AV_OPT_TYPE_STRING, .flags = FLAGS },
@@ -279,17 +294,94 @@ error:
return ret;
}
-static av_cold int init(AVFilterContext *ctx)
+static int parse_font(AVFilterContext *ctx)
{
- int err;
DrawTextContext *s = ctx->priv;
- Glyph *glyph;
-
+#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)
+{
+ int err;
+ DrawTextContext *s = ctx->priv;
+ Glyph *glyph;
+
+ if ((err = parse_font(ctx)) < 0)
+ return err;
+
if (s->textfile) {
uint8_t *textbuf;
size_t textbuf_size;