diff options
author | jmarshallnz <jmarshallnz@svn> | 2010-07-24 05:20:36 +0000 |
---|---|---|
committer | jmarshallnz <jmarshallnz@svn> | 2010-07-24 05:20:36 +0000 |
commit | 8d7151e540dc1a05c0eb559569748c47a24cc54a (patch) | |
tree | 50e3f5b93e685f186b49489eaa4f915b58cbf9af /guilib | |
parent | be1d0b43e7a7a3a618a8ff6f81d277f36911be31 (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.cpp | 13 | ||||
-rw-r--r-- | guilib/GUIFontManager.h | 3 | ||||
-rw-r--r-- | guilib/GUIFontTTF.cpp | 38 | ||||
-rw-r--r-- | guilib/GUIFontTTF.h | 5 | ||||
-rw-r--r-- | guilib/GUITextLayout.cpp | 21 | ||||
-rw-r--r-- | guilib/GUITextLayout.h | 4 |
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) |