Make updating the subtitle preview window roughly 50% faster

Originally committed to SVN as r4478.
This commit is contained in:
Thomas Goyne 2010-06-11 02:25:34 +00:00
parent 4ef9d41601
commit 40da39e1c8
5 changed files with 93 additions and 183 deletions

View file

@ -429,8 +429,8 @@ void AssFile::AddLine (wxString data,wxString group,int &version,wxString *outGr
/// @brief Clears contents of assfile /// @brief Clears contents of assfile
void AssFile::Clear () { void AssFile::Clear () {
for (std::list<AssEntry*>::iterator cur=Line.begin();cur != Line.end();cur++) { for (entryIter cur=Line.begin();cur != Line.end();cur++) {
if (*cur) delete *cur; delete *cur;
} }
Line.clear(); Line.clear();

View file

@ -368,7 +368,7 @@ DialogStyleEditor::DialogStyleEditor (wxWindow *parent, AssStyle *_style, Subtit
SubsPreview = new SubtitlesPreview(this,-1,wxDefaultPosition,wxSize(100,60),wxSUNKEN_BORDER,lagi_wxColour(OPT_GET("Colour/Style Editor/Background/Preview")->GetColour())); SubsPreview = new SubtitlesPreview(this,-1,wxDefaultPosition,wxSize(100,60),wxSUNKEN_BORDER,lagi_wxColour(OPT_GET("Colour/Style Editor/Background/Preview")->GetColour()));
SubsPreview->SetToolTip(_("Preview of current style.")); SubsPreview->SetToolTip(_("Preview of current style."));
SubsPreview->SetStyle(style); SubsPreview->SetStyle(*style);
SubsPreview->SetText(PreviewText->GetValue()); SubsPreview->SetText(PreviewText->GetValue());
PreviewText->SetToolTip(_("Text to be used for the preview.")); PreviewText->SetToolTip(_("Text to be used for the preview."));
previewButton->SetToolTip(_("Colour of preview background.")); previewButton->SetToolTip(_("Colour of preview background."));
@ -593,7 +593,7 @@ void DialogStyleEditor::Apply (bool apply,bool close) {
} }
// Update preview // Update preview
else if (SubsPreview) SubsPreview->SetStyle(style); else if (SubsPreview) SubsPreview->SetStyle(*style);
} }
// Close // Close
@ -672,7 +672,7 @@ void DialogStyleEditor::OnChooseFont (wxCommandEvent &event) {
work->italic = (newfont.GetStyle() == wxFONTSTYLE_ITALIC); work->italic = (newfont.GetStyle() == wxFONTSTYLE_ITALIC);
work->underline = newfont.GetUnderlined(); work->underline = newfont.GetUnderlined();
UpdateWorkStyle(); UpdateWorkStyle();
if (SubsPreview) SubsPreview->SetStyle(work); if (SubsPreview) SubsPreview->SetStyle(*work);
// Comic sans warning // Comic sans warning
if (newfont.GetFaceName() == _T("Comic Sans MS")) { if (newfont.GetFaceName() == _T("Comic Sans MS")) {
@ -694,7 +694,7 @@ void DialogStyleEditor::OnSetColor (int n) {
default: throw _T("Internal error in style editor, attempted setting colour id outside range"); default: throw _T("Internal error in style editor, attempted setting colour id outside range");
} }
modify->SetWXColor(colorButton[n-1]->GetColour()); modify->SetWXColor(colorButton[n-1]->GetColour());
if (SubsPreview) SubsPreview->SetStyle(work); if (SubsPreview) SubsPreview->SetStyle(*work);
} }
/// @brief Child focus change /// @brief Child focus change
@ -702,7 +702,7 @@ void DialogStyleEditor::OnSetColor (int n) {
/// ///
void DialogStyleEditor::OnChildFocus (wxChildFocusEvent &event) { void DialogStyleEditor::OnChildFocus (wxChildFocusEvent &event) {
UpdateWorkStyle(); UpdateWorkStyle();
if (SubsPreview) SubsPreview->SetStyle(work); if (SubsPreview) SubsPreview->SetStyle(*work);
event.Skip(); event.Skip();
} }
@ -731,7 +731,7 @@ void DialogStyleEditor::OnPreviewColourChange (wxCommandEvent &event) {
void DialogStyleEditor::OnCommandPreviewUpdate (wxCommandEvent &event) { void DialogStyleEditor::OnCommandPreviewUpdate (wxCommandEvent &event) {
if (!IsShownOnScreen()) return; if (!IsShownOnScreen()) return;
UpdateWorkStyle(); UpdateWorkStyle();
if (SubsPreview) SubsPreview->SetStyle(work); if (SubsPreview) SubsPreview->SetStyle(*work);
event.Skip(); event.Skip();
} }

View file

@ -35,8 +35,6 @@
/// ///
////////////
// Includes
#include "config.h" #include "config.h"
#ifndef AGI_PRE #ifndef AGI_PRE
@ -45,6 +43,7 @@
#include <wx/msgdlg.h> #include <wx/msgdlg.h>
#endif #endif
#include "ass_dialogue.h"
#include "ass_file.h" #include "ass_file.h"
#include "ass_style.h" #include "ass_style.h"
#include "subs_preview.h" #include "subs_preview.h"
@ -62,184 +61,103 @@
/// ///
SubtitlesPreview::SubtitlesPreview(wxWindow *parent,int id,wxPoint pos,wxSize size,int winStyle,wxColour col) SubtitlesPreview::SubtitlesPreview(wxWindow *parent,int id,wxPoint pos,wxSize size,int winStyle,wxColour col)
: wxWindow(parent,id,pos,size,winStyle) : wxWindow(parent,id,pos,size,winStyle)
, backColour(col)
, subFile(new AssFile)
, line(new AssDialogue)
, style(new AssStyle)
{ {
AssStyle temp; line->Text = "{\\q2}preview";
bmp = NULL;
style = NULL; SetStyle(*style);
vid = NULL;
SetStyle(&temp); subFile->LoadDefault();
SetText(_T("preview")); subFile->InsertStyle(style);
subFile->Line.push_back(line);
SetSizeHints(size.GetWidth(), size.GetHeight(), -1, -1); SetSizeHints(size.GetWidth(), size.GetHeight(), -1, -1);
backColour = col; wxSizeEvent evt(size);
OnSize(evt);
UpdateBitmap();
} }
/// @brief Destructor
///
SubtitlesPreview::~SubtitlesPreview() { SubtitlesPreview::~SubtitlesPreview() {
delete bmp;
bmp = NULL;
delete style;
style = NULL;
delete vid;
vid = NULL;
} }
void SubtitlesPreview::SetStyle(AssStyle const& newStyle) {
*style = newStyle;
/// @brief Set style style->name = "Default";
/// @param _style style->alignment = 5;
/// @return memset(style->Margin, 0, 4 * sizeof(int));
/// style->UpdateData();
void SubtitlesPreview::SetStyle(AssStyle *_style) {
// Prepare style
AssStyle *tmpStyle = dynamic_cast<AssStyle*>(_style->Clone());
tmpStyle->name = _T("Preview");
tmpStyle->alignment = 5;
for (int i=0;i<4;i++) tmpStyle->Margin[i] = 0;
tmpStyle->UpdateData();
// See if it's any different from the current
if (style) {
if (tmpStyle->IsEqualTo(style)) {
delete tmpStyle;
return;
}
delete style;
}
// Update
style = tmpStyle;
UpdateBitmap(); UpdateBitmap();
} }
/// @brief Set text
/// @param text
///
void SubtitlesPreview::SetText(wxString text) { void SubtitlesPreview::SetText(wxString text) {
if (text != showText) { wxString newText = L"{\\q2}" + text;
showText = text; if (newText != line->Text) {
line->Text = newText;
UpdateBitmap(); UpdateBitmap();
} }
} }
void SubtitlesPreview::UpdateBitmap() {
/// @brief Update image
/// @param w
/// @param h
/// @return
///
void SubtitlesPreview::UpdateBitmap(int w,int h) {
// Visible?
if (!IsShownOnScreen()) return; if (!IsShownOnScreen()) return;
// Get size
if (w == -1) {
w = GetClientSize().GetWidth();
h = GetClientSize().GetHeight();
}
// Delete old bmp if needed
if (bmp) {
if (bmp->GetWidth() != w || bmp->GetHeight() != h) {
delete bmp;
bmp = NULL;
}
}
// Create bitmap
if (!bmp) {
bmp = new wxBitmap(w,h,-1);
}
// Get AegiVideoFrame
if (!vid) vid = new DummyVideoProvider(0.0,10,w,h,backColour,true);
AegiVideoFrame frame; AegiVideoFrame frame;
frame.CopyFrom(vid->GetFrame(0)); frame.CopyFrom(vid->GetFrame(0));
// Try to get subtitles provider if (provider.get()) {
SubtitlesProvider *provider = NULL;
try { try {
provider = SubtitlesProviderFactoryManager::GetProvider(); provider->LoadSubtitles(subFile.get());
}
catch (...) {
wxMessageBox(_T("Could not get any subtitles provider for the preview box. Make sure that you have a provider installed."),_T("No subtitles provider"),wxICON_ERROR|wxOK);
}
// Provider OK
if (provider) {
// Generate subtitles
AssFile *subs = new AssFile();
subs->LoadDefault();
int ver = 1;
wxString outGroup;
subs->InsertStyle((AssStyle *)style->Clone());
subs->SetScriptInfo(_T("PlayResX"),wxString::Format(_T("%i"),w));
subs->SetScriptInfo(_T("PlayResY"),wxString::Format(_T("%i"),h));
subs->AddLine(_T("Dialogue: 0,0:00:00.00,0:00:05.00,Preview,,0000,0000,0000,,{\\q2}") + showText,_T("[Events]"),ver,&outGroup);
// Apply subtitles
try {
provider->LoadSubtitles(subs);
provider->DrawSubtitles(frame, 0.1); provider->DrawSubtitles(frame, 0.1);
} }
catch (...) { } catch (...) { }
delete provider;
} }
// Convert frame to bitmap // Convert frame to bitmap
wxMemoryDC dc(*bmp); *bmp = static_cast<wxBitmap>(frame.GetImage());
wxBitmap tempBmp(frame.GetImage());
frame.Clear(); frame.Clear();
dc.DrawBitmap(tempBmp,0,0);
Refresh(); Refresh();
} }
///////////////
// Event table
BEGIN_EVENT_TABLE(SubtitlesPreview,wxWindow) BEGIN_EVENT_TABLE(SubtitlesPreview,wxWindow)
EVT_PAINT(SubtitlesPreview::OnPaint) EVT_PAINT(SubtitlesPreview::OnPaint)
EVT_SIZE(SubtitlesPreview::OnSize) EVT_SIZE(SubtitlesPreview::OnSize)
END_EVENT_TABLE() END_EVENT_TABLE()
void SubtitlesPreview::OnPaint(wxPaintEvent &) {
/// @brief Paint event
/// @param event
///
void SubtitlesPreview::OnPaint(wxPaintEvent &event) {
wxPaintDC dc(this); wxPaintDC dc(this);
if (!bmp) UpdateBitmap(); dc.DrawBitmap(*bmp,0,0);
if (bmp) dc.DrawBitmap(*bmp,0,0);
} }
void SubtitlesPreview::OnSize(wxSizeEvent &evt) {
if (bmp.get() && evt.GetSize() == bmp->GetSize()) return;
int w = evt.GetSize().GetWidth();
int h = evt.GetSize().GetHeight();
/// @brief Size event bmp.reset(new wxBitmap(w, h, -1));
/// @param event vid.reset(new DummyVideoProvider(0.0, 10, w, h, backColour, true));
/// try {
void SubtitlesPreview::OnSize(wxSizeEvent &event) { provider.reset(SubtitlesProviderFactoryManager::GetProvider());
delete vid; }
vid = NULL; catch (...) {
UpdateBitmap(event.GetSize().GetWidth(),event.GetSize().GetHeight()); wxMessageBox(
"Could not get any subtitles provider for the preview box. Make "
"sure that you have a provider installed.",
"No subtitles provider", wxICON_ERROR | wxOK);
} }
subFile->SetScriptInfo("PlayResX", wxString::Format("%i", w));
subFile->SetScriptInfo("PlayResY", wxString::Format("%i", h));
/// @brief Set colour
/// @param col
///
void SubtitlesPreview::SetColour(wxColour col) {
backColour = col;
delete vid;
vid = NULL;
UpdateBitmap(); UpdateBitmap();
} }
void SubtitlesPreview::SetColour(wxColour col) {
if (col != backColour) {
backColour = col;
vid.reset(new DummyVideoProvider(0.0, 10, bmp->GetWidth(), bmp->GetHeight(), backColour, true));
UpdateBitmap();
}
}

View file

@ -34,58 +34,52 @@
/// @ingroup custom_control /// @ingroup custom_control
/// ///
////////////
// Includes
#ifndef AGI_PRE #ifndef AGI_PRE
#include <memory>
#include <wx/window.h> #include <wx/window.h>
#include <wx/bitmap.h> #include <wx/bitmap.h>
#endif #endif
class AssFile;
//////////////
// Prototypes
class AssStyle; class AssStyle;
class SubtitlesProvider;
class VideoProvider; class VideoProvider;
/// DOCME /// DOCME
/// @class SubtitlesPreview /// @class SubtitlesPreview
/// @brief DOCME /// @brief Preview window to show a short string with a given ass style
///
/// DOCME
class SubtitlesPreview : public wxWindow { class SubtitlesPreview : public wxWindow {
private: private:
/// The subtitle provider used to render the string
/// DOCME std::auto_ptr<SubtitlesProvider> provider;
wxBitmap *bmp; /// Bitmap to render into
std::auto_ptr<wxBitmap> bmp;
/// DOCME /// The currently display style
AssStyle* style; AssStyle* style;
/// Video provider to render into
/// DOCME std::auto_ptr<VideoProvider> vid;
wxString showText; /// Current background color
/// DOCME
VideoProvider *vid;
/// DOCME
wxColour backColour; wxColour backColour;
/// Subtitle file containing the style and displayed line
std::auto_ptr<AssFile> subFile;
/// Line used to render the specified text
AssDialogue* line;
void UpdateBitmap(int w=-1,int h=-1); /// Regenerate the bitmap
void UpdateBitmap();
/// Resize event handler
void OnSize(wxSizeEvent &event); void OnSize(wxSizeEvent &event);
void OnPaint(wxPaintEvent &event); /// Paint event handler
void OnPaint(wxPaintEvent &);
public: public:
void SetStyle(AssStyle *style); /// Set the style to use
void SetStyle(AssStyle const& style);
/// Set the text to display
void SetText(wxString text); void SetText(wxString text);
/// Set the background color
void SetColour(wxColour col); void SetColour(wxColour col);
/// @brief DOCME
///
void Update() { UpdateBitmap(); } void Update() { UpdateBitmap(); }
SubtitlesPreview(wxWindow *parent,int id,wxPoint pos,wxSize size,int style,wxColour colour); SubtitlesPreview(wxWindow *parent,int id,wxPoint pos,wxSize size,int style,wxColour colour);
@ -93,5 +87,3 @@ public:
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
}; };

View file

@ -172,7 +172,7 @@ void AegiVideoFrame::SetTo(const unsigned char *const source[], int width, int h
} }
/// @brief This function is only used on screenshots, so it doesn't have to be fast ------ Get wxImage /// @brief Get wxImage
/// @return /// @return
wxImage AegiVideoFrame::GetImage() const { wxImage AegiVideoFrame::GetImage() const {
if (format == FORMAT_RGB32 || format == FORMAT_RGB24) { if (format == FORMAT_RGB32 || format == FORMAT_RGB24) {