From acb9b8adac40fa5a483e215902ee5b469234d0c8 Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Sun, 8 Feb 2015 09:13:53 -0800 Subject: [PATCH] Reinitialize libass every time the font is changed in the style editor libass doesn't free any font data it requests until the ass_renderer is destroyed, so recreate it every time the font is changed to avoid holding on to extremely large amounts of data when the user quickly switches between fonts. Closes #1320. --- src/include/aegisub/subtitles_provider.h | 1 + src/subs_preview.cpp | 3 +++ src/subtitles_provider_libass.cpp | 19 ++++++++++++++++--- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/include/aegisub/subtitles_provider.h b/src/include/aegisub/subtitles_provider.h index 532d94a3b..c2b42ddb4 100644 --- a/src/include/aegisub/subtitles_provider.h +++ b/src/include/aegisub/subtitles_provider.h @@ -49,6 +49,7 @@ public: virtual ~SubtitlesProvider() = default; void LoadSubtitles(AssFile *subs, int time = -1); virtual void DrawSubtitles(VideoFrame &dst, double time)=0; + virtual void Reinitialize() { } }; namespace agi { class BackgroundRunner; } diff --git a/src/subs_preview.cpp b/src/subs_preview.cpp index 2f28fa818..ba24ad1de 100644 --- a/src/subs_preview.cpp +++ b/src/subs_preview.cpp @@ -74,6 +74,9 @@ SubtitlesPreview::~SubtitlesPreview() { } void SubtitlesPreview::SetStyle(AssStyle const& new_style) { + if (provider && style->font != new_style.font) + provider->Reinitialize(); + *style = new_style; style->name = "Default"; style->alignment = 5; diff --git a/src/subtitles_provider_libass.cpp b/src/subtitles_provider_libass.cpp index 3dc047e71..67e06ffcb 100644 --- a/src/subtitles_provider_libass.cpp +++ b/src/subtitles_provider_libass.cpp @@ -108,7 +108,9 @@ class LibassSubtitlesProvider final : public SubtitlesProvider { if (shared->ready) return shared->renderer; - auto block = [&]{ + auto block = [&] { + if (shared->ready) + return; br->Run([=](agi::ProgressSink *ps) { ps->SetTitle(from_wx(_("Updating font index"))); ps->SetMessage(from_wx(_("This may take several minutes"))); @@ -136,6 +138,17 @@ public: } void DrawSubtitles(VideoFrame &dst, double time) override; + + void Reinitialize() override { + // No need to reinit if we're not even done with the initial init + if (!shared->ready) + return; + + ass_renderer_done(shared->renderer); + shared->renderer = ass_renderer_init(library); + ass_set_font_scale(shared->renderer, 1.); + ass_set_fonts(shared->renderer, nullptr, "Sans", 1, CONFIG_PATH, true); + } }; LibassSubtitlesProvider::LibassSubtitlesProvider(agi::BackgroundRunner *br) @@ -143,7 +156,7 @@ LibassSubtitlesProvider::LibassSubtitlesProvider(agi::BackgroundRunner *br) , shared(std::make_shared()) { auto state = shared; - cache_queue->Async([state]{ + cache_queue->Async([state] { auto ass_renderer = ass_renderer_init(library); if (ass_renderer) { ass_set_font_scale(ass_renderer, 1.); @@ -215,7 +228,7 @@ void CacheFonts() { ass_set_message_cb(library, msg_callback, nullptr); // Initialize a renderer to force fontconfig to update its cache - cache_queue->Async([]{ + cache_queue->Async([] { auto ass_renderer = ass_renderer_init(library); ass_set_fonts(ass_renderer, nullptr, "Sans", 1, CONFIG_PATH, true); ass_renderer_done(ass_renderer);