@@ -80,29 +80,16 @@ const float MAX_UINT8_CAST = 255.9 / 255;
8080#define CLAMP_UINT8 (value ) ((value > MIN_UINT8_CAST) ? ((value < MAX_UINT8_CAST) ? (int )(value * 255 ) : 255 ) : 0 )
8181
8282typedef struct {
83- public:
8483 int changed;
8584 double blend_time;
8685 int dest_x, dest_y, dest_width, dest_height;
8786 unsigned char * image;
8887} RenderBlendResult;
8988
90- double libassjs_find_next_event_start (double tm) {
91- if (!track || track->n_events == 0 ) return -1 ;
92-
93- ASS_Event *cur = track->events ;
94- long long now = (long long )(tm * 1000 );
95- long long closest = -1 ;
96-
97- for (int i = 0 ; i < track->n_events ; i++, cur++) {
98- long long start = cur->Start ;
99- if (start >= now && (start < closest || closest == -1 )) {
100- closest = start;
101- }
102- }
103-
104- return closest / 1000.0 ;
105- }
89+ typedef struct {
90+ double eventFinish, emptyFinish;
91+ int is_animated;
92+ } EventStopTimesResult;
10693
10794static int _is_move_tag_animated (char *begin, char *end) {
10895 int params[6 ];
@@ -201,63 +188,6 @@ static int _is_event_animated(ASS_Event *event) {
201188 return 0 ;
202189}
203190
204- static void detect_animated_events () {
205- ASS_Event *cur = track->events ;
206- int *animated = is_animated_events;
207- for (int i = 0 ; i < track->n_events ; i++, cur++, animated++) {
208- *animated = _is_event_animated (cur);
209- }
210- }
211-
212- void libassjs_find_event_stop_times (double tm, double *eventFinish, double *emptyFinish, int *is_animated) {
213- if (!track || track->n_events == 0 ) {
214- *eventFinish = *emptyFinish = -1 ;
215- return ;
216- }
217-
218- ASS_Event *cur = track->events ;
219- long long now = (long long )(tm * 1000 );
220-
221- long long minFinish = -1 , maxFinish = -1 , minStart = -1 ;
222- int current_animated = 0 ;
223-
224- for (int i = 0 ; i < track->n_events ; i++, cur++) {
225- long long start = cur->Start ;
226- long long finish = start + cur->Duration ;
227- if (start <= now) {
228- if (finish > now) {
229- if (finish < minFinish || minFinish == -1 ) {
230- minFinish = finish;
231- }
232- if (finish > maxFinish) {
233- maxFinish = finish;
234- }
235- if (!current_animated) current_animated = m_is_event_animated[i];
236- }
237- } else if (start < minStart || minStart == -1 ) {
238- minStart = start;
239- }
240- }
241- *is_animated = current_animated;
242-
243- if (minFinish != -1 ) {
244- // some event is going on, so we need to re-draw either when it stops
245- // or when some other event starts
246- *eventFinish = ((minFinish < minStart) ? minFinish : minStart) / 1000.0 ;
247- } else {
248- // there's no current event, so no need to draw anything
249- *eventFinish = -1 ;
250- }
251-
252- if (minFinish == maxFinish && (minStart == -1 || minStart > maxFinish)) {
253- // there's empty space after this event ends
254- *emptyFinish = minStart / 1000.0 ;
255- } else {
256- // there's no empty space after eventFinish happens
257- *emptyFinish = *eventFinish;
258- }
259- }
260-
261191class SubtitleOctopus {
262192public:
263193 ASS_Library* ass_library;
@@ -319,7 +249,7 @@ class SubtitleOctopus {
319249 printf (" cannot parse animated events\n " );
320250 exit (5 );
321251 }
322- detect_animated_events ();
252+ detectAnimatedEvents ();
323253 }
324254
325255 void createTrackMem (char *buf, unsigned long bufsize) {
@@ -522,7 +452,84 @@ class SubtitleOctopus {
522452 return &m_blendResult;
523453 }
524454
455+ double findNextEventStart (double tm) {
456+ if (!track || track->n_events == 0 ) return -1 ;
457+
458+ ASS_Event *cur = track->events ;
459+ long long now = (long long )(tm * 1000 );
460+ long long closest = -1 ;
461+
462+ for (int i = 0 ; i < track->n_events ; i++, cur++) {
463+ long long start = cur->Start ;
464+ if (start >= now && (start < closest || closest == -1 )) {
465+ closest = start;
466+ }
467+ }
468+
469+ return closest / 1000.0 ;
470+ }
471+
472+ EventStopTimesResult findEventStopTimes (double tm) {
473+ EventStopTimesResult result;
474+ if (!track || track->n_events == 0 ) {
475+ result.eventFinish = result.emptyFinish = -1 ;
476+ return result;
477+ }
478+
479+ ASS_Event *cur = track->events ;
480+ long long now = (long long )(tm * 1000 );
481+
482+ long long minFinish = -1 , maxFinish = -1 , minStart = -1 ;
483+ int current_animated = 0 ;
484+
485+ for (int i = 0 ; i < track->n_events ; i++, cur++) {
486+ long long start = cur->Start ;
487+ long long finish = start + cur->Duration ;
488+ if (start <= now) {
489+ if (finish > now) {
490+ if (finish < minFinish || minFinish == -1 ) {
491+ minFinish = finish;
492+ }
493+ if (finish > maxFinish) {
494+ maxFinish = finish;
495+ }
496+ if (!current_animated) current_animated = m_is_event_animated[i];
497+ }
498+ } else if (start < minStart || minStart == -1 ) {
499+ minStart = start;
500+ }
501+ }
502+ result.is_animated = current_animated;
503+
504+ if (minFinish != -1 ) {
505+ // some event is going on, so we need to re-draw either when it stops
506+ // or when some other event starts
507+ result.eventFinish = ((minFinish < minStart) ? minFinish : minStart) / 1000.0 ;
508+ } else {
509+ // there's no current event, so no need to draw anything
510+ result.eventFinish = -1 ;
511+ }
512+
513+ if (minFinish == maxFinish && (minStart == -1 || minStart > maxFinish)) {
514+ // there's empty space after this event ends
515+ result.emptyFinish = minStart / 1000.0 ;
516+ } else {
517+ // there's no empty space after eventFinish happens
518+ result.emptyFinish = result.eventFinish ;
519+ }
520+
521+ return result;
522+ }
523+
525524private:
525+ void detectAnimatedEvents () {
526+ ASS_Event *cur = track->events ;
527+ int *animated = m_is_event_animated;
528+ for (int i = 0 ; i < track->n_events ; i++, cur++, animated++) {
529+ *animated = _is_event_animated (cur);
530+ }
531+ }
532+
526533 ReusableBuffer m_blend;
527534 RenderBlendResult m_blendResult;
528535 int *m_is_event_animated;
0 commit comments