mirror of https://github.com/odrling/Aegisub
Reuse previously calculated string widths
This commit is contained in:
parent
427037a552
commit
2269dbcfe0
|
@ -156,6 +156,7 @@
|
|||
<ClInclude Include="$(SrcDir)factory_manager.h" />
|
||||
<ClInclude Include="$(SrcDir)ffmpegsource_common.h" />
|
||||
<ClInclude Include="$(SrcDir)fft.h" />
|
||||
<ClInclude Include="$(SrcDir)flyweight_hash.h" />
|
||||
<ClInclude Include="$(SrcDir)font_file_lister.h" />
|
||||
<ClInclude Include="$(SrcDir)frame_main.h" />
|
||||
<ClInclude Include="$(SrcDir)gl_text.h" />
|
||||
|
|
|
@ -549,6 +549,9 @@
|
|||
<ClInclude Include="$(SrcDir)dialogs.h">
|
||||
<Filter>Features</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(SrcDir)flyweight_hash.h">
|
||||
<Filter>Utilities</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="$(SrcDir)ass_dialogue.cpp">
|
||||
|
@ -1040,9 +1043,6 @@
|
|||
<ClCompile Include="$(SrcDir)ass_parser.cpp">
|
||||
<Filter>ASS</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(SrcDir)audio_provider_lock.cpp">
|
||||
<Filter>Audio\Providers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(SrcDir)command\keyframe.cpp">
|
||||
<Filter>Commands</Filter>
|
||||
</ClCompile>
|
||||
|
@ -1093,4 +1093,4 @@
|
|||
<ResourceCompile Include="$(SrcDir)res\res.rc" />
|
||||
<ResourceCompile Include="$(SrcDir)res\strings.rc" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
|
@ -45,6 +45,7 @@
|
|||
#include "subs_controller.h"
|
||||
#include "video_controller.h"
|
||||
|
||||
#include <libaegisub/make_unique.h>
|
||||
#include <libaegisub/util.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
@ -598,15 +599,17 @@ void BaseGrid::SetColumnWidths() {
|
|||
text_refresh_rects.clear();
|
||||
int x = 0;
|
||||
|
||||
WidthHelper helper{dc, std::unordered_map<boost::flyweight<std::string>, int>{}};
|
||||
helper.widths.reserve(prev_unique_string_widths);
|
||||
if (!width_helper)
|
||||
width_helper = agi::make_unique<WidthHelper>();
|
||||
width_helper->SetDC(&dc);
|
||||
|
||||
for (auto const& column : columns) {
|
||||
column->UpdateWidth(context, helper);
|
||||
column->UpdateWidth(context, *width_helper);
|
||||
if (column->Width() && column->RefreshOnTextChange())
|
||||
text_refresh_rects.emplace_back(x, 0, column->Width(), h);
|
||||
x += column->Width();
|
||||
}
|
||||
prev_unique_string_widths = helper.widths.size();
|
||||
width_helper->Age();
|
||||
}
|
||||
|
||||
AssDialogue *BaseGrid::GetDialogue(int n) const {
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <libaegisub/signal.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <wx/window.h>
|
||||
|
||||
|
@ -39,6 +40,7 @@ namespace agi {
|
|||
}
|
||||
class AssDialogue;
|
||||
class GridColumn;
|
||||
class WidthHelper;
|
||||
|
||||
class BaseGrid final : public wxWindow {
|
||||
std::vector<agi::signal::Connection> connections;
|
||||
|
@ -57,7 +59,7 @@ class BaseGrid final : public wxWindow {
|
|||
|
||||
int active_row = -1;
|
||||
|
||||
size_t prev_unique_string_widths = 0;
|
||||
std::unique_ptr<WidthHelper> width_helper;
|
||||
|
||||
/// Rows which are visible on the current video frame
|
||||
std::vector<int> visible_rows;
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright (c) 2015, Thomas Goyne <plorkyeran@aegisub.org>
|
||||
//
|
||||
// Permission to use, copy, modify, and distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
//
|
||||
// Aegisub Project http://www.aegisub.org/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/flyweight.hpp>
|
||||
|
||||
namespace std {
|
||||
template <typename T>
|
||||
struct hash<boost::flyweight<T>> {
|
||||
size_t operator()(boost::flyweight<T> const& ss) const {
|
||||
return hash<const void*>()(&ss.get());
|
||||
}
|
||||
};
|
||||
}
|
|
@ -27,39 +27,52 @@
|
|||
|
||||
#include <wx/dc.h>
|
||||
|
||||
void WidthHelper::Age() {
|
||||
for (auto it = begin(widths), e = end(widths); it != e; ) {
|
||||
if (it->second.age == age)
|
||||
++it;
|
||||
else
|
||||
it = widths.erase(it);
|
||||
}
|
||||
++age;
|
||||
}
|
||||
|
||||
int WidthHelper::operator()(boost::flyweight<std::string> const& str) {
|
||||
if (str.get().empty()) return 0;
|
||||
auto it = widths.find(str);
|
||||
if (it != end(widths)) return it->second;
|
||||
if (it != end(widths)) {
|
||||
it->second.age = age;
|
||||
return it->second.width;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
wxMBConvUTF8 conv;
|
||||
size_t len = conv.ToWChar(nullptr, 0, str.get().c_str(), str.get().size());
|
||||
scratch.resize(len);
|
||||
conv.ToWChar(const_cast<wchar_t *>(scratch.wx_str()), len, str.get().c_str(), str.get().size());
|
||||
int width = dc.GetTextExtent(scratch).GetWidth();
|
||||
int width = dc->GetTextExtent(scratch).GetWidth();
|
||||
#else
|
||||
int width = dc.GetTextExtent(to_wx(str)).GetWidth();
|
||||
int width = dc->GetTextExtent(to_wx(str)).GetWidth();
|
||||
#endif
|
||||
|
||||
widths[str] = width;
|
||||
widths[str] = {width, age};
|
||||
return width;
|
||||
}
|
||||
|
||||
int WidthHelper::operator()(std::string const& str) {
|
||||
return dc.GetTextExtent(to_wx(str)).GetWidth();
|
||||
return dc->GetTextExtent(to_wx(str)).GetWidth();
|
||||
}
|
||||
|
||||
int WidthHelper::operator()(wxString const& str) {
|
||||
return dc.GetTextExtent(str).GetWidth();
|
||||
return dc->GetTextExtent(str).GetWidth();
|
||||
}
|
||||
|
||||
int WidthHelper::operator()(const char *str) {
|
||||
return dc.GetTextExtent(wxString::FromUTF8(str)).GetWidth();
|
||||
return dc->GetTextExtent(wxString::FromUTF8(str)).GetWidth();
|
||||
}
|
||||
|
||||
int WidthHelper::operator()(const wchar_t *str) {
|
||||
return dc.GetTextExtent(str).GetWidth();
|
||||
return dc->GetTextExtent(str).GetWidth();
|
||||
}
|
||||
|
||||
void GridColumn::UpdateWidth(const agi::Context *c, WidthHelper &helper) {
|
||||
|
|
|
@ -14,7 +14,8 @@
|
|||
//
|
||||
// Aegisub Project http://www.aegisub.org/
|
||||
|
||||
#include <boost/flyweight.hpp>
|
||||
#include "flyweight_hash.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -25,19 +26,21 @@ class wxDC;
|
|||
class wxString;
|
||||
namespace agi { struct Context; }
|
||||
|
||||
namespace std {
|
||||
template <typename T>
|
||||
struct hash<boost::flyweight<T>> {
|
||||
size_t operator()(boost::flyweight<T> const& ss) const {
|
||||
return hash<const void*>()(&ss.get());
|
||||
}
|
||||
class WidthHelper {
|
||||
struct Entry {
|
||||
int width;
|
||||
int age;
|
||||
};
|
||||
}
|
||||
|
||||
struct WidthHelper {
|
||||
wxDC &dc;
|
||||
std::unordered_map<boost::flyweight<std::string>, int> widths;
|
||||
int age = 0;
|
||||
wxDC *dc = nullptr;
|
||||
std::unordered_map<boost::flyweight<std::string>, Entry> widths;
|
||||
#ifdef _WIN32
|
||||
wxString scratch;
|
||||
#endif
|
||||
|
||||
public:
|
||||
void SetDC(wxDC *dc) { this->dc = dc; }
|
||||
void Age();
|
||||
|
||||
int operator()(boost::flyweight<std::string> const& str);
|
||||
int operator()(std::string const& str);
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "command/command.h"
|
||||
#include "compat.h"
|
||||
#include "dialog_style_editor.h"
|
||||
#include "flyweight_hash.h"
|
||||
#include "include/aegisub/context.h"
|
||||
#include "include/aegisub/hotkey.h"
|
||||
#include "initial_line_state.h"
|
||||
|
@ -69,15 +70,6 @@
|
|||
#include <wx/sizer.h>
|
||||
#include <wx/spinctrl.h>
|
||||
|
||||
namespace std {
|
||||
template <typename T>
|
||||
struct hash<boost::flyweight<T>> {
|
||||
size_t operator()(boost::flyweight<T> const& ss) const {
|
||||
return hash<const void*>()(&ss.get());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/// Work around wxGTK's fondness for generating events from ChangeValue
|
||||
|
|
Loading…
Reference in New Issue