aboutsummaryrefslogtreecommitdiff
path: root/guilib
diff options
context:
space:
mode:
authorjmarshallnz <jmarshallnz@svn>2010-07-24 05:20:36 +0000
committerjmarshallnz <jmarshallnz@svn>2010-07-24 05:20:36 +0000
commit8d7151e540dc1a05c0eb559569748c47a24cc54a (patch)
tree50e3f5b93e685f186b49489eaa4f915b58cbf9af /guilib
parentbe1d0b43e7a7a3a618a8ff6f81d277f36911be31 (diff)
changed: Switch RenderOutline to use a separate border font, inflated by freetype rather than re-rendering the same text over and over. Fixes #9713.
git-svn-id: https://xbmc.svn.sourceforge.net/svnroot/xbmc/trunk@32114 568bbfeb-2a22-0410-94d2-cc84cf5bfa90
Diffstat (limited to 'guilib')
-rw-r--r--guilib/GUIFontManager.cpp13
-rw-r--r--guilib/GUIFontManager.h3
-rw-r--r--guilib/GUIFontTTF.cpp38
-rw-r--r--guilib/GUIFontTTF.h5
-rw-r--r--guilib/GUITextLayout.cpp21
-rw-r--r--guilib/GUITextLayout.h4
6 files changed, 72 insertions, 12 deletions
diff --git a/guilib/GUIFontManager.cpp b/guilib/GUIFontManager.cpp
index e3ab9f709a..b3ea2baa7d 100644
--- a/guilib/GUIFontManager.cpp
+++ b/guilib/GUIFontManager.cpp
@@ -75,7 +75,7 @@ void GUIFontManager::RescaleFontSizeAndAspect(float *size, float *aspect, RESOLU
*size /= g_graphicsContext.GetGUIScaleY();
}
-CGUIFont* GUIFontManager::LoadTTF(const CStdString& strFontName, const CStdString& strFilename, color_t textColor, color_t shadowColor, const int iSize, const int iStyle, float lineSpacing, float aspect, RESOLUTION sourceRes, bool preserveAspect)
+CGUIFont* GUIFontManager::LoadTTF(const CStdString& strFontName, const CStdString& strFilename, color_t textColor, color_t shadowColor, const int iSize, const int iStyle, bool border, float lineSpacing, float aspect, RESOLUTION sourceRes, bool preserveAspect)
{
float originalAspect = aspect;
@@ -115,13 +115,13 @@ CGUIFont* GUIFontManager::LoadTTF(const CStdString& strFontName, const CStdStrin
// check if we already have this font file loaded (font object could differ only by color or style)
CStdString TTFfontName;
- TTFfontName.Format("%s_%f_%f", strFilename, newSize, aspect);
+ TTFfontName.Format("%s_%f_%f%s", strFilename, newSize, aspect, border ? "_border" : "");
CGUIFontTTFBase* pFontFile = GetFontFile(TTFfontName);
if (!pFontFile)
{
pFontFile = new CGUIFontTTF(TTFfontName);
- bool bFontLoaded = pFontFile->Load(strPath, newSize, aspect);
+ bool bFontLoaded = pFontFile->Load(strPath, newSize, aspect, 1.0f, border);
if (!bFontLoaded)
{
@@ -131,7 +131,7 @@ CGUIFont* GUIFontManager::LoadTTF(const CStdString& strFontName, const CStdStrin
if (strFilename != "arial.ttf")
{
CLog::Log(LOGERROR, "Couldn't load font name: %s(%s), trying to substitute arial.ttf", strFontName.c_str(), strFilename.c_str());
- return LoadTTF(strFontName, "arial.ttf", textColor, shadowColor, iSize, iStyle, lineSpacing, originalAspect);
+ return LoadTTF(strFontName, "arial.ttf", textColor, shadowColor, iSize, iStyle, border, lineSpacing, originalAspect);
}
CLog::Log(LOGERROR, "Couldn't load font name:%s file:%s", strFontName.c_str(), strPath.c_str());
@@ -153,6 +153,7 @@ CGUIFont* GUIFontManager::LoadTTF(const CStdString& strFontName, const CStdStrin
fontInfo.fileName = strFilename;
fontInfo.sourceRes = sourceRes;
fontInfo.preserveAspect = preserveAspect;
+ fontInfo.border = border;
m_vecFontInfo.push_back(fontInfo);
return pNewFont;
@@ -208,7 +209,7 @@ void GUIFontManager::ReloadTTFFonts(void)
RescaleFontSizeAndAspect(&newSize, &aspect, fontInfo.sourceRes, fontInfo.preserveAspect);
CStdString TTFfontName;
- TTFfontName.Format("%s_%f_%f", strFilename, newSize, aspect);
+ TTFfontName.Format("%s_%f_%f%s", strFilename, newSize, aspect, fontInfo.border ? "_border" : "");
CGUIFontTTFBase* pFontFile = GetFontFile(TTFfontName);
if (!pFontFile)
{
@@ -400,7 +401,7 @@ void GUIFontManager::LoadFonts(const TiXmlNode* fontNode)
XMLUtils::GetFloat(fontNode, "linespacing", lineSpacing);
XMLUtils::GetFloat(fontNode, "aspect", aspect);
- LoadTTF(strFontName, strFontFileName, textColor, shadowColor, iSize, iStyle, lineSpacing, aspect);
+ LoadTTF(strFontName, strFontFileName, textColor, shadowColor, iSize, iStyle, false, lineSpacing, aspect);
}
}
}
diff --git a/guilib/GUIFontManager.h b/guilib/GUIFontManager.h
index 170f89f199..e0469a9813 100644
--- a/guilib/GUIFontManager.h
+++ b/guilib/GUIFontManager.h
@@ -46,6 +46,7 @@ struct OrigFontInfo
CStdString fileName;
RESOLUTION sourceRes;
bool preserveAspect;
+ bool border;
};
/*!
@@ -62,7 +63,7 @@ public:
void Unload(const CStdString& strFontName);
void LoadFonts(const CStdString& strFontSet);
- CGUIFont* LoadTTF(const CStdString& strFontName, const CStdString& strFilename, color_t textColor, color_t shadowColor, const int iSize, const int iStyle, float lineSpacing = 1.0f, float aspect = 1.0f, RESOLUTION res = RES_INVALID, bool preserveAspect = false);
+ CGUIFont* LoadTTF(const CStdString& strFontName, const CStdString& strFilename, color_t textColor, color_t shadowColor, const int iSize, const int iStyle, bool border = false, float lineSpacing = 1.0f, float aspect = 1.0f, RESOLUTION res = RES_INVALID, bool preserveAspect = false);
CGUIFont* GetFont(const CStdString& strFontName, bool fallback = true);
void Clear();
void FreeFontFile(CGUIFontTTFBase *pFont);
diff --git a/guilib/GUIFontTTF.cpp b/guilib/GUIFontTTF.cpp
index 93aba4c9d7..5270844199 100644
--- a/guilib/GUIFontTTF.cpp
+++ b/guilib/GUIFontTTF.cpp
@@ -40,6 +40,7 @@
#include FT_FREETYPE_H
#include FT_GLYPH_H
#include FT_OUTLINE_H
+#include FT_STROKER_H
#define USE_RELEASE_LIBS
@@ -99,12 +100,30 @@ public:
return face;
};
+
+ FT_Stroker GetStroker()
+ {
+ if (!m_library)
+ return NULL;
+
+ FT_Stroker stroker;
+ if (FT_Stroker_New(m_library, &stroker))
+ return NULL;
+
+ return stroker;
+ };
void ReleaseFont(FT_Face face)
{
assert(face);
FT_Done_Face(face);
};
+
+ void ReleaseStroker(FT_Stroker stroker)
+ {
+ assert(stroker);
+ FT_Stroker_Done(stroker);
+ }
unsigned int GetDPI() const
{
@@ -129,6 +148,7 @@ CGUIFontTTFBase::CGUIFontTTFBase(const CStdString& strFileName)
m_vertex = (SVertex*)malloc(m_vertex_size * sizeof(SVertex));
m_face = NULL;
+ m_stroker = NULL;
memset(m_charquick, 0, sizeof(m_charquick));
m_strFileName = strFileName;
m_referenceCount = 0;
@@ -197,13 +217,16 @@ void CGUIFontTTFBase::Clear()
if (m_face)
g_freeTypeLibrary.ReleaseFont(m_face);
m_face = NULL;
+ if (m_stroker)
+ g_freeTypeLibrary.ReleaseStroker(m_stroker);
+ m_stroker = NULL;
free(m_vertex);
m_vertex = NULL;
m_vertex_count = 0;
}
-bool CGUIFontTTFBase::Load(const CStdString& strFilename, float height, float aspect, float lineSpacing)
+bool CGUIFontTTFBase::Load(const CStdString& strFilename, float height, float aspect, float lineSpacing, bool border)
{
// we now know that this object is unique - only the GUIFont objects are non-unique, so no need
// for reference tracking these fonts
@@ -212,6 +235,17 @@ bool CGUIFontTTFBase::Load(const CStdString& strFilename, float height, float as
if (!m_face)
return false;
+ if (border)
+ {
+ m_stroker = g_freeTypeLibrary.GetStroker();
+
+ FT_Pos strength = FT_MulFix( m_face->units_per_EM, m_face->size->metrics.y_scale) / 16;
+ if (strength < 128) strength = 128;
+
+ if (m_stroker)
+ FT_Stroker_Set(m_stroker, strength, FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 0);
+ }
+
// grab the maximum cell height and width
unsigned int m_cellWidth = m_face->bbox.xMax - m_face->bbox.xMin;
m_cellHeight = m_face->bbox.yMax - m_face->bbox.yMin;
@@ -517,6 +551,8 @@ bool CGUIFontTTFBase::CacheCharacter(wchar_t letter, uint32_t style, Character *
CLog::Log(LOGDEBUG, "%s Failed to get glyph %x", __FUNCTION__, letter);
return false;
}
+ if (m_stroker)
+ FT_Glyph_StrokeBorder(&glyph, m_stroker, 0, 1);
// render the glyph
if (FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, NULL, 1))
{
diff --git a/guilib/GUIFontTTF.h b/guilib/GUIFontTTF.h
index e39455946f..c509ad0552 100644
--- a/guilib/GUIFontTTF.h
+++ b/guilib/GUIFontTTF.h
@@ -35,11 +35,13 @@ struct FT_FaceRec_;
struct FT_LibraryRec_;
struct FT_GlyphSlotRec_;
struct FT_BitmapGlyphRec_;
+struct FT_StrokerRec_;
typedef struct FT_FaceRec_ *FT_Face;
typedef struct FT_LibraryRec_ *FT_Library;
typedef struct FT_GlyphSlotRec_ *FT_GlyphSlot;
typedef struct FT_BitmapGlyphRec_ *FT_BitmapGlyph;
+typedef struct FT_StrokerRec_ *FT_Stroker;
typedef uint32_t character_t;
typedef uint32_t color_t;
@@ -70,7 +72,7 @@ public:
void Clear();
- bool Load(const CStdString& strFilename, float height = 20.0f, float aspect = 1.0f, float lineSpacing = 1.0f);
+ bool Load(const CStdString& strFilename, float height = 20.0f, float aspect = 1.0f, float lineSpacing = 1.0f, bool border = false);
virtual void Begin() = 0;
virtual void End() = 0;
@@ -138,6 +140,7 @@ protected:
// freetype stuff
FT_Face m_face;
+ FT_Stroker m_stroker;
float m_originX;
float m_originY;
diff --git a/guilib/GUITextLayout.cpp b/guilib/GUITextLayout.cpp
index 3a69d0c8ad..4208573641 100644
--- a/guilib/GUITextLayout.cpp
+++ b/guilib/GUITextLayout.cpp
@@ -44,9 +44,10 @@ CStdString CGUIString::GetAsString() const
return text;
}
-CGUITextLayout::CGUITextLayout(CGUIFont *font, bool wrap, float fHeight)
+CGUITextLayout::CGUITextLayout(CGUIFont *font, bool wrap, float fHeight, CGUIFont *borderFont)
{
m_font = font;
+ m_borderFont = borderFont;
m_textColor = 0;
m_wrap = wrap;
m_maxHeight = fHeight;
@@ -156,6 +157,22 @@ void CGUITextLayout::RenderOutline(float x, float y, color_t color, color_t outl
y -= m_font->GetTextHeight(m_lines.size()) * 0.5f;;
alignment &= ~XBFONT_CENTER_Y;
}
+ if (m_borderFont)
+ {
+ float by = y;
+ m_borderFont->Begin();
+ for (vector<CGUIString>::iterator i = m_lines.begin(); i != m_lines.end(); i++)
+ {
+ const CGUIString &string = *i;
+ uint32_t align = alignment;
+ if (align & XBFONT_JUSTIFIED && string.m_carriageReturn)
+ align &= ~XBFONT_JUSTIFIED;
+
+ m_borderFont->DrawText(x, by, m_colors, 0, string.m_text, align, maxWidth);
+ by += m_borderFont->GetLineHeight();
+ }
+ m_borderFont->End();
+ }
m_font->Begin();
for (vector<CGUIString>::iterator i = m_lines.begin(); i != m_lines.end(); i++)
{
@@ -164,7 +181,7 @@ void CGUITextLayout::RenderOutline(float x, float y, color_t color, color_t outl
if (align & XBFONT_JUSTIFIED && string.m_carriageReturn)
align &= ~XBFONT_JUSTIFIED;
- DrawOutlineText(m_font, x, y, m_colors, outlineColor, outlineWidth, string.m_text, align, maxWidth);
+ m_font->DrawText(x, y, m_colors, 0, string.m_text, align, maxWidth);
y += m_font->GetLineHeight();
}
m_font->End();
diff --git a/guilib/GUITextLayout.h b/guilib/GUITextLayout.h
index 165c5a39cb..515d423172 100644
--- a/guilib/GUITextLayout.h
+++ b/guilib/GUITextLayout.h
@@ -65,7 +65,7 @@ public:
class CGUITextLayout
{
public:
- CGUITextLayout(CGUIFont *font, bool wrap, float fHeight=0.0f); // this may need changing - we may just use this class to replace CLabelInfo completely
+ CGUITextLayout(CGUIFont *font, bool wrap, float fHeight=0.0f, CGUIFont *borderFont = NULL); // this may need changing - we may just use this class to replace CLabelInfo completely
// main function to render strings
void Render(float x, float y, float angle, color_t color, color_t shadowColor, uint32_t alignment, float maxWidth, bool solid = false);
@@ -116,6 +116,8 @@ protected:
// the layout and font details
CGUIFont *m_font; // has style, colour info
+ CGUIFont *m_borderFont; // only used for outlined text
+
bool m_wrap; // wrapping (true if justify is enabled!)
float m_maxHeight;
// the default color (may differ from the font objects defaults)