diff options
Diffstat (limited to 'libass/ass_render.c')
-rw-r--r-- | libass/ass_render.c | 101 |
1 files changed, 80 insertions, 21 deletions
diff --git a/libass/ass_render.c b/libass/ass_render.c index 0cc1848..625a77d 100644 --- a/libass/ass_render.c +++ b/libass/ass_render.c @@ -208,6 +208,8 @@ void ass_renderer_done(ASS_Renderer *render_priv) free(render_priv->settings.default_font); free(render_priv->settings.default_family); + free(render_priv->user_override_style.FontName); + free_list_clear(render_priv); free(render_priv); } @@ -763,14 +765,89 @@ static void compute_string_bbox(TextInfo *text, DBBox *bbox) bbox->xMin = bbox->xMax = bbox->yMin = bbox->yMax = 0.; } +static ASS_Style *handle_selective_style_overrides(ASS_Renderer *render_priv, + ASS_Style *rstyle) +{ + // The script style is the one the event was declared with. + // The rstyle is either NULL, or the style used with a \r tag. + ASS_Style *script = render_priv->track->styles + + render_priv->state.event->Style; + ASS_Style *new = &render_priv->state.override_style_temp_storage; + int override = !event_is_positioned(render_priv->state.event->Text); + double scale; + + if (!rstyle) + rstyle = script; + + render_priv->state.style = script; + + if (!override || !render_priv->settings.selective_style_overrides) + return rstyle; + + // Create a new style that contains a mix of the original style and + // user_style (the user's override style). Copy only fields from the + // script's style that are deemed necessary. + *new = render_priv->user_override_style; + + new->StrikeOut = rstyle->StrikeOut; + new->Underline = rstyle->Underline; + new->Angle = rstyle->Angle; + + new->MarginL = script->MarginL; + new->MarginR = script->MarginR; + new->MarginV = script->MarginV; + new->Alignment = script->Alignment; + new->Encoding = script->Encoding; + new->treat_fontname_as_pattern = script->treat_fontname_as_pattern; + + // The user style is supposed to be independent of the script resolution. + // Treat the user style's values as if they were specified for a script with + // PlayResY=288, and rescale the values to the current script. + scale = render_priv->track->PlayResY / 288.0; + new->FontSize *= scale; + new->Spacing *= scale; + new->Outline *= scale; + new->Shadow *= scale; + + render_priv->state.style = new; + + return new; +} + +static void init_font_scale(ASS_Renderer *render_priv) +{ + ASS_Settings *settings_priv = &render_priv->settings; + + render_priv->font_scale = ((double) render_priv->orig_height) / + render_priv->track->PlayResY; + if (settings_priv->storage_height) + render_priv->blur_scale = ((double) render_priv->orig_height) / + settings_priv->storage_height; + else + render_priv->blur_scale = 1.; + if (render_priv->track->ScaledBorderAndShadow) + render_priv->border_scale = + ((double) render_priv->orig_height) / + render_priv->track->PlayResY; + else + render_priv->border_scale = render_priv->blur_scale; + if (!settings_priv->storage_height) + render_priv->blur_scale = render_priv->border_scale; + + render_priv->font_scale *= settings_priv->font_size_coeff; + render_priv->border_scale *= settings_priv->font_size_coeff; + render_priv->blur_scale *= settings_priv->font_size_coeff; +} + /** * \brief partially reset render_context to style values * Works like {\r}: resets some style overrides */ void reset_render_context(ASS_Renderer *render_priv, ASS_Style *style) { - if (!style) - style = render_priv->state.style; + style = handle_selective_style_overrides(render_priv, style); + + init_font_scale(render_priv); render_priv->state.c[0] = style->PrimaryColour; render_priv->state.c[1] = style->SecondaryColour; @@ -814,11 +891,10 @@ static void init_render_context(ASS_Renderer *render_priv, ASS_Event *event) { render_priv->state.event = event; - render_priv->state.style = render_priv->track->styles + event->Style; render_priv->state.parsed_tags = 0; render_priv->state.has_clips = 0; - reset_render_context(render_priv, render_priv->state.style); + reset_render_context(render_priv, NULL); render_priv->state.wrap_style = render_priv->track->WrapStyle; render_priv->state.evt_type = EVENT_NORMAL; @@ -2636,23 +2712,6 @@ ass_start_frame(ASS_Renderer *render_priv, ASS_Track *track, ass_lazy_track_init(render_priv->library, render_priv->track); - render_priv->font_scale = settings_priv->font_size_coeff * - render_priv->orig_height / render_priv->track->PlayResY; - if (settings_priv->storage_height) - render_priv->blur_scale = ((double) render_priv->orig_height) / - settings_priv->storage_height; - else - render_priv->blur_scale = 1.; - if (render_priv->track->ScaledBorderAndShadow) - render_priv->border_scale = - ((double) render_priv->orig_height) / - render_priv->track->PlayResY; - else - render_priv->border_scale = render_priv->blur_scale; - if (!settings_priv->storage_height) - render_priv->blur_scale = render_priv->border_scale; - render_priv->border_scale *= settings_priv->font_size_coeff; - ass_shaper_set_kerning(render_priv->shaper, track->Kerning); ass_shaper_set_language(render_priv->shaper, track->Language); ass_shaper_set_level(render_priv->shaper, render_priv->settings.shaper); |