Some minor llfont cleanup..more to come

This commit is contained in:
Drake Arconis
2013-03-07 01:40:07 -05:00
parent 394d8afa17
commit f6713559e9
9 changed files with 209 additions and 218 deletions

View File

@@ -25,8 +25,8 @@ include_directories(
set(llrender_SOURCE_FILES
llcubemap.cpp
llfont.cpp
llfontbitmapcache.cpp
llfontfreetype.cpp
llfontgl.cpp
llfontregistry.cpp
llgl.cpp
@@ -49,8 +49,8 @@ set(llrender_HEADER_FILES
CMakeLists.txt
llcubemap.h
llfont.h
llfontbitmapcache.h
llfontfreetype.h
llfontgl.h
llfontregistry.h
llgl.h

View File

@@ -1,6 +1,6 @@
/**
* @file llfont.cpp
* @brief Font library wrapper
* @file llfontfreetype.cpp
* @brief Freetype font library wrapper
*
* $LicenseInfo:firstyear=2002&license=viewergpl$
*
@@ -32,18 +32,10 @@
#include "linden_common.h"
#include "llfont.h"
#include "llfontfreetype.h"
// Freetype stuff
#if !defined(LL_LINUX) || defined(LL_STANDALONE)
# include <ft2build.h>
#else
// I had to do some work to avoid the system-installed FreeType headers... --ryan.
//This path no longer exists.
//# include "llfreetype2/freetype/ft2build.h"
//This works fine.
# include "../include/ft2build.h"
#endif
#include <ft2build.h>
// For some reason, this won't work if it's not wrapped in the ifdef
#ifdef FT_FREETYPE_H
@@ -65,12 +57,15 @@ LLFontManager *gFontManagerp = NULL;
FT_Library gFTLibrary = NULL;
bool LLFont::sOpenGLcrashOnRestart = false;
bool LLFontFreetype::sOpenGLcrashOnRestart = false;
//static
void LLFontManager::initClass()
{
gFontManagerp = new LLFontManager;
if (!gFontManagerp)
{
gFontManagerp = new LLFontManager;
}
}
//static
@@ -125,33 +120,29 @@ LLFontList::~LLFontList()
// The (now dangling) pointers in the vector will be cleaned up when the vector is deleted by the superclass destructor.
}
}
void LLFontList::addAtEnd(LLFont *font)
void LLFontList::addAtEnd(LLFontFreetype *font)
{
// Purely a convenience function
this->push_back(font);
}
LLFont::LLFont()
LLFontFreetype::LLFontFreetype()
: mFontBitmapCachep(new LLFontBitmapCache),
mValid(FALSE),
mAscender(0.f),
mDescender(0.f),
mLineHeight(0.f),
mFallbackFontp(NULL),
mIsFallback(FALSE),
mFTFace(NULL),
mRenderGlyphCount(0),
mAddGlyphCount(0),
mPointSize(0)
{
mFontBitmapCachep = new LLFontBitmapCache;
mValid = FALSE;
mAscender = 0.f;
mDescender = 0.f;
mLineHeight = 0.f;
mFallbackFontp = NULL;
mIsFallback = FALSE;
mFTFace = NULL;
mRenderGlyphCount = 0;
mAddGlyphCount = 0;
mPointSize = 0;
}
LLFont::~LLFont()
LLFontFreetype::~LLFontFreetype()
{
// Clean up freetype libs.
if (mFTFace)
@@ -164,25 +155,7 @@ LLFont::~LLFont()
// mFontBitmapCachep will be cleaned up by LLPointer destructor.
}
// virtual
F32 LLFont::getLineHeight() const
{
return mLineHeight;
}
// virtual
F32 LLFont::getAscenderHeight() const
{
return mAscender;
}
// virtual
F32 LLFont::getDescenderHeight() const
{
return mDescender;
}
BOOL LLFont::loadFace(const std::string& filename, const F32 point_size, const F32 vert_dpi, const F32 horz_dpi, const S32 components, BOOL is_fallback)
BOOL LLFontFreetype::loadFace(const std::string& filename, const F32 point_size, const F32 vert_dpi, const F32 horz_dpi, const S32 components, BOOL is_fallback)
{
// Don't leak face objects. This is also needed to deal with
// changed font file names.
@@ -259,38 +232,115 @@ BOOL LLFont::loadFace(const std::string& filename, const F32 point_size, const F
return TRUE;
}
void LLFont::resetBitmapCache()
//virtual
F32 LLFontFreetype::getLineHeight() const
{
// Iterate through glyphs and clear the mIsRendered flag
for (char_glyph_info_map_t::iterator iter = mCharGlyphInfoMap.begin();
iter != mCharGlyphInfoMap.end(); ++iter)
{
iter->second->mIsRendered = FALSE;
//FIXME: this is only strictly necessary when resetting the entire font,
//not just flushing the bitmap
iter->second->mMetricsValid = FALSE;
}
mFontBitmapCachep->reset();
if (!mIsFallback || !sOpenGLcrashOnRestart) // because this often crashes under Linux...
{
// Add the empty glyph`5
addGlyph(0, 0);
}
return mLineHeight;
}
LLFontGlyphInfo* LLFont::getGlyphInfo(const llwchar wch) const
//virtual
F32 LLFontFreetype::getAscenderHeight() const
{
char_glyph_info_map_t::iterator iter = mCharGlyphInfoMap.find(wch);
if (iter != mCharGlyphInfoMap.end())
{
return iter->second;
}
return NULL;
return mAscender;
}
//virtual
F32 LLFontFreetype::getDescenderHeight() const
{
return mDescender;
}
BOOL LLFont::hasGlyph(const llwchar wch) const
F32 LLFontFreetype::getXAdvance(const llwchar wch) const
{
if (mFTFace == NULL)
return 0.0;
llassert(!mIsFallback);
U32 glyph_index;
// Return existing info only if it is current
LLFontGlyphInfo* gi = getGlyphInfo(wch);
if (gi && gi->mMetricsValid)
{
return gi->mXAdvance;
}
const LLFontFreetype* fontp = this;
// Initialize char to glyph map
glyph_index = FT_Get_Char_Index(mFTFace, wch);
if (glyph_index == 0 && mFallbackFontp)
{
LLFontList::iterator iter;
for(iter = mFallbackFontp->begin(); (iter != mFallbackFontp->end()) && (glyph_index == 0); iter++)
{
glyph_index = FT_Get_Char_Index((*iter)->mFTFace, wch);
if(glyph_index)
{
fontp = *iter;
}
}
}
if (glyph_index)
{
// This font has this glyph
fontp->renderGlyph(glyph_index);
// Create the entry if it's not there
char_glyph_info_map_t::iterator iter2 = mCharGlyphInfoMap.find(wch);
if (iter2 == mCharGlyphInfoMap.end())
{
gi = new LLFontGlyphInfo(glyph_index);
insertGlyphInfo(wch, gi);
}
else
{
gi = iter2->second;
}
gi->mWidth = fontp->mFTFace->glyph->bitmap.width;
gi->mHeight = fontp->mFTFace->glyph->bitmap.rows;
// Convert these from 26.6 units to float pixels.
gi->mXAdvance = fontp->mFTFace->glyph->advance.x / 64.f;
gi->mYAdvance = fontp->mFTFace->glyph->advance.y / 64.f;
gi->mMetricsValid = TRUE;
return gi->mXAdvance;
}
else
{
gi = get_if_there(mCharGlyphInfoMap, (llwchar)0, (LLFontGlyphInfo*)NULL);
if (gi)
{
return gi->mXAdvance;
}
}
// Last ditch fallback - no glyphs defined at all.
return (F32)mFontBitmapCachep->getMaxCharWidth();
}
F32 LLFontFreetype::getXKerning(const llwchar char_left, const llwchar char_right) const
{
if (mFTFace == NULL)
return 0.0;
llassert(!mIsFallback);
LLFontGlyphInfo* left_glyph_info = get_if_there(mCharGlyphInfoMap, char_left, (LLFontGlyphInfo*)NULL);
U32 left_glyph = left_glyph_info ? left_glyph_info->mGlyphIndex : 0;
// Kern this puppy.
LLFontGlyphInfo* right_glyph_info = get_if_there(mCharGlyphInfoMap, char_right, (LLFontGlyphInfo*)NULL);
U32 right_glyph = right_glyph_info ? right_glyph_info->mGlyphIndex : 0;
FT_Vector delta;
llverify(!FT_Get_Kerning(mFTFace, left_glyph, right_glyph, ft_kerning_unfitted, &delta));
return delta.x*(1.f/64.f);
}
BOOL LLFontFreetype::hasGlyph(const llwchar wch) const
{
llassert(!mIsFallback);
const LLFontGlyphInfo* gi = getGlyphInfo(wch);
@@ -304,7 +354,7 @@ BOOL LLFont::hasGlyph(const llwchar wch) const
}
}
BOOL LLFont::addChar(const llwchar wch) const
BOOL LLFontFreetype::addChar(const llwchar wch) const
{
if (mFTFace == NULL)
return FALSE;
@@ -344,21 +394,7 @@ BOOL LLFont::addChar(const llwchar wch) const
return FALSE;
}
void LLFont::insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const
{
char_glyph_info_map_t::iterator iter = mCharGlyphInfoMap.find(wch);
if (iter != mCharGlyphInfoMap.end())
{
delete iter->second;
iter->second = gi;
}
else
{
mCharGlyphInfoMap[wch] = gi;
}
}
BOOL LLFont::addGlyphFromFont(const LLFont *fontp, const llwchar wch, const U32 glyph_index) const
BOOL LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, const llwchar wch, const U32 glyph_index) const
{
if (mFTFace == NULL)
return FALSE;
@@ -459,85 +495,36 @@ BOOL LLFont::addGlyphFromFont(const LLFont *fontp, const llwchar wch, const U32
return TRUE;
}
BOOL LLFont::addGlyph(const llwchar wch, const U32 glyph_index) const
LLFontGlyphInfo* LLFontFreetype::getGlyphInfo(const llwchar wch) const
{
char_glyph_info_map_t::iterator iter = mCharGlyphInfoMap.find(wch);
if (iter != mCharGlyphInfoMap.end())
{
return iter->second;
}
return NULL;
}
void LLFontFreetype::insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const
{
char_glyph_info_map_t::iterator iter = mCharGlyphInfoMap.find(wch);
if (iter != mCharGlyphInfoMap.end())
{
delete iter->second;
iter->second = gi;
}
else
{
mCharGlyphInfoMap[wch] = gi;
}
}
BOOL LLFontFreetype::addGlyph(const llwchar wch, const U32 glyph_index) const
{
return addGlyphFromFont(this, wch, glyph_index);
}
F32 LLFont::getXAdvance(const llwchar wch) const
{
if (mFTFace == NULL)
return 0.0;
llassert(!mIsFallback);
U32 glyph_index;
// Return existing info only if it is current
LLFontGlyphInfo* gi = getGlyphInfo(wch);
if (gi && gi->mMetricsValid)
{
return gi->mXAdvance;
}
const LLFont* fontp = this;
// Initialize char to glyph map
glyph_index = FT_Get_Char_Index(mFTFace, wch);
if (glyph_index == 0 && mFallbackFontp)
{
LLFontList::iterator iter;
for(iter = mFallbackFontp->begin(); (iter != mFallbackFontp->end()) && (glyph_index == 0); iter++)
{
glyph_index = FT_Get_Char_Index((*iter)->mFTFace, wch);
if(glyph_index)
{
fontp = *iter;
}
}
}
if (glyph_index)
{
// This font has this glyph
fontp->renderGlyph(glyph_index);
// Create the entry if it's not there
char_glyph_info_map_t::iterator iter2 = mCharGlyphInfoMap.find(wch);
if (iter2 == mCharGlyphInfoMap.end())
{
gi = new LLFontGlyphInfo(glyph_index);
insertGlyphInfo(wch, gi);
}
else
{
gi = iter2->second;
}
gi->mWidth = fontp->mFTFace->glyph->bitmap.width;
gi->mHeight = fontp->mFTFace->glyph->bitmap.rows;
// Convert these from 26.6 units to float pixels.
gi->mXAdvance = fontp->mFTFace->glyph->advance.x / 64.f;
gi->mYAdvance = fontp->mFTFace->glyph->advance.y / 64.f;
gi->mMetricsValid = TRUE;
return gi->mXAdvance;
}
else
{
gi = get_if_there(mCharGlyphInfoMap, (llwchar)0, (LLFontGlyphInfo*)NULL);
if (gi)
{
return gi->mXAdvance;
}
}
// Last ditch fallback - no glyphs defined at all.
return (F32)mFontBitmapCachep->getMaxCharWidth();
}
void LLFont::renderGlyph(const U32 glyph_index) const
void LLFontFreetype::renderGlyph(const U32 glyph_index) const
{
if (mFTFace == NULL)
return;
@@ -549,27 +536,28 @@ void LLFont::renderGlyph(const U32 glyph_index) const
mRenderGlyphCount++;
}
F32 LLFont::getXKerning(const llwchar char_left, const llwchar char_right) const
void LLFontFreetype::resetBitmapCache()
{
if (mFTFace == NULL)
return 0.0;
// Iterate through glyphs and clear the mIsRendered flag
for (char_glyph_info_map_t::iterator iter = mCharGlyphInfoMap.begin();
iter != mCharGlyphInfoMap.end(); ++iter)
{
iter->second->mIsRendered = FALSE;
//FIXME: this is only strictly necessary when resetting the entire font,
//not just flushing the bitmap
iter->second->mMetricsValid = FALSE;
}
mFontBitmapCachep->reset();
llassert(!mIsFallback);
LLFontGlyphInfo* left_glyph_info = get_if_there(mCharGlyphInfoMap, char_left, (LLFontGlyphInfo*)NULL);
U32 left_glyph = left_glyph_info ? left_glyph_info->mGlyphIndex : 0;
// Kern this puppy.
LLFontGlyphInfo* right_glyph_info = get_if_there(mCharGlyphInfoMap, char_right, (LLFontGlyphInfo*)NULL);
U32 right_glyph = right_glyph_info ? right_glyph_info->mGlyphIndex : 0;
FT_Vector delta;
llverify(!FT_Get_Kerning(mFTFace, left_glyph, right_glyph, ft_kerning_unfitted, &delta));
return delta.x*(1.f/64.f);
if (!mIsFallback || !sOpenGLcrashOnRestart) // because this often crashes under Linux...
{
// Add the empty glyph`5
addGlyph(0, 0);
}
}
void LLFont::setSubImageLuminanceAlpha(const U32 x,
void LLFontFreetype::setSubImageLuminanceAlpha(const U32 x,
const U32 y,
const U32 bitmap_num,
const U32 width,

View File

@@ -30,11 +30,10 @@
* $/LicenseInfo$
*/
#ifndef LL_LLFONT_H
#define LL_LLFONT_H
#ifndef LL_LLFONTFREETYPE_H
#define LL_LLFONTFREETYPE_H
#include <map>
//#include "lllocalidhashmap.h"
#include "llmemory.h"
#include "llstl.h"
@@ -43,7 +42,7 @@
class LLImageRaw;
class LLFontManager;
class LLFont;
class LLFontFreetype;
// Hack. FT_Face is just a typedef for a pointer to a struct,
// but there's no simple forward declarations file for FreeType,
@@ -59,7 +58,7 @@ class LLFontManager
public:
static void initClass();
static void cleanupClass();
public:
LLFontManager();
virtual ~LLFontManager();
@@ -88,19 +87,19 @@ public:
};
// Used for lists of fallback fonts
class LLFontList : public std::vector<LLFont*>
class LLFontList : public std::vector<LLFontFreetype*>
{
public:
LLFontList();
~LLFontList();
void addAtEnd(LLFont *font);
void addAtEnd(LLFontFreetype *font);
};
class LLFont
class LLFontFreetype
{
public:
LLFont();
virtual ~LLFont();
LLFontFreetype();
~LLFontFreetype();
// is_fallback should be true for fallback fonts that aren't used
// to render directly (Unicode backup, primarily)
@@ -157,7 +156,7 @@ protected:
virtual BOOL hasGlyph(const llwchar wch) const; // Has a glyph for this character
virtual BOOL addChar(const llwchar wch) const; // Add a new character to the font if necessary
virtual BOOL addGlyph(const llwchar wch, const U32 glyph_index) const; // Add a new glyph to the existing font
virtual BOOL addGlyphFromFont(const LLFont *fontp, const llwchar wch, const U32 glyph_index) const; // Add a glyph from this font to the other (returns the glyph_index, 0 if not found)
virtual BOOL addGlyphFromFont(const LLFontFreetype *fontp, const llwchar wch, const U32 glyph_index) const; // Add a glyph from this font to the other (returns the glyph_index, 0 if not found)
virtual LLFontGlyphInfo* getGlyphInfo(const llwchar wch) const;
@@ -195,4 +194,4 @@ protected:
mutable S32 mAddGlyphCount;
};
#endif // LL_FONT_
#endif // LL_FONTFREETYPE_H

View File

@@ -26,10 +26,12 @@
#include "linden_common.h"
#include <boost/tokenizer.hpp>
#include "llfont.h"
#include "llfontgl.h"
// Linden library includes
#include "llfontfreetype.h"
#include "llfontbitmapcache.h"
#include "llfontregistry.h"
#include "llgl.h"
@@ -38,6 +40,9 @@
#include "llstl.h"
#include "llfasttimer.h"
// Third party library includes
#include <boost/tokenizer.hpp>
const S32 BOLD_OFFSET = 1;
// static class members
@@ -79,7 +84,7 @@ F32 llfont_round_y(F32 y)
}
LLFontGL::LLFontGL()
: LLFont()
: LLFontFreetype()
{
clearEmbeddedChars();
}
@@ -128,7 +133,7 @@ void LLFontGL::destroyGL()
BOOL LLFontGL::loadFace(const std::string& filename, const F32 point_size, const F32 vert_dpi, const F32 horz_dpi, const S32 components, BOOL is_fallback)
{
if (!LLFont::loadFace(filename, point_size, vert_dpi, horz_dpi, components, is_fallback))
if (!LLFontFreetype::loadFace(filename, point_size, vert_dpi, horz_dpi, components, is_fallback))
{
return FALSE;
}
@@ -138,7 +143,7 @@ BOOL LLFontGL::loadFace(const std::string& filename, const F32 point_size, const
BOOL LLFontGL::addChar(const llwchar wch) const
{
if (!LLFont::addChar(wch))
if (!LLFontFreetype::addChar(wch))
{
return FALSE;
}
@@ -288,7 +293,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
F32 inv_width = 1.f / mFontBitmapCachep->getBitmapWidth();
F32 inv_height = 1.f / mFontBitmapCachep->getBitmapHeight();
const S32 LAST_CHARACTER = LLFont::LAST_CHAR_FULL;
const S32 LAST_CHARACTER = LLFontFreetype::LAST_CHAR_FULL;
BOOL draw_ellipses = FALSE;
@@ -546,7 +551,7 @@ F32 LLFontGL::getWidthF32(const std::string& utf8text, const S32 begin_offset, c
F32 LLFontGL::getWidthF32(const llwchar* wchars, const S32 begin_offset, const S32 max_chars, BOOL use_embedded) const
{
const S32 LAST_CHARACTER = LLFont::LAST_CHAR_FULL;
const S32 LAST_CHARACTER = LLFontFreetype::LAST_CHAR_FULL;
F32 cur_x = 0;
const S32 max_index = begin_offset + max_chars;
@@ -981,7 +986,7 @@ void LLFontGL::destroyAllGL()
{
if (sFontRegistry)
{
if (LLFont::sOpenGLcrashOnRestart)
if (LLFontFreetype::sOpenGLcrashOnRestart)
{
// This will leak memory but will prevent a crash...
sFontRegistry = NULL;

View File

@@ -28,7 +28,7 @@
#ifndef LL_LLFONTGL_H
#define LL_LLFONTGL_H
#include "llfont.h"
#include "llfontfreetype.h"
#include "lltexture.h"
#include "v2math.h"
#include "llcoord.h"
@@ -44,7 +44,7 @@ class LLFontDescriptor;
// Structure used to store previously requested fonts.
class LLFontRegistry;
class LLFontGL : public LLFont
class LLFontGL : public LLFontFreetype
{
public:
enum HAlign
@@ -66,12 +66,11 @@ public:
enum StyleFlags
{
// text style to render. May be combined (these are bit flags)
// text style to render. May be combined (these are bit flags)
NORMAL = 0x00,
BOLD = 0x01,
ITALIC = 0x02,
UNDERLINE = 0x04,
UNDERLINE = 0x04
};
enum ShadowType

View File

@@ -27,6 +27,7 @@
#include "linden_common.h"
#include "llgl.h"
#include "llfontfreetype.h"
#include "llfontgl.h"
#include "llfontregistry.h"
#include <boost/tokenizer.hpp>
@@ -188,21 +189,20 @@ bool LLFontRegistry::parseFontInfo(const std::string& xml_filename)
path_it != xml_paths.end();
++path_it)
{
LLXMLNodePtr root;
std::string full_filename = gDirUtilp->findSkinnedFilename(*path_it, xml_filename);
bool parsed_file = LLXMLNode::parseFile(full_filename, root, NULL);
if (!parsed_file)
continue;
if ( root.isNull() || ! root->hasName( "fonts" ) )
{
llwarns << "Bad font info file: "
<< full_filename << llendl;
continue;
}
std::string root_name;
root->getAttributeString("name",root_name);
if (root->hasName("fonts"))
@@ -214,7 +214,7 @@ bool LLFontRegistry::parseFontInfo(const std::string& xml_filename)
}
if (success)
dump();
return success;
}

View File

@@ -35,7 +35,7 @@
#include "v4color.h"
#include "llresmgr.h"
#include "llfont.h"
#include "llfontfreetype.h"
#include "llui.h"
#include "lluiimage.h"

View File

@@ -2228,7 +2228,7 @@ void LLTextEditor::pasteHelper(bool is_primary)
for( S32 i = 0; i < len; i++ )
{
llwchar wc = clean_string[i];
if( (wc < LLFont::FIRST_CHAR) && (wc != LF) )
if( (wc < LLFontFreetype::FIRST_CHAR) && (wc != LF) )
{
clean_string[i] = LL_UNKNOWN_CHAR;
}

View File

@@ -80,7 +80,7 @@
#include "llfirstuse.h"
#include "llrender.h"
#include "llvector4a.h"
#include "llfont.h"
#include "llfontfreetype.h"
#include "llvocache.h"
#include "llvopartgroup.h"
#include "llfloaterteleporthistory.h"
@@ -803,7 +803,7 @@ bool LLAppViewer::init()
// Modify settings based on system configuration and compile options
settings_modify();
// Work around for a crash bug when changing OpenGL settings
LLFont::sOpenGLcrashOnRestart = (getenv("LL_OPENGL_RESTART_CRASH_BUG") != NULL);
LLFontFreetype::sOpenGLcrashOnRestart = (getenv("LL_OPENGL_RESTART_CRASH_BUG") != NULL);
// Find partition serial number (Windows) or hardware serial (Mac)
mSerialNumber = generateSerialNumber();