Add background fontconfig cache updating

When the libass provider is enabled, initialize fontconfig on program
startup rather than waiting for the user to open a video. If the user
tries to open a video while the cache is still being updated, display a
"progress" dialog,

Updates #1115.

Originally committed to SVN as r4768.
This commit is contained in:
Thomas Goyne 2010-09-01 06:50:35 +00:00
parent f77f908611
commit 7e72a9e0cf
5 changed files with 69 additions and 29 deletions

View File

@ -211,4 +211,6 @@ void DialogProgressThread::Close() {
dialog->GetEventHandler()->ProcessEvent(event);
}
void DialogProgress::Pulse() {
gauge->Pulse();
}

View File

@ -81,6 +81,7 @@ public:
void SetProgress(int cur,int max);
void SetText(wxString text);
void Run();
void Pulse();
DECLARE_EVENT_TABLE()
};

View File

@ -62,6 +62,7 @@ SubtitlesProvider* SubtitlesProviderFactory::GetProvider() {
SubtitlesProvider *provider = Create(list[i], subType);
if (provider) return provider;
}
catch (agi::UserCancelException const&) { throw; }
catch (wxString err) { error += list[i] + _T(" factory: ") + err + _T("\n"); }
catch (const wxChar *err) { error += list[i] + _T(" factory: ") + wxString(err) + _T("\n"); }
catch (...) { error += list[i] + _T(" factory: Unknown error\n"); }
@ -79,6 +80,7 @@ void SubtitlesProviderFactory::RegisterProviders() {
#endif
#ifdef WITH_LIBASS
Register<LibassSubtitlesProvider>("libass");
LibassSubtitlesProvider::CacheFonts();
#endif
}

View File

@ -40,6 +40,7 @@
#ifndef AGI_PRE
#include <wx/filefn.h>
#include <wx/utils.h>
#endif
#ifdef __APPLE__
@ -50,6 +51,9 @@
#include <libaegisub/log.h>
#include "ass_file.h"
#include "dialog_progress.h"
#include "frame_main.h"
#include "main.h"
#include "standard_paths.h"
#include "subtitles_provider_libass.h"
#include "utils.h"
@ -73,33 +77,7 @@ static void msg_callback(int level, const char *fmt, va_list args, void *data) {
LOG_D("subtitle/provider/libass") << buf;
}
/// @brief Constructor
///
LibassSubtitlesProvider::LibassSubtitlesProvider(std::string) {
// Initialize library
static bool first = true;
if (first) {
ass_library = ass_library_init();
if (!ass_library) throw _T("ass_library_init failed");
wxString fonts_dir = StandardPaths::DecodePath(_T("?user/libass_fonts/"));
if (!wxDirExists(fonts_dir))
// It's only one level below the user dir, and we assume the user dir already exists at this point.
wxMkdir(fonts_dir);
ass_set_fonts_dir(ass_library, fonts_dir.mb_str(wxConvFile));
ass_set_extract_fonts(ass_library, 0);
ass_set_style_overrides(ass_library, NULL);
ass_set_message_cb(ass_library, msg_callback, this);
first = false;
}
// Initialize renderer
ass_track = NULL;
ass_renderer = ass_renderer_init(ass_library);
if (!ass_renderer) throw _T("ass_renderer_init failed");
ass_set_font_scale(ass_renderer, 1.);
static void load_config(ASS_Renderer *ass_renderer) {
#ifdef __APPLE__
char config_path[MAXPATHLEN];
char *config_dir;
@ -111,7 +89,32 @@ LibassSubtitlesProvider::LibassSubtitlesProvider(std::string) {
const char *config_path = NULL;
#endif
ass_set_fonts(ass_renderer, NULL, "Sans", 1, config_path, 1);
ass_set_fonts(ass_renderer, NULL, "Sans", 1, config_path, true);
}
/// @brief Constructor
///
LibassSubtitlesProvider::LibassSubtitlesProvider(std::string) {
if (cache_worker) {
bool canceled;
DialogProgress *progress = new DialogProgress(AegisubApp::Get()->frame, L"", &canceled, L"Caching fonts", 0, 1);
progress->Show();
while (cache_worker) {
if (canceled) throw agi::UserCancelException("Font caching cancelled");
progress->Pulse();
wxYield();
wxMilliSleep(100);
}
progress->Destroy();
}
ass_set_message_cb(ass_library, msg_callback, this);
// Initialize renderer
ass_track = NULL;
ass_renderer = ass_renderer_init(ass_library);
if (!ass_renderer) throw _T("ass_renderer_init failed");
ass_set_font_scale(ass_renderer, 1.);
load_config(ass_renderer);
}
/// @brief Destructor
@ -201,7 +204,34 @@ void LibassSubtitlesProvider::DrawSubtitles(AegiVideoFrame &frame,double time) {
}
}
class FontConfigCacheThread : public wxThread {
ASS_Library *ass_library;
FontConfigCacheThread** thisPtr;
ExitCode Entry() {
ASS_Renderer *ass_renderer = ass_renderer_init(ass_library);
load_config(ass_renderer);
ass_renderer_done(ass_renderer);
*thisPtr = NULL;
return EXIT_SUCCESS;
}
public:
FontConfigCacheThread(ASS_Library *ass_library, FontConfigCacheThread **thisPtr)
: ass_library(ass_library)
, thisPtr(thisPtr)
{
*thisPtr = this;
Create();
Run();
}
};
void LibassSubtitlesProvider::CacheFonts() {
ass_library = ass_library_init();
new FontConfigCacheThread(ass_library, &cache_worker);
}
/// DOCME
ASS_Library* LibassSubtitlesProvider::ass_library;
FontConfigCacheThread* LibassSubtitlesProvider::cache_worker = NULL;
#endif // WITH_LIBASS

View File

@ -45,6 +45,7 @@ extern "C" {
#include "../libass/ass.h"
}
class FontConfigCacheThread;
/// DOCME
/// @class LibassSubtitlesProvider
@ -61,11 +62,15 @@ class LibassSubtitlesProvider : public SubtitlesProvider {
/// DOCME
ASS_Track* ass_track;
static FontConfigCacheThread *cache_worker;
public:
LibassSubtitlesProvider(std::string);
~LibassSubtitlesProvider();
void LoadSubtitles(AssFile *subs);
void DrawSubtitles(AegiVideoFrame &dst,double time);
static void CacheFonts();
};
#endif