Showing the changes to libavfilter (1 of 2 files). Show all
Unified · Split
| @@ -177,6 +177,13 @@ enum y_alignment { · 176 unmodified lines | |||
| 177 | YA_FONT, | 177 | YA_FONT, |
| 178 | }; | 178 | }; |
| 179 | 179 | ||
| 180 | enum text_alignment { | ||
| 181 | TA_LEFT = (1 << 0), | ||
| 182 | TA_RIGHT = (1 << 1), | ||
| 183 | TA_TOP = (1 << 2), | ||
| 184 | TA_BOTTOM = (1 << 3), | ||
| 185 | }; | ||
| 186 | |||
| 180 | typedef struct HarfbuzzData { | 187 | typedef 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 parameter | 323 | int boxw; ///< the value of the boxw parameter |
| 317 | int boxh; ///< the value of the boxh parameter | 324 | int boxh; ///< the value of the boxh parameter |
| 318 | uint8_t *text_align; ///< the horizontal and vertical text alignment | 325 | int text_align; ///< the horizontal and vertical text alignment |
| 319 | int y_align; ///< the value of the y_align parameter | 326 | int y_align; ///< the value of the y_align parameter |
| 320 | 327 | ||
| 321 | TextLine *lines; ///< computed information about text lines | 328 | 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 | ||
| 869 | static 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 | |||
| 882 | static av_cold int init(AVFilterContext *ctx) | 888 | static 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_LIBFRIBIDI | 953 | #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 glyphs | 1147 | // 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; |