Font update. Minor refactor, and removed some pointless code that was leaking.
This commit is contained in:
@@ -2,37 +2,32 @@
|
|||||||
* @file llfontfreetype.cpp
|
* @file llfontfreetype.cpp
|
||||||
* @brief Freetype font library wrapper
|
* @brief Freetype font library wrapper
|
||||||
*
|
*
|
||||||
* $LicenseInfo:firstyear=2002&license=viewergpl$
|
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
||||||
*
|
|
||||||
* Copyright (c) 2002-2009, Linden Research, Inc.
|
|
||||||
*
|
|
||||||
* Second Life Viewer Source Code
|
* Second Life Viewer Source Code
|
||||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
* Copyright (C) 2010, Linden Research, Inc.
|
||||||
* 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
|
|
||||||
*
|
*
|
||||||
* There are special exceptions to the terms and conditions of the GPL as
|
* This library is free software; you can redistribute it and/or
|
||||||
* it is applied to this Source Code. View the full text of the exception
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
* License as published by the Free Software Foundation;
|
||||||
* online at
|
* version 2.1 of the License only.
|
||||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
|
||||||
*
|
*
|
||||||
* By copying, modifying or distributing this software, you acknowledge
|
* This library is distributed in the hope that it will be useful,
|
||||||
* that you have read and understood your obligations described above,
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* and agree to abide by those obligations.
|
* 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
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
* License along with this library; if not, write to the Free Software
|
||||||
* COMPLETENESS OR PERFORMANCE.
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||||
* $/LicenseInfo$
|
* $/LicenseInfo$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "linden_common.h"
|
#include "linden_common.h"
|
||||||
|
|
||||||
#include "llfontfreetype.h"
|
#include "llfontfreetype.h"
|
||||||
|
#include "llfontgl.h"
|
||||||
|
|
||||||
// Freetype stuff
|
// Freetype stuff
|
||||||
#include <ft2build.h>
|
#include <ft2build.h>
|
||||||
@@ -103,36 +98,18 @@ LLFontGlyphInfo::LLFontGlyphInfo(U32 index)
|
|||||||
mYBitmapOffset(0), // Offset to the origin in the bitmap
|
mYBitmapOffset(0), // Offset to the origin in the bitmap
|
||||||
mXBearing(0), // Distance from baseline to left in pixels
|
mXBearing(0), // Distance from baseline to left in pixels
|
||||||
mYBearing(0), // Distance from baseline to top in pixels
|
mYBearing(0), // Distance from baseline to top in pixels
|
||||||
|
mBitmapNum(0), // Which bitmap in the bitmap cache contains this glyph
|
||||||
mIsRendered(FALSE),
|
mIsRendered(FALSE),
|
||||||
mMetricsValid(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()
|
LLFontFreetype::LLFontFreetype()
|
||||||
: mFontBitmapCachep(new LLFontBitmapCache),
|
: mFontBitmapCachep(new LLFontBitmapCache),
|
||||||
mValid(FALSE),
|
mValid(FALSE),
|
||||||
mAscender(0.f),
|
mAscender(0.f),
|
||||||
mDescender(0.f),
|
mDescender(0.f),
|
||||||
mLineHeight(0.f),
|
mLineHeight(0.f),
|
||||||
mFallbackFontp(NULL),
|
|
||||||
mIsFallback(FALSE),
|
mIsFallback(FALSE),
|
||||||
mFTFace(NULL),
|
mFTFace(NULL),
|
||||||
mRenderGlyphCount(0),
|
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...
|
if (!mIsFallback || !sOpenGLcrashOnRestart) // because this often crashes under Linux...
|
||||||
{
|
{
|
||||||
// Add the empty glyph`5
|
// Add the default glyph
|
||||||
addGlyph(0, 0);
|
addGlyphFromFont(this, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
mName = filename;
|
mName = filename;
|
||||||
@@ -232,19 +209,26 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, const F32 point_size,
|
|||||||
return TRUE;
|
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
|
F32 LLFontFreetype::getLineHeight() const
|
||||||
{
|
{
|
||||||
return mLineHeight;
|
return mLineHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
//virtual
|
|
||||||
F32 LLFontFreetype::getAscenderHeight() const
|
F32 LLFontFreetype::getAscenderHeight() const
|
||||||
{
|
{
|
||||||
return mAscender;
|
return mAscender;
|
||||||
}
|
}
|
||||||
|
|
||||||
//virtual
|
|
||||||
F32 LLFontFreetype::getDescenderHeight() const
|
F32 LLFontFreetype::getDescenderHeight() const
|
||||||
{
|
{
|
||||||
return mDescender;
|
return mDescender;
|
||||||
@@ -256,7 +240,7 @@ F32 LLFontFreetype::getXAdvance(const llwchar wch) const
|
|||||||
return 0.0;
|
return 0.0;
|
||||||
|
|
||||||
llassert(!mIsFallback);
|
llassert(!mIsFallback);
|
||||||
U32 glyph_index;
|
//U32 glyph_index;
|
||||||
|
|
||||||
// Return existing info only if it is current
|
// Return existing info only if it is current
|
||||||
LLFontGlyphInfo* gi = getGlyphInfo(wch);
|
LLFontGlyphInfo* gi = getGlyphInfo(wch);
|
||||||
@@ -264,18 +248,26 @@ F32 LLFontFreetype::getXAdvance(const llwchar wch) const
|
|||||||
{
|
{
|
||||||
return gi->mXAdvance;
|
return gi->mXAdvance;
|
||||||
}
|
}
|
||||||
|
//new
|
||||||
const LLFontFreetype* fontp = this;
|
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
|
// Initialize char to glyph map
|
||||||
glyph_index = FT_Get_Char_Index(mFTFace, wch);
|
glyph_index = FT_Get_Char_Index(mFTFace, wch);
|
||||||
if (glyph_index == 0 && mFallbackFontp)
|
if (glyph_index == 0)
|
||||||
{
|
{
|
||||||
LLFontList::iterator iter;
|
font_vector_t::const_iterator iter;
|
||||||
for(iter = mFallbackFontp->begin(); (iter != mFallbackFontp->end()) && (glyph_index == 0); iter++)
|
for(iter = mFallbackFonts.begin(); iter != mFallbackFonts.end(); iter++)
|
||||||
{
|
{
|
||||||
glyph_index = FT_Get_Char_Index((*iter)->mFTFace, wch);
|
glyph_index = FT_Get_Char_Index((*iter)->mFTFace, wch);
|
||||||
if(glyph_index)
|
if (glyph_index)
|
||||||
{
|
{
|
||||||
fontp = *iter;
|
fontp = *iter;
|
||||||
}
|
}
|
||||||
@@ -306,6 +298,7 @@ F32 LLFontFreetype::getXAdvance(const llwchar wch) const
|
|||||||
gi->mXAdvance = fontp->mFTFace->glyph->advance.x / 64.f;
|
gi->mXAdvance = fontp->mFTFace->glyph->advance.x / 64.f;
|
||||||
gi->mYAdvance = fontp->mFTFace->glyph->advance.y / 64.f;
|
gi->mYAdvance = fontp->mFTFace->glyph->advance.y / 64.f;
|
||||||
gi->mMetricsValid = TRUE;
|
gi->mMetricsValid = TRUE;
|
||||||
|
//gi->mIsRendered = TRUE;
|
||||||
return gi->mXAdvance;
|
return gi->mXAdvance;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -315,7 +308,7 @@ F32 LLFontFreetype::getXAdvance(const llwchar wch) const
|
|||||||
{
|
{
|
||||||
return gi->mXAdvance;
|
return gi->mXAdvance;
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// Last ditch fallback - no glyphs defined at all.
|
// Last ditch fallback - no glyphs defined at all.
|
||||||
return (F32)mFontBitmapCachep->getMaxCharWidth();
|
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
|
BOOL LLFontFreetype::hasGlyph(const llwchar wch) const
|
||||||
{
|
{
|
||||||
llassert(!mIsFallback);
|
llassert(!mIsFallback);
|
||||||
const LLFontGlyphInfo* gi = getGlyphInfo(wch);
|
return(mCharGlyphInfoMap.find(wch) != mCharGlyphInfoMap.end());
|
||||||
|
/*const LLFontGlyphInfo* gi = getGlyphInfo(wch);
|
||||||
if (gi && gi->mIsRendered)
|
if (gi && gi->mIsRendered)
|
||||||
{
|
{
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@@ -351,10 +345,10 @@ BOOL LLFontFreetype::hasGlyph(const llwchar wch) const
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL LLFontFreetype::addChar(const llwchar wch) const
|
BOOL LLFontFreetype::addGlyph(const llwchar wch) const
|
||||||
{
|
{
|
||||||
if (mFTFace == NULL)
|
if (mFTFace == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -368,19 +362,15 @@ BOOL LLFontFreetype::addChar(const llwchar wch) const
|
|||||||
glyph_index = FT_Get_Char_Index(mFTFace, wch);
|
glyph_index = FT_Get_Char_Index(mFTFace, wch);
|
||||||
if (glyph_index == 0)
|
if (glyph_index == 0)
|
||||||
{
|
{
|
||||||
// Try looking it up in the backup Unicode font
|
//llinfos << "Trying to add glyph from fallback font!" << llendl;
|
||||||
if (mFallbackFontp)
|
font_vector_t::const_iterator iter;
|
||||||
|
for(iter = mFallbackFonts.begin(); iter != mFallbackFonts.end(); iter++)
|
||||||
{
|
{
|
||||||
//llinfos << "Trying to add glyph from fallback font!" << llendl;
|
glyph_index = FT_Get_Char_Index((*iter)->mFTFace, wch);
|
||||||
LLFontList::iterator iter;
|
if (glyph_index)
|
||||||
for(iter = mFallbackFontp->begin(); iter != mFallbackFontp->end(); iter++)
|
|
||||||
{
|
{
|
||||||
glyph_index = FT_Get_Char_Index((*iter)->mFTFace, wch);
|
addGlyphFromFont(*iter, wch, glyph_index);
|
||||||
if (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);
|
char_glyph_info_map_t::iterator iter = mCharGlyphInfoMap.find(wch);
|
||||||
if (iter == mCharGlyphInfoMap.end() || !(iter->second->mIsRendered))
|
if (iter == mCharGlyphInfoMap.end() || !(iter->second->mIsRendered))
|
||||||
{
|
{
|
||||||
BOOL result = addGlyph(wch, glyph_index);
|
return addGlyphFromFont(this, wch, glyph_index);
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -492,6 +481,11 @@ BOOL LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, const llwchar
|
|||||||
// omit it from the font-image.
|
// 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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -502,6 +496,15 @@ LLFontGlyphInfo* LLFontFreetype::getGlyphInfo(const llwchar wch) const
|
|||||||
{
|
{
|
||||||
return iter->second;
|
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;
|
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
|
void LLFontFreetype::renderGlyph(const U32 glyph_index) const
|
||||||
{
|
{
|
||||||
if (mFTFace == NULL)
|
if (mFTFace == NULL)
|
||||||
@@ -536,34 +534,74 @@ void LLFontFreetype::renderGlyph(const U32 glyph_index) const
|
|||||||
mRenderGlyphCount++;
|
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()
|
void LLFontFreetype::resetBitmapCache()
|
||||||
{
|
{
|
||||||
// Iterate through glyphs and clear the mIsRendered flag
|
// 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 != mCharGlyphInfoMap.end(); ++iter)
|
||||||
{
|
{
|
||||||
iter->second->mIsRendered = FALSE;
|
iter->second->mIsRendered = FALSE;
|
||||||
//FIXME: this is only strictly necessary when resetting the entire font,
|
//FIXME: this is only strictly necessary when resetting the entire font,
|
||||||
//not just flushing the bitmap
|
//not just flushing the bitmap
|
||||||
iter->second->mMetricsValid = FALSE;
|
iter->second->mMetricsValid = FALSE;
|
||||||
}
|
}*/
|
||||||
|
//new
|
||||||
|
for_each(mCharGlyphInfoMap.begin(), mCharGlyphInfoMap.end(), DeletePairedPointer());
|
||||||
|
mCharGlyphInfoMap.clear();
|
||||||
|
|
||||||
mFontBitmapCachep->reset();
|
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...
|
if (!mIsFallback || !sOpenGLcrashOnRestart) // because this often crashes under Linux...
|
||||||
{
|
{
|
||||||
// Add the empty glyph`5
|
// Add the empty glyph
|
||||||
addGlyph(0, 0);
|
addGlyphFromFont(this, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LLFontFreetype::destroyGL()
|
||||||
|
{
|
||||||
|
mFontBitmapCachep->destroyGL();
|
||||||
|
}
|
||||||
|
|
||||||
void LLFontFreetype::setSubImageLuminanceAlpha(const U32 x,
|
const std::string &LLFontFreetype::getName() const
|
||||||
const U32 y,
|
{
|
||||||
const U32 bitmap_num,
|
return mName;
|
||||||
const U32 width,
|
}
|
||||||
const U32 height,
|
|
||||||
const U8 *data,
|
const LLPointer<LLFontBitmapCache> LLFontFreetype::getFontBitmapCache() const
|
||||||
S32 stride) 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);
|
LLImageRaw *image_raw = mFontBitmapCachep->getImageRaw(bitmap_num);
|
||||||
|
|
||||||
|
|||||||
@@ -1,32 +1,26 @@
|
|||||||
/**
|
/**
|
||||||
* @file llfont.h
|
* @file llfontfreetype.h
|
||||||
* @brief Font library wrapper
|
* @brief Font library wrapper
|
||||||
*
|
*
|
||||||
* $LicenseInfo:firstyear=2002&license=viewergpl$
|
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
||||||
*
|
|
||||||
* Copyright (c) 2002-2009, Linden Research, Inc.
|
|
||||||
*
|
|
||||||
* Second Life Viewer Source Code
|
* Second Life Viewer Source Code
|
||||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
* Copyright (C) 2010, Linden Research, Inc.
|
||||||
* 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
|
|
||||||
*
|
*
|
||||||
* There are special exceptions to the terms and conditions of the GPL as
|
* This library is free software; you can redistribute it and/or
|
||||||
* it is applied to this Source Code. View the full text of the exception
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
* License as published by the Free Software Foundation;
|
||||||
* online at
|
* version 2.1 of the License only.
|
||||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
|
||||||
*
|
*
|
||||||
* By copying, modifying or distributing this software, you acknowledge
|
* This library is distributed in the hope that it will be useful,
|
||||||
* that you have read and understood your obligations described above,
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* and agree to abide by those obligations.
|
* 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
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
* License along with this library; if not, write to the Free Software
|
||||||
* COMPLETENESS OR PERFORMANCE.
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||||
* $/LicenseInfo$
|
* $/LicenseInfo$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -34,7 +28,7 @@
|
|||||||
#define LL_LLFONTFREETYPE_H
|
#define LL_LLFONTFREETYPE_H
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include "llmemory.h"
|
#include "llpointer.h"
|
||||||
#include "llstl.h"
|
#include "llstl.h"
|
||||||
|
|
||||||
#include "llimagegl.h"
|
#include "llimagegl.h"
|
||||||
@@ -51,25 +45,23 @@ class LLFontFreetype;
|
|||||||
struct FT_FaceRec_;
|
struct FT_FaceRec_;
|
||||||
typedef struct FT_FaceRec_* LLFT_Face;
|
typedef struct FT_FaceRec_* LLFT_Face;
|
||||||
|
|
||||||
extern LLFontManager *gFontManagerp;
|
|
||||||
|
|
||||||
class LLFontManager
|
class LLFontManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void initClass();
|
static void initClass();
|
||||||
static void cleanupClass();
|
static void cleanupClass();
|
||||||
|
|
||||||
public:
|
private:
|
||||||
LLFontManager();
|
LLFontManager();
|
||||||
virtual ~LLFontManager();
|
~LLFontManager();
|
||||||
};
|
};
|
||||||
|
|
||||||
class LLFontGlyphInfo
|
struct LLFontGlyphInfo
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
LLFontGlyphInfo(U32 index);
|
LLFontGlyphInfo(U32 index);
|
||||||
public:
|
|
||||||
U32 mGlyphIndex;
|
U32 mGlyphIndex;
|
||||||
|
|
||||||
// Metrics
|
// Metrics
|
||||||
S32 mWidth; // In pixels
|
S32 mWidth; // In pixels
|
||||||
S32 mHeight; // In pixels
|
S32 mHeight; // In pixels
|
||||||
@@ -86,37 +78,29 @@ public:
|
|||||||
S32 mBitmapNum; // Which bitmap in the bitmap cache contains this glyph
|
S32 mBitmapNum; // Which bitmap in the bitmap cache contains this glyph
|
||||||
};
|
};
|
||||||
|
|
||||||
// Used for lists of fallback fonts
|
extern LLFontManager *gFontManagerp;
|
||||||
class LLFontList : public std::vector<LLFontFreetype*>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
LLFontList();
|
|
||||||
~LLFontList();
|
|
||||||
void addAtEnd(LLFontFreetype *font);
|
|
||||||
};
|
|
||||||
|
|
||||||
class LLFontFreetype
|
class LLFontFreetype : public LLRefCount
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LLFontFreetype();
|
LLFontFreetype();
|
||||||
virtual ~LLFontFreetype();
|
~LLFontFreetype();
|
||||||
|
|
||||||
// is_fallback should be true for fallback fonts that aren't used
|
// is_fallback should be true for fallback fonts that aren't used
|
||||||
// to render directly (Unicode backup, primarily)
|
// to render directly (Unicode backup, primarily)
|
||||||
virtual BOOL loadFace(const std::string& filename,
|
BOOL loadFace(const std::string& filename, const F32 point_size, const F32 vert_dpi, const F32 horz_dpi, const S32 components, BOOL is_fallback);
|
||||||
const F32 point_size,
|
|
||||||
const F32 vert_dpi,
|
typedef std::vector<LLPointer<LLFontFreetype> > font_vector_t;
|
||||||
const F32 horz_dpi,
|
|
||||||
const S32 components,
|
void setFallbackFonts(const font_vector_t &font);
|
||||||
BOOL is_fallback);
|
const font_vector_t &getFallbackFonts() const;
|
||||||
void setFallbackFont(LLFontList *fontp) { mFallbackFontp = fontp; }
|
|
||||||
|
|
||||||
void setCharToGlyphMap(llwchar wch, U32 glyph_index) const;
|
void setCharToGlyphMap(llwchar wch, U32 glyph_index) const;
|
||||||
|
|
||||||
// Global font metrics - in units of pixels
|
// Global font metrics - in units of pixels
|
||||||
virtual F32 getLineHeight() const;
|
F32 getLineHeight() const;
|
||||||
virtual F32 getAscenderHeight() const;
|
F32 getAscenderHeight() const;
|
||||||
virtual F32 getDescenderHeight() const;
|
F32 getDescenderHeight() const;
|
||||||
|
|
||||||
|
|
||||||
// For a lowercase "g":
|
// For a lowercase "g":
|
||||||
@@ -148,48 +132,49 @@ public:
|
|||||||
const LLFontGlyphInfo &getMetrics(const llwchar wc) const;
|
const LLFontGlyphInfo &getMetrics(const llwchar wc) const;
|
||||||
F32 getXAdvance(const llwchar wc) const;
|
F32 getXAdvance(const llwchar wc) const;
|
||||||
F32 getXKerning(const llwchar char_left, const llwchar char_right) const; // Get the kerning between the two characters
|
F32 getXKerning(const llwchar char_left, const llwchar char_right) const; // Get the kerning between the two characters
|
||||||
virtual void reset() = 0;
|
LLFontGlyphInfo* getGlyphInfo(const llwchar wch) const;
|
||||||
|
|
||||||
|
void reset(F32 vert_dpi, F32 horz_dpi);
|
||||||
|
|
||||||
|
void destroyGL();
|
||||||
|
|
||||||
|
const std::string& getName() const;
|
||||||
|
|
||||||
|
const LLPointer<LLFontBitmapCache> getFontBitmapCache() const;
|
||||||
|
|
||||||
static bool sOpenGLcrashOnRestart;
|
static bool sOpenGLcrashOnRestart;
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
virtual BOOL hasGlyph(const llwchar wch) const; // Has a glyph for this character
|
void resetBitmapCache();
|
||||||
virtual BOOL addChar(const llwchar wch) const; // Add a new character to the font if necessary
|
void setSubImageLuminanceAlpha(const U32 x, const U32 y, const U32 bitmap_num, const U32 width, const U32 height, const U8 *data, S32 stride = 0) const;
|
||||||
virtual BOOL addGlyph(const llwchar wch, const U32 glyph_index) const; // Add a new glyph to the existing font
|
public:
|
||||||
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)
|
BOOL hasGlyph(const llwchar wch) const; // Has a glyph for this character
|
||||||
|
BOOL addGlyph(const llwchar wch) const; // Add a new character to the font if necessary
|
||||||
virtual LLFontGlyphInfo* getGlyphInfo(const llwchar wch) const;
|
private:
|
||||||
|
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)
|
||||||
void insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const;
|
|
||||||
void renderGlyph(const U32 glyph_index) const;
|
void renderGlyph(const U32 glyph_index) const;
|
||||||
|
|
||||||
void resetBitmapCache();
|
void insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const;
|
||||||
|
|
||||||
protected:
|
|
||||||
std::string mName;
|
std::string mName;
|
||||||
|
|
||||||
F32 mPointSize;
|
F32 mPointSize;
|
||||||
F32 mAscender;
|
F32 mAscender;
|
||||||
F32 mDescender;
|
F32 mDescender;
|
||||||
F32 mLineHeight;
|
F32 mLineHeight;
|
||||||
|
|
||||||
mutable LLPointer<LLFontBitmapCache> mFontBitmapCachep;
|
|
||||||
|
|
||||||
LLFT_Face mFTFace;
|
LLFT_Face mFTFace;
|
||||||
|
|
||||||
BOOL mIsFallback;
|
BOOL mIsFallback;
|
||||||
LLFontList *mFallbackFontp; // A list of fallback fonts to look for glyphs in (for Unicode chars)
|
font_vector_t mFallbackFonts; // A list of fallback fonts to look for glyphs in (for Unicode chars)
|
||||||
|
|
||||||
|
BOOL mValid;
|
||||||
|
|
||||||
typedef std::map<llwchar, LLFontGlyphInfo*> char_glyph_info_map_t;
|
typedef std::map<llwchar, LLFontGlyphInfo*> char_glyph_info_map_t;
|
||||||
mutable char_glyph_info_map_t mCharGlyphInfoMap; // Information about glyph location in bitmap
|
mutable char_glyph_info_map_t mCharGlyphInfoMap; // Information about glyph location in bitmap
|
||||||
|
|
||||||
BOOL mValid;
|
mutable LLPointer<LLFontBitmapCache> mFontBitmapCachep;
|
||||||
void setSubImageLuminanceAlpha(const U32 x,
|
|
||||||
const U32 y,
|
|
||||||
const U32 bitmap_num,
|
|
||||||
const U32 width,
|
|
||||||
const U32 height,
|
|
||||||
const U8 *data,
|
|
||||||
S32 stride = 0) const;
|
|
||||||
mutable S32 mRenderGlyphCount;
|
mutable S32 mRenderGlyphCount;
|
||||||
mutable S32 mAddGlyphCount;
|
mutable S32 mAddGlyphCount;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -84,7 +84,6 @@ F32 llfont_round_y(F32 y)
|
|||||||
}
|
}
|
||||||
|
|
||||||
LLFontGL::LLFontGL()
|
LLFontGL::LLFontGL()
|
||||||
: LLFontFreetype()
|
|
||||||
{
|
{
|
||||||
clearEmbeddedChars();
|
clearEmbeddedChars();
|
||||||
}
|
}
|
||||||
@@ -96,66 +95,22 @@ LLFontGL::~LLFontGL()
|
|||||||
|
|
||||||
void LLFontGL::reset()
|
void LLFontGL::reset()
|
||||||
{
|
{
|
||||||
if (!mIsFallback)
|
mFontFreetype->reset(sVertDPI, sHorizDPI);
|
||||||
{
|
|
||||||
// This is the head of the list - need to rebuild ourself and all fallbacks.
|
|
||||||
loadFace(mName,mPointSize,sVertDPI,sHorizDPI,mFontBitmapCachep->getNumComponents(),mIsFallback);
|
|
||||||
if (mFallbackFontp==NULL)
|
|
||||||
{
|
|
||||||
llwarns << "LLFontGL::reset(), no fallback fonts present" << llendl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (LLFontList::iterator it = mFallbackFontp->begin();
|
|
||||||
it != mFallbackFontp->end();
|
|
||||||
++it)
|
|
||||||
{
|
|
||||||
(*it)->reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
resetBitmapCache();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool findOrCreateFont(LLFontGL*& fontp, const LLFontDescriptor& desc)
|
|
||||||
{
|
|
||||||
// Don't delete existing fonts, if any, here, because they've
|
|
||||||
// already been deleted by LLFontRegistry::clear()
|
|
||||||
fontp = LLFontGL::getFont(desc);
|
|
||||||
return (fontp != NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LLFontGL::destroyGL()
|
void LLFontGL::destroyGL()
|
||||||
{
|
{
|
||||||
mFontBitmapCachep->destroyGL();
|
mFontFreetype->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)
|
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 (!LLFontFreetype::loadFace(filename, point_size, vert_dpi, horz_dpi, components, is_fallback))
|
if(mFontFreetype == reinterpret_cast<LLFontFreetype*>(NULL))
|
||||||
{
|
{
|
||||||
return FALSE;
|
mFontFreetype = new LLFontFreetype;
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BOOL LLFontGL::addChar(const llwchar wch) const
|
|
||||||
{
|
|
||||||
if (!LLFontFreetype::addChar(wch))
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stop_glerror();
|
return mFontFreetype->loadFace(filename, point_size, vert_dpi, horz_dpi, components, is_fallback);
|
||||||
|
|
||||||
LLFontGlyphInfo *glyph_info = getGlyphInfo(wch);
|
|
||||||
U32 bitmap_num = glyph_info->mBitmapNum;
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static LLFastTimer::DeclareTimer FTM_RENDER_FONTS("Fonts");
|
static LLFastTimer::DeclareTimer FTM_RENDER_FONTS("Fonts");
|
||||||
@@ -255,13 +210,13 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
|||||||
switch (valign)
|
switch (valign)
|
||||||
{
|
{
|
||||||
case TOP:
|
case TOP:
|
||||||
cur_y -= llceil(mAscender);
|
cur_y -= llceil(mFontFreetype->getAscenderHeight());
|
||||||
break;
|
break;
|
||||||
case BOTTOM:
|
case BOTTOM:
|
||||||
cur_y += llceil(mDescender);
|
cur_y += llceil(mFontFreetype->getDescenderHeight());
|
||||||
break;
|
break;
|
||||||
case VCENTER:
|
case VCENTER:
|
||||||
cur_y -= llceil((llceil(mAscender) - llceil(mDescender))/2.f);
|
cur_y -= llceil((llceil(mFontFreetype->getAscenderHeight()) - llceil(mFontFreetype->getDescenderHeight())) / 2.f);
|
||||||
break;
|
break;
|
||||||
case BASELINE:
|
case BASELINE:
|
||||||
// Baseline, do nothing.
|
// Baseline, do nothing.
|
||||||
@@ -289,7 +244,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
|||||||
|
|
||||||
F32 start_x = (F32)llround(cur_x);
|
F32 start_x = (F32)llround(cur_x);
|
||||||
|
|
||||||
const LLFontBitmapCache* font_bitmap_cache = mFontBitmapCachep;
|
const LLFontBitmapCache* font_bitmap_cache = mFontFreetype->getFontBitmapCache();
|
||||||
|
|
||||||
F32 inv_width = 1.f / font_bitmap_cache->getBitmapWidth();
|
F32 inv_width = 1.f / font_bitmap_cache->getBitmapWidth();
|
||||||
F32 inv_height = 1.f / font_bitmap_cache->getBitmapHeight();
|
F32 inv_height = 1.f / font_bitmap_cache->getBitmapHeight();
|
||||||
@@ -351,7 +306,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
|||||||
|
|
||||||
// snap origin to whole screen pixel
|
// snap origin to whole screen pixel
|
||||||
const F32 ext_x = (F32)llround(cur_render_x + (EXT_X_BEARING * sScaleX));
|
const F32 ext_x = (F32)llround(cur_render_x + (EXT_X_BEARING * sScaleX));
|
||||||
const F32 ext_y = (F32)llround(cur_render_y + (EXT_Y_BEARING * sScaleY + mAscender - mLineHeight));
|
const F32 ext_y = (F32)llround(cur_render_y + (EXT_Y_BEARING * sScaleY + mFontFreetype->getAscenderHeight() - mFontFreetype->getLineHeight()));
|
||||||
|
|
||||||
LLRectf uv_rect(0.f, 1.f, 1.f, 0.f);
|
LLRectf uv_rect(0.f, 1.f, 1.f, 0.f);
|
||||||
LLRectf screen_rect(ext_x, ext_y + ext_height, ext_x + ext_width, ext_y);
|
LLRectf screen_rect(ext_x, ext_y + ext_height, ext_x + ext_width, ext_y);
|
||||||
@@ -381,19 +336,20 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!hasGlyph(wch))
|
//new
|
||||||
|
/*if (!mFontFreetype->hasGlyph(wch))
|
||||||
{
|
{
|
||||||
addChar(wch);
|
addChar(wch);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
const LLFontGlyphInfo* fgi= getGlyphInfo(wch);
|
const LLFontGlyphInfo* fgi= mFontFreetype->getGlyphInfo(wch);
|
||||||
if (!fgi)
|
if (!fgi)
|
||||||
{
|
{
|
||||||
llerrs << "Missing Glyph Info" << llendl;
|
llerrs << "Missing Glyph Info" << llendl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Per-glyph bitmap texture.
|
// Per-glyph bitmap texture.
|
||||||
LLImageGL *image_gl = mFontBitmapCachep->getImageGL(fgi->mBitmapNum);
|
LLImageGL *image_gl = font_bitmap_cache->getImageGL(fgi->mBitmapNum);
|
||||||
if (last_bound_texture != image_gl)
|
if (last_bound_texture != image_gl)
|
||||||
{
|
{
|
||||||
gGL.getTexUnit(0)->bind(image_gl);
|
gGL.getTexUnit(0)->bind(image_gl);
|
||||||
@@ -428,11 +384,13 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
|||||||
if (next_char && (next_char < LAST_CHARACTER))
|
if (next_char && (next_char < LAST_CHARACTER))
|
||||||
{
|
{
|
||||||
// Kern this puppy.
|
// Kern this puppy.
|
||||||
if (!hasGlyph(next_char))
|
//new
|
||||||
|
/*if (!mFontFreetype->hasGlyph(next_char))
|
||||||
{
|
{
|
||||||
addChar(next_char);
|
addChar(next_char);
|
||||||
}
|
}*/
|
||||||
cur_x += getXKerning(wch, next_char);
|
mFontFreetype->getGlyphInfo(next_char);
|
||||||
|
cur_x += mFontFreetype->getXKerning(wch, next_char);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Round after kerning.
|
// Round after kerning.
|
||||||
@@ -454,7 +412,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
|||||||
|
|
||||||
if (style & UNDERLINE)
|
if (style & UNDERLINE)
|
||||||
{
|
{
|
||||||
F32 descender = (F32)llfloor(mDescender);
|
F32 descender = (F32)llfloor(mFontFreetype->getDescenderHeight());
|
||||||
|
|
||||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||||
gGL.begin(LLRender::LINES);
|
gGL.begin(LLRender::LINES);
|
||||||
@@ -507,6 +465,22 @@ S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y
|
|||||||
return renderUTF8(text, begin_offset, (F32)x, (F32)y, color, halign, valign, style, shadow, S32_MAX, S32_MAX, NULL, FALSE);
|
return renderUTF8(text, begin_offset, (F32)x, (F32)y, color, halign, valign, style, shadow, S32_MAX, S32_MAX, NULL, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// font metrics - override for LLFontFreetype that returns units of virtual pixels
|
||||||
|
F32 LLFontGL::getAscenderHeight() const
|
||||||
|
{
|
||||||
|
return mFontFreetype->getAscenderHeight() / sScaleY;
|
||||||
|
}
|
||||||
|
|
||||||
|
F32 LLFontGL::getDescenderHeight() const
|
||||||
|
{
|
||||||
|
return mFontFreetype->getDescenderHeight() / sScaleY;
|
||||||
|
}
|
||||||
|
|
||||||
|
F32 LLFontGL::getLineHeight() const
|
||||||
|
{
|
||||||
|
return (F32)llround(mFontFreetype->getLineHeight() / sScaleY);
|
||||||
|
}
|
||||||
|
|
||||||
S32 LLFontGL::getWidth(const std::string& utf8text) const
|
S32 LLFontGL::getWidth(const std::string& utf8text) const
|
||||||
{
|
{
|
||||||
LLWString wtext = utf8str_to_wstring(utf8text);
|
LLWString wtext = utf8str_to_wstring(utf8text);
|
||||||
@@ -573,7 +547,7 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, const S32 begin_offset, const S
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cur_x += getXAdvance(wch);
|
cur_x += mFontFreetype->getXAdvance(wch);
|
||||||
llwchar next_char = wchars[i+1];
|
llwchar next_char = wchars[i+1];
|
||||||
|
|
||||||
if (((i + 1) < begin_offset + max_chars)
|
if (((i + 1) < begin_offset + max_chars)
|
||||||
@@ -581,7 +555,7 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, const S32 begin_offset, const S
|
|||||||
&& (next_char < LAST_CHARACTER))
|
&& (next_char < LAST_CHARACTER))
|
||||||
{
|
{
|
||||||
// Kern this puppy.
|
// Kern this puppy.
|
||||||
cur_x += getXKerning(wch, next_char);
|
cur_x += mFontFreetype->getXKerning(wch, next_char);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Round after kerning.
|
// Round after kerning.
|
||||||
@@ -677,7 +651,7 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_x += getXAdvance(wch);
|
cur_x += mFontFreetype->getXAdvance(wch);
|
||||||
|
|
||||||
if (scaled_max_pixels < cur_x)
|
if (scaled_max_pixels < cur_x)
|
||||||
{
|
{
|
||||||
@@ -688,7 +662,7 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
|
|||||||
if (((i+1) < max_chars) && wchars[i+1])
|
if (((i+1) < max_chars) && wchars[i+1])
|
||||||
{
|
{
|
||||||
// Kern this puppy.
|
// Kern this puppy.
|
||||||
cur_x += getXKerning(wch, wchars[i+1]);
|
cur_x += mFontFreetype->getXKerning(wch, wchars[i+1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Round after kerning.
|
// Round after kerning.
|
||||||
@@ -743,7 +717,27 @@ S32 LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_
|
|||||||
llwchar wch = wchars[i];
|
llwchar wch = wchars[i];
|
||||||
|
|
||||||
const embedded_data_t* ext_data = getEmbeddedCharData(wch);
|
const embedded_data_t* ext_data = getEmbeddedCharData(wch);
|
||||||
F32 char_width = ext_data ? getEmbeddedCharAdvance(ext_data) : getXAdvance(wch);
|
F32 char_width = 0;
|
||||||
|
|
||||||
|
if(ext_data)
|
||||||
|
{
|
||||||
|
char_width = getEmbeddedCharAdvance(ext_data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//new
|
||||||
|
const LLFontGlyphInfo* fgi= mFontFreetype->getGlyphInfo(wch);
|
||||||
|
|
||||||
|
// last character uses character width, since the whole character needs to be visible
|
||||||
|
// other characters just use advance
|
||||||
|
char_width = (i == start)
|
||||||
|
? (F32)(fgi->mWidth + fgi->mXBearing) // use actual width for last character
|
||||||
|
: fgi->mXAdvance; // use advance for all other characters
|
||||||
|
|
||||||
|
//old
|
||||||
|
//const LLFontGlyphInfo* fgi= mFontFreetype->getGlyphInfo(wch);
|
||||||
|
//mFontFreetype->getXAdvance(wch);
|
||||||
|
}
|
||||||
|
|
||||||
if( scaled_max_pixels < (total_width + char_width) )
|
if( scaled_max_pixels < (total_width + char_width) )
|
||||||
{
|
{
|
||||||
@@ -761,7 +755,7 @@ S32 LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_
|
|||||||
if ( i > 0 )
|
if ( i > 0 )
|
||||||
{
|
{
|
||||||
// kerning
|
// kerning
|
||||||
total_width += ext_data ? (EXT_KERNING * sScaleX) : getXKerning(wchars[i-1], wch);
|
total_width += ext_data ? (EXT_KERNING * sScaleX) : mFontFreetype->getXKerning(wchars[i-1], wch);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Round after kerning.
|
// Round after kerning.
|
||||||
@@ -780,7 +774,6 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, const S32 begin_offset,
|
|||||||
}
|
}
|
||||||
|
|
||||||
F32 cur_x = 0;
|
F32 cur_x = 0;
|
||||||
S32 pos = 0;
|
|
||||||
|
|
||||||
target_x *= sScaleX;
|
target_x *= sScaleX;
|
||||||
|
|
||||||
@@ -789,9 +782,10 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, const S32 begin_offset,
|
|||||||
|
|
||||||
F32 scaled_max_pixels = max_pixels * sScaleX;
|
F32 scaled_max_pixels = max_pixels * sScaleX;
|
||||||
|
|
||||||
for (S32 i = begin_offset; (i < max_index); i++)
|
S32 pos;
|
||||||
|
for (pos = begin_offset; pos < max_index; pos++)
|
||||||
{
|
{
|
||||||
llwchar wch = wchars[i];
|
llwchar wch = wchars[pos];
|
||||||
if (!wch)
|
if (!wch)
|
||||||
{
|
{
|
||||||
break; // done
|
break; // done
|
||||||
@@ -826,8 +820,8 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, const S32 begin_offset,
|
|||||||
pos++;
|
pos++;
|
||||||
cur_x += ext_advance;
|
cur_x += ext_advance;
|
||||||
|
|
||||||
if (((i + 1) < max_index)
|
if (((pos + 1) < max_index)
|
||||||
&& (wchars[(i + 1)]))
|
&& (wchars[(pos + 1)]))
|
||||||
{
|
{
|
||||||
cur_x += EXT_KERNING * sScaleX;
|
cur_x += EXT_KERNING * sScaleX;
|
||||||
}
|
}
|
||||||
@@ -836,7 +830,7 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, const S32 begin_offset,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
F32 char_width = getXAdvance(wch);
|
F32 char_width = mFontFreetype->getXAdvance(wch);
|
||||||
|
|
||||||
if (round)
|
if (round)
|
||||||
{
|
{
|
||||||
@@ -860,12 +854,11 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, const S32 begin_offset,
|
|||||||
pos++;
|
pos++;
|
||||||
cur_x += char_width;
|
cur_x += char_width;
|
||||||
|
|
||||||
if (((i + 1) < max_index)
|
if (((pos + 1) < max_index)
|
||||||
&& (wchars[(i + 1)]))
|
&& (wchars[(pos + 1)]))
|
||||||
{
|
{
|
||||||
llwchar next_char = wchars[i + 1];
|
|
||||||
// Kern this puppy.
|
// Kern this puppy.
|
||||||
cur_x += getXKerning(wch, next_char);
|
cur_x += mFontFreetype->getXKerning(wch, wchars[pos + 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Round after kerning.
|
// Round after kerning.
|
||||||
@@ -876,6 +869,10 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, const S32 begin_offset,
|
|||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const LLFontDescriptor& LLFontGL::getFontDesc() const
|
||||||
|
{
|
||||||
|
return mFontDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
const LLFontGL::embedded_data_t* LLFontGL::getEmbeddedCharData(const llwchar wch) const
|
const LLFontGL::embedded_data_t* LLFontGL::getEmbeddedCharData(const llwchar wch) const
|
||||||
{
|
{
|
||||||
@@ -1041,9 +1038,11 @@ std::string LLFontGL::getStringFromStyle(U8 style)
|
|||||||
}
|
}
|
||||||
return style_string;
|
return style_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
std::string LLFontGL::nameFromFont(const LLFontGL* fontp)
|
std::string LLFontGL::nameFromFont(const LLFontGL* fontp)
|
||||||
{
|
{
|
||||||
return fontp->getFontDesc().getName();
|
return fontp->mFontDescriptor.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
@@ -1249,7 +1248,7 @@ void LLFontGL::renderQuad(const LLRectf& screen_rect, const LLRectf& uv_rect, F3
|
|||||||
void LLFontGL::drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4& color, U8 style, ShadowType shadow, F32 drop_shadow_strength) const
|
void LLFontGL::drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4& color, U8 style, ShadowType shadow, F32 drop_shadow_strength) const
|
||||||
{
|
{
|
||||||
F32 slant_offset;
|
F32 slant_offset;
|
||||||
slant_offset = ((style & ITALIC) ? ( -mAscender * 0.2f) : 0.f);
|
slant_offset = ((style & ITALIC) ? ( -mFontFreetype->getAscenderHeight() * 0.2f) : 0.f);
|
||||||
|
|
||||||
gGL.begin(LLRender::QUADS);
|
gGL.begin(LLRender::QUADS);
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -28,23 +28,24 @@
|
|||||||
#ifndef LL_LLFONTGL_H
|
#ifndef LL_LLFONTGL_H
|
||||||
#define LL_LLFONTGL_H
|
#define LL_LLFONTGL_H
|
||||||
|
|
||||||
#include "llfontfreetype.h"
|
|
||||||
#include "lltexture.h"
|
|
||||||
#include "v2math.h"
|
|
||||||
#include "llcoord.h"
|
#include "llcoord.h"
|
||||||
#include "llrect.h"
|
|
||||||
|
|
||||||
#include "llfontregistry.h"
|
#include "llfontregistry.h"
|
||||||
|
#include "lltexture.h"
|
||||||
|
#include "llpointer.h"
|
||||||
|
#include "llrect.h"
|
||||||
|
#include "v2math.h"
|
||||||
|
|
||||||
|
class LLImageGL;
|
||||||
|
|
||||||
class LLColor4;
|
class LLColor4;
|
||||||
|
|
||||||
// Key used to request a font.
|
// Key used to request a font.
|
||||||
class LLFontDescriptor;
|
class LLFontDescriptor;
|
||||||
|
class LLFontFreetype;
|
||||||
|
|
||||||
// Structure used to store previously requested fonts.
|
// Structure used to store previously requested fonts.
|
||||||
class LLFontRegistry;
|
class LLFontRegistry;
|
||||||
|
|
||||||
class LLFontGL : public LLFontFreetype
|
class LLFontGL
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum HAlign
|
enum HAlign
|
||||||
@@ -88,7 +89,7 @@ public:
|
|||||||
|
|
||||||
void destroyGL();
|
void destroyGL();
|
||||||
|
|
||||||
/* virtual*/ BOOL loadFace(const std::string& filename, const F32 point_size, const F32 vert_dpi, const F32 horz_dpi, const S32 components, BOOL is_fallback);
|
BOOL loadFace(const std::string& filename, const F32 point_size, const F32 vert_dpi, const F32 horz_dpi, const S32 components, BOOL is_fallback);
|
||||||
|
|
||||||
S32 render(const LLWString &text, S32 begin_offset,
|
S32 render(const LLWString &text, S32 begin_offset,
|
||||||
const LLRect& rect,
|
const LLRect& rect,
|
||||||
@@ -118,9 +119,9 @@ public:
|
|||||||
S32 renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style = NORMAL, ShadowType shadow = NO_SHADOW) const;
|
S32 renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style = NORMAL, ShadowType shadow = NO_SHADOW) const;
|
||||||
|
|
||||||
// font metrics - override for LLFont that returns units of virtual pixels
|
// font metrics - override for LLFont that returns units of virtual pixels
|
||||||
/*virtual*/ F32 getLineHeight() const { return (F32)llround(mLineHeight / sScaleY); }
|
F32 getAscenderHeight() const;
|
||||||
/*virtual*/ F32 getAscenderHeight() const { return (F32)llround(mAscender / sScaleY); }
|
F32 getDescenderHeight() const;
|
||||||
/*virtual*/ F32 getDescenderHeight() const { return (F32)llround(mDescender / sScaleY); }
|
F32 getLineHeight() const;
|
||||||
|
|
||||||
S32 getWidth(const std::string& utf8text) const;
|
S32 getWidth(const std::string& utf8text) const;
|
||||||
S32 getWidth(const llwchar* wchars) const;
|
S32 getWidth(const llwchar* wchars) const;
|
||||||
@@ -151,8 +152,7 @@ public:
|
|||||||
// Returns the index of the character closest to pixel position x (ignoring text to the right of max_pixels and max_chars)
|
// Returns the index of the character closest to pixel position x (ignoring text to the right of max_pixels and max_chars)
|
||||||
S32 charFromPixelOffset(const llwchar* wchars, const S32 char_offset, F32 x, F32 max_pixels=F32_MAX, S32 max_chars = S32_MAX, BOOL round = TRUE, BOOL use_embedded = FALSE) const;
|
S32 charFromPixelOffset(const llwchar* wchars, const S32 char_offset, F32 x, F32 max_pixels=F32_MAX, S32 max_chars = S32_MAX, BOOL round = TRUE, BOOL use_embedded = FALSE) const;
|
||||||
|
|
||||||
const LLFontDescriptor &getFontDesc() const { return mFontDesc; }
|
const LLFontDescriptor& getFontDesc() const;
|
||||||
void setFontDesc(const LLFontDescriptor& font_desc) { mFontDesc = font_desc; }
|
|
||||||
|
|
||||||
LLTexture *getTexture() const;
|
LLTexture *getTexture() const;
|
||||||
|
|
||||||
@@ -217,19 +217,20 @@ public:
|
|||||||
static F32 sScaleY;
|
static F32 sScaleY;
|
||||||
static BOOL sDisplayFont ;
|
static BOOL sDisplayFont ;
|
||||||
static std::string sAppDir; // For loading fonts
|
static std::string sAppDir; // For loading fonts
|
||||||
|
private:
|
||||||
|
friend class LLFontRegistry;
|
||||||
friend class LLTextBillboard;
|
friend class LLTextBillboard;
|
||||||
friend class LLHUDText;
|
friend class LLHUDText;
|
||||||
|
|
||||||
LLFontGL(const LLFontGL &source);
|
LLFontGL(const LLFontGL &source);
|
||||||
LLFontGL &operator=(const LLFontGL &source);
|
LLFontGL &operator=(const LLFontGL &source);
|
||||||
protected:
|
|
||||||
/*virtual*/ BOOL addChar(const llwchar wch) const;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typedef std::map<llwchar,embedded_data_t*> embedded_map_t;
|
typedef std::map<llwchar,embedded_data_t*> embedded_map_t;
|
||||||
mutable embedded_map_t mEmbeddedChars;
|
mutable embedded_map_t mEmbeddedChars;
|
||||||
|
|
||||||
LLFontDescriptor mFontDesc;
|
LLFontDescriptor mFontDescriptor;
|
||||||
|
LLPointer<LLFontFreetype> mFontFreetype;
|
||||||
|
|
||||||
void renderQuad(const LLRectf& screen_rect, const LLRectf& uv_rect, F32 slant_amt) const;
|
void renderQuad(const LLRectf& screen_rect, const LLRectf& uv_rect, F32 slant_amt) const;
|
||||||
void drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4& color, U8 style, ShadowType shadow, F32 drop_shadow_fade) const;
|
void drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4& color, U8 style, ShadowType shadow, F32 drop_shadow_fade) const;
|
||||||
|
|||||||
@@ -421,7 +421,8 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
|
|||||||
llwarns << "createFont failed, no file names specified" << llendl;
|
llwarns << "createFont failed, no file names specified" << llendl;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
LLFontList *fontlistp = new LLFontList;
|
|
||||||
|
LLFontFreetype::font_vector_t fontlist;
|
||||||
LLFontGL *result = NULL;
|
LLFontGL *result = NULL;
|
||||||
|
|
||||||
// Snarf all fonts we can into fontlistp. First will get pulled
|
// Snarf all fonts we can into fontlistp. First will get pulled
|
||||||
@@ -466,19 +467,24 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
|
|||||||
is_first_found = false;
|
is_first_found = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
fontlistp->addAtEnd(fontp);
|
{
|
||||||
|
fontlist.push_back(fontp->mFontFreetype);
|
||||||
|
delete fontp;
|
||||||
|
fontp = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (result && !fontlistp->empty())
|
|
||||||
|
if (result && !fontlist.empty())
|
||||||
{
|
{
|
||||||
result->setFallbackFont(fontlistp);
|
result->mFontFreetype->setFallbackFonts(fontlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
norm_desc.setStyle(match_desc->getStyle());
|
|
||||||
if (result)
|
if (result)
|
||||||
result->setFontDesc(norm_desc);
|
{
|
||||||
|
result->mFontDescriptor = desc;
|
||||||
if (!result)
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
llwarns << "createFont failed in some way" << llendl;
|
llwarns << "createFont failed in some way" << llendl;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
#include "linden_common.h"
|
#include "linden_common.h"
|
||||||
|
|
||||||
#include "llresmgr.h"
|
#include "llresmgr.h"
|
||||||
|
#include "llimagegl.h"
|
||||||
#include "llfontgl.h"
|
#include "llfontgl.h"
|
||||||
#include "llerror.h"
|
#include "llerror.h"
|
||||||
#include "llstring.h"
|
#include "llstring.h"
|
||||||
|
|||||||
@@ -33,6 +33,8 @@
|
|||||||
#include "linden_common.h"
|
#include "linden_common.h"
|
||||||
|
|
||||||
#include "llstyle.h"
|
#include "llstyle.h"
|
||||||
|
|
||||||
|
#include "llfontgl.h"
|
||||||
#include "llstring.h"
|
#include "llstring.h"
|
||||||
#include "llui.h"
|
#include "llui.h"
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,8 @@
|
|||||||
|
|
||||||
#include "llappviewerwin32.h"
|
#include "llappviewerwin32.h"
|
||||||
|
|
||||||
#include "llwindowwin32.cpp" // *FIX: for setting gIconResource.
|
#include "llwindowwin32.h" // *FIX: for setting gIconResource.
|
||||||
|
#include "llgl.h"
|
||||||
#include "res/resource.h" // *FIX: for setting gIconResource.
|
#include "res/resource.h" // *FIX: for setting gIconResource.
|
||||||
|
|
||||||
#include <fcntl.h> //_O_APPEND
|
#include <fcntl.h> //_O_APPEND
|
||||||
|
|||||||
@@ -60,6 +60,7 @@
|
|||||||
#include "llaudioengine.h" // mute on minimize
|
#include "llaudioengine.h" // mute on minimize
|
||||||
#include "llassetstorage.h"
|
#include "llassetstorage.h"
|
||||||
#include "llfontgl.h"
|
#include "llfontgl.h"
|
||||||
|
#include "llfontfreetype.h"
|
||||||
#include "llmousehandler.h"
|
#include "llmousehandler.h"
|
||||||
#include "llrect.h"
|
#include "llrect.h"
|
||||||
#include "llsky.h"
|
#include "llsky.h"
|
||||||
|
|||||||
Reference in New Issue
Block a user