m_option: add OPT_RECT

Parsed as WxH+X+Y to mp_rect. Allows also WxH without the offset.
This commit is contained in:
Kacper Michajłow 2023-08-25 19:00:31 +02:00 committed by Dudemanguy
parent 765b68f971
commit 21048291be
2 changed files with 64 additions and 0 deletions

View File

@ -2381,6 +2381,64 @@ const m_option_type_t m_option_type_size_box = {
.equal = geometry_equal,
};
void m_rect_apply(struct mp_rect *rc, int scrw, int scrh, struct m_geometry *gm)
{
*rc = (struct mp_rect){0};
m_geometry_apply(&rc->x0, &rc->y0, &rc->x1, &rc->y1, scrw, scrh, gm);
if (!gm->xy_valid && gm->wh_valid && rc->x1 == 0 && rc->y1 == 0)
return;
if (!gm->xy_valid) {
rc->x0 = 0;
rc->y0 = 0;
}
if (!gm->wh_valid || rc->x1 == 0 || rc->x1 == INT_MIN)
rc->x1 = scrw - rc->x0;
if (!gm->wh_valid || rc->y1 == 0 || rc->y1 == INT_MIN)
rc->y1 = scrh - rc->y0;
rc->x1 += rc->x0;
rc->y1 += rc->y0;
}
static int parse_rect(struct mp_log *log, const m_option_t *opt,
struct bstr name, struct bstr param, void *dst)
{
bool is_help = bstr_equals0(param, "help");
if (is_help)
goto exit;
struct m_geometry gm;
if (!parse_geometry_str(&gm, param))
goto exit;
if (gm.x_sign || gm.y_sign || gm.ws ||
(gm.wh_valid && (gm.w < 0 || gm.h < 0)) ||
(gm.xy_valid && (gm.x < 0 || gm.y < 0)))
{
goto exit;
}
if (dst)
*((struct m_geometry *)dst) = gm;
return 1;
exit:
if (!is_help) {
mp_err(log, "Option %.*s: invalid rect: '%.*s'\n",
BSTR_P(name), BSTR_P(param));
}
mp_info(log, "Valid format: W[%%][xH[%%]][+x+y]\n");
return is_help ? M_OPT_EXIT : M_OPT_INVALID;
}
const m_option_type_t m_option_type_rect = {
.name = "Video rect",
.size = sizeof(struct m_geometry),
.parse = parse_rect,
.print = print_geometry,
.copy = copy_opt,
.equal = geometry_equal,
};
#include "video/img_format.h"

View File

@ -25,6 +25,7 @@
#include "misc/bstr.h"
#include "audio/chmap.h"
#include "common/common.h"
// m_option allows to parse, print and copy data of various types.
@ -66,6 +67,7 @@ extern const m_option_type_t m_option_type_channels;
extern const m_option_type_t m_option_type_aspect;
extern const m_option_type_t m_option_type_obj_settings_list;
extern const m_option_type_t m_option_type_node;
extern const m_option_type_t m_option_type_rect;
// Used internally by m_config.c
extern const m_option_type_t m_option_type_alias;
@ -103,6 +105,7 @@ struct m_geometry {
void m_geometry_apply(int *xpos, int *ypos, int *widw, int *widh,
int scrw, int scrh, struct m_geometry *gm);
void m_rect_apply(struct mp_rect *rc, int scrw, int scrh, struct m_geometry *gm);
struct m_channels {
bool set : 1;
@ -654,6 +657,9 @@ extern const char m_option_path_separator;
#define OPT_SIZE_BOX(field) \
OPT_TYPED_FIELD(m_option_type_size_box, struct m_geometry, field)
#define OPT_RECT(field) \
OPT_TYPED_FIELD(m_option_type_rect, struct m_geometry, field)
#define OPT_TRACKCHOICE(field) \
OPT_CHOICE(field, {"no", -2}, {"auto", -1}), \
M_RANGE(0, 8190)