From a9019421f1580c3b734aaf25b6c2aabb358ebc69 Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Fri, 11 Jul 2014 07:11:10 -0700 Subject: [PATCH] Fix memory leak in aegisub.text_extents on Windows The old object returned by SelectObject has to be made active again before the DC is destroyed or it doesn't get deleted. --- src/auto4_base.cpp | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/auto4_base.cpp b/src/auto4_base.cpp index d51a3e98f..dd11ba837 100644 --- a/src/auto4_base.cpp +++ b/src/auto4_base.cpp @@ -70,12 +70,12 @@ namespace Automation4 { #ifdef WIN32 // This is almost copypasta from TextSub - HDC thedc = CreateCompatibleDC(0); - if (!thedc) return false; - SetMapMode(thedc, MM_TEXT); + auto dc = CreateCompatibleDC(nullptr); + if (!dc) return false; - LOGFONTW lf; - ZeroMemory(&lf, sizeof(lf)); + SetMapMode(dc, MM_TEXT); + + LOGFONTW lf = {0}; lf.lfHeight = (LONG)fontsize; lf.lfWeight = style->bold ? FW_BOLD : FW_NORMAL; lf.lfItalic = style->italic; @@ -88,33 +88,36 @@ namespace Automation4 { lf.lfPitchAndFamily = DEFAULT_PITCH|FF_DONTCARE; wcsncpy(lf.lfFaceName, agi::charset::ConvertW(style->font).c_str(), 31); - HFONT thefont = CreateFontIndirect(&lf); - if (!thefont) return false; - SelectObject(thedc, thefont); + auto font = CreateFontIndirect(&lf); + if (!font) return false; + + auto old_font = SelectObject(dc, font); std::wstring wtext(agi::charset::ConvertW(text)); - SIZE sz; if (spacing != 0 ) { width = 0; for (auto c : wtext) { - GetTextExtentPoint32(thedc, &c, 1, &sz); + SIZE sz; + GetTextExtentPoint32(dc, &c, 1, &sz); width += sz.cx + spacing; height = sz.cy; } } else { - GetTextExtentPoint32(thedc, &wtext[0], (int)wtext.size(), &sz); + SIZE sz; + GetTextExtentPoint32(dc, &wtext[0], (int)wtext.size(), &sz); width = sz.cx; height = sz.cy; } TEXTMETRIC tm; - GetTextMetrics(thedc, &tm); + GetTextMetrics(dc, &tm); descent = tm.tmDescent; - extlead= tm.tmExternalLeading; + extlead = tm.tmExternalLeading; - DeleteObject(thedc); - DeleteObject(thefont); + SelectObject(dc, old_font); + DeleteObject(font); + DeleteObject(dc); #else // not WIN32 wxMemoryDC thedc;