From 5787ca4ae0f04acf96195ef3e5f1749a4497bb84 Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Mon, 16 Sep 2013 10:43:21 -0700 Subject: [PATCH] Cache widths of strings in SetColumnWidths --- aegisub/src/base_grid.cpp | 45 ++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/aegisub/src/base_grid.cpp b/aegisub/src/base_grid.cpp index 0f903cc95..7d6a40909 100644 --- a/aegisub/src/base_grid.cpp +++ b/aegisub/src/base_grid.cpp @@ -34,16 +34,6 @@ #include "config.h" -#include -#include -#include -#include - -#include -#include -#include -#include - #include "base_grid.h" #include "include/aegisub/context.h" @@ -64,6 +54,17 @@ #include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + enum { GRID_SCROLLBAR = 1730, MENU_SHOW_COL = 1250 // Needs 15 IDs after this @@ -86,6 +87,15 @@ static inline void set_difference(const S1 &src1, const S2 &src2, D &dst) { std::inserter(dst, dst.begin())); } +namespace std { + template + struct hash> { + size_t operator()(boost::flyweight const& ss) const { + return hash()(&ss.get()); + } + }; +} + BaseGrid::BaseGrid(wxWindow* parent, agi::Context *context, const wxSize& size, long style, const wxString& name) : wxWindow(parent, -1, wxDefaultPosition, size, style, name) , lineHeight(1) // non-zero to avoid div by 0 @@ -837,6 +847,15 @@ void BaseGrid::SetColumnWidths() { if (!byFrame) startLen = endLen = dc.GetTextExtent(to_wx(AssTime().GetAssFormated())).GetWidth(); + std::unordered_map, int> widths; + auto get_width = [&](boost::flyweight const& str) -> int { + auto it = widths.find(str); + if (it != end(widths)) return it->second; + int width = dc.GetTextExtent(to_wx(str)).GetWidth(); + widths[str] = width; + return width; + }; + // O(n) widths bool showMargin[3] = { false, false, false }; int styleLen = 0; @@ -849,9 +868,9 @@ void BaseGrid::SetColumnWidths() { AssDialogue *curDiag = GetDialogue(i); maxLayer = std::max(maxLayer, curDiag->Layer); - actorLen = std::max(actorLen, dc.GetTextExtent(to_wx(curDiag->Actor)).GetWidth()); - styleLen = std::max(styleLen, dc.GetTextExtent(to_wx(curDiag->Style)).GetWidth()); - effectLen = std::max(effectLen, dc.GetTextExtent(to_wx(curDiag->Effect)).GetWidth()); + actorLen = std::max(actorLen, get_width(curDiag->Actor)); + styleLen = std::max(styleLen, get_width(curDiag->Style)); + effectLen = std::max(effectLen, get_width(curDiag->Effect)); // Margins for (int j = 0; j < 3; j++) {