FreeType: Fixed mem leak and adjustments
This commit is contained in:
@@ -8,17 +8,22 @@
|
||||
#include <ft2build.h>
|
||||
#include FT_BITMAP_H
|
||||
|
||||
#include <cmath>
|
||||
|
||||
// Same gamma LUT as GrpFontTexture for consistent text sharpness
|
||||
static struct STextBarGammaLUT {
|
||||
unsigned char table[256];
|
||||
STextBarGammaLUT() {
|
||||
table[0] = 0;
|
||||
for (int i = 1; i < 256; ++i)
|
||||
table[i] = (unsigned char)(pow(i / 255.0, 0.80) * 255.0 + 0.5);
|
||||
}
|
||||
} s_textBarGammaLUT;
|
||||
|
||||
void CTextBar::__SetFont(int fontSize, bool isBold)
|
||||
{
|
||||
m_ftFace = CFontManager::Instance().GetFace("Tahoma");
|
||||
if (!m_ftFace)
|
||||
return;
|
||||
|
||||
__ApplyFaceState();
|
||||
}
|
||||
|
||||
void CTextBar::__ApplyFaceState()
|
||||
{
|
||||
// Create a per-instance FT_Face (this instance owns it)
|
||||
m_ftFace = CFontManager::Instance().CreateFace("Tahoma");
|
||||
if (!m_ftFace)
|
||||
return;
|
||||
|
||||
@@ -27,7 +32,7 @@ void CTextBar::__ApplyFaceState()
|
||||
pixelSize = 12;
|
||||
|
||||
FT_Set_Pixel_Sizes(m_ftFace, 0, pixelSize);
|
||||
FT_Set_Transform(m_ftFace, NULL, NULL); // TextBar never uses italic
|
||||
FT_Set_Transform(m_ftFace, NULL, NULL);
|
||||
|
||||
m_ascender = (int)(m_ftFace->size->metrics.ascender >> 6);
|
||||
m_lineHeight = (int)(m_ftFace->size->metrics.height >> 6);
|
||||
@@ -57,9 +62,6 @@ void CTextBar::GetTextExtent(const char* c_szText, SIZE* p_size)
|
||||
return;
|
||||
}
|
||||
|
||||
// Re-apply face state (shared FT_Face may have been changed by another user)
|
||||
__ApplyFaceState();
|
||||
|
||||
std::wstring wText = Utf8ToWide(c_szText);
|
||||
|
||||
int totalAdvance = 0;
|
||||
@@ -70,7 +72,7 @@ void CTextBar::GetTextExtent(const char* c_szText, SIZE* p_size)
|
||||
glyphIndex = FT_Get_Char_Index(m_ftFace, L' ');
|
||||
|
||||
if (FT_Load_Glyph(m_ftFace, glyphIndex, FT_LOAD_DEFAULT) == 0)
|
||||
totalAdvance += (int)(m_ftFace->glyph->advance.x >> 6);
|
||||
totalAdvance += (int)ceilf((float)(m_ftFace->glyph->advance.x) / 64.0f);
|
||||
}
|
||||
|
||||
p_size->cx = totalAdvance;
|
||||
@@ -82,9 +84,6 @@ void CTextBar::TextOut(int ix, int iy, const char * c_szText)
|
||||
if (!c_szText || !*c_szText || !m_ftFace)
|
||||
return;
|
||||
|
||||
// Re-apply face state (shared FT_Face may have been changed by another user)
|
||||
__ApplyFaceState();
|
||||
|
||||
DWORD* pdwBuf = (DWORD*)m_dib.GetPointer();
|
||||
if (!pdwBuf)
|
||||
return;
|
||||
@@ -111,9 +110,9 @@ void CTextBar::TextOut(int ix, int iy, const char * c_szText)
|
||||
|
||||
FT_GlyphSlot slot = m_ftFace->glyph;
|
||||
|
||||
// Apply synthetic bold by embolden
|
||||
// Apply synthetic bold (32 = 0.5px embolden; 64 = 1px was too aggressive)
|
||||
if (m_isBold && slot->bitmap.buffer)
|
||||
FT_Bitmap_Embolden(CFontManager::Instance().GetLibrary(), &slot->bitmap, 64, 0);
|
||||
FT_Bitmap_Embolden(CFontManager::Instance().GetLibrary(), &slot->bitmap, 32, 0);
|
||||
|
||||
FT_Bitmap& bitmap = slot->bitmap;
|
||||
|
||||
@@ -138,8 +137,7 @@ void CTextBar::TextOut(int ix, int iy, const char * c_szText)
|
||||
unsigned char alpha = srcRow[col];
|
||||
if (alpha)
|
||||
{
|
||||
// D3DFMT_A8R8G8B8 = ARGB in DWORD
|
||||
// colorRGB is stored as 0x00BBGGRR, convert to ARGB
|
||||
alpha = s_textBarGammaLUT.table[alpha];
|
||||
DWORD r = (colorRGB >> 0) & 0xFF;
|
||||
DWORD g = (colorRGB >> 8) & 0xFF;
|
||||
DWORD b = (colorRGB >> 16) & 0xFF;
|
||||
@@ -148,7 +146,7 @@ void CTextBar::TextOut(int ix, int iy, const char * c_szText)
|
||||
}
|
||||
}
|
||||
|
||||
penX += (int)(slot->advance.x >> 6);
|
||||
penX += (int)ceilf((float)(slot->advance.x) / 64.0f);
|
||||
}
|
||||
|
||||
Invalidate();
|
||||
@@ -171,5 +169,9 @@ CTextBar::CTextBar(int fontSize, bool isBold)
|
||||
|
||||
CTextBar::~CTextBar()
|
||||
{
|
||||
// FT_Face is owned by CFontManager, do NOT free it here
|
||||
if (m_ftFace)
|
||||
{
|
||||
FT_Done_Face(m_ftFace);
|
||||
m_ftFace = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user