Font update. Minor refactor, and removed some pointless code that was leaking.

This commit is contained in:
Shyotl
2013-11-18 09:56:49 -06:00
parent 2badc1c79c
commit be249ac8a1
9 changed files with 298 additions and 264 deletions

View File

@@ -2,37 +2,32 @@
* @file llfontfreetype.cpp
* @brief Freetype font library wrapper
*
* $LicenseInfo:firstyear=2002&license=viewergpl$
*
* Copyright (c) 2002-2009, Linden Research, Inc.
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
* Copyright (C) 2010, Linden Research, Inc.
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "llfontfreetype.h"
#include "llfontgl.h"
// Freetype stuff
#include <ft2build.h>
@@ -103,36 +98,18 @@ LLFontGlyphInfo::LLFontGlyphInfo(U32 index)
mYBitmapOffset(0), // Offset to the origin in the bitmap
mXBearing(0), // Distance from baseline to left in pixels
mYBearing(0), // Distance from baseline to top in pixels
mBitmapNum(0), // Which bitmap in the bitmap cache contains this glyph
mIsRendered(FALSE),
mMetricsValid(FALSE)
{}
LLFontList::LLFontList()
{
}
LLFontList::~LLFontList()
{
LLFontList::iterator iter;
for(iter = this->begin(); iter != this->end(); iter++)
{
delete *iter;
// The (now dangling) pointers in the vector will be cleaned up when the vector is deleted by the superclass destructor.
}
}
void LLFontList::addAtEnd(LLFontFreetype *font)
{
// Purely a convenience function
this->push_back(font);
}
LLFontFreetype::LLFontFreetype()
: mFontBitmapCachep(new LLFontBitmapCache),
mValid(FALSE),
mAscender(0.f),
mDescender(0.f),
mLineHeight(0.f),
mFallbackFontp(NULL),
mIsFallback(FALSE),
mFTFace(NULL),
mRenderGlyphCount(0),
@@ -222,8 +199,8 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, const F32 point_size,
if (!mIsFallback || !sOpenGLcrashOnRestart) // because this often crashes under Linux...
{
// Add the empty glyph`5
addGlyph(0, 0);
// Add the default glyph
addGlyphFromFont(this, 0, 0);
}
mName = filename;
@@ -232,19 +209,26 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, const F32 point_size,
return TRUE;
}
//virtual
void LLFontFreetype::setFallbackFonts(const font_vector_t &font)
{
mFallbackFonts = font;
}
const LLFontFreetype::font_vector_t &LLFontFreetype::getFallbackFonts() const
{
return mFallbackFonts;
}
F32 LLFontFreetype::getLineHeight() const
{
return mLineHeight;
}
//virtual
F32 LLFontFreetype::getAscenderHeight() const
{
return mAscender;
}
//virtual
F32 LLFontFreetype::getDescenderHeight() const
{
return mDescender;
@@ -256,7 +240,7 @@ F32 LLFontFreetype::getXAdvance(const llwchar wch) const
return 0.0;
llassert(!mIsFallback);
U32 glyph_index;
//U32 glyph_index;
// Return existing info only if it is current
LLFontGlyphInfo* gi = getGlyphInfo(wch);
@@ -264,18 +248,26 @@ F32 LLFontFreetype::getXAdvance(const llwchar wch) const
{
return gi->mXAdvance;
}
const LLFontFreetype* fontp = this;
//new
else
{
char_glyph_info_map_t::iterator found_it = mCharGlyphInfoMap.find((llwchar)0);
if (found_it != mCharGlyphInfoMap.end())
{
return found_it->second->mXAdvance;
}
}
/*const LLFontFreetype* fontp = this;
// Initialize char to glyph map
glyph_index = FT_Get_Char_Index(mFTFace, wch);
if (glyph_index == 0 && mFallbackFontp)
if (glyph_index == 0)
{
LLFontList::iterator iter;
for(iter = mFallbackFontp->begin(); (iter != mFallbackFontp->end()) && (glyph_index == 0); iter++)
font_vector_t::const_iterator iter;
for(iter = mFallbackFonts.begin(); iter != mFallbackFonts.end(); iter++)
{
glyph_index = FT_Get_Char_Index((*iter)->mFTFace, wch);
if(glyph_index)
if (glyph_index)
{
fontp = *iter;
}
@@ -306,6 +298,7 @@ F32 LLFontFreetype::getXAdvance(const llwchar wch) const
gi->mXAdvance = fontp->mFTFace->glyph->advance.x / 64.f;
gi->mYAdvance = fontp->mFTFace->glyph->advance.y / 64.f;
gi->mMetricsValid = TRUE;
//gi->mIsRendered = TRUE;
return gi->mXAdvance;
}
else
@@ -315,7 +308,7 @@ F32 LLFontFreetype::getXAdvance(const llwchar wch) const
{
return gi->mXAdvance;
}
}
}*/
// Last ditch fallback - no glyphs defined at all.
return (F32)mFontBitmapCachep->getMaxCharWidth();
@@ -343,7 +336,8 @@ F32 LLFontFreetype::getXKerning(const llwchar char_left, const llwchar char_righ
BOOL LLFontFreetype::hasGlyph(const llwchar wch) const
{
llassert(!mIsFallback);
const LLFontGlyphInfo* gi = getGlyphInfo(wch);
return(mCharGlyphInfoMap.find(wch) != mCharGlyphInfoMap.end());
/*const LLFontGlyphInfo* gi = getGlyphInfo(wch);
if (gi && gi->mIsRendered)
{
return TRUE;
@@ -351,10 +345,10 @@ BOOL LLFontFreetype::hasGlyph(const llwchar wch) const
else
{
return FALSE;
}
}*/
}
BOOL LLFontFreetype::addChar(const llwchar wch) const
BOOL LLFontFreetype::addGlyph(const llwchar wch) const
{
if (mFTFace == NULL)
return FALSE;
@@ -368,19 +362,15 @@ BOOL LLFontFreetype::addChar(const llwchar wch) const
glyph_index = FT_Get_Char_Index(mFTFace, wch);
if (glyph_index == 0)
{
// Try looking it up in the backup Unicode font
if (mFallbackFontp)
//llinfos << "Trying to add glyph from fallback font!" << llendl;
font_vector_t::const_iterator iter;
for(iter = mFallbackFonts.begin(); iter != mFallbackFonts.end(); iter++)
{
//llinfos << "Trying to add glyph from fallback font!" << llendl;
LLFontList::iterator iter;
for(iter = mFallbackFontp->begin(); iter != mFallbackFontp->end(); iter++)
glyph_index = FT_Get_Char_Index((*iter)->mFTFace, wch);
if (glyph_index)
{
glyph_index = FT_Get_Char_Index((*iter)->mFTFace, wch);
if (glyph_index)
{
addGlyphFromFont(*iter, wch, glyph_index);
return TRUE;
}
addGlyphFromFont(*iter, wch, glyph_index);
return TRUE;
}
}
}
@@ -388,8 +378,7 @@ BOOL LLFontFreetype::addChar(const llwchar wch) const
char_glyph_info_map_t::iterator iter = mCharGlyphInfoMap.find(wch);
if (iter == mCharGlyphInfoMap.end() || !(iter->second->mIsRendered))
{
BOOL result = addGlyph(wch, glyph_index);
return result;
return addGlyphFromFont(this, wch, glyph_index);
}
return FALSE;
}
@@ -492,6 +481,11 @@ BOOL LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, const llwchar
// omit it from the font-image.
}
//new
LLImageGL *image_gl = mFontBitmapCachep->getImageGL(bitmap_num);
LLImageRaw *image_raw = mFontBitmapCachep->getImageRaw(bitmap_num);
image_gl->setSubImage(image_raw, 0, 0, image_gl->getWidth(), image_gl->getHeight());
return TRUE;
}
@@ -502,6 +496,15 @@ LLFontGlyphInfo* LLFontFreetype::getGlyphInfo(const llwchar wch) const
{
return iter->second;
}
else if(addGlyph(wch))//new
{
// this glyph doesn't yet exist, so render it and return the result
char_glyph_info_map_t::iterator iter = mCharGlyphInfoMap.find(wch);
if (iter != mCharGlyphInfoMap.end())
{
return iter->second;
}
}
return NULL;
}
@@ -519,11 +522,6 @@ void LLFontFreetype::insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const
}
}
BOOL LLFontFreetype::addGlyph(const llwchar wch, const U32 glyph_index) const
{
return addGlyphFromFont(this, wch, glyph_index);
}
void LLFontFreetype::renderGlyph(const U32 glyph_index) const
{
if (mFTFace == NULL)
@@ -536,34 +534,74 @@ void LLFontFreetype::renderGlyph(const U32 glyph_index) const
mRenderGlyphCount++;
}
void LLFontFreetype::reset(F32 vert_dpi, F32 horz_dpi)
{
//new
resetBitmapCache();
loadFace(mName,mPointSize,vert_dpi,horz_dpi,mFontBitmapCachep->getNumComponents(),mIsFallback);
if (!mIsFallback)
{
// This is the head of the list - need to rebuild ourself and all fallbacks.
//loadFace(mName,mPointSize,vert_dpi,horz_dpi,mFontBitmapCachep->getNumComponents(),mIsFallback);
if (mFallbackFonts.empty())
{
llwarns << "LLFontGL::reset(), no fallback fonts present" << llendl;
}
else
{
for(font_vector_t::iterator it = mFallbackFonts.begin();
it != mFallbackFonts.end();
++it)
{
(*it)->reset(vert_dpi, horz_dpi);
}
}
}
//resetBitmapCache();
}
void LLFontFreetype::resetBitmapCache()
{
// Iterate through glyphs and clear the mIsRendered flag
for (char_glyph_info_map_t::iterator iter = mCharGlyphInfoMap.begin();
/*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;
}
}*/
//new
for_each(mCharGlyphInfoMap.begin(), mCharGlyphInfoMap.end(), DeletePairedPointer());
mCharGlyphInfoMap.clear();
mFontBitmapCachep->reset();
// Adding default glyph is skipped for fallback fonts here as well as in loadFace().
// This if was added as fix for EXT-4971.
if (!mIsFallback || !sOpenGLcrashOnRestart) // because this often crashes under Linux...
{
// Add the empty glyph`5
addGlyph(0, 0);
// Add the empty glyph
addGlyphFromFont(this, 0, 0);
}
}
void LLFontFreetype::destroyGL()
{
mFontBitmapCachep->destroyGL();
}
void LLFontFreetype::setSubImageLuminanceAlpha(const U32 x,
const U32 y,
const U32 bitmap_num,
const U32 width,
const U32 height,
const U8 *data,
S32 stride) const
const std::string &LLFontFreetype::getName() const
{
return mName;
}
const LLPointer<LLFontBitmapCache> LLFontFreetype::getFontBitmapCache() const
{
return mFontBitmapCachep;
}
void LLFontFreetype::setSubImageLuminanceAlpha(const U32 x, const U32 y, const U32 bitmap_num, const U32 width, const U32 height, const U8 *data, S32 stride) const
{
LLImageRaw *image_raw = mFontBitmapCachep->getImageRaw(bitmap_num);