[FFmpeg-cvslog] avfilter/vf_drawtext: use flags type of option for text_align

Paul B Mahol git at videolan.org
Mon Jun 19 23:41:47 EEST 2023


ffmpeg | branch: master | Paul B Mahol <onemda at gmail.com> | Mon Jun 19 21:50:26 2023 +0200| [ea190b8a2385ae527c2539ab63e668d02ca56b00] | committer: Paul B Mahol

avfilter/vf_drawtext: use flags type of option for text_align

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=ea190b8a2385ae527c2539ab63e668d02ca56b00
---

 doc/filters.texi          |  2 +-
 libavfilter/vf_drawtext.c | 65 +++++++++++++++++++++--------------------------
 2 files changed, 30 insertions(+), 37 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index 3afcc23b6a..5972145763 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -12386,7 +12386,7 @@ Set the line spacing in pixels. The default value of @var{line_spacing} is 0.
 
 @item text_align
 Set the vertical and horizontal alignment of the text with respect to the box boundaries.
-The value must contain exactly two letters, one for the vertical alignment (T=top,
+The value is combination of flags, one for the vertical alignment (T=top,
 M=middle, B=bottom) and one for the horizontal alignment (L=left, C=center, R=right).
 Please note that tab characters are only supported with the left horizontal alignment.
 
diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c
index 4c5c5d8bd6..7854362eab 100644
--- a/libavfilter/vf_drawtext.c
+++ b/libavfilter/vf_drawtext.c
@@ -177,6 +177,13 @@ enum y_alignment {
     YA_FONT,
 };
 
+enum text_alignment {
+    TA_LEFT   = (1 << 0),
+    TA_RIGHT  = (1 << 1),
+    TA_TOP    = (1 << 2),
+    TA_BOTTOM = (1 << 3),
+};
+
 typedef struct HarfbuzzData {
     hb_buffer_t* buf;
     hb_font_t* font;
@@ -315,7 +322,7 @@ typedef struct DrawTextContext {
 
     int boxw;                       ///< the value of the boxw parameter
     int boxh;                       ///< the value of the boxh parameter
-    uint8_t *text_align;            ///< the horizontal and vertical text alignment
+    int text_align;                 ///< the horizontal and vertical text alignment
     int y_align;                    ///< the value of the y_align parameter
 
     TextLine *lines;                ///< computed information about text lines
@@ -343,7 +350,19 @@ static const AVOption drawtext_options[]= {
     {"boxborderw",     "set box borders width", OFFSET(boxborderw),         AV_OPT_TYPE_STRING, {.str="0"},   0, 0, TFLAGS},
     {"line_spacing",   "set line spacing in pixels", OFFSET(line_spacing),  AV_OPT_TYPE_INT,    {.i64=0},     INT_MIN, INT_MAX, TFLAGS},
     {"fontsize",       "set font size",         OFFSET(fontsize_expr),      AV_OPT_TYPE_STRING, {.str=NULL},  0, 0, TFLAGS},
-    {"text_align",     "set text alignment",    OFFSET(text_align),         AV_OPT_TYPE_STRING, {.str="TL"},  0, 0, TFLAGS},
+    {"text_align",     "set text alignment",    OFFSET(text_align),         AV_OPT_TYPE_FLAGS,  {.i64=0}, 0, (TA_LEFT|TA_RIGHT|TA_TOP|TA_BOTTOM), TFLAGS, "text_align"},
+        { "left",    NULL, 0, AV_OPT_TYPE_CONST, { .i64 = TA_LEFT   }, .flags = TFLAGS, .unit = "text_align" },
+        { "L",       NULL, 0, AV_OPT_TYPE_CONST, { .i64 = TA_LEFT   }, .flags = TFLAGS, .unit = "text_align" },
+        { "right",   NULL, 0, AV_OPT_TYPE_CONST, { .i64 = TA_RIGHT  }, .flags = TFLAGS, .unit = "text_align" },
+        { "R",       NULL, 0, AV_OPT_TYPE_CONST, { .i64 = TA_RIGHT  }, .flags = TFLAGS, .unit = "text_align" },
+        { "center",  NULL, 0, AV_OPT_TYPE_CONST, { .i64 = (TA_LEFT|TA_RIGHT) }, .flags = TFLAGS, .unit = "text_align" },
+        { "C",       NULL, 0, AV_OPT_TYPE_CONST, { .i64 = (TA_LEFT|TA_RIGHT) }, .flags = TFLAGS, .unit = "text_align" },
+        { "top",     NULL, 0, AV_OPT_TYPE_CONST, { .i64 = TA_TOP    }, .flags = TFLAGS, .unit = "text_align" },
+        { "T",       NULL, 0, AV_OPT_TYPE_CONST, { .i64 = TA_TOP    }, .flags = TFLAGS, .unit = "text_align" },
+        { "bottom",  NULL, 0, AV_OPT_TYPE_CONST, { .i64 = TA_BOTTOM }, .flags = TFLAGS, .unit = "text_align" },
+        { "B",       NULL, 0, AV_OPT_TYPE_CONST, { .i64 = TA_BOTTOM }, .flags = TFLAGS, .unit = "text_align" },
+        { "middle",  NULL, 0, AV_OPT_TYPE_CONST, { .i64 = (TA_TOP|TA_BOTTOM) }, .flags = TFLAGS, .unit = "text_align" },
+        { "M",       NULL, 0, AV_OPT_TYPE_CONST, { .i64 = (TA_TOP|TA_BOTTOM) }, .flags = TFLAGS, .unit = "text_align" },
     {"x",              "set x expression",      OFFSET(x_expr),             AV_OPT_TYPE_STRING, {.str="0"},   0, 0, TFLAGS},
     {"y",              "set y expression",      OFFSET(y_expr),             AV_OPT_TYPE_STRING, {.str="0"},   0, 0, TFLAGS},
     {"boxw",           "set box width",         OFFSET(boxw),               AV_OPT_TYPE_INT,    {.i64=0},     0, INT_MAX, TFLAGS},
@@ -866,19 +885,6 @@ static int string_to_array(const char *source, int *result, int result_size)
     return counter;
 }
 
-static int validate_text_align(char* text_align)
-{
-    int err = 0;
-    if (strlen(text_align) != 2
-        || strchr("LCRTMB", text_align[0]) == NULL || strchr("LCRTMB", text_align[1]) == NULL
-        || (strchr("TMB", text_align[0]) != NULL && strchr("LCR", text_align[1]) == NULL)
-        || (strchr("LCR", text_align[0]) != NULL && strchr("TMB", text_align[1]) == NULL)) {
-        err = AVERROR(EINVAL);
-    }
-
-    return err;
-}
-
 static av_cold int init(AVFilterContext *ctx)
 {
     int err;
@@ -944,14 +950,6 @@ static av_cold int init(AVFilterContext *ctx)
         return AVERROR(EINVAL);
     }
 
-    if ((err = validate_text_align(s->text_align))) {
-        av_log(ctx, AV_LOG_ERROR,
-               "The value provided for parameter 'text_align' is not valid,\n");
-        av_log(ctx, AV_LOG_ERROR,
-               "please specify a two characters string containing only one letter for horizontal alignment ('LCR') and one for vertical alignment ('TMB')\n");
-        return err;
-    }
-
 #if CONFIG_LIBFRIBIDI
     if (s->text_shaping)
         if ((err = shape_text(ctx)) < 0)
@@ -1148,11 +1146,6 @@ static int command(AVFilterContext *ctx, const char *cmd, const char *arg, char
                         FT_STROKER_LINEJOIN_ROUND, 0);
             // Dispose the old border glyphs
             av_tree_enumerate(old->glyphs, NULL, NULL, glyph_enu_border_free);
-        } else if (strcmp(cmd, "text_align") == 0) {
-            if (validate_text_align(old->text_align) != 0) {
-                av_log(ctx, AV_LOG_ERROR,
-                    "Invalid command value '%s' for 'text_align'\n", old->text_align);
-            }
         } else if (strcmp(cmd, "fontsize") == 0) {
             av_expr_free(old->fontsize_pexpr);
             old->fontsize_pexpr = NULL;
@@ -1561,22 +1554,22 @@ static int draw_glyphs(DrawTextContext *s, AVFrame *frame,
     Glyph dummy = { 0 }, *glyph;
     FT_Bitmap bitmap;
     FT_BitmapGlyph b_glyph;
-    uint8_t j_center = 0, j_right = 0, j_middle = 0, j_bottom = 0;
+    uint8_t j_left = 0, j_right = 0, j_top = 0, j_bottom = 0;
     int line_w, offset_y = 0;
     int clip_x = 0, clip_y = 0;
 
-    j_center = strstr(s->text_align, "C") > 0;
-    j_right = strstr(s->text_align, "R") > 0;
-    j_middle = strstr(s->text_align, "M") > 0;
-    j_bottom = strstr(s->text_align, "B") > 0;
+    j_left = !!(s->text_align & TA_LEFT);
+    j_right = !!(s->text_align & TA_RIGHT);
+    j_top = !!(s->text_align & TA_TOP);
+    j_bottom = !!(s->text_align & TA_BOTTOM);
 
-    if (j_middle) {
+    if (j_top && j_bottom) {
         offset_y = (s->box_height - metrics->height) / 2;
     } else if (j_bottom) {
         offset_y = s->box_height - metrics->height;
     }
 
-    if ((j_right || j_center) && !s->tab_warning_printed && s->tab_count > 0) {
+    if ((!j_left || j_right) && !s->tab_warning_printed && s->tab_count > 0) {
         s->tab_warning_printed = 1;
         av_log(s, AV_LOG_WARNING, "Tab characters are only supported with left horizontal alignment\n");
     }
@@ -1604,7 +1597,7 @@ static int draw_glyphs(DrawTextContext *s, AVFrame *frame,
             w1 = bitmap.width;
             h1 = bitmap.rows;
 
-            if (j_center) {
+            if (j_left && j_right) {
                 x1 += (s->box_width - line_w) / 2;
             } else if (j_right) {
                 x1 += s->box_width - line_w;



More information about the ffmpeg-cvslog mailing list