diff options
author | greg <greg@blackbox> | 2009-06-18 14:08:27 +0200 |
---|---|---|
committer | greg <greg@blackbox> | 2009-06-19 05:17:22 +0200 |
commit | 4bf43431ac566f59e29a8c72dfd822bab283ddec (patch) | |
tree | b9a165f8a4b92957e1d9a9e2dce10fdd75df404e | |
parent | 7336b01091b127beb292aecc3e6ce84fd1e00b14 (diff) | |
download | libass-4bf43431ac566f59e29a8c72dfd822bab283ddec.tar.bz2 libass-4bf43431ac566f59e29a8c72dfd822bab283ddec.tar.xz |
Eliminate render_context global; move it into ass_renderer.
-rw-r--r-- | libass/ass_render.c | 623 |
1 files changed, 312 insertions, 311 deletions
diff --git a/libass/ass_render.c b/libass/ass_render.c index 71f1300..643db81 100644 --- a/libass/ass_render.c +++ b/libass/ass_render.c @@ -77,33 +77,6 @@ typedef struct event_images_s { ass_event_t* event; } event_images_t; -struct ass_renderer_s { - ass_library_t* library; - FT_Library ftlibrary; - fc_instance_t* fontconfig_priv; - ass_settings_t settings; - int render_id; - ass_synth_priv_t* synth_priv; - - ass_image_t* images_root; // rendering result is stored here - ass_image_t* prev_images_root; - - event_images_t* eimg; // temporary buffer for sorting rendered events - int eimg_size; // allocated buffer size - - // frame-global data - int width, height; // screen dimensions - int orig_height; // frame height ( = screen height - margins ) - int orig_width; // frame width ( = screen width - margins ) - int orig_height_nocrop; // frame height ( = screen height - margins + cropheight) - int orig_width_nocrop; // frame width ( = screen width - margins + cropwidth) - ass_track_t* track; - long long time; // frame's timestamp, ms - double font_scale; - double font_scale_x; // x scale applied to all glyphs to preserve text aspect ratio - double border_scale; -}; - typedef enum {EF_NONE = 0, EF_KARAOKE, EF_KARAOKE_KF, EF_KARAOKE_KO} effect_t; // describes a glyph @@ -201,7 +174,36 @@ typedef struct render_context_s { } render_context_t; static text_info_t text_info; -static render_context_t render_context; + +struct ass_renderer_s { + ass_library_t* library; + FT_Library ftlibrary; + fc_instance_t* fontconfig_priv; + ass_settings_t settings; + int render_id; + ass_synth_priv_t* synth_priv; + + ass_image_t* images_root; // rendering result is stored here + ass_image_t* prev_images_root; + + event_images_t* eimg; // temporary buffer for sorting rendered events + int eimg_size; // allocated buffer size + + // frame-global data + int width, height; // screen dimensions + int orig_height; // frame height ( = screen height - margins ) + int orig_width; // frame width ( = screen width - margins ) + int orig_height_nocrop; // frame height ( = screen height - margins + cropheight) + int orig_width_nocrop; // frame width ( = screen width - margins + cropwidth) + ass_track_t* track; + long long time; // frame's timestamp, ms + double font_scale; + double font_scale_x; // x scale applied to all glyphs to preserve text aspect ratio + double border_scale; + + render_context_t state; + text_info_t text_info; +}; struct render_priv_s { int top, height; @@ -245,7 +247,6 @@ ass_renderer_t* ass_renderer_init(ass_library_t* library) ass_renderer_t* priv = 0; int vmajor, vminor, vpatch; - memset(&render_context, 0, sizeof(render_context)); memset(&text_info, 0, sizeof(text_info)); error = FT_Init_FreeType( &ft ); @@ -286,21 +287,21 @@ ass_init_exit: return priv; } -void ass_renderer_done(ass_renderer_t* priv) +void ass_renderer_done(ass_renderer_t* render_priv) { ass_font_cache_done(); ass_bitmap_cache_done(); ass_composite_cache_done(); ass_glyph_cache_done(); - if (render_context.stroker) { - FT_Stroker_Done(render_context.stroker); - render_context.stroker = 0; + if (render_priv->state.stroker) { + FT_Stroker_Done(render_priv->state.stroker); + render_priv->state.stroker = 0; } - if (priv && priv->ftlibrary) FT_Done_FreeType(priv->ftlibrary); - if (priv && priv->fontconfig_priv) fontconfig_done(priv->fontconfig_priv); - if (priv && priv->synth_priv) ass_synth_done(priv->synth_priv); - if (priv && priv->eimg) free(priv->eimg); - free(priv); + if (render_priv && render_priv->ftlibrary) FT_Done_FreeType(render_priv->ftlibrary); + if (render_priv && render_priv->fontconfig_priv) fontconfig_done(render_priv->fontconfig_priv); + if (render_priv && render_priv->synth_priv) ass_synth_done(render_priv->synth_priv); + if (render_priv && render_priv->eimg) free(render_priv->eimg); + free(render_priv); if (text_info.glyphs) free(text_info.glyphs); } @@ -335,7 +336,7 @@ static ass_image_t* my_draw_bitmap(unsigned char* bitmap, int bitmap_w, int bitm * \return pointer to the new list tail * Performs clipping. Uses my_draw_bitmap for actual bitmap convertion. */ -static ass_image_t** render_glyph(bitmap_t* bm, int dst_x, int dst_y, uint32_t color, uint32_t color2, int brk, ass_image_t** tail) +static ass_image_t** render_glyph(ass_renderer_t* render_priv, bitmap_t* bm, int dst_x, int dst_y, uint32_t color, uint32_t color2, int brk, ass_image_t** tail) { // brk is relative to dst_x // color = color left of brk @@ -350,10 +351,10 @@ static ass_image_t** render_glyph(bitmap_t* bm, int dst_x, int dst_y, uint32_t c brk -= bm->left; // clipping - clip_x0 = render_context.clip_x0; - clip_y0 = render_context.clip_y0; - clip_x1 = render_context.clip_x1; - clip_y1 = render_context.clip_y1; + clip_x0 = render_priv->state.clip_x0; + clip_y0 = render_priv->state.clip_y0; + clip_x1 = render_priv->state.clip_x1; + clip_y1 = render_priv->state.clip_y1; b_x0 = 0; b_y0 = 0; b_x1 = bm->w; @@ -520,7 +521,7 @@ static ass_image_t* render_text(ass_renderer_t* render_priv, text_info_t* text_i bm = info->bm_s; here_tail = tail; - tail = render_glyph(bm, pen_x, pen_y, info->c[3], 0, 1000000, tail); + tail = render_glyph(render_priv, bm, pen_x, pen_y, info->c[3], 0, 1000000, tail); if (last_tail && tail != here_tail && ((info->c[3] & 0xff) > 0)) render_overlap(last_tail, here_tail, last_hash, &info->hash_key); last_tail = here_tail; @@ -541,7 +542,7 @@ static ass_image_t* render_text(ass_renderer_t* render_priv, text_info_t* text_i // do nothing } else { here_tail = tail; - tail = render_glyph(bm, pen_x, pen_y, info->c[2], 0, 1000000, tail); + tail = render_glyph(render_priv, bm, pen_x, pen_y, info->c[2], 0, 1000000, tail); if (last_tail && tail != here_tail && ((info->c[2] & 0xff) > 0)) render_overlap(last_tail, here_tail, last_hash, &info->hash_key); last_tail = here_tail; @@ -559,13 +560,13 @@ static ass_image_t* render_text(ass_renderer_t* render_priv, text_info_t* text_i if ((info->effect_type == EF_KARAOKE) || (info->effect_type == EF_KARAOKE_KO)) { if (info->effect_timing > info->bbox.xMax) - tail = render_glyph(bm, pen_x, pen_y, info->c[0], 0, 1000000, tail); + tail = render_glyph(render_priv, bm, pen_x, pen_y, info->c[0], 0, 1000000, tail); else - tail = render_glyph(bm, pen_x, pen_y, info->c[1], 0, 1000000, tail); + tail = render_glyph(render_priv, bm, pen_x, pen_y, info->c[1], 0, 1000000, tail); } else if (info->effect_type == EF_KARAOKE_KF) { - tail = render_glyph(bm, pen_x, pen_y, info->c[0], info->c[1], info->effect_timing, tail); + tail = render_glyph(render_priv, bm, pen_x, pen_y, info->c[0], info->c[1], info->effect_timing, tail); } else - tail = render_glyph(bm, pen_x, pen_y, info->c[0], 0, 1000000, tail); + tail = render_glyph(render_priv, bm, pen_x, pen_y, info->c[0], 0, 1000000, tail); } *tail = 0; @@ -659,37 +660,37 @@ static void change_font_size(ass_renderer_t* render_priv, double sz) else if (size > render_priv->height * 2) size = render_priv->height * 2; - ass_font_set_size(render_context.font, size); + ass_font_set_size(render_priv->state.font, size); - render_context.font_size = sz; + render_priv->state.font_size = sz; } /** - * \brief Change current font, using setting from render_context. + * \brief Change current font, using setting from render_priv->state. */ static void update_font(ass_renderer_t* render_priv) { unsigned val; ass_font_desc_t desc; - desc.family = strdup(render_context.family); - desc.treat_family_as_pattern = render_context.treat_family_as_pattern; + desc.family = strdup(render_priv->state.family); + desc.treat_family_as_pattern = render_priv->state.treat_family_as_pattern; - val = render_context.bold; + val = render_priv->state.bold; // 0 = normal, 1 = bold, >1 = exact weight if (val == 0) val = 80; // normal else if (val == 1) val = 200; // bold desc.bold = val; - val = render_context.italic; + val = render_priv->state.italic; if (val == 0) val = 0; // normal else if (val == 1) val = 110; //italic desc.italic = val; - render_context.font = ass_font_new(render_priv->library, render_priv->ftlibrary, render_priv->fontconfig_priv, &desc); + render_priv->state.font = ass_font_new(render_priv->library, render_priv->ftlibrary, render_priv->fontconfig_priv, &desc); free(desc.family); - if (render_context.font) - change_font_size(render_priv, render_context.font_size); + if (render_priv->state.font) + change_font_size(render_priv, render_priv->state.font_size); } /** @@ -699,38 +700,38 @@ static void update_font(ass_renderer_t* render_priv) static void change_border(ass_renderer_t* render_priv, double border) { int b; - if (!render_context.font) return; + if (!render_priv->state.font) return; if (border < 0) { - if (render_context.style->BorderStyle == 1) - border = render_context.style->Outline; + if (render_priv->state.style->BorderStyle == 1) + border = render_priv->state.style->Outline; else border = 1.; } - render_context.border = border; + render_priv->state.border = border; b = 64 * border * render_priv->border_scale; if (b > 0) { - if (!render_context.stroker) { + if (!render_priv->state.stroker) { int error; #if (FREETYPE_MAJOR > 2) || ((FREETYPE_MAJOR == 2) && (FREETYPE_MINOR > 1)) - error = FT_Stroker_New( render_priv->ftlibrary, &render_context.stroker ); + error = FT_Stroker_New( render_priv->ftlibrary, &render_priv->state.stroker ); #else // < 2.2 - error = FT_Stroker_New( render_context.font->faces[0]->memory, &render_context.stroker ); + error = FT_Stroker_New( render_priv->state.font->faces[0]->memory, &render_priv->state.stroker ); #endif if (error) { mp_msg(MSGT_ASS, MSGL_V, "failed to get stroker\n"); - render_context.stroker = 0; + render_priv->state.stroker = 0; } } - if (render_context.stroker) - FT_Stroker_Set( render_context.stroker, b, + if (render_priv->state.stroker) + FT_Stroker_Set( render_priv->state.stroker, b, FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 0 ); } else { - FT_Stroker_Done(render_context.stroker); - render_context.stroker = 0; + FT_Stroker_Done(render_priv->state.stroker); + render_priv->state.stroker = 0; } } @@ -855,9 +856,9 @@ static char* parse_tag(ass_renderer_t* render_priv, char* p, double pwr) { if (mystrtod(&p, &val)) { val = (val < 0) ? 0 : val; val = (val > BLUR_MAX_RADIUS) ? BLUR_MAX_RADIUS : val; - render_context.blur = val; + render_priv->state.blur = val; } else - render_context.blur = 0.0; + render_priv->state.blur = 0.0; // ASS standard tags } else if (mystrcmp(&p, "fsc")) { char tp = *p++; @@ -865,34 +866,34 @@ static char* parse_tag(ass_renderer_t* render_priv, char* p, double pwr) { if (tp == 'x') { if (mystrtod(&p, &val)) { val /= 100; - render_context.scale_x = render_context.scale_x * ( 1 - pwr) + val * pwr; + render_priv->state.scale_x = render_priv->state.scale_x * ( 1 - pwr) + val * pwr; } else - render_context.scale_x = render_context.style->ScaleX; + render_priv->state.scale_x = render_priv->state.style->ScaleX; } else if (tp == 'y') { if (mystrtod(&p, &val)) { val /= 100; - render_context.scale_y = render_context.scale_y * ( 1 - pwr) + val * pwr; + render_priv->state.scale_y = render_priv->state.scale_y * ( 1 - pwr) + val * pwr; } else - render_context.scale_y = render_context.style->ScaleY; + render_priv->state.scale_y = render_priv->state.style->ScaleY; } } else if (mystrcmp(&p, "fsp")) { double val; if (mystrtod(&p, &val)) - render_context.hspacing = render_context.hspacing * ( 1 - pwr ) + val * pwr; + render_priv->state.hspacing = render_priv->state.hspacing * ( 1 - pwr ) + val * pwr; else - render_context.hspacing = render_context.style->Spacing; + render_priv->state.hspacing = render_priv->state.style->Spacing; } else if (mystrcmp(&p, "fs")) { double val; if (mystrtod(&p, &val)) - val = render_context.font_size * ( 1 - pwr ) + val * pwr; + val = render_priv->state.font_size * ( 1 - pwr ) + val * pwr; else - val = render_context.style->FontSize; - if (render_context.font) + val = render_priv->state.style->FontSize; + if (render_priv->state.font) change_font_size(render_priv, val); } else if (mystrcmp(&p, "bord")) { double val; if (mystrtod(&p, &val)) - val = render_context.border * ( 1 - pwr ) + val * pwr; + val = render_priv->state.border * ( 1 - pwr ) + val * pwr; else val = -1.; // reset to default change_border(render_priv, val); @@ -918,12 +919,12 @@ static char* parse_tag(ass_renderer_t* render_priv, char* p, double pwr) { x1, y1, x2, y2, (int64_t)t1, (int64_t)t2); } else { t1 = 0; - t2 = render_context.event->Duration; + t2 = render_priv->state.event->Duration; mp_msg(MSGT_ASS, MSGL_DBG2, "movement: (%f, %f) -> (%f, %f)\n", x1, y1, x2, y2); } skip(')'); delta_t = t2 - t1; - t = render_priv->time - render_context.event->Start; + t = render_priv->time - render_priv->state.event->Start; if (t < t1) k = 0.; else if (t > t2) @@ -931,33 +932,33 @@ static char* parse_tag(ass_renderer_t* render_priv, char* p, double pwr) { else k = ((double)(t - t1)) / delta_t; x = k * (x2 - x1) + x1; y = k * (y2 - y1) + y1; - if (render_context.evt_type != EVENT_POSITIONED) { - render_context.pos_x = x; - render_context.pos_y = y; - render_context.detect_collisions = 0; - render_context.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; } } else if (mystrcmp(&p, "frx")) { double val; if (mystrtod(&p, &val)) { val *= M_PI / 180; - render_context.frx = val * pwr + render_context.frx * (1-pwr); + render_priv->state.frx = val * pwr + render_priv->state.frx * (1-pwr); } else - render_context.frx = 0.; + render_priv->state.frx = 0.; } else if (mystrcmp(&p, "fry")) { double val; if (mystrtod(&p, &val)) { val *= M_PI / 180; - render_context.fry = val * pwr + render_context.fry * (1-pwr); + render_priv->state.fry = val * pwr + render_priv->state.fry * (1-pwr); } else - render_context.fry = 0.; + render_priv->state.fry = 0.; } else if (mystrcmp(&p, "frz") || mystrcmp(&p, "fr")) { double val; if (mystrtod(&p, &val)) { val *= M_PI / 180; - render_context.frz = val * pwr + render_context.frz * (1-pwr); + render_priv->state.frz = val * pwr + render_priv->state.frz * (1-pwr); } else - render_context.frz = M_PI * render_context.style->Angle / 180.; + render_priv->state.frz = M_PI * render_priv->state.style->Angle / 180.; } else if (mystrcmp(&p, "fn")) { char* start = p; char* family; @@ -967,10 +968,10 @@ static char* parse_tag(ass_renderer_t* render_priv, char* p, double pwr) { strncpy(family, start, p - start); family[p - start] = '\0'; } else - family = strdup(render_context.style->FontName); - if (render_context.family) - free(render_context.family); - render_context.family = family; + family = strdup(render_priv->state.style->FontName); + if (render_priv->state.family) + free(render_priv->state.family); + render_priv->state.family = family; update_font(render_priv); } else if (mystrcmp(&p, "alpha")) { uint32_t val; @@ -978,12 +979,12 @@ static char* parse_tag(ass_renderer_t* render_priv, char* p, double pwr) { if (strtocolor(&p, &val)) { unsigned char a = val >> 24; for (i = 0; i < 4; ++i) - change_alpha(&render_context.c[i], a, pwr); + change_alpha(&render_priv->state.c[i], a, pwr); } else { - change_alpha(&render_context.c[0], render_context.style->PrimaryColour, pwr); - change_alpha(&render_context.c[1], render_context.style->SecondaryColour, pwr); - change_alpha(&render_context.c[2], render_context.style->OutlineColour, pwr); - change_alpha(&render_context.c[3], render_context.style->BackColour, pwr); + change_alpha(&render_priv->state.c[0], render_priv->state.style->PrimaryColour, pwr); + change_alpha(&render_priv->state.c[1], render_priv->state.style->SecondaryColour, pwr); + change_alpha(&render_priv->state.c[2], render_priv->state.style->OutlineColour, pwr); + change_alpha(&render_priv->state.c[3], render_priv->state.style->BackColour, pwr); } // FIXME: simplify } else if (mystrcmp(&p, "an")) { @@ -995,15 +996,15 @@ static char* parse_tag(ass_renderer_t* render_priv, char* p, double pwr) { val = ((val - 1) % 3) + 1; // horizontal alignment val += v*4; mp_msg(MSGT_ASS, MSGL_DBG2, "align %d\n", val); - render_context.alignment = val; + render_priv->state.alignment = val; } else - render_context.alignment = render_context.style->Alignment; + render_priv->state.alignment = render_priv->state.style->Alignment; } else if (mystrcmp(&p, "a")) { int val; if (mystrtoi(&p, &val) && val) - render_context.alignment = val; + render_priv->state.alignment = val; else - render_context.alignment = render_context.style->Alignment; + render_priv->state.alignment = render_priv->state.style->Alignment; } else if (mystrcmp(&p, "pos")) { double v1, v2; skip('('); @@ -1012,14 +1013,14 @@ static char* parse_tag(ass_renderer_t* render_priv, char* p, double pwr) { mystrtod(&p, &v2); skip(')'); mp_msg(MSGT_ASS, MSGL_DBG2, "pos(%f, %f)\n", v1, v2); - if (render_context.evt_type == EVENT_POSITIONED) { + if (render_priv->state.evt_type == EVENT_POSITIONED) { mp_msg(MSGT_ASS, MSGL_V, "Subtitle has a new \\pos " "after \\move or \\pos, ignoring\n"); } else { - render_context.evt_type = EVENT_POSITIONED; - render_context.detect_collisions = 0; - render_context.pos_x = v1; - render_context.pos_y = v2; + 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; } } else if (mystrcmp(&p, "fad")) { int a1, a2, a3; @@ -1033,7 +1034,7 @@ static char* parse_tag(ass_renderer_t* render_priv, char* p, double pwr) { // 2-argument version (\fad, according to specs) // a1 and a2 are fade-in and fade-out durations t1 = 0; - t4 = render_context.event->Duration; + t4 = render_priv->state.event->Duration; t2 = a1; t3 = t4 - a2; a1 = 0xFF; @@ -1054,7 +1055,7 @@ static char* parse_tag(ass_renderer_t* render_priv, char* p, double pwr) { mystrtoll(&p, &t4); } skip(')'); - render_context.fade = interpolate_alpha(render_priv->time - render_context.event->Start, t1, t2, t3, t4, a1, a2, a3); + render_priv->state.fade = interpolate_alpha(render_priv->time - render_priv->state.event->Start, t1, t2, t3, t4, a1, a2, a3); } else if (mystrcmp(&p, "org")) { int v1, v2; skip('('); @@ -1063,12 +1064,12 @@ static char* parse_tag(ass_renderer_t* render_priv, char* p, double pwr) { mystrtoi(&p, &v2); skip(')'); mp_msg(MSGT_ASS, MSGL_DBG2, "org(%d, %d)\n", v1, v2); - // render_context.evt_type = EVENT_POSITIONED; - if (!render_context.have_origin) { - render_context.org_x = v1; - render_context.org_y = v2; - render_context.have_origin = 1; - render_context.detect_collisions = 0; + // render_priv->state.evt_type = EVENT_POSITIONED; + if (!render_priv->state.have_origin) { + render_priv->state.org_x = v1; + render_priv->state.org_y = v2; + render_priv->state.have_origin = 1; + render_priv->state.detect_collisions = 0; } } else if (mystrcmp(&p, "t")) { double v[3]; @@ -1089,17 +1090,17 @@ static char* parse_tag(ass_renderer_t* render_priv, char* p, double pwr) { } else if (cnt == 2) { v1 = v[0]; v2 = v[1]; v3 = 1.; } else if (cnt == 1) { - v1 = 0; v2 = render_context.event->Duration; v3 = v[0]; + v1 = 0; v2 = render_priv->state.event->Duration; v3 = v[0]; } else { // cnt == 0 - v1 = 0; v2 = render_context.event->Duration; v3 = 1.; + v1 = 0; v2 = render_priv->state.event->Duration; v3 = 1.; } - render_context.detect_collisions = 0; + render_priv->state.detect_collisions = 0; t1 = v1; t2 = v2; delta_t = v2 - v1; if (v3 < 0.) v3 = 0.; - t = render_priv->time - render_context.event->Start; // FIXME: move to render_context + t = render_priv->time - render_priv->state.event->Start; // FIXME: move to render_context if (t <= t1) k = 0.; else if (t >= t2) @@ -1125,22 +1126,22 @@ static char* parse_tag(ass_renderer_t* render_priv, char* p, double pwr) { res &= mystrtoi(&p, &y1); skip(')'); if (res) { - render_context.clip_x0 = render_context.clip_x0 * (1-pwr) + x0 * pwr; - render_context.clip_x1 = render_context.clip_x1 * (1-pwr) + x1 * pwr; - render_context.clip_y0 = render_context.clip_y0 * (1-pwr) + y0 * pwr; - render_context.clip_y1 = render_context.clip_y1 * (1-pwr) + y1 * pwr; + render_priv->state.clip_x0 = render_priv->state.clip_x0 * (1-pwr) + x0 * pwr; + render_priv->state.clip_x1 = render_priv->state.clip_x1 * (1-pwr) + x1 * pwr; + render_priv->state.clip_y0 = render_priv->state.clip_y0 * (1-pwr) + y0 * pwr; + render_priv->state.clip_y1 = render_priv->state.clip_y1 * (1-pwr) + y1 * pwr; } else { - render_context.clip_x0 = 0; - render_context.clip_y0 = 0; - render_context.clip_x1 = render_priv->track->PlayResX; - render_context.clip_y1 = render_priv->track->PlayResY; + render_priv->state.clip_x0 = 0; + render_priv->state.clip_y0 = 0; + render_priv->state.clip_x1 = render_priv->track->PlayResX; + render_priv->state.clip_y1 = render_priv->track->PlayResY; } } else if (mystrcmp(&p, "c")) { uint32_t val; if (!strtocolor(&p, &val)) - val = render_context.style->PrimaryColour; + val = render_priv->state.style->PrimaryColour; mp_msg(MSGT_ASS, MSGL_DBG2, "color: %X\n", val); - change_color(&render_context.c[0], val, pwr); + change_color(&render_priv->state.c[0], val, pwr); } else if ((*p >= '1') && (*p <= '4') && (++p) && (mystrcmp(&p, "c") || mystrcmp(&p, "a"))) { char n = *(p-2); int cidx = n - '1'; @@ -1149,18 +1150,18 @@ static char* parse_tag(ass_renderer_t* render_priv, char* p, double pwr) { assert((n >= '1') && (n <= '4')); if (!strtocolor(&p, &val)) switch(n) { - case '1': val = render_context.style->PrimaryColour; break; - case '2': val = render_context.style->SecondaryColour; break; - case '3': val = render_context.style->OutlineColour; break; - case '4': val = render_context.style->BackColour; break; + case '1': val = render_priv->state.style->PrimaryColour; break; + case '2': val = render_priv->state.style->SecondaryColour; break; + case '3': val = render_priv->state.style->OutlineColour; break; + case '4': val = render_priv->state.style->BackColour; break; default : val = 0; break; // impossible due to assert; avoid compilation warning } switch (cmd) { - case 'c': change_color(render_context.c + cidx, val, pwr); break; - case 'a': change_alpha(render_context.c + cidx, val >> 24, pwr); break; + case 'c': change_color(render_priv->state.c + cidx, val, pwr); break; + case 'a': change_alpha(render_priv->state.c + cidx, val >> 24, pwr); break; default: mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_BadCommand, n, cmd); break; } - mp_msg(MSGT_ASS, MSGL_DBG2, "single c/a at %f: %c%c = %X \n", pwr, n, cmd, render_context.c[cidx]); + mp_msg(MSGT_ASS, MSGL_DBG2, "single c/a at %f: %c%c = %X \n", pwr, n, cmd, render_priv->state.c[cidx]); } else if (mystrcmp(&p, "r")) { reset_render_context(render_priv); } else if (mystrcmp(&p, "be")) { @@ -1169,52 +1170,52 @@ static char* parse_tag(ass_renderer_t* render_priv, char* p, double pwr) { // Clamp to a safe upper limit, since high values need excessive CPU val = (val < 0) ? 0 : val; val = (val > MAX_BE) ? MAX_BE : val; - render_context.be = val; + render_priv->state.be = val; } else - render_context.be = 0; + render_priv->state.be = 0; } else if (mystrcmp(&p, "b")) { int b; if (mystrtoi(&p, &b)) { if (pwr >= .5) - render_context.bold = b; + render_priv->state.bold = b; } else - render_context.bold = render_context.style->Bold; + render_priv->state.bold = render_priv->state.style->Bold; update_font(render_priv); } else if (mystrcmp(&p, "i")) { int i; if (mystrtoi(&p, &i)) { if (pwr >= .5) - render_context.italic = i; + render_priv->state.italic = i; } else - render_context.italic = render_context.style->Italic; + render_priv->state.italic = render_priv->state.style->Italic; update_font(render_priv); } else if (mystrcmp(&p, "kf") || mystrcmp(&p, "K")) { int val = 0; mystrtoi(&p, &val); - render_context.effect_type = EF_KARAOKE_KF; - if (render_context.effect_timing) - render_context.effect_skip_timing += render_context.effect_timing; - render_context.effect_timing = val * 10; + render_priv->state.effect_type = EF_KARAOKE_KF; + if (render_priv->state.effect_timing) + render_priv->state.effect_skip_timing += render_priv->state.effect_timing; + render_priv->state.effect_timing = val * 10; } else if (mystrcmp(&p, "ko")) { int val = 0; mystrtoi(&p, &val); - render_context.effect_type = EF_KARAOKE_KO; - if (render_context.effect_timing) - render_context.effect_skip_timing += render_context.effect_timing; - render_context.effect_timing = val * 10; + render_priv->state.effect_type = EF_KARAOKE_KO; + if (render_priv->state.effect_timing) + render_priv->state.effect_skip_timing += render_priv->state.effect_timing; + render_priv->state.effect_timing = val * 10; } else if (mystrcmp(&p, "k")) { int val = 0; mystrtoi(&p, &val); - render_context.effect_type = EF_KARAOKE; - if (render_context.effect_timing) - render_context.effect_skip_timing += render_context.effect_timing; - render_context.effect_timing = val * 10; + render_priv->state.effect_type = EF_KARAOKE; + if (render_priv->state.effect_timing) + render_priv->state.effect_skip_timing += render_priv->state.effect_timing; + render_priv->state.effect_timing = val * 10; } else if (mystrcmp(&p, "shad")) { int val; if (mystrtoi(&p, &val)) - render_context.shadow = val; + render_priv->state.shadow = val; else - render_context.shadow = render_context.style->Shadow; + render_priv->state.shadow = render_priv->state.style->Shadow; } else if (mystrcmp(&p, "pbo")) { int val = 0; mystrtoi(&p, &val); // ignored @@ -1222,7 +1223,7 @@ static char* parse_tag(ass_renderer_t* render_priv, char* p, double pwr) { int val; if (!mystrtoi(&p, &val)) val = 0; - render_context.drawing_mode = !!val; + render_priv->state.drawing_mode = !!val; } return p; @@ -1299,21 +1300,21 @@ static void apply_transition_effects(ass_renderer_t* render_priv, ass_event_t* e return; } if (cnt >= 2 && v[1] == 0) // right-to-left - render_context.scroll_direction = SCROLL_RL; + render_priv->state.scroll_direction = SCROLL_RL; else // left-to-right - render_context.scroll_direction = SCROLL_LR; + render_priv->state.scroll_direction = SCROLL_LR; delay = v[0]; if (delay == 0) delay = 1; // ? - render_context.scroll_shift = (render_priv->time - render_context.event->Start) / delay; - render_context.evt_type = EVENT_HSCROLL; + render_priv->state.scroll_shift = (render_priv->time - render_priv->state.event->Start) / delay; + render_priv->state.evt_type = EVENT_HSCROLL; return; } if (strncmp(event->Effect, "Scroll up;", 10) == 0) { - render_context.scroll_direction = SCROLL_BT; + render_priv->state.scroll_direction = SCROLL_BT; } else if (strncmp(event->Effect, "Scroll down;", 12) == 0) { - render_context.scroll_direction = SCROLL_TB; + render_priv->state.scroll_direction = SCROLL_TB; } else { mp_msg(MSGT_ASS, MSGL_V, "Unknown transition effect: %s \n", event->Effect); return; @@ -1328,7 +1329,7 @@ static void apply_transition_effects(ass_renderer_t* render_priv, ass_event_t* e } delay = v[2]; if (delay == 0) delay = 1; // ? - render_context.scroll_shift = (render_priv->time - render_context.event->Start) / delay; + render_priv->state.scroll_shift = (render_priv->time - render_priv->state.event->Start) / delay; if (v[0] < v[1]) { y0 = v[0]; y1 = v[1]; } else { @@ -1336,10 +1337,10 @@ static void apply_transition_effects(ass_renderer_t* render_priv, ass_event_t* e } if (y1 == 0) y1 = render_priv->track->PlayResY; // y0=y1=0 means fullscreen scrolling - render_context.clip_y0 = y0; - render_context.clip_y1 = y1; - render_context.evt_type = EVENT_VSCROLL; - render_context.detect_collisions = 0; + render_priv->state.clip_y0 = y0; + render_priv->state.clip_y1 = y1; + render_priv->state.evt_type = EVENT_VSCROLL; + render_priv->state.detect_collisions = 0; } } @@ -1350,60 +1351,60 @@ static void apply_transition_effects(ass_renderer_t* render_priv, ass_event_t* e */ static void reset_render_context(ass_renderer_t* render_priv) { - render_context.c[0] = render_context.style->PrimaryColour; - render_context.c[1] = render_context.style->SecondaryColour; - render_context.c[2] = render_context.style->OutlineColour; - render_context.c[3] = render_context.style->BackColour; - render_context.font_size = render_context.style->FontSize; - - if (render_context.family) - free(render_context.family); - render_context.family = strdup(render_context.style->FontName); - render_context.treat_family_as_pattern = render_context.style->treat_fontname_as_pattern; - render_context.bold = render_context.style->Bold; - render_context.italic = render_context.style->Italic; + render_priv->state.c[0] = render_priv->state.style->PrimaryColour; + render_priv->state.c[1] = render_priv->state.style->SecondaryColour; + render_priv->state.c[2] = render_priv->state.style->OutlineColour; + render_priv->state.c[3] = render_priv->state.style->BackColour; + render_priv->state.font_size = render_priv->state.style->FontSize; + + if (render_priv->state.family) + free(render_priv->state.family); + render_priv->state.family = strdup(render_priv->state.style->FontName); + render_priv->state.treat_family_as_pattern = render_priv->state.style->treat_fontname_as_pattern; + render_priv->state.bold = render_priv->state.style->Bold; + render_priv->state.italic = render_priv->state.style->Italic; update_font(render_priv); change_border(render_priv, -1.); - render_context.scale_x = render_context.style->ScaleX; - render_context.scale_y = render_context.style->ScaleY; - render_context.hspacing = render_context.style->Spacing; - render_context.be = 0; - render_context.blur = 0.0; - render_context.shadow = render_context.style->Shadow; - render_context.frx = render_context.fry = 0.; - render_context.frz = M_PI * render_context.style->Angle / 180.; + render_priv->state.scale_x = render_priv->state.style->ScaleX; + render_priv->state.scale_y = render_priv->state.style->ScaleY; + render_priv->state.hspacing = render_priv->state.style->Spacing; + render_priv->state.be = 0; + render_priv->state.blur = 0.0; + render_priv->state.shadow = render_priv->state.style->Shadow; + render_priv->state.frx = render_priv->state.fry = 0.; + render_priv->state.frz = M_PI * render_priv->state.style->Angle / 180.; // FIXME: does not reset unsupported attributes. } /** - * \brief Start new event. Reset render_context. + * \brief Start new event. Reset render_priv->state. */ static void init_render_context(ass_renderer_t* render_priv, ass_event_t* event) { - render_context.event = event; - render_context.style = render_priv->track->styles + event->Style; + render_priv->state.event = event; + render_priv->state.style = render_priv->track->styles + event->Style; reset_render_context(render_priv); - render_context.evt_type = EVENT_NORMAL; - render_context.alignment = render_context.style->Alignment; - render_context.pos_x = 0; - render_context.pos_y = 0; - render_context.org_x = 0; - render_context.org_y = 0; - render_context.have_origin = 0; - render_context.clip_x0 = 0; - render_context.clip_y0 = 0; - render_context.clip_x1 = render_priv->track->PlayResX; - render_context.clip_y1 = render_priv->track->PlayResY; - render_context.detect_collisions = 1; - render_context.fade = 0; - render_context.drawing_mode = 0; - render_context.effect_type = EF_NONE; - render_context.effect_timing = 0; - render_context.effect_skip_timing = 0; + render_priv->state.evt_type = EVENT_NORMAL; + render_priv->state.alignment = render_priv->state.style->Alignment; + render_priv->state.pos_x = 0; + render_priv->state.pos_y = 0; + render_priv->state.org_x = 0; + render_priv->state.org_y = 0; + render_priv->state.have_origin = 0; + render_priv->state.clip_x0 = 0; + render_priv->state.clip_y0 = 0; + render_priv->state.clip_x1 = render_priv->track->PlayResX; + render_priv->state.clip_y1 = render_priv->track->PlayResY; + render_priv->state.detect_collisions = 1; + render_priv->state.fade = 0; + render_priv->state.drawing_mode = 0; + render_priv->state.effect_type = EF_NONE; + render_priv->state.effect_timing = 0; + render_priv->state.effect_skip_timing = 0; apply_transition_effects(render_priv, event); } @@ -1428,15 +1429,15 @@ static void get_outline_glyph(ass_renderer_t* render_priv, int symbol, glyph_inf glyph_hash_val_t* val; glyph_hash_key_t key; memset(&key, 0, sizeof(key)); - key.font = render_context.font; - key.size = render_context.font_size; + key.font = render_priv->state.font; + key.size = render_priv->state.font_size; key.ch = symbol; - key.scale_x = (render_context.scale_x * 0xFFFF); - key.scale_y = (render_context.scale_y * 0xFFFF); + key.scale_x = (render_priv->state.scale_x * 0xFFFF); + key.scale_y = (render_priv->state.scale_y * 0xFFFF); key.advance = *advance; - key.bold = render_context.bold; - key.italic = render_context.italic; - key.outline = render_context.border * 0xFFFF; + key.bold = render_priv->state.bold; + key.italic = render_priv->state.italic; + key.outline = render_priv->state.border * 0xFFFF; memset(info, 0, sizeof(glyph_info_t)); @@ -1450,16 +1451,16 @@ static void get_outline_glyph(ass_renderer_t* render_priv, int symbol, glyph_inf info->advance.y = val->advance.y; } else { glyph_hash_val_t v; - info->glyph = ass_font_get_glyph(render_priv->fontconfig_priv, render_context.font, symbol, render_priv->settings.hinting); + info->glyph = ass_font_get_glyph(render_priv->fontconfig_priv, render_priv->state.font, symbol, render_priv->settings.hinting); if (!info->glyph) return; info->advance.x = d16_to_d6(info->glyph->advance.x); info->advance.y = d16_to_d6(info->glyph->advance.y); FT_Glyph_Get_CBox( info->glyph, FT_GLYPH_BBOX_PIXELS, &info->bbox); - if (render_context.stroker) { + if (render_priv->state.stroker) { info->outline_glyph = info->glyph; - error = FT_Glyph_StrokeBorder( &(info->outline_glyph), render_context.stroker, 0 , 0 ); // don't destroy original + error = FT_Glyph_StrokeBorder( &(info->outline_glyph), render_priv->state.stroker, 0 , 0 ); // don't destroy original if (error) { mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_FT_Glyph_Stroke_Error, error); } @@ -1723,7 +1724,7 @@ static void process_karaoke_effects(ass_renderer_t* render_priv) int x; int x_start, x_end; - tm_current = render_priv->time - render_context.event->Start; + tm_current = render_priv->time - render_priv->state.event->Start; timing = 0; s1 = s2 = 0; for (i = 0; i <= text_info.length; ++i) { @@ -1914,10 +1915,10 @@ static int ass_render_event(ass_renderer_t* render_priv, ass_event_t* event, eve // this affects render_context do { code = get_next_char(render_priv, &p); - } while (code && render_context.drawing_mode); // skip everything in drawing mode + } while (code && render_priv->state.drawing_mode); // skip everything in drawing mode // face could have been changed in get_next_char - if (!render_context.font) { + if (!render_priv->state.font) { free_render_context(); return 1; } @@ -1933,22 +1934,22 @@ static int ass_render_event(ass_renderer_t* render_priv, ass_event_t* event, eve if ( previous && code ) { FT_Vector delta; - delta = ass_font_get_kerning(render_context.font, previous, code); - pen.x += delta.x * render_context.scale_x; - pen.y += delta.y * render_context.scale_y; + delta = ass_font_get_kerning(render_priv->state.font, previous, code); + pen.x += delta.x * render_priv->state.scale_x; + pen.y += delta.y * render_priv->state.scale_y; } shift.x |