summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOleg Oshmyan <chortos@inbox.lv>2020-10-17 00:31:31 +0300
committerOleg Oshmyan <chortos@inbox.lv>2020-10-18 05:03:17 +0300
commit5a279a787887c0254f2fa7c94b8d9e4ee7c995ea (patch)
tree4df3b809bce14da420a233968321631de6966db9
parent16befcfd5abb3cb32ace1eb72eb721d8c67fcdbd (diff)
downloadlibass-5a279a787887c0254f2fa7c94b8d9e4ee7c995ea.tar.bz2
libass-5a279a787887c0254f2fa7c94b8d9e4ee7c995ea.tar.xz
Support Banner/Scroll effects with \pos/\move
-rw-r--r--libass/ass_parse.c12
-rw-r--r--libass/ass_render.c67
-rw-r--r--libass/ass_render.h8
3 files changed, 43 insertions, 44 deletions
diff --git a/libass/ass_parse.c b/libass/ass_parse.c
index fb57304..cf52b24 100644
--- a/libass/ass_parse.c
+++ b/libass/ass_parse.c
@@ -480,11 +480,11 @@ char *parse_tags(ASS_Renderer *render_priv, char *p, char *end, double pwr,
k = ((double) (int32_t) ((uint32_t) t - t1)) / delta_t;
x = k * (x2 - x1) + x1;
y = k * (y2 - y1) + y1;
- if (render_priv->state.evt_type != EVENT_POSITIONED) {
+ if (!(render_priv->state.evt_type & EVENT_POSITIONED)) {
render_priv->state.pos_x = x;
render_priv->state.pos_y = y;
render_priv->state.detect_collisions = 0;
- render_priv->state.evt_type = EVENT_POSITIONED;
+ render_priv->state.evt_type |= EVENT_POSITIONED;
}
} else if (tag("frx")) {
double val;
@@ -571,11 +571,11 @@ char *parse_tags(ASS_Renderer *render_priv, char *p, char *end, double pwr,
v2 = argtod(args[1]);
} else
continue;
- if (render_priv->state.evt_type == EVENT_POSITIONED) {
+ if (render_priv->state.evt_type & EVENT_POSITIONED) {
ass_msg(render_priv->library, MSGL_V, "Subtitle has a new \\pos "
"after \\move or \\pos, ignoring");
} else {
- render_priv->state.evt_type = EVENT_POSITIONED;
+ render_priv->state.evt_type |= EVENT_POSITIONED;
render_priv->state.detect_collisions = 0;
render_priv->state.pos_x = v1;
render_priv->state.pos_y = v2;
@@ -907,7 +907,7 @@ void apply_transition_effects(ASS_Renderer *render_priv, ASS_Event *event)
delay = 1; // ?
render_priv->state.scroll_shift =
(render_priv->time - render_priv->state.event->Start) / delay;
- render_priv->state.evt_type = EVENT_HSCROLL;
+ render_priv->state.evt_type |= EVENT_HSCROLL;
render_priv->state.wrap_style = 2;
return;
}
@@ -946,7 +946,7 @@ void apply_transition_effects(ASS_Renderer *render_priv, ASS_Event *event)
y1 = render_priv->track->PlayResY; // y0=y1=0 means fullscreen scrolling
render_priv->state.clip_y0 = y0;
render_priv->state.clip_y1 = y1;
- render_priv->state.evt_type = EVENT_VSCROLL;
+ render_priv->state.evt_type |= EVENT_VSCROLL;
render_priv->state.detect_collisions = 0;
}
diff --git a/libass/ass_render.c b/libass/ass_render.c
index 2cec0e4..b405153 100644
--- a/libass/ass_render.c
+++ b/libass/ass_render.c
@@ -2130,7 +2130,7 @@ static void align_lines(ASS_Renderer *render_priv, double max_text_width)
int justify = render_priv->state.justify;
double max_width = 0;
- if (render_priv->state.evt_type == EVENT_HSCROLL) {
+ if (render_priv->state.evt_type & EVENT_HSCROLL) {
justify = halign;
halign = HALIGN_LEFT;
}
@@ -2652,13 +2652,23 @@ ass_render_event(ASS_Renderer *render_priv, ASS_Event *event,
compute_string_bbox(text_info, &bbox);
// determine device coordinates for text
-
- // x coordinate for everything except positioned events
double device_x = 0;
- if (render_priv->state.evt_type == EVENT_NORMAL ||
- render_priv->state.evt_type == EVENT_VSCROLL) {
- device_x = x2scr_left(render_priv, MarginL);
- } else if (render_priv->state.evt_type == EVENT_HSCROLL) {
+ double device_y = 0;
+
+ // handle positioned events first: an event can be both positioned and
+ // scrolling, and the scrolling effect overrides the position on one axis
+ if (render_priv->state.evt_type & EVENT_POSITIONED) {
+ double base_x = 0;
+ double base_y = 0;
+ get_base_point(&bbox, render_priv->state.alignment, &base_x, &base_y);
+ device_x =
+ x2scr_pos(render_priv, render_priv->state.pos_x) - base_x;
+ device_y =
+ y2scr_pos(render_priv, render_priv->state.pos_y) - base_y;
+ }
+
+ // x coordinate
+ if (render_priv->state.evt_type & EVENT_HSCROLL) {
if (render_priv->state.scroll_direction == SCROLL_RL)
device_x =
x2scr_pos(render_priv,
@@ -2668,12 +2678,24 @@ ass_render_event(ASS_Renderer *render_priv, ASS_Event *event,
device_x =
x2scr_pos(render_priv, render_priv->state.scroll_shift) -
(bbox.x_max - bbox.x_min);
+ } else if (!(render_priv->state.evt_type & EVENT_POSITIONED)) {
+ device_x = x2scr_left(render_priv, MarginL);
}
- // y coordinate for everything except positioned events
- double device_y = 0;
- if (render_priv->state.evt_type == EVENT_NORMAL ||
- render_priv->state.evt_type == EVENT_HSCROLL) {
+ // y coordinate
+ if (render_priv->state.evt_type & EVENT_VSCROLL) {
+ if (render_priv->state.scroll_direction == SCROLL_TB)
+ device_y =
+ y2scr(render_priv,
+ render_priv->state.clip_y0 +
+ render_priv->state.scroll_shift) -
+ (bbox.y_max - bbox.y_min);
+ else if (render_priv->state.scroll_direction == SCROLL_BT)
+ device_y =
+ y2scr(render_priv,
+ render_priv->state.clip_y1 -
+ render_priv->state.scroll_shift);
+ } else if (!(render_priv->state.evt_type & EVENT_POSITIONED)) {
if (valign == VALIGN_TOP) { // toptitle
device_y =
y2scr_top(render_priv,
@@ -2704,29 +2726,6 @@ ass_render_event(ASS_Renderer *render_priv, ASS_Event *event,
device_y = scr_y0;
}
}
- } else if (render_priv->state.evt_type == EVENT_VSCROLL) {
- if (render_priv->state.scroll_direction == SCROLL_TB)
- device_y =
- y2scr(render_priv,
- render_priv->state.clip_y0 +
- render_priv->state.scroll_shift) -
- (bbox.y_max - bbox.y_min);
- else if (render_priv->state.scroll_direction == SCROLL_BT)
- device_y =
- y2scr(render_priv,
- render_priv->state.clip_y1 -
- render_priv->state.scroll_shift);
- }
-
- // positioned events are totally different
- if (render_priv->state.evt_type == EVENT_POSITIONED) {
- double base_x = 0;
- double base_y = 0;
- get_base_point(&bbox, render_priv->state.alignment, &base_x, &base_y);
- device_x =
- x2scr_pos(render_priv, render_priv->state.pos_x) - base_x;
- device_y =
- y2scr_pos(render_priv, render_priv->state.pos_y) - base_y;
}
// fix clip coordinates
diff --git a/libass/ass_render.h b/libass/ass_render.h
index 93f661a..22d7230 100644
--- a/libass/ass_render.h
+++ b/libass/ass_render.h
@@ -224,10 +224,10 @@ typedef struct {
double border_x; // outline width
double border_y;
enum {
- EVENT_NORMAL, // "normal" top-, sub- or mid- title
- EVENT_POSITIONED, // happens after pos(,), margins are ignored
- EVENT_HSCROLL, // "Banner" transition effect, text_width is unlimited
- EVENT_VSCROLL // "Scroll up", "Scroll down" transition effects
+ EVENT_NORMAL = 0, // "normal" top-, sub- or mid- title
+ EVENT_POSITIONED = 1, // happens after \pos or \move, margins are ignored
+ EVENT_HSCROLL = 2, // "Banner" transition effect, text_width is unlimited
+ EVENT_VSCROLL = 4 // "Scroll up", "Scroll down" transition effects
} evt_type;
int border_style;
uint32_t c[4]; // colors(Primary, Secondary, so on) in RGBA