mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2024-12-25 00:32:31 +00:00
Merge commit 'f1b239ec8b38474d31f3bfea1f0b1693774fa432'
* commit 'f1b239ec8b38474d31f3bfea1f0b1693774fa432':
drawtext: Add fontconfig support
Conflicts:
configure
doc/filters.texi
libavfilter/vf_drawtext.c
See: 40b7a27bad
Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
commit
443261cbbd
6
configure
vendored
6
configure
vendored
@ -1304,7 +1304,6 @@ EXTERNAL_LIBRARY_LIST="
|
||||
bzlib
|
||||
crystalhd
|
||||
decklink
|
||||
fontconfig
|
||||
frei0r
|
||||
gnutls
|
||||
iconv
|
||||
@ -1319,6 +1318,7 @@ EXTERNAL_LIBRARY_LIST="
|
||||
libfaac
|
||||
libfdk_aac
|
||||
libflite
|
||||
libfontconfig
|
||||
libfreetype
|
||||
libgme
|
||||
libgsm
|
||||
@ -1445,6 +1445,7 @@ CONFIG_LIST="
|
||||
$LIBRARY_LIST
|
||||
$PROGRAM_LIST
|
||||
$SUBSYSTEM_LIST
|
||||
fontconfig
|
||||
incompatible_libav_abi
|
||||
incompatible_fork_abi
|
||||
memalign_hack
|
||||
@ -4587,7 +4588,6 @@ enabled avisynth && { { check_lib2 "windows.h" LoadLibrary; } ||
|
||||
{ check_lib2 "dlfcn.h" dlopen -ldl; } ||
|
||||
die "ERROR: LoadLibrary/dlopen not found for avisynth"; }
|
||||
enabled decklink && { check_header DeckLinkAPI.h || die "ERROR: DeckLinkAPI.h header not found"; }
|
||||
enabled fontconfig && require_pkg_config fontconfig "fontconfig/fontconfig.h" FcInit
|
||||
enabled frei0r && { check_header frei0r.h || die "ERROR: frei0r.h header not found"; }
|
||||
enabled gnutls && require_pkg_config gnutls gnutls/gnutls.h gnutls_global_init
|
||||
enabled ladspa && { check_header ladspa.h || die "ERROR: ladspa.h header not found"; }
|
||||
@ -4603,6 +4603,8 @@ enabled libfaac && require2 libfaac "stdint.h faac.h" faacEncGetVersio
|
||||
enabled libfdk_aac && require libfdk_aac fdk-aac/aacenc_lib.h aacEncOpen -lfdk-aac
|
||||
flite_libs="-lflite_cmu_time_awb -lflite_cmu_us_awb -lflite_cmu_us_kal -lflite_cmu_us_kal16 -lflite_cmu_us_rms -lflite_cmu_us_slt -lflite_usenglish -lflite_cmulex -lflite"
|
||||
enabled libflite && require2 libflite "flite/flite.h" flite_init $flite_libs
|
||||
enabled fontconfig && enable libfontconfig
|
||||
enabled libfontconfig && require_pkg_config fontconfig "fontconfig/fontconfig.h" FcInit
|
||||
enabled libfreetype && require_libfreetype
|
||||
enabled libgme && require libgme gme/gme.h gme_new_emu -lgme -lstdc++
|
||||
enabled libgsm && { for gsm_hdr in "gsm.h" "gsm/gsm.h"; do
|
||||
|
@ -3580,6 +3580,8 @@ libfreetype library.
|
||||
|
||||
To enable compilation of this filter, you need to configure FFmpeg with
|
||||
@code{--enable-libfreetype}.
|
||||
To enable default font fallback and the @var{font} option you need to
|
||||
configure FFmpeg with @code{--enable-libfontconfig}.
|
||||
|
||||
@subsection Syntax
|
||||
|
||||
@ -3623,9 +3625,12 @@ the "Color" section in the ffmpeg-utils manual.
|
||||
|
||||
The default value of @var{fontcolor} is "black".
|
||||
|
||||
@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 fontsize
|
||||
The font size to be used for drawing text.
|
||||
@ -3786,9 +3791,6 @@ These parameters allow the @var{x} and @var{y} expressions to refer
|
||||
each other, so you can for example specify @code{y=x/dar}.
|
||||
@end table
|
||||
|
||||
If libavfilter was built with @code{--enable-fontconfig}, then
|
||||
@option{fontfile} can be a fontconfig pattern or omitted.
|
||||
|
||||
@anchor{drawtext_expansion}
|
||||
@subsection Text expansion
|
||||
|
||||
|
@ -27,10 +27,18 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#if HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if CONFIG_LIBFONTCONFIG
|
||||
#include <fontconfig/fontconfig.h>
|
||||
#endif
|
||||
|
||||
#include "libavutil/avstring.h"
|
||||
#include "libavutil/bprint.h"
|
||||
@ -53,9 +61,6 @@
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_GLYPH_H
|
||||
#include FT_STROKER_H
|
||||
#if CONFIG_FONTCONFIG
|
||||
#include <fontconfig/fontconfig.h>
|
||||
#endif
|
||||
|
||||
static const char *const var_names[] = {
|
||||
"dar",
|
||||
@ -125,6 +130,9 @@ typedef struct {
|
||||
const AVClass *class;
|
||||
enum expansion_mode exp_mode; ///< expansion mode to use for the text
|
||||
int reinit; ///< tells if the filter is being reinited
|
||||
#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
|
||||
AVBPrint expanded_text; ///< used to contain the expanded text
|
||||
@ -198,6 +206,9 @@ static const AVOption drawtext_options[]= {
|
||||
#if FF_API_DRAWTEXT_OLD_TIMELINE
|
||||
{"draw", "if false do not draw (deprecated)", OFFSET(draw_expr), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS},
|
||||
#endif
|
||||
#if CONFIG_LIBFONTCONFIG
|
||||
{ "font", "Font name", OFFSET(font), AV_OPT_TYPE_STRING, { .str = "Sans" }, .flags = FLAGS },
|
||||
#endif
|
||||
|
||||
{"expansion", "set the expansion mode", OFFSET(exp_mode), AV_OPT_TYPE_INT, {.i64=EXP_NORMAL}, 0, 2, FLAGS, "expansion"},
|
||||
{"none", "set no expansion", OFFSET(exp_mode), AV_OPT_TYPE_CONST, {.i64=EXP_NONE}, 0, 0, FLAGS, "expansion"},
|
||||
@ -337,68 +348,90 @@ error:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int load_font_file(AVFilterContext *ctx, const char *path, int index,
|
||||
const char **error)
|
||||
static int load_font_file(AVFilterContext *ctx, const char *path, int index)
|
||||
{
|
||||
DrawTextContext *s = ctx->priv;
|
||||
int err;
|
||||
|
||||
err = FT_New_Face(s->library, path, index, &s->face);
|
||||
if (err) {
|
||||
*error = FT_ERRMSG(err);
|
||||
av_log(ctx, AV_LOG_ERROR, "Could not load font \"%s\": %s\n",
|
||||
s->fontfile, FT_ERRMSG(err));
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if CONFIG_FONTCONFIG
|
||||
static int load_font_fontconfig(AVFilterContext *ctx, const char **error)
|
||||
#if CONFIG_LIBFONTCONFIG
|
||||
static int load_font_fontconfig(AVFilterContext *ctx)
|
||||
{
|
||||
DrawTextContext *s = ctx->priv;
|
||||
FcConfig *fontconfig;
|
||||
FcPattern *pattern, *fpat;
|
||||
FcPattern *pat, *best;
|
||||
FcResult result = FcResultMatch;
|
||||
FcChar8 *filename;
|
||||
int err, index;
|
||||
int index;
|
||||
double size;
|
||||
int err = AVERROR(ENOENT);
|
||||
|
||||
fontconfig = FcInitLoadConfigAndFonts();
|
||||
if (!fontconfig) {
|
||||
*error = "impossible to init fontconfig\n";
|
||||
return AVERROR(EINVAL);
|
||||
av_log(ctx, AV_LOG_ERROR, "impossible to init fontconfig\n");
|
||||
return AVERROR_UNKNOWN;
|
||||
}
|
||||
pattern = FcNameParse(s->fontfile ? s->fontfile :
|
||||
pat = FcNameParse(s->fontfile ? s->fontfile :
|
||||
(uint8_t *)(intptr_t)"default");
|
||||
if (!pattern) {
|
||||
*error = "could not parse fontconfig pattern";
|
||||
if (!pat) {
|
||||
av_log(ctx, AV_LOG_ERROR, "could not parse fontconfig pat");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
if (!FcConfigSubstitute(fontconfig, pattern, FcMatchPattern)) {
|
||||
*error = "could not substitue fontconfig options"; /* very unlikely */
|
||||
|
||||
FcPatternAddString(pat, FC_FAMILY, s->font);
|
||||
if (s->fontsize)
|
||||
FcPatternAddDouble(pat, FC_SIZE, (double)s->fontsize);
|
||||
|
||||
FcDefaultSubstitute(pat);
|
||||
|
||||
if (!FcConfigSubstitute(fontconfig, pat, FcMatchPattern)) {
|
||||
av_log(ctx, AV_LOG_ERROR, "could not substitue fontconfig options"); /* very unlikely */
|
||||
FcPatternDestroy(pat);
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
best = FcFontMatch(fontconfig, pat, &result);
|
||||
FcPatternDestroy(pat);
|
||||
|
||||
if (!best || result != FcResultMatch) {
|
||||
av_log(ctx, AV_LOG_ERROR,
|
||||
"Cannot find a valid font for the family %s\n",
|
||||
s->font);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (
|
||||
FcPatternGetInteger(best, FC_INDEX, 0, &index ) != FcResultMatch ||
|
||||
FcPatternGetDouble (best, FC_SIZE, 0, &size ) != FcResultMatch) {
|
||||
av_log(ctx, AV_LOG_ERROR, "impossible to find font information");
|
||||
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);
|
||||
|
||||
if (FcPatternGetString(best, FC_FILE, 0, &filename) != FcResultMatch) {
|
||||
av_log(ctx, AV_LOG_ERROR, "No file path for %s\n",
|
||||
s->font);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
av_log(ctx, AV_LOG_INFO, "Using \"%s\"\n", filename);
|
||||
if (!s->fontsize)
|
||||
s->fontsize = size + 0.5;
|
||||
err = load_font_file(ctx, filename, index, error);
|
||||
|
||||
err = load_font_file(ctx, filename, index);
|
||||
if (err)
|
||||
return err;
|
||||
FcPatternDestroy(fpat);
|
||||
FcPatternDestroy(pattern);
|
||||
FcConfigDestroy(fontconfig);
|
||||
return 0;
|
||||
fail:
|
||||
FcPatternDestroy(best);
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -406,19 +439,16 @@ static int load_font(AVFilterContext *ctx)
|
||||
{
|
||||
DrawTextContext *s = 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, s->fontfile, 0, &error);
|
||||
err = load_font_file(ctx, s->fontfile, 0);
|
||||
if (!err)
|
||||
return 0;
|
||||
#if CONFIG_FONTCONFIG
|
||||
err = load_font_fontconfig(ctx, &error);
|
||||
#if CONFIG_LIBFONTCONFIG
|
||||
err = load_font_fontconfig(ctx);
|
||||
if (!err)
|
||||
return 0;
|
||||
#endif
|
||||
av_log(ctx, AV_LOG_ERROR, "Could not load font \"%s\": %s\n",
|
||||
s->fontfile, error);
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -457,7 +487,7 @@ static av_cold int init(AVFilterContext *ctx)
|
||||
"you are encouraged to use the generic timeline support through the 'enable' option\n");
|
||||
#endif
|
||||
|
||||
if (!s->fontfile && !CONFIG_FONTCONFIG) {
|
||||
if (!s->fontfile && !CONFIG_LIBFONTCONFIG) {
|
||||
av_log(ctx, AV_LOG_ERROR, "No font filename provided\n");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user