History

avfilter/vf_drawtext: use flags type of option for text_align

Paul B Mahol committed 3 years ago

Commit ea190b81 parent 01420312 files · +30 −37Browse files

Unified · Split

2 files
  1. doc/filters.texi +1 −1
  2. libavfilter/vf_drawtext.c +29 −36
doc/filters.texi+1−1
@@ -12386,7 +12386,7 @@ Set the line spacing in pixels. The default value of @var{line_spacing} is 0. · 12385 unmodified lines
12386 12386
12387@item text_align12387@item text_align
12388Set the vertical and horizontal alignment of the text with respect to the box boundaries.12388Set the vertical and horizontal alignment of the text with respect to the box boundaries.
12389The value must contain exactly two letters, one for the vertical alignment (T=top,12389The value is combination of flags, one for the vertical alignment (T=top,
12390M=middle, B=bottom) and one for the horizontal alignment (L=left, C=center, R=right).12390M=middle, B=bottom) and one for the horizontal alignment (L=left, C=center, R=right).
12391Please note that tab characters are only supported with the left horizontal alignment.12391Please note that tab characters are only supported with the left horizontal alignment.
12392 12392
libavfilter/vf_drawtext.c+29−36
@@ -177,6 +177,13 @@ enum y_alignment { · 176 unmodified lines
177 YA_FONT,177 YA_FONT,
178};178};
179 179
180enum text_alignment {
181 TA_LEFT = (1 << 0),
182 TA_RIGHT = (1 << 1),
183 TA_TOP = (1 << 2),
184 TA_BOTTOM = (1 << 3),
185};
186
180typedef struct HarfbuzzData {187typedef struct HarfbuzzData {
181 hb_buffer_t* buf;188 hb_buffer_t* buf;
182 hb_font_t* font;189 hb_font_t* font;
@@ -315,7 +322,7 @@ typedef struct DrawTextContext { · 132 unmodified lines
315 322
316 int boxw; ///< the value of the boxw parameter323 int boxw; ///< the value of the boxw parameter
317 int boxh; ///< the value of the boxh parameter324 int boxh; ///< the value of the boxh parameter
318 uint8_t *text_align; ///< the horizontal and vertical text alignment325 int text_align; ///< the horizontal and vertical text alignment
319 int y_align; ///< the value of the y_align parameter326 int y_align; ///< the value of the y_align parameter
320 327
321 TextLine *lines; ///< computed information about text lines328 TextLine *lines; ///< computed information about text lines
@@ -343,7 +350,19 @@ static const AVOption drawtext_options[]= { · 21 unmodified lines
343 {"boxborderw", "set box borders width", OFFSET(boxborderw), AV_OPT_TYPE_STRING, {.str="0"}, 0, 0, TFLAGS},350 {"boxborderw", "set box borders width", OFFSET(boxborderw), AV_OPT_TYPE_STRING, {.str="0"}, 0, 0, TFLAGS},
344 {"line_spacing", "set line spacing in pixels", OFFSET(line_spacing), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, TFLAGS},351 {"line_spacing", "set line spacing in pixels", OFFSET(line_spacing), AV_OPT_TYPE_INT, {.i64=0}, INT_MIN, INT_MAX, TFLAGS},
345 {"fontsize", "set font size", OFFSET(fontsize_expr), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, TFLAGS},352 {"fontsize", "set font size", OFFSET(fontsize_expr), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, TFLAGS},
346 {"text_align", "set text alignment", OFFSET(text_align), AV_OPT_TYPE_STRING, {.str="TL"}, 0, 0, TFLAGS},353 {"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"},
354 { "left", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = TA_LEFT }, .flags = TFLAGS, .unit = "text_align" },
355 { "L", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = TA_LEFT }, .flags = TFLAGS, .unit = "text_align" },
356 { "right", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = TA_RIGHT }, .flags = TFLAGS, .unit = "text_align" },
357 { "R", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = TA_RIGHT }, .flags = TFLAGS, .unit = "text_align" },
358 { "center", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = (TA_LEFT|TA_RIGHT) }, .flags = TFLAGS, .unit = "text_align" },
359 { "C", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = (TA_LEFT|TA_RIGHT) }, .flags = TFLAGS, .unit = "text_align" },
360 { "top", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = TA_TOP }, .flags = TFLAGS, .unit = "text_align" },
361 { "T", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = TA_TOP }, .flags = TFLAGS, .unit = "text_align" },
362 { "bottom", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = TA_BOTTOM }, .flags = TFLAGS, .unit = "text_align" },
363 { "B", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = TA_BOTTOM }, .flags = TFLAGS, .unit = "text_align" },
364 { "middle", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = (TA_TOP|TA_BOTTOM) }, .flags = TFLAGS, .unit = "text_align" },
365 { "M", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = (TA_TOP|TA_BOTTOM) }, .flags = TFLAGS, .unit = "text_align" },
347 {"x", "set x expression", OFFSET(x_expr), AV_OPT_TYPE_STRING, {.str="0"}, 0, 0, TFLAGS},366 {"x", "set x expression", OFFSET(x_expr), AV_OPT_TYPE_STRING, {.str="0"}, 0, 0, TFLAGS},
348 {"y", "set y expression", OFFSET(y_expr), AV_OPT_TYPE_STRING, {.str="0"}, 0, 0, TFLAGS},367 {"y", "set y expression", OFFSET(y_expr), AV_OPT_TYPE_STRING, {.str="0"}, 0, 0, TFLAGS},
349 {"boxw", "set box width", OFFSET(boxw), AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX, TFLAGS},368 {"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) · 516 unmodified lines
866 return counter;885 return counter;
867}886}
868 887
869static int validate_text_align(char* text_align)
870{
871 int err = 0;
872 if (strlen(text_align) != 2
873 || strchr("LCRTMB", text_align[0]) == NULL || strchr("LCRTMB", text_align[1]) == NULL
874 || (strchr("TMB", text_align[0]) != NULL && strchr("LCR", text_align[1]) == NULL)
875 || (strchr("LCR", text_align[0]) != NULL && strchr("TMB", text_align[1]) == NULL)) {
876 err = AVERROR(EINVAL);
877 }
878
879 return err;
880}
881
882static av_cold int init(AVFilterContext *ctx)888static av_cold int init(AVFilterContext *ctx)
883{889{
884 int err;890 int err;
@@ -944,14 +950,6 @@ static av_cold int init(AVFilterContext *ctx) · 59 unmodified lines
944 return AVERROR(EINVAL);950 return AVERROR(EINVAL);
945 }951 }
946 952
947 if ((err = validate_text_align(s->text_align))) {
948 av_log(ctx, AV_LOG_ERROR,
949 "The value provided for parameter 'text_align' is not valid,\n");
950 av_log(ctx, AV_LOG_ERROR,
951 "please specify a two characters string containing only one letter for horizontal alignment ('LCR') and one for vertical alignment ('TMB')\n");
952 return err;
953 }
954
955#if CONFIG_LIBFRIBIDI953#if CONFIG_LIBFRIBIDI
956 if (s->text_shaping)954 if (s->text_shaping)
957 if ((err = shape_text(ctx)) < 0)955 if ((err = shape_text(ctx)) < 0)
@@ -1148,11 +1146,6 @@ static int command(AVFilterContext *ctx, const char *cmd, const char *arg, char · 190 unmodified lines
1148 FT_STROKER_LINEJOIN_ROUND, 0);1146 FT_STROKER_LINEJOIN_ROUND, 0);
1149 // Dispose the old border glyphs1147 // Dispose the old border glyphs
1150 av_tree_enumerate(old->glyphs, NULL, NULL, glyph_enu_border_free);1148 av_tree_enumerate(old->glyphs, NULL, NULL, glyph_enu_border_free);
1151 } else if (strcmp(cmd, "text_align") == 0) {
1152 if (validate_text_align(old->text_align) != 0) {
1153 av_log(ctx, AV_LOG_ERROR,
1154 "Invalid command value '%s' for 'text_align'\n", old->text_align);
1155 }
1156 } else if (strcmp(cmd, "fontsize") == 0) {1149 } else if (strcmp(cmd, "fontsize") == 0) {
1157 av_expr_free(old->fontsize_pexpr);1150 av_expr_free(old->fontsize_pexpr);
1158 old->fontsize_pexpr = NULL;1151 old->fontsize_pexpr = NULL;
@@ -1561,22 +1554,22 @@ static int draw_glyphs(DrawTextContext *s, AVFrame *frame, · 402 unmodified lines
1561 Glyph dummy = { 0 }, *glyph;1554 Glyph dummy = { 0 }, *glyph;
1562 FT_Bitmap bitmap;1555 FT_Bitmap bitmap;
1563 FT_BitmapGlyph b_glyph;1556 FT_BitmapGlyph b_glyph;
1564 uint8_t j_center = 0, j_right = 0, j_middle = 0, j_bottom = 0;1557 uint8_t j_left = 0, j_right = 0, j_top = 0, j_bottom = 0;
1565 int line_w, offset_y = 0;1558 int line_w, offset_y = 0;
1566 int clip_x = 0, clip_y = 0;1559 int clip_x = 0, clip_y = 0;
1567 1560
1568 j_center = strstr(s->text_align, "C") > 0;1561 j_left = !!(s->text_align & TA_LEFT);
1569 j_right = strstr(s->text_align, "R") > 0;1562 j_right = !!(s->text_align & TA_RIGHT);
1570 j_middle = strstr(s->text_align, "M") > 0;1563 j_top = !!(s->text_align & TA_TOP);
1571 j_bottom = strstr(s->text_align, "B") > 0;1564 j_bottom = !!(s->text_align & TA_BOTTOM);
1572 1565
1573 if (j_middle) {1566 if (j_top && j_bottom) {
1574 offset_y = (s->box_height - metrics->height) / 2;1567 offset_y = (s->box_height - metrics->height) / 2;
1575 } else if (j_bottom) {1568 } else if (j_bottom) {
1576 offset_y = s->box_height - metrics->height;1569 offset_y = s->box_height - metrics->height;
1577 }1570 }
1578 1571
1579 if ((j_right || j_center) && !s->tab_warning_printed && s->tab_count > 0) {1572 if ((!j_left || j_right) && !s->tab_warning_printed && s->tab_count > 0) {
1580 s->tab_warning_printed = 1;1573 s->tab_warning_printed = 1;
1581 av_log(s, AV_LOG_WARNING, "Tab characters are only supported with left horizontal alignment\n");1574 av_log(s, AV_LOG_WARNING, "Tab characters are only supported with left horizontal alignment\n");
1582 }1575 }
@@ -1604,7 +1597,7 @@ static int draw_glyphs(DrawTextContext *s, AVFrame *frame, · 21 unmodified lines
1604 w1 = bitmap.width;1597 w1 = bitmap.width;
1605 h1 = bitmap.rows;1598 h1 = bitmap.rows;
1606 1599
1607 if (j_center) {1600 if (j_left && j_right) {
1608 x1 += (s->box_width - line_w) / 2;1601 x1 += (s->box_width - line_w) / 2;
1609 } else if (j_right) {1602 } else if (j_right) {
1610 x1 += s->box_width - line_w;1603 x1 += s->box_width - line_w;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t