From 52aeaa32841e7d0b37abab0a2a2540c2be2f16b7 Mon Sep 17 00:00:00 2001 From: James Cook Date: Tue, 7 Jul 2009 00:53:05 +0000 Subject: Merge skinning-14 to viewer-2, including refactoring many floaters to register them with LLFloaterReg, support for introspection of ParamBlock based UI widgets to dump XML schema, splitting llfolderview.cpp into three separate files to unravel dependencies and skeleton for for LLListView widget. Resolved conflicts in these files: lldraghandle.h, lluictrl.h, llchiclet.cpp, llfolderview.h/cpp, lliinventorybridge.cpp, llpanelpicks.cpp, llviewermenu.cpp, floater_mute.xml, floater_preferences.xml, notifications.xml, panel_preferences_audio.xml, panel_preferences_graphics1.xml, panel_region_general.xml svn merge -r124961:126284 svn+ssh://svn.lindenlab.com/svn/linden/branches/skinning/skinning-14 --- indra/llrender/llfontgl.h | 6 +++--- indra/llrender/llfontregistry.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'indra/llrender') diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h index 204c6908af..77cd12250c 100644 --- a/indra/llrender/llfontgl.h +++ b/indra/llrender/llfontgl.h @@ -264,7 +264,7 @@ protected: typedef std::map embedded_map_t; mutable embedded_map_t mEmbeddedChars; - LLFontDescriptor mFontDesc; + LLFontDescriptor mFontDescriptor; // Registry holds all instantiated fonts. static LLFontRegistry* sFontRegistry; @@ -276,8 +276,8 @@ public: static LLCoordFont sCurOrigin; static std::vector sOriginStack; - const LLFontDescriptor &getFontDesc() const { return mFontDesc; } - void setFontDesc(const LLFontDescriptor& font_desc) { mFontDesc = font_desc; } + const LLFontDescriptor &getFontDesc() const { return mFontDescriptor; } + void setFontDesc(const LLFontDescriptor& font_desc) { mFontDescriptor = font_desc; } }; #endif diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp index 18e4a6915d..3b5c62a5ea 100644 --- a/indra/llrender/llfontregistry.cpp +++ b/indra/llrender/llfontregistry.cpp @@ -104,7 +104,7 @@ bool removeSubString(std::string& str, const std::string& substr) size_t pos = str.find(substr); if (pos != string::npos) { - str.replace(pos,substr.length(),(const char *)NULL, 0); + str.erase(pos); return true; } return false; -- cgit v1.2.3 From 77f56a3f3db72b2938eadb0868fc7be975dabafa Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Fri, 10 Jul 2009 22:02:26 +0000 Subject: merge QAR-1579: texture-cleanup-1. --- indra/llrender/CMakeLists.txt | 2 + indra/llrender/llfontgl.cpp | 7 +-- indra/llrender/llfontgl.h | 4 +- indra/llrender/llimagegl.cpp | 123 ++++-------------------------------------- indra/llrender/llimagegl.h | 47 +++------------- indra/llrender/llrender.cpp | 79 ++++++++++++++++++++++----- indra/llrender/llrender.h | 2 + indra/llrender/lltexture.cpp | 37 +++++++++++++ indra/llrender/lltexture.h | 77 ++++++++++++++++++++++++++ 9 files changed, 206 insertions(+), 172 deletions(-) create mode 100644 indra/llrender/lltexture.cpp create mode 100644 indra/llrender/lltexture.h (limited to 'indra/llrender') diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt index 0bb835970f..0e0fc6ce6c 100644 --- a/indra/llrender/CMakeLists.txt +++ b/indra/llrender/CMakeLists.txt @@ -36,6 +36,7 @@ set(llrender_SOURCE_FILES llpostprocess.cpp llrendersphere.cpp llshadermgr.cpp + lltexture.cpp llvertexbuffer.cpp ) @@ -58,6 +59,7 @@ set(llrender_HEADER_FILES llrender.h llrendersphere.h llshadermgr.h + lltexture.h llvertexbuffer.h ) diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 048bfe8e0d..0b57d86c78 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -43,6 +43,7 @@ #include "llrender.h" #include "llstl.h" #include "v4color.h" +#include "lltexture.h" // Third party library includes #include @@ -1114,15 +1115,15 @@ void LLFontGL::clearEmbeddedChars() mEmbeddedChars.clear(); } -void LLFontGL::addEmbeddedChar( llwchar wc, LLImageGL* image, const std::string& label ) const +void LLFontGL::addEmbeddedChar( llwchar wc, LLTexture* image, const std::string& label ) const { LLWString wlabel = utf8str_to_wstring(label); addEmbeddedChar(wc, image, wlabel); } -void LLFontGL::addEmbeddedChar( llwchar wc, LLImageGL* image, const LLWString& wlabel ) const +void LLFontGL::addEmbeddedChar( llwchar wc, LLTexture* image, const LLWString& wlabel ) const { - embedded_data_t* ext_data = new embedded_data_t(image, wlabel); + embedded_data_t* ext_data = new embedded_data_t(image->getGLTexture(), wlabel); mEmbeddedChars[wc] = ext_data; } diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h index 77cd12250c..2298db0ef3 100644 --- a/indra/llrender/llfontgl.h +++ b/indra/llrender/llfontgl.h @@ -206,8 +206,8 @@ public: LLImageGL *getImageGL() const; - void addEmbeddedChar( llwchar wc, LLImageGL* image, const std::string& label) const; - void addEmbeddedChar( llwchar wc, LLImageGL* image, const LLWString& label) const; + void addEmbeddedChar( llwchar wc, LLTexture* image, const std::string& label) const; + void addEmbeddedChar( llwchar wc, LLTexture* image, const LLWString& label) const; void removeEmbeddedChar( llwchar wc ) const; static std::string nameFromFont(const LLFontGL* fontp); diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index e1231eeeb4..c4d91209e6 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -46,7 +46,6 @@ //---------------------------------------------------------------------------- - const F32 MIN_TEXTURE_LIFETIME = 10.f; //statics @@ -61,7 +60,7 @@ S32 LLImageGL::sCount = 0; BOOL LLImageGL::sGlobalUseAnisotropic = FALSE; F32 LLImageGL::sLastFrameTime = 0.f; - +LLImageGL* LLImageGL::sDefaultGLTexture = NULL ; std::set LLImageGL::sImageList; //************************************************************************************** @@ -263,28 +262,6 @@ void LLImageGL::restoreGL() } //---------------------------------------------------------------------------- - -//static -BOOL LLImageGL::create(LLPointer& dest, BOOL usemipmaps) -{ - dest = new LLImageGL(usemipmaps); - return TRUE; -} - -BOOL LLImageGL::create(LLPointer& dest, U32 width, U32 height, U8 components, BOOL usemipmaps) -{ - dest = new LLImageGL(width, height, components, usemipmaps); - return TRUE; -} - -BOOL LLImageGL::create(LLPointer& dest, const LLImageRaw* imageraw, BOOL usemipmaps) -{ - dest = new LLImageGL(imageraw, usemipmaps); - return TRUE; -} - -//---------------------------------------------------------------------------- - LLImageGL::LLImageGL(BOOL usemipmaps) : mSaveData(0) { @@ -331,7 +308,6 @@ void LLImageGL::init(BOOL usemipmaps) #endif mPickMask = NULL; - mTextureState = NO_DELETE ; mTextureMemory = 0; mLastBindTime = 0.f; @@ -351,8 +327,7 @@ void LLImageGL::init(BOOL usemipmaps) mComponents = 0; mMaxDiscardLevel = MAX_DISCARD_LEVEL; - mCurrentDiscardLevel = -1; - mDontDiscard = FALSE; + mCurrentDiscardLevel = -1; mFormatInternal = -1; mFormatPrimary = (LLGLenum) 0; @@ -462,7 +437,7 @@ void LLImageGL::dump() //---------------------------------------------------------------------------- -void LLImageGL::updateBindStats(void) const +BOOL LLImageGL::updateBindStats(S32 tex_mem) const { if (mTexName != 0) { @@ -474,38 +449,18 @@ void LLImageGL::updateBindStats(void) const { // we haven't accounted for this texture yet this frame sUniqueCount++; - updateBoundTexMem(mTextureMemory); + updateBoundTexMem(tex_mem); mLastBindTime = sLastFrameTime; - if(LLFastTimer::sMetricLog) - { - updateTestStats() ; - } + return TRUE ; } } + return FALSE ; } -//virtual -void LLImageGL::updateTestStats(void) const -{ -} - -//virtual -bool LLImageGL::bindError(const S32 stage) const -{ - return false; -} - -//virtual -bool LLImageGL::bindDefaultImage(const S32 stage) const -{ - return false; -} - -//virtual -void LLImageGL::forceImmediateUpdate() +F32 LLImageGL::getTimePassedSinceLastBound() { - return ; + return sLastFrameTime - mLastBindTime ; } void LLImageGL::setExplicitFormat( LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes ) @@ -1052,7 +1007,6 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_ mTextureMemory = getMipBytes(discard_level); sGlobalTextureMemoryInBytes += mTextureMemory; - setActive() ; // mark this as bound at this point, so we don't throw it out immediately mLastBindTime = sLastFrameTime; @@ -1068,12 +1022,7 @@ BOOL LLImageGL::setDiscardLevel(S32 discard_level) discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel); - if (mDontDiscard) - { - // don't discard! - return FALSE; - } - else if (discard_level == mCurrentDiscardLevel) + if (discard_level == mCurrentDiscardLevel) { // nothing to do return FALSE; @@ -1255,8 +1204,7 @@ void LLImageGL::destroyGLTexture() sGlobalTextureMemoryInBytes -= mTextureMemory; mTextureMemory = 0; - LLImageGL::deleteTextures(1, &mTexName); - mTextureState = DELETED ; + LLImageGL::deleteTextures(1, &mTexName); mTexName = 0; mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel. mGLTextureCreated = FALSE ; @@ -1440,57 +1388,6 @@ void LLImageGL::analyzeAlpha(const void* data_in, S32 w, S32 h) } } -BOOL LLImageGL::isDeleted() -{ - return mTextureState == DELETED ; -} - -BOOL LLImageGL::isInactive() -{ - return mTextureState == INACTIVE ; -} - -BOOL LLImageGL::isDeletionCandidate() -{ - return mTextureState == DELETION_CANDIDATE ; -} - -void LLImageGL::setDeletionCandidate() -{ - if(mTexName && (mTextureState == INACTIVE)) - { - mTextureState = DELETION_CANDIDATE ; - } -} - -void LLImageGL::forceActive() -{ - mTextureState = ACTIVE ; -} - -void LLImageGL::setActive() -{ - if(mTextureState != NO_DELETE) - { - mTextureState = ACTIVE ; - } -} - -//set the texture inactive -void LLImageGL::setInactive() -{ - if(mTexName && (mTextureState == ACTIVE) && !getBoundRecently()) - { - mTextureState = INACTIVE ; - } -} - -//set the texture to stay in memory -void LLImageGL::setNoDelete() -{ - mTextureState = NO_DELETE ; -} - //---------------------------------------------------------------------------- void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in) { diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index 1775ae7de9..84c0f8746e 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -57,8 +57,8 @@ public: static S32 dataFormatBytes(S32 dataformat, S32 width, S32 height); static S32 dataFormatComponents(S32 dataformat); - void updateBindStats(void) const; - virtual void updateTestStats(void) const; + BOOL updateBindStats(S32 tex_mem) const ; + F32 getTimePassedSinceLastBound(); // needs to be called every frame static void updateStats(F32 current_time); @@ -72,12 +72,6 @@ public: static bool checkSize(S32 width, S32 height); - // Not currently necessary for LLImageGL, but required in some derived classes, - // so include for compatability - static BOOL create(LLPointer& dest, BOOL usemipmaps = TRUE); - static BOOL create(LLPointer& dest, U32 width, U32 height, U8 components, BOOL usemipmaps = TRUE); - static BOOL create(LLPointer& dest, const LLImageRaw* imageraw, BOOL usemipmaps = TRUE); - public: LLImageGL(BOOL usemipmaps = TRUE); LLImageGL(U32 width, U32 height, U8 components, BOOL usemipmaps = TRUE); @@ -90,11 +84,9 @@ protected: public: virtual void dump(); // debugging info to llinfos - virtual bool bindError(const S32 stage = 0) const; - virtual bool bindDefaultImage(const S32 stage = 0) const; - virtual void forceImmediateUpdate() ; - + void setSize(S32 width, S32 height, S32 ncomponents); + void setComponents(S32 ncomponents) { mComponents = (S8)ncomponents ;} // These 3 functions currently wrap glGenTextures(), glDeleteTextures(), and glTexImage2D() // for tracking purposes and will be deprecated in the future @@ -116,7 +108,6 @@ public: void destroyGLTexture(); void setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE); - void dontDiscard() { mDontDiscard = 1; mTextureState = NO_DELETE; } S32 getDiscardLevel() const { return mCurrentDiscardLevel; } S32 getMaxDiscardLevel() const { return mMaxDiscardLevel; } @@ -145,9 +136,7 @@ public: void setGLTextureCreated (bool initialized) { mGLTextureCreated = initialized; } BOOL getUseMipMaps() const { return mUseMipMaps; } - void setUseMipMaps(BOOL usemips) { mUseMipMaps = usemips; } - BOOL getUseDiscard() const { return mUseMipMaps && !mDontDiscard; } - BOOL getDontDiscard() const { return mDontDiscard; } + void setUseMipMaps(BOOL usemips) { mUseMipMaps = usemips; } BOOL isValidForSculpt(S32 discard_level, S32 image_width, S32 image_height, S32 ncomponents) ; @@ -168,16 +157,6 @@ public: void setFilteringOption(LLTexUnit::eTextureFilterOptions option); LLTexUnit::eTextureFilterOptions getFilteringOption(void) const { return mFilterOption; } - BOOL isDeleted() ; - BOOL isInactive() ; - BOOL isDeletionCandidate(); - void setDeletionCandidate() ; - void setInactive() ; - void setActive() ; - void forceActive() ; - void setNoDelete() ; - -protected: void init(BOOL usemipmaps); virtual void cleanup(); // Clean up the LLImageGL so it can be reinitialized. Be careful when using this in derived class destructors @@ -210,28 +189,15 @@ protected: S8 mComponents; S8 mMaxDiscardLevel; - S8 mDontDiscard; // Keep full res version of this image (for UI, etc) - + bool mTexOptionsDirty; LLTexUnit::eTextureAddressMode mAddressMode; // Defaults to TAM_WRAP LLTexUnit::eTextureFilterOptions mFilterOption; // Defaults to TFO_TRILINEAR - LLGLint mFormatInternal; // = GL internalformat LLGLenum mFormatPrimary; // = GL format (pixel data format) LLGLenum mFormatType; BOOL mFormatSwapBytes;// if true, use glPixelStorei(GL_UNPACK_SWAP_BYTES, 1) - -protected: - typedef enum - { - DELETED = 0, //removed from memory - DELETION_CANDIDATE, //ready to be removed from memory - INACTIVE, //not be used for the last certain period (i.e., 30 seconds). - ACTIVE, //just being used, can become inactive if not being used for a certain time (10 seconds). - NO_DELETE = 99 //stay in memory, can not be removed. - } LLGLTexureState; - LLGLTexureState mTextureState ; // STATICS public: @@ -249,6 +215,7 @@ public: static U32 sBindCount; // Tracks number of texture binds for current frame static U32 sUniqueCount; // Tracks number of unique texture binds for current frame static BOOL sGlobalUseAnisotropic; + static LLImageGL* sDefaultGLTexture ; #if DEBUG_MISS BOOL mMissed; // Missed on last bind? diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index d3a230b37b..d577daf3f4 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -38,6 +38,7 @@ #include "llcubemap.h" #include "llimagegl.h" #include "llrendertarget.h" +#include "lltexture.h" LLRender gGL; @@ -177,20 +178,21 @@ void LLTexUnit::disable(void) } } -bool LLTexUnit::bind(LLImageGL* texture, bool forceBind) +bool LLTexUnit::bind(LLTexture* texture, bool forceBind) { stop_glerror(); if (mIndex < 0) return false; gGL.flush(); - if (texture == NULL) + LLImageGL* gl_tex = NULL ; + if (texture == NULL || !(gl_tex = texture->getGLTexture())) { llwarns << "NULL LLTexUnit::bind texture" << llendl; return false; } - if (!texture->getTexName()) //if texture does not exist + if (!gl_tex->getTexName()) //if texture does not exist { //if deleted, will re-generate it immediately texture->forceImmediateUpdate() ; @@ -198,14 +200,57 @@ bool LLTexUnit::bind(LLImageGL* texture, bool forceBind) return texture->bindDefaultImage(mIndex); } + if ((mCurrTexture != gl_tex->getTexName()) || forceBind) + { + activate(); + enable(gl_tex->getTarget()); + mCurrTexture = gl_tex->getTexName(); + glBindTexture(sGLTextureType[gl_tex->getTarget()], mCurrTexture); + if(gl_tex->updateBindStats(gl_tex->mTextureMemory)) + { + texture->setActive() ; + texture->updateBindStatsForTester() ; + } + mHasMipMaps = gl_tex->mHasMipMaps; + if (gl_tex->mTexOptionsDirty) + { + gl_tex->mTexOptionsDirty = false; + setTextureAddressMode(gl_tex->mAddressMode); + setTextureFilteringOption(gl_tex->mFilterOption); + } + } + return true; +} + +bool LLTexUnit::bind(LLImageGL* texture, bool forceBind) +{ + stop_glerror(); + if (mIndex < 0) return false; + + if(!texture) + { + llwarns << "NULL LLTexUnit::bind texture" << llendl; + return false; + } + + if(!texture->getTexName()) + { + if(LLImageGL::sDefaultGLTexture && LLImageGL::sDefaultGLTexture->getTexName()) + { + return bind(LLImageGL::sDefaultGLTexture) ; + } + return false ; + } + + gGL.flush(); + if ((mCurrTexture != texture->getTexName()) || forceBind) { activate(); enable(texture->getTarget()); mCurrTexture = texture->getTexName(); glBindTexture(sGLTextureType[texture->getTarget()], mCurrTexture); - texture->updateBindStats(); - texture->setActive() ; + texture->updateBindStats(texture->mTextureMemory); mHasMipMaps = texture->mHasMipMaps; if (texture->mTexOptionsDirty) { @@ -238,7 +283,7 @@ bool LLTexUnit::bind(LLCubeMap* cubeMap) mCurrTexture = cubeMap->mImages[0]->getTexName(); glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, mCurrTexture); mHasMipMaps = cubeMap->mImages[0]->mHasMipMaps; - cubeMap->mImages[0]->updateBindStats(); + cubeMap->mImages[0]->updateBindStats(cubeMap->mImages[0]->mTextureMemory); if (cubeMap->mImages[0]->mTexOptionsDirty) { cubeMap->mImages[0]->mTexOptionsDirty = false; @@ -279,15 +324,21 @@ bool LLTexUnit::bind(LLRenderTarget* renderTarget, bool bindDepth) bool LLTexUnit::bindManual(eTextureType type, U32 texture, bool hasMips) { - if (mIndex < 0 || mCurrTexture == texture) return false; + if (mIndex < 0) + { + return false; + } - gGL.flush(); - - activate(); - enable(type); - mCurrTexture = texture; - glBindTexture(sGLTextureType[type], texture); - mHasMipMaps = hasMips; + if(mCurrTexture != texture) + { + gGL.flush(); + + activate(); + enable(type); + mCurrTexture = texture; + glBindTexture(sGLTextureType[type], texture); + mHasMipMaps = hasMips; + } return true; } diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index 31083d8286..74f87f6d40 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -51,6 +51,7 @@ class LLVertexBuffer; class LLCubeMap; class LLImageGL; class LLRenderTarget; +class LLTexture ; class LLTexUnit { @@ -149,6 +150,7 @@ public: // Binds the LLImageGL to this texture unit // (automatically enables the unit for the LLImageGL's texture type) bool bind(LLImageGL* texture, bool forceBind = false); + bool bind(LLTexture* texture, bool forceBind = false); // Binds a cubemap to this texture unit // (automatically enables the texture unit for cubemaps) diff --git a/indra/llrender/lltexture.cpp b/indra/llrender/lltexture.cpp new file mode 100644 index 0000000000..156ffb953c --- /dev/null +++ b/indra/llrender/lltexture.cpp @@ -0,0 +1,37 @@ +/** + * @file lltexture.cpp + * + * $LicenseInfo:firstyear=2000&license=viewergpl$ + * + * Copyright (c) 2000-2009, Linden Research, Inc. + * + * 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 + * + * 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 + * + * 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. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ +#include "linden_common.h" +#include "lltexture.h" + +//virtual +LLTexture::~LLTexture() +{ +} diff --git a/indra/llrender/lltexture.h b/indra/llrender/lltexture.h new file mode 100644 index 0000000000..c18917b663 --- /dev/null +++ b/indra/llrender/lltexture.h @@ -0,0 +1,77 @@ +/** + * @file lltexture.h + * @brief LLTexture definition + * + * This class acts as a wrapper for OpenGL calls. + * The goal of this class is to minimize the number of api calls due to legacy rendering + * code, to define an interface for a multiple rendering API abstraction of the UI + * rendering, and to abstract out direct rendering calls in a way that is cleaner and easier to maintain. + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2009, Linden Research, Inc. + * + * 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 + * + * 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 + * + * 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. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_TEXTURE_H +#define LL_TEXTURE_H + +#include "llrefcount.h" +class LLImageGL ; +class LLTexUnit ; +class LLFontGL ; + +// +//this is an abstract class as the parent for the class LLViewerTexture +//through the following virtual functions, the class LLViewerTexture can be reached from /llrender. +// +class LLTexture : public LLRefCount +{ + friend class LLTexUnit ; + friend class LLFontGL ; + +protected: + virtual ~LLTexture(); + +public: + LLTexture(){} + + // + //interfaces to access LLViewerTexture + // + virtual bool bindDefaultImage(const S32 stage = 0) const = 0 ; + virtual void forceImmediateUpdate() = 0 ; + virtual void setActive() = 0 ; + virtual S32 getWidth(S32 discard_level = -1) const = 0 ; + virtual S32 getHeight(S32 discard_level = -1) const = 0 ; + +private: + //note: do not make this function public. + virtual LLImageGL* getGLTexture() const = 0 ; + + virtual void updateBindStatsForTester() = 0 ; +}; +#endif + -- cgit v1.2.3 From 104f32750e6ac3349e85d2c9b00a8b26c78c017a Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Sat, 11 Jul 2009 02:09:37 +0000 Subject: add LLImageGL::create(...) back for server side use. --- indra/llrender/llimagegl.cpp | 25 +++++++++++++++++++++++++ indra/llrender/llimagegl.h | 9 ++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) (limited to 'indra/llrender') diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index c4d91209e6..a86a0aac23 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -262,6 +262,31 @@ void LLImageGL::restoreGL() } //---------------------------------------------------------------------------- + +//for server side use only. +//static +BOOL LLImageGL::create(LLPointer& dest, BOOL usemipmaps) +{ + dest = new LLImageGL(usemipmaps); + return TRUE; +} + +//for server side use only. +BOOL LLImageGL::create(LLPointer& dest, U32 width, U32 height, U8 components, BOOL usemipmaps) +{ + dest = new LLImageGL(width, height, components, usemipmaps); + return TRUE; +} + +//for server side use only. +BOOL LLImageGL::create(LLPointer& dest, const LLImageRaw* imageraw, BOOL usemipmaps) +{ + dest = new LLImageGL(imageraw, usemipmaps); + return TRUE; +} + +//---------------------------------------------------------------------------- + LLImageGL::LLImageGL(BOOL usemipmaps) : mSaveData(0) { diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index 84c0f8746e..09210b1ef1 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -71,7 +71,14 @@ public: static S32 updateBoundTexMem(const S32 delta); static bool checkSize(S32 width, S32 height); - + + //for server side use only. + // Not currently necessary for LLImageGL, but required in some derived classes, + // so include for compatability + static BOOL create(LLPointer& dest, BOOL usemipmaps = TRUE); + static BOOL create(LLPointer& dest, U32 width, U32 height, U8 components, BOOL usemipmaps = TRUE); + static BOOL create(LLPointer& dest, const LLImageRaw* imageraw, BOOL usemipmaps = TRUE); + public: LLImageGL(BOOL usemipmaps = TRUE); LLImageGL(U32 width, U32 height, U8 components, BOOL usemipmaps = TRUE); -- cgit v1.2.3 From 6a198eed3b784a0495e9710288bddcf73b44ae15 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Thu, 16 Jul 2009 23:51:22 +0000 Subject: add a flag in LLImageGL to turn off calling LLImageGL::analyzeAlpha() and LLImageGL::updatePickMask(). --- indra/llrender/llimagegl.cpp | 11 +++++++++++ indra/llrender/llimagegl.h | 2 ++ 2 files changed, 13 insertions(+) (limited to 'indra/llrender') diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index a86a0aac23..311009064f 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -362,6 +362,7 @@ void LLImageGL::init(BOOL usemipmaps) mGLTextureCreated = FALSE ; mIsMask = FALSE; + mNeedsAlpahAndPickMask = TRUE ; } void LLImageGL::cleanup() @@ -1356,6 +1357,11 @@ void LLImageGL::setTarget(const LLGLenum target, const LLTexUnit::eTextureType b void LLImageGL::analyzeAlpha(const void* data_in, S32 w, S32 h) { + if(!mNeedsAlpahAndPickMask) + { + return ; + } + if (mFormatType != GL_UNSIGNED_BYTE) { llwarns << "Cannot analyze alpha for image with format type " << std::hex << mFormatType << std::dec << llendl; @@ -1416,6 +1422,11 @@ void LLImageGL::analyzeAlpha(const void* data_in, S32 w, S32 h) //---------------------------------------------------------------------------- void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in) { + if(!mNeedsAlpahAndPickMask) + { + return ; + } + if (mFormatType != GL_UNSIGNED_BYTE || mFormatPrimary != GL_RGBA) { diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index 09210b1ef1..b58472d398 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -167,6 +167,7 @@ public: void init(BOOL usemipmaps); virtual void cleanup(); // Clean up the LLImageGL so it can be reinitialized. Be careful when using this in derived class destructors + void setNeedsAlpahAndPickMask(BOOL need_mask) {mNeedsAlpahAndPickMask = need_mask;} public: // Various GL/Rendering options S32 mTextureMemory; @@ -180,6 +181,7 @@ private: S8 mAutoGenMips; BOOL mIsMask; + BOOL mNeedsAlpahAndPickMask; bool mGLTextureCreated ; LLGLuint mTexName; -- cgit v1.2.3 From 9ffb8addf7db0a512fcd2931ff13c8400cd2227b Mon Sep 17 00:00:00 2001 From: Adam Moss Date: Fri, 17 Jul 2009 07:32:06 +0000 Subject: six instances of Alpah -> Alpha --- indra/llrender/llimagegl.cpp | 6 +++--- indra/llrender/llimagegl.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'indra/llrender') diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 311009064f..c3d1d9e894 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -362,7 +362,7 @@ void LLImageGL::init(BOOL usemipmaps) mGLTextureCreated = FALSE ; mIsMask = FALSE; - mNeedsAlpahAndPickMask = TRUE ; + mNeedsAlphaAndPickMask = TRUE ; } void LLImageGL::cleanup() @@ -1357,7 +1357,7 @@ void LLImageGL::setTarget(const LLGLenum target, const LLTexUnit::eTextureType b void LLImageGL::analyzeAlpha(const void* data_in, S32 w, S32 h) { - if(!mNeedsAlpahAndPickMask) + if(!mNeedsAlphaAndPickMask) { return ; } @@ -1422,7 +1422,7 @@ void LLImageGL::analyzeAlpha(const void* data_in, S32 w, S32 h) //---------------------------------------------------------------------------- void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in) { - if(!mNeedsAlpahAndPickMask) + if(!mNeedsAlphaAndPickMask) { return ; } diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index b58472d398..5f32b23356 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -167,7 +167,7 @@ public: void init(BOOL usemipmaps); virtual void cleanup(); // Clean up the LLImageGL so it can be reinitialized. Be careful when using this in derived class destructors - void setNeedsAlpahAndPickMask(BOOL need_mask) {mNeedsAlpahAndPickMask = need_mask;} + void setNeedsAlphaAndPickMask(BOOL need_mask) {mNeedsAlphaAndPickMask = need_mask;} public: // Various GL/Rendering options S32 mTextureMemory; @@ -181,7 +181,7 @@ private: S8 mAutoGenMips; BOOL mIsMask; - BOOL mNeedsAlpahAndPickMask; + BOOL mNeedsAlphaAndPickMask; bool mGLTextureCreated ; LLGLuint mTexName; -- cgit v1.2.3 From 8f7ec64899c54dcee6caa0307510cc4003ba7bdd Mon Sep 17 00:00:00 2001 From: James Cook Date: Mon, 27 Jul 2009 17:56:26 +0000 Subject: Merged skinning-17 into viewer-2 for bug fixes. Commented out new IM window for now, not complete. Merging revisions 127913-128319 of svn+ssh://svn.lindenlab.com/svn/linden/branches/skinning/skinning-17 into D:\viewer-2.0.0-3, respecting ancestry --- indra/llrender/CMakeLists.txt | 4 +- indra/llrender/llfontbitmapcache.h | 2 +- indra/llrender/llfontfreetype.cpp | 630 +++++++++++++++++++++++++++ indra/llrender/llfontfreetype.h | 380 ++++++++++++++++ indra/llrender/llfontgl.cpp | 868 ++++++++++++++++++------------------- indra/llrender/llfontgl.h | 217 ++++------ indra/llrender/llfontregistry.cpp | 57 ++- indra/llrender/llfontregistry.h | 2 +- 8 files changed, 1553 insertions(+), 607 deletions(-) create mode 100644 indra/llrender/llfontfreetype.cpp create mode 100644 indra/llrender/llfontfreetype.h (limited to 'indra/llrender') diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt index 0e0fc6ce6c..aac650bec9 100644 --- a/indra/llrender/CMakeLists.txt +++ b/indra/llrender/CMakeLists.txt @@ -26,7 +26,7 @@ include_directories( set(llrender_SOURCE_FILES llcubemap.cpp - llfont.cpp + llfontfreetype.cpp llfontgl.cpp llfontbitmapcache.cpp llfontregistry.cpp @@ -45,7 +45,7 @@ set(llrender_HEADER_FILES llcubemap.h llfontgl.h - llfont.h + llfontfreetype.h llfontbitmapcache.h llfontregistry.h llgl.h diff --git a/indra/llrender/llfontbitmapcache.h b/indra/llrender/llfontbitmapcache.h index 4beea0d026..4a57052b91 100644 --- a/indra/llrender/llfontbitmapcache.h +++ b/indra/llrender/llfontbitmapcache.h @@ -36,7 +36,7 @@ #include // Maintain a collection of bitmaps containing rendered glyphs. -// Generalizes the single-bitmap logic from LLFont and LLFontGL. +// Generalizes the single-bitmap logic from LLFontFreetype and LLFontGL. class LLFontBitmapCache: public LLRefCount { public: diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp new file mode 100644 index 0000000000..91a95cdd25 --- /dev/null +++ b/indra/llrender/llfontfreetype.cpp @@ -0,0 +1,630 @@ +/** + * @file llfontfreetype.cpp + * @brief Freetype font library wrapper + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + * + * Copyright (c) 2002-2009, Linden Research, Inc. + * + * 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 + * + * 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 + * + * 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. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llfontfreetype.h" + +// Freetype stuff +#include + +// For some reason, this won't work if it's not wrapped in the ifdef +#ifdef FT_FREETYPE_H +#include FT_FREETYPE_H +#endif + +#include "llerror.h" +#include "llimage.h" +//#include "llimagej2c.h" +#include "llmath.h" // Linden math +#include "llstring.h" +//#include "imdebug.h" +#include "llfontbitmapcache.h" +#include "llgl.h" + +FT_Render_Mode gFontRenderMode = FT_RENDER_MODE_NORMAL; + +LLFontManager *gFontManagerp = NULL; + +FT_Library gFTLibrary = NULL; + +//static +void LLFontManager::initClass() +{ + gFontManagerp = new LLFontManager; +} + +//static +void LLFontManager::cleanupClass() +{ + delete gFontManagerp; + gFontManagerp = NULL; +} + +LLFontManager::LLFontManager() +{ + int error; + error = FT_Init_FreeType(&gFTLibrary); + if (error) + { + // Clean up freetype libs. + llerrs << "Freetype initialization failure!" << llendl; + FT_Done_FreeType(gFTLibrary); + } +} + +LLFontManager::~LLFontManager() +{ + FT_Done_FreeType(gFTLibrary); +} + + +LLFontGlyphInfo::LLFontGlyphInfo(U32 index) +: mGlyphIndex(index), + mXBitmapOffset(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 + mYBearing(0), // Distance from baseline to top in pixels + mWidth(0), // In pixels + mHeight(0), // In pixels + mXAdvance(0.f), // In pixels + mYAdvance(0.f), // In pixels + mIsRendered(FALSE), + mMetricsValid(FALSE) +{ +} + +LLFontFreetype::LLFontFreetype() +: mFontBitmapCachep(new LLFontBitmapCache), + mValid(FALSE), + mAscender(0.f), + mDescender(0.f), + mLineHeight(0.f), + mIsFallback(FALSE), + mFTFace(NULL), + mRenderGlyphCount(0), + mAddGlyphCount(0), + mPointSize(0) +{ +} + + +LLFontFreetype::~LLFontFreetype() +{ + // Clean up freetype libs. + if (mFTFace) + FT_Done_Face(mFTFace); + mFTFace = NULL; + + // Delete glyph info + std::for_each(mCharGlyphInfoMap.begin(), mCharGlyphInfoMap.end(), DeletePairedPointer()); + + // mFontBitmapCachep will be cleaned up by LLPointer destructor. + // mFallbackFonts cleaned up by LLPointer destructor +} + +BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback) +{ + // Don't leak face objects. This is also needed to deal with + // changed font file names. + if (mFTFace) + { + FT_Done_Face(mFTFace); + mFTFace = NULL; + } + + int error; + + error = FT_New_Face( gFTLibrary, + filename.c_str(), + 0, + &mFTFace ); + + if (error) + { + return FALSE; + } + + mIsFallback = is_fallback; + F32 pixels_per_em = (point_size / 72.f)*vert_dpi; // Size in inches * dpi + + error = FT_Set_Char_Size(mFTFace, /* handle to face object */ + 0, /* char_width in 1/64th of points */ + (S32)(point_size*64), /* char_height in 1/64th of points */ + (U32)horz_dpi, /* horizontal device resolution */ + (U32)vert_dpi); /* vertical device resolution */ + + if (error) + { + // Clean up freetype libs. + FT_Done_Face(mFTFace); + mFTFace = NULL; + return FALSE; + } + + F32 y_max, y_min, x_max, x_min; + F32 ems_per_unit = 1.f/ mFTFace->units_per_EM; + F32 pixels_per_unit = pixels_per_em * ems_per_unit; + + // Get size of bbox in pixels + y_max = mFTFace->bbox.yMax * pixels_per_unit; + y_min = mFTFace->bbox.yMin * pixels_per_unit; + x_max = mFTFace->bbox.xMax * pixels_per_unit; + x_min = mFTFace->bbox.xMin * pixels_per_unit; + mAscender = mFTFace->ascender * pixels_per_unit; + mDescender = -mFTFace->descender * pixels_per_unit; + mLineHeight = mFTFace->height * pixels_per_unit; + + S32 max_char_width = llround(0.5f + (x_max - x_min)); + S32 max_char_height = llround(0.5f + (y_max - y_min)); + + mFontBitmapCachep->init(components, max_char_width, max_char_height); + + if (!mFTFace->charmap) + { + //llinfos << " no unicode encoding, set whatever encoding there is..." << llendl; + FT_Set_Charmap(mFTFace, mFTFace->charmaps[0]); + } + + if (!mIsFallback) + { + // Add the default glyph + addGlyph(0, 0); + } + + mName = filename; + mPointSize = point_size; + + return TRUE; +} + +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; +} + +F32 LLFontFreetype::getAscenderHeight() const +{ + return mAscender; +} + +F32 LLFontFreetype::getDescenderHeight() const +{ + return mDescender; +} + +F32 LLFontFreetype::getXAdvance(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) + { + font_vector_t::const_iterator iter; + for(iter = mFallbackFonts.begin(); (iter != mFallbackFonts.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(llwchar char_left, 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(llwchar wch) const +{ + llassert(!mIsFallback); + const LLFontGlyphInfo* gi = getGlyphInfo(wch); + if (gi && gi->mIsRendered) + { + return TRUE; + } + else + { + return FALSE; + } +} + +BOOL LLFontFreetype::addChar(llwchar wch) const +{ + if (mFTFace == NULL) + return FALSE; + + llassert(!mIsFallback); + //lldebugs << "Adding new glyph for " << wch << " to font" << llendl; + + FT_UInt glyph_index; + + // Initialize char to glyph map + glyph_index = FT_Get_Char_Index(mFTFace, wch); + if (glyph_index == 0) + { + //llinfos << "Trying to add glyph from fallback font!" << llendl + 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) + { + addGlyphFromFont(*iter, wch, glyph_index); + return TRUE; + } + } + } + + 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 FALSE; +} + +BOOL LLFontFreetype::addGlyph(llwchar wch, U32 glyph_index) const +{ + return addGlyphFromFont(this, wch, glyph_index); +} + +BOOL LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index) const +{ + if (mFTFace == NULL) + return FALSE; + + llassert(!mIsFallback); + fontp->renderGlyph(glyph_index); + S32 width = fontp->mFTFace->glyph->bitmap.width; + S32 height = fontp->mFTFace->glyph->bitmap.rows; + + S32 pos_x, pos_y; + S32 bitmap_num; + mFontBitmapCachep->nextOpenPos(width, pos_x, pos_y, bitmap_num); + mAddGlyphCount++; + + LLFontGlyphInfo* gi = new LLFontGlyphInfo(glyph_index); + gi->mXBitmapOffset = pos_x; + gi->mYBitmapOffset = pos_y; + gi->mBitmapNum = bitmap_num; + gi->mWidth = width; + gi->mHeight = height; + gi->mXBearing = fontp->mFTFace->glyph->bitmap_left; + gi->mYBearing = fontp->mFTFace->glyph->bitmap_top; + // 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->mIsRendered = TRUE; + gi->mMetricsValid = TRUE; + + insertGlyphInfo(wch, gi); + + llassert(fontp->mFTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO + || fontp->mFTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY); + + if (fontp->mFTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO + || fontp->mFTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY) + { + U8 *buffer_data = fontp->mFTFace->glyph->bitmap.buffer; + S32 buffer_row_stride = fontp->mFTFace->glyph->bitmap.pitch; + U8 *tmp_graydata = NULL; + + if (fontp->mFTFace->glyph->bitmap.pixel_mode + == FT_PIXEL_MODE_MONO) + { + // need to expand 1-bit bitmap to 8-bit graymap. + tmp_graydata = new U8[width * height]; + S32 xpos, ypos; + for (ypos = 0; ypos < height; ++ypos) + { + S32 bm_row_offset = buffer_row_stride * ypos; + for (xpos = 0; xpos < width; ++xpos) + { + U32 bm_col_offsetbyte = xpos / 8; + U32 bm_col_offsetbit = 7 - (xpos % 8); + U32 bit = + !!(buffer_data[bm_row_offset + + bm_col_offsetbyte + ] & (1 << bm_col_offsetbit) ); + tmp_graydata[width*ypos + xpos] = + 255 * bit; + } + } + // use newly-built graymap. + buffer_data = tmp_graydata; + buffer_row_stride = width; + } + + switch (mFontBitmapCachep->getNumComponents()) + { + case 1: + mFontBitmapCachep->getImageRaw(bitmap_num)->setSubImage(pos_x, + pos_y, + width, + height, + buffer_data, + buffer_row_stride, + TRUE); + break; + case 2: + setSubImageLuminanceAlpha(pos_x, + pos_y, + bitmap_num, + width, + height, + buffer_data, + buffer_row_stride); + break; + default: + break; + } + + if (tmp_graydata) + delete[] tmp_graydata; + } else { + // we don't know how to handle this pixel format from FreeType; + // omit it from the font-image. + } + + return TRUE; +} + +LLFontGlyphInfo* LLFontFreetype::getGlyphInfo(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; + } +} + +void LLFontFreetype::renderGlyph(U32 glyph_index) const +{ + if (mFTFace == NULL) + return; + + int error = FT_Load_Glyph(mFTFace, glyph_index, FT_LOAD_DEFAULT ); + llassert(!error); + + error = FT_Render_Glyph(mFTFace->glyph, gFontRenderMode); + + mRenderGlyphCount++; + + llassert(!error); +} + +void LLFontFreetype::reset(F32 vert_dpi, F32 horz_dpi) +{ + 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(); + 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(); + + // Add the empty glyph`5 + addGlyph(0, 0); +} + +void LLFontFreetype::destroyGL() +{ + mFontBitmapCachep->destroyGL(); +} + +BOOL LLFontFreetype::getIsFallback() const +{ + return mIsFallback; +} + +const std::string &LLFontFreetype::getName() const +{ + return mName; +} + +F32 LLFontFreetype::getPointSize() const +{ + return mPointSize; +} + +const LLPointer LLFontFreetype::getFontBitmapCache() const +{ + return mFontBitmapCachep; +} + +void LLFontFreetype::setStyle(U8 style) +{ + mStyle = style; +} + +U8 LLFontFreetype::getStyle() const +{ + return mStyle; +} + +void LLFontFreetype::setSubImageLuminanceAlpha(U32 x, U32 y, U32 bitmap_num, U32 width, U32 height, U8 *data, S32 stride) const +{ + LLImageRaw *image_raw = mFontBitmapCachep->getImageRaw(bitmap_num); + + llassert(!mIsFallback); + llassert(image_raw && (image_raw->getComponents() == 2)); + + + U8 *target = image_raw->getData(); + + if (!data) + { + return; + } + + if (0 == stride) + stride = width; + + U32 i, j; + U32 to_offset; + U32 from_offset; + U32 target_width = image_raw->getWidth(); + for (i = 0; i < height; i++) + { + to_offset = (y + i)*target_width + x; + from_offset = (height - 1 - i)*stride; + for (j = 0; j < width; j++) + { + *(target + to_offset*2 + 1) = *(data + from_offset); + to_offset++; + from_offset++; + } + } +} + diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h new file mode 100644 index 0000000000..0520ef2cd6 --- /dev/null +++ b/indra/llrender/llfontfreetype.h @@ -0,0 +1,380 @@ +/** + * @file llfontfreetype.h + * @brief Font library wrapper + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + * + * Copyright (c) 2002-2009, Linden Research, Inc. + * + * 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 + * + * 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 + * + * 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. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLFONTFREETYPE_H +#define LL_LLFONTFREETYPE_H + +#include +#include "llpointer.h" +#include "llstl.h" + +#include "llimagegl.h" +#include "llfontbitmapcache.h" + +// Hack. FT_Face is just a typedef for a pointer to a struct, +// but there's no simple forward declarations file for FreeType, +// and the main include file is 200K. +// We'll forward declare the struct here. JC +struct FT_FaceRec_; +typedef struct FT_FaceRec_* LLFT_Face; + +class LLFontManager +{ +public: + static void initClass(); + static void cleanupClass(); + +private: + LLFontManager(); + ~LLFontManager(); +}; + +class LLFontGlyphInfo +{ +public: + LLFontGlyphInfo(U32 index); + + U32 mGlyphIndex; + + // Metrics + S32 mWidth; // In pixels + S32 mHeight; // In pixels + F32 mXAdvance; // In pixels + F32 mYAdvance; // In pixels + BOOL mMetricsValid; // We have up-to-date metrics for this glyph + + // Information for actually rendering + BOOL mIsRendered; // We actually have rendered this glyph + S32 mXBitmapOffset; // Offset to the origin in the bitmap + S32 mYBitmapOffset; // Offset to the origin in the bitmap + S32 mXBearing; // Distance from baseline to left in pixels + S32 mYBearing; // Distance from baseline to top in pixels + S32 mBitmapNum; // Which bitmap in the bitmap cache contains this glyph +}; + +extern LLFontManager *gFontManagerp; + +class LLFontFreetype : public LLRefCount +{ +public: + LLFontFreetype(); + ~LLFontFreetype(); + + // is_fallback should be true for fallback fonts that aren't used + // to render directly (Unicode backup, primarily) + BOOL loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback); + + typedef std::vector > font_vector_t; + + void setFallbackFonts(const font_vector_t &font); + const font_vector_t &getFallbackFonts() const; + + // Global font metrics - in units of pixels + F32 getLineHeight() const; + F32 getAscenderHeight() const; + F32 getDescenderHeight() const; + + +// For a lowercase "g": +// +// ------------------------------ +// ^ ^ +// | | +// xxx x |Ascender +// x x v | +// --------- xxxx-------------- Baseline +// ^ x | +// | Descender x | +// v xxxx |LineHeight +// ----------------------- | +// v +// ------------------------------ + + enum + { + FIRST_CHAR = 32, + NUM_CHARS = 127 - 32, + LAST_CHAR_BASIC = 127, + + // Need full 8-bit ascii range for spanish + NUM_CHARS_FULL = 255 - 32, + LAST_CHAR_FULL = 255 + }; + + F32 getXAdvance(llwchar wc) const; + F32 getXKerning(llwchar char_left, llwchar char_right) const; // Get the kerning between the two characters + + BOOL hasGlyph(llwchar wch) const; // Has a glyph for this character + BOOL addChar(llwchar wch) const; // Add a new character to the font if necessary + BOOL addGlyph(llwchar wch, U32 glyph_index) const; // Add a new glyph to the existing font + BOOL addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index) const; // Add a glyph from this font to the other (returns the glyph_index, 0 if not found) + + LLFontGlyphInfo* getGlyphInfo(llwchar wch) const; + + void insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const; + void renderGlyph(U32 glyph_index) const; + + void reset(F32 vert_dpi, F32 horz_dpi); + void resetBitmapCache(); + + void destroyGL(); + + BOOL getIsFallback() const; + + const std::string& getName() const; + + F32 getPointSize() const; + + const LLPointer getFontBitmapCache() const; + + void setStyle(U8 style); + U8 getStyle() const; + +private: + void setSubImageLuminanceAlpha(U32 x, U32 y, U32 bitmap_num, U32 width, U32 height, U8 *data, S32 stride = 0) const; + + std::string mName; + + U8 mStyle; + + F32 mPointSize; + F32 mAscender; + F32 mDescender; + F32 mLineHeight; + + LLFT_Face mFTFace; + + BOOL mIsFallback; + font_vector_t mFallbackFonts; // A list of fallback fonts to look for glyphs in (for Unicode chars) + + BOOL mValid; + + typedef std::map char_glyph_info_map_t; + mutable char_glyph_info_map_t mCharGlyphInfoMap; // Information about glyph location in bitmap + + mutable LLPointer mFontBitmapCachep; + + mutable S32 mRenderGlyphCount; + mutable S32 mAddGlyphCount; +}; + +#endif // LL_FONTFREETYPE_H +/** + * @file llfontfreetype.h + * @brief Font library wrapper + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + * + * Copyright (c) 2002-2009, Linden Research, Inc. + * + * 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 + * + * 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 + * + * 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. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLFONTFREETYPE_H +#define LL_LLFONTFREETYPE_H + +#include +#include "llpointer.h" +#include "llstl.h" + +#include "llimagegl.h" +#include "llfontbitmapcache.h" + +// Hack. FT_Face is just a typedef for a pointer to a struct, +// but there's no simple forward declarations file for FreeType, +// and the main include file is 200K. +// We'll forward declare the struct here. JC +struct FT_FaceRec_; +typedef struct FT_FaceRec_* LLFT_Face; + +class LLFontManager +{ +public: + static void initClass(); + static void cleanupClass(); + +private: + LLFontManager(); + ~LLFontManager(); +}; + +class LLFontGlyphInfo +{ +public: + LLFontGlyphInfo(U32 index); + + U32 mGlyphIndex; + + // Metrics + S32 mWidth; // In pixels + S32 mHeight; // In pixels + F32 mXAdvance; // In pixels + F32 mYAdvance; // In pixels + BOOL mMetricsValid; // We have up-to-date metrics for this glyph + + // Information for actually rendering + BOOL mIsRendered; // We actually have rendered this glyph + S32 mXBitmapOffset; // Offset to the origin in the bitmap + S32 mYBitmapOffset; // Offset to the origin in the bitmap + S32 mXBearing; // Distance from baseline to left in pixels + S32 mYBearing; // Distance from baseline to top in pixels + S32 mBitmapNum; // Which bitmap in the bitmap cache contains this glyph +}; + +extern LLFontManager *gFontManagerp; + +class LLFontFreetype : public LLRefCount +{ +public: + LLFontFreetype(); + ~LLFontFreetype(); + + // is_fallback should be true for fallback fonts that aren't used + // to render directly (Unicode backup, primarily) + BOOL loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback); + + typedef std::vector > font_vector_t; + + void setFallbackFonts(const font_vector_t &font); + const font_vector_t &getFallbackFonts() const; + + // Global font metrics - in units of pixels + F32 getLineHeight() const; + F32 getAscenderHeight() const; + F32 getDescenderHeight() const; + + +// For a lowercase "g": +// +// ------------------------------ +// ^ ^ +// | | +// xxx x |Ascender +// x x v | +// --------- xxxx-------------- Baseline +// ^ x | +// | Descender x | +// v xxxx |LineHeight +// ----------------------- | +// v +// ------------------------------ + + enum + { + FIRST_CHAR = 32, + NUM_CHARS = 127 - 32, + LAST_CHAR_BASIC = 127, + + // Need full 8-bit ascii range for spanish + NUM_CHARS_FULL = 255 - 32, + LAST_CHAR_FULL = 255 + }; + + F32 getXAdvance(llwchar wc) const; + F32 getXKerning(llwchar char_left, llwchar char_right) const; // Get the kerning between the two characters + + BOOL hasGlyph(llwchar wch) const; // Has a glyph for this character + BOOL addChar(llwchar wch) const; // Add a new character to the font if necessary + BOOL addGlyph(llwchar wch, U32 glyph_index) const; // Add a new glyph to the existing font + BOOL addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index) const; // Add a glyph from this font to the other (returns the glyph_index, 0 if not found) + + LLFontGlyphInfo* getGlyphInfo(llwchar wch) const; + + void insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const; + void renderGlyph(U32 glyph_index) const; + + void reset(F32 vert_dpi, F32 horz_dpi); + void resetBitmapCache(); + + void destroyGL(); + + BOOL getIsFallback() const; + + const std::string& getName() const; + + F32 getPointSize() const; + + const LLPointer getFontBitmapCache() const; + + void setStyle(U8 style); + U8 getStyle() const; + +private: + void setSubImageLuminanceAlpha(U32 x, U32 y, U32 bitmap_num, U32 width, U32 height, U8 *data, S32 stride = 0) const; + + std::string mName; + + U8 mStyle; + + F32 mPointSize; + F32 mAscender; + F32 mDescender; + F32 mLineHeight; + + LLFT_Face mFTFace; + + BOOL mIsFallback; + font_vector_t mFallbackFonts; // A list of fallback fonts to look for glyphs in (for Unicode chars) + + BOOL mValid; + + typedef std::map char_glyph_info_map_t; + mutable char_glyph_info_map_t mCharGlyphInfoMap; // Information about glyph location in bitmap + + mutable LLPointer mFontBitmapCachep; + + mutable S32 mRenderGlyphCount; + mutable S32 mAddGlyphCount; +}; + +#endif // LL_FONTFREETYPE_H diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 0b57d86c78..32a008047c 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -35,7 +35,7 @@ #include "llfontgl.h" // Linden library includes -#include "llfont.h" +#include "llfontfreetype.h" #include "llfontbitmapcache.h" #include "llfontregistry.h" #include "llgl.h" @@ -73,54 +73,25 @@ const F32 PIXEL_CORRECTION_DISTANCE = 0.01f; const F32 PAD_UVY = 0.5f; // half of vertical padding between glyphs in the glyph texture const F32 DROP_SHADOW_SOFT_STRENGTH = 0.3f; -F32 llfont_round_x(F32 x) +static F32 llfont_round_x(F32 x) { //return llfloor((x-LLFontGL::sCurOrigin.mX)/LLFontGL::sScaleX+0.5f)*LLFontGL::sScaleX+LLFontGL::sCurOrigin.mX; //return llfloor(x/LLFontGL::sScaleX+0.5f)*LLFontGL::sScaleY; return x; } -F32 llfont_round_y(F32 y) +static F32 llfont_round_y(F32 y) { //return llfloor((y-LLFontGL::sCurOrigin.mY)/LLFontGL::sScaleY+0.5f)*LLFontGL::sScaleY+LLFontGL::sCurOrigin.mY; //return llfloor(y+0.5f); return y; } -// static -U8 LLFontGL::getStyleFromString(const std::string &style) -{ - S32 ret = 0; - if (style.find("NORMAL") != style.npos) - { - ret |= NORMAL; - } - if (style.find("BOLD") != style.npos) - { - ret |= BOLD; - } - if (style.find("ITALIC") != style.npos) - { - ret |= ITALIC; - } - if (style.find("UNDERLINE") != style.npos) - { - ret |= UNDERLINE; - } - return ret; -} - LLFontGL::LLFontGL() - : LLFont() { clearEmbeddedChars(); } -LLFontGL::LLFontGL(const LLFontGL &source) -{ - llerrs << "Not implemented!" << llendl; -} - LLFontGL::~LLFontGL() { clearEmbeddedChars(); @@ -128,293 +99,26 @@ LLFontGL::~LLFontGL() void LLFontGL::reset() { - if (!mIsFallback) - { - // 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(); -} - -// static -std::string LLFontGL::getFontPathSystem() -{ - std::string system_path; - - // Try to figure out where the system's font files are stored. - char *system_root = NULL; -#if LL_WINDOWS - system_root = getenv("SystemRoot"); /* Flawfinder: ignore */ - if (!system_root) - { - llwarns << "SystemRoot not found, attempting to load fonts from default path." << llendl; - } -#endif - - if (system_root) - { - system_path = llformat("%s/fonts/", system_root); - } - else - { -#if LL_WINDOWS - // HACK for windows 98/Me - system_path = "/WINDOWS/FONTS/"; -#elif LL_DARWIN - // HACK for Mac OS X - system_path = "/System/Library/Fonts/"; -#endif - } - return system_path; -} - - -// static -std::string LLFontGL::getFontPathLocal() -{ - std::string local_path; - - // Backup files if we can't load from system fonts directory. - // We could store this in an end-user writable directory to allow - // end users to switch fonts. - if (LLFontGL::sAppDir.length()) - { - // use specified application dir to look for fonts - local_path = LLFontGL::sAppDir + "/fonts/"; - } - else - { - // assume working directory is executable directory - local_path = "./fonts/"; - } - return local_path; -} - -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); -} - -// static -void LLFontGL::initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, - const std::string& app_dir, - const std::vector& xui_paths, - bool create_gl_textures) -{ - sVertDPI = (F32)llfloor(screen_dpi * y_scale); - sHorizDPI = (F32)llfloor(screen_dpi * x_scale); - sScaleX = x_scale; - sScaleY = y_scale; - sAppDir = app_dir; - - // Font registry init - if (!sFontRegistry) - { - sFontRegistry = new LLFontRegistry(xui_paths, create_gl_textures); - sFontRegistry->parseFontInfo("fonts.xml"); - } - else - { - sFontRegistry->reset(); - } -} - -// Force standard fonts to get generated up front. -// This is primarily for error detection purposes. -// Don't do this during initClass because it can be slow and we want to get -// the viewer window on screen first. JC -// static -bool LLFontGL::loadDefaultFonts() -{ - bool succ = true; - succ &= (NULL != getFontSansSerifSmall()); - succ &= (NULL != getFontSansSerif()); - succ &= (NULL != getFontSansSerifBig()); - succ &= (NULL != getFontSansSerifHuge()); - succ &= (NULL != getFontSansSerifBold()); - succ &= (NULL != getFontMonospace()); - succ &= (NULL != getFontExtChar()); - return succ; -} - - - -// static -void LLFontGL::destroyDefaultFonts() -{ - // Remove the actual fonts. - delete sFontRegistry; - sFontRegistry = NULL; -} - -//static -void LLFontGL::destroyAllGL() -{ - if (sFontRegistry) - { - sFontRegistry->destroyGL(); - } + mFontFreetype->reset(sVertDPI, sHorizDPI); } void LLFontGL::destroyGL() { - mFontBitmapCachep->destroyGL(); -} - - - -LLFontGL &LLFontGL::operator=(const LLFontGL &source) -{ - llerrs << "Not implemented" << llendl; - return *this; -} - -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)) - { - return FALSE; - } - return TRUE; -} - -//static -LLFontGL* LLFontGL::getFontMonospace() -{ - return getFont(LLFontDescriptor("Monospace","Monospace",0)); -} - -//static -LLFontGL* LLFontGL::getFontSansSerifSmall() -{ - return getFont(LLFontDescriptor("SansSerif","Small",0)); -} - -//static -LLFontGL* LLFontGL::getFontSansSerif() -{ - return getFont(LLFontDescriptor("SansSerif","Medium",0)); -} - -//static -LLFontGL* LLFontGL::getFontSansSerifBig() -{ - return getFont(LLFontDescriptor("SansSerif","Large",0)); -} - -//static -LLFontGL* LLFontGL::getFontSansSerifHuge() -{ - return getFont(LLFontDescriptor("SansSerif","Huge",0)); -} - -//static -LLFontGL* LLFontGL::getFontSansSerifBold() -{ - return getFont(LLFontDescriptor("SansSerif","Medium",BOLD)); -} - -//static -LLFontGL* LLFontGL::getFontExtChar() -{ - return getFontSansSerif(); -} - -//static -LLFontGL* LLFontGL::getFont(const LLFontDescriptor& desc) -{ - return sFontRegistry->getFont(desc); -} - -//static -LLFontGL* LLFontGL::getFontByName(const std::string& name) -{ - // check for most common fonts first - if (name == "SANSSERIF") - { - return getFontSansSerif(); - } - else if (name == "SANSSERIF_SMALL") - { - return getFontSansSerifSmall(); - } - else if (name == "SANSSERIF_BIG") - { - return getFontSansSerifBig(); - } - else if (name == "SMALL" || name == "OCRA") - { - // *BUG: Should this be "MONOSPACE"? Do we use "OCRA" anymore? - // Does "SMALL" mean "SERIF"? - return getFontMonospace(); - } - else - { - return NULL; - } + mFontFreetype->destroyGL(); } -BOOL LLFontGL::addChar(const llwchar wch) const +BOOL LLFontGL::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback) { - if (!LLFont::addChar(wch)) + if(mFontFreetype == reinterpret_cast(NULL)) { - return FALSE; + mFontFreetype = new LLFontFreetype; } - stop_glerror(); - - 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; -} - - -S32 LLFontGL::renderUTF8(const std::string &text, const S32 offset, - const F32 x, const F32 y, - const LLColor4 &color, - const HAlign halign, const VAlign valign, - U8 style, - ShadowType shadow, - const S32 max_chars, const S32 max_pixels, - F32* right_x, - BOOL use_ellipses) const -{ - LLWString wstr = utf8str_to_wstring(text); - return render(wstr, offset, x, y, color, halign, valign, style, shadow, max_chars, max_pixels, right_x, FALSE, use_ellipses); + return mFontFreetype->loadFace(filename, point_size, vert_dpi, horz_dpi, components, is_fallback); } -S32 LLFontGL::render(const LLWString &wstr, - const S32 begin_offset, - const F32 x, const F32 y, - const LLColor4 &color, - const HAlign halign, const VAlign valign, - U8 style, - ShadowType shadow, - const S32 max_chars, S32 max_pixels, - F32* right_x, - BOOL use_embedded, - BOOL use_ellipses) const +S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, + ShadowType shadow, S32 max_chars, S32 max_pixels, F32* right_x, BOOL use_embedded, BOOL use_ellipses) const { if(!sDisplayFont) //do not display texts { @@ -430,8 +134,9 @@ S32 LLFontGL::render(const LLWString &wstr, S32 scaled_max_pixels = max_pixels == S32_MAX ? S32_MAX : llceil((F32)max_pixels * sScaleX); - // Strip off any style bits that are already accounted for by the font. - style = style & (~getFontDesc().getStyle()); + // determine which style flags need to be added programmatically by striping off the + // style bits that are drawn by the underlying Freetype font + U8 style_to_add = (style | mFontDescriptor.getStyle()) & ~mFontFreetype->getStyle(); F32 drop_shadow_strength = 0.f; if (shadow != NO_SHADOW) @@ -483,13 +188,13 @@ S32 LLFontGL::render(const LLWString &wstr, switch (valign) { case TOP: - cur_y -= mAscender; + cur_y -= mFontFreetype->getAscenderHeight(); break; case BOTTOM: - cur_y += mDescender; + cur_y += mFontFreetype->getDescenderHeight(); break; case VCENTER: - cur_y -= ((mAscender - mDescender)/2.f); + cur_y -= ((mFontFreetype->getAscenderHeight() - mFontFreetype->getDescenderHeight())/2.f); break; case BASELINE: // Baseline, do nothing. @@ -517,10 +222,12 @@ S32 LLFontGL::render(const LLWString &wstr, F32 start_x = cur_x; - F32 inv_width = 1.f / mFontBitmapCachep->getBitmapWidth(); - F32 inv_height = 1.f / mFontBitmapCachep->getBitmapHeight(); + const LLFontBitmapCache* font_bitmap_cache = mFontFreetype->getFontBitmapCache(); - const S32 LAST_CHARACTER = LLFont::LAST_CHAR_FULL; + F32 inv_width = 1.f / font_bitmap_cache->getBitmapWidth(); + F32 inv_height = 1.f / font_bitmap_cache->getBitmapHeight(); + + const S32 LAST_CHARACTER = LLFontFreetype::LAST_CHAR_FULL; BOOL draw_ellipses = FALSE; @@ -576,11 +283,11 @@ S32 LLFontGL::render(const LLWString &wstr, // snap origin to whole screen pixel 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 screen_rect(ext_x, ext_y + ext_height, ext_x + ext_width, ext_y); - drawGlyph(screen_rect, uv_rect, LLColor4::white, style, shadow, drop_shadow_strength); + drawGlyph(screen_rect, uv_rect, LLColor4::white, style_to_add, shadow, drop_shadow_strength); if (!label.empty()) { @@ -609,19 +316,19 @@ S32 LLFontGL::render(const LLWString &wstr, } else { - if (!hasGlyph(wch)) + if (!mFontFreetype->hasGlyph(wch)) { addChar(wch); } - const LLFontGlyphInfo* fgi= getGlyphInfo(wch); + const LLFontGlyphInfo* fgi= mFontFreetype->getGlyphInfo(wch); if (!fgi) { llerrs << "Missing Glyph Info" << llendl; break; } // Per-glyph bitmap texture. - LLImageGL *image_gl = mFontBitmapCachep->getImageGL(fgi->mBitmapNum); + LLImageGL *image_gl = mFontFreetype->getFontBitmapCache()->getImageGL(fgi->mBitmapNum); if (last_bound_texture != image_gl) { gGL.getTexUnit(0)->bind(image_gl); @@ -646,7 +353,7 @@ S32 LLFontGL::render(const LLWString &wstr, llround(cur_render_x + (F32)fgi->mXBearing) + (F32)fgi->mWidth, llround(cur_render_y + (F32)fgi->mYBearing) - (F32)fgi->mHeight); - drawGlyph(screen_rect, uv_rect, color, style, shadow, drop_shadow_strength); + drawGlyph(screen_rect, uv_rect, color, style_to_add, shadow, drop_shadow_strength); chars_drawn++; cur_x += fgi->mXAdvance; @@ -656,11 +363,11 @@ S32 LLFontGL::render(const LLWString &wstr, if (next_char && (next_char < LAST_CHARACTER)) { // Kern this puppy. - if (!hasGlyph(next_char)) + if (!mFontFreetype->hasGlyph(next_char)) { addChar(next_char); } - cur_x += getXKerning(wch, next_char); + cur_x += mFontFreetype->getXKerning(wch, next_char); } // Round after kerning. @@ -680,12 +387,14 @@ S32 LLFontGL::render(const LLWString &wstr, *right_x = cur_x / sScaleX; } - if (style & UNDERLINE) + if (style_to_add & UNDERLINE) { + F32 descender = mFontFreetype->getDescenderHeight(); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.begin(LLRender::LINES); - gGL.vertex2f(start_x, cur_y - (mDescender)); - gGL.vertex2f(cur_x, cur_y - (mDescender)); + gGL.vertex2f(start_x, cur_y - (descender)); + gGL.vertex2f(cur_x, cur_y - (descender)); gGL.end(); } @@ -703,7 +412,7 @@ S32 LLFontGL::render(const LLWString &wstr, cur_x / sScaleX, (F32)y, color, LEFT, valign, - style, + style_to_add, shadow, S32_MAX, max_pixels, right_x, @@ -716,8 +425,43 @@ S32 LLFontGL::render(const LLWString &wstr, return chars_drawn; } - -S32 LLFontGL::getWidth(const std::string& utf8text) const +S32 LLFontGL::render(const LLWString &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color) const +{ + return render(text, begin_offset, x, y, color, LEFT, BASELINE, NORMAL, NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE, FALSE); +} + +S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, ShadowType shadow, S32 max_chars, S32 max_pixels, F32* right_x, BOOL use_ellipses) const +{ + return render(utf8str_to_wstring(text), begin_offset, x, y, color, halign, valign, style, shadow, max_chars, max_pixels, right_x, FALSE, use_ellipses); +} + +S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color) const +{ + return renderUTF8(text, begin_offset, (F32)x, (F32)y, color, LEFT, BASELINE, NORMAL, NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE); +} + +S32 LLFontGL::renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, ShadowType shadow) const +{ + 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::getLineHeight() const +{ + return (F32)llround(mFontFreetype->getLineHeight() / sScaleY); +} + +F32 LLFontGL::getAscenderHeight() const +{ + return (F32)llround(mFontFreetype->getAscenderHeight() / sScaleY); +} + +F32 LLFontGL::getDescenderHeight() const +{ + return (F32)llround(mFontFreetype->getDescenderHeight() / sScaleY); +} + +S32 LLFontGL::getWidth(const std::string& utf8text) const { LLWString wtext = utf8str_to_wstring(utf8text); return getWidth(wtext.c_str(), 0, S32_MAX); @@ -728,13 +472,13 @@ S32 LLFontGL::getWidth(const llwchar* wchars) const return getWidth(wchars, 0, S32_MAX); } -S32 LLFontGL::getWidth(const std::string& utf8text, const S32 begin_offset, const S32 max_chars) const +S32 LLFontGL::getWidth(const std::string& utf8text, S32 begin_offset, S32 max_chars) const { LLWString wtext = utf8str_to_wstring(utf8text); return getWidth(wtext.c_str(), begin_offset, max_chars); } -S32 LLFontGL::getWidth(const llwchar* wchars, const S32 begin_offset, const S32 max_chars, BOOL use_embedded) const +S32 LLFontGL::getWidth(const llwchar* wchars, S32 begin_offset, S32 max_chars, BOOL use_embedded) const { F32 width = getWidthF32(wchars, begin_offset, max_chars, use_embedded); return llround(width); @@ -751,15 +495,15 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars) const return getWidthF32(wchars, 0, S32_MAX); } -F32 LLFontGL::getWidthF32(const std::string& utf8text, const S32 begin_offset, const S32 max_chars ) const +F32 LLFontGL::getWidthF32(const std::string& utf8text, S32 begin_offset, S32 max_chars ) const { LLWString wtext = utf8str_to_wstring(utf8text); return getWidthF32(wtext.c_str(), begin_offset, max_chars); } -F32 LLFontGL::getWidthF32(const llwchar* wchars, const S32 begin_offset, const S32 max_chars, BOOL use_embedded) const +F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, 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; @@ -783,7 +527,7 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, const S32 begin_offset, const S } else { - cur_x += getXAdvance(wch); + cur_x += mFontFreetype->getXAdvance(wch); llwchar next_char = wchars[i+1]; if (((i + 1) < max_chars) @@ -791,7 +535,7 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, const S32 begin_offset, const S && (next_char < LAST_CHARACTER)) { // Kern this puppy. - cur_x += getXKerning(wch, next_char); + cur_x += mFontFreetype->getXKerning(wch, next_char); } } // Round after kerning. @@ -801,12 +545,8 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, const S32 begin_offset, const S return cur_x / sScaleX; } - - // Returns the max number of complete characters from text (up to max_chars) that can be drawn in max_pixels -S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars, - BOOL end_on_word_boundary, const BOOL use_embedded, - F32* drawn_pixels) const +S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars, BOOL end_on_word_boundary, BOOL use_embedded, F32* drawn_pixels) const { if (!wchars || !wchars[0] || max_chars == 0) { @@ -899,7 +639,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) { @@ -910,7 +650,7 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch if (((i+1) < max_chars) && wchars[i+1]) { // Kern this puppy. - cur_x += getXKerning(wch, wchars[i+1]); + cur_x += mFontFreetype->getXKerning(wch, wchars[i+1]); } } // Round after kerning. @@ -929,7 +669,6 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch return i; } - S32 LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_len, S32 start_pos, S32 max_chars) const { if (!wchars || !wchars[0] || max_chars == 0) @@ -948,7 +687,7 @@ S32 LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_ llwchar wch = wchars[i]; const embedded_data_t* ext_data = getEmbeddedCharData(wch); - F32 char_width = ext_data ? getEmbeddedCharAdvance(ext_data) : getXAdvance(wch); + F32 char_width = ext_data ? getEmbeddedCharAdvance(ext_data) : mFontFreetype->getXAdvance(wch); if( scaled_max_pixels < (total_width + char_width) ) { @@ -966,7 +705,7 @@ S32 LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_ if ( i > 0 ) { // 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. @@ -976,8 +715,7 @@ S32 LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_ return start_pos - drawable_chars; } - -S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, const S32 begin_offset, F32 target_x, F32 max_pixels, S32 max_chars, BOOL round, BOOL use_embedded) const +S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, S32 begin_offset, F32 target_x, F32 max_pixels, S32 max_chars, BOOL round, BOOL use_embedded) const { if (!wchars || !wchars[0] || max_chars == 0) { @@ -1041,7 +779,7 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, const S32 begin_offset, } else { - F32 char_width = getXAdvance(wch); + F32 char_width = mFontFreetype->getXAdvance(wch); if (round) { @@ -1070,7 +808,7 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, const S32 begin_offset, { llwchar next_char = wchars[i + 1]; // Kern this puppy. - cur_x += getXKerning(wch, next_char); + cur_x += mFontFreetype->getXKerning(wch, next_char); } // Round after kerning. @@ -1081,60 +819,370 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, const S32 begin_offset, return pos; } +void LLFontGL::addEmbeddedChar( llwchar wc, LLTexture* image, const std::string& label ) const +{ + LLWString wlabel = utf8str_to_wstring(label); + addEmbeddedChar(wc, image, wlabel); +} -const LLFontGL::embedded_data_t* LLFontGL::getEmbeddedCharData(const llwchar wch) const +void LLFontGL::addEmbeddedChar( llwchar wc, LLTexture* image, const LLWString& wlabel ) const { - // Handle crappy embedded hack - embedded_map_t::const_iterator iter = mEmbeddedChars.find(wch); + embedded_data_t* ext_data = new embedded_data_t(image->getGLTexture(), wlabel); + mEmbeddedChars[wc] = ext_data; +} + +void LLFontGL::removeEmbeddedChar(llwchar wc) const +{ + embedded_map_t::iterator iter = mEmbeddedChars.find(wc); if (iter != mEmbeddedChars.end()) { - return iter->second; + delete iter->second; + mEmbeddedChars.erase(wc); } - return NULL; } +BOOL LLFontGL::addChar(llwchar wch) const +{ + if (!mFontFreetype->addChar(wch)) + { + return FALSE; + } -F32 LLFontGL::getEmbeddedCharAdvance(const embedded_data_t* ext_data) const + stop_glerror(); + + LLFontGlyphInfo *glyph_info = mFontFreetype->getGlyphInfo(wch); + U32 bitmap_num = glyph_info->mBitmapNum; + + const LLFontBitmapCache* font_bitmap_cache = mFontFreetype->getFontBitmapCache(); + LLImageGL *image_gl = font_bitmap_cache->getImageGL(bitmap_num); + LLImageRaw *image_raw = font_bitmap_cache->getImageRaw(bitmap_num); + image_gl->setSubImage(image_raw, 0, 0, image_gl->getWidth(), image_gl->getHeight()); + return TRUE; +} + +const LLFontDescriptor& LLFontGL::getFontDesc() const { - const LLWString& label = ext_data->mLabel; - LLImageGL* ext_image = ext_data->mImage; + return mFontDescriptor; +} - F32 ext_width = (F32)ext_image->getWidth(); - if( !label.empty() ) +// static +void LLFontGL::initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::string& app_dir, const std::vector& xui_paths, bool create_gl_textures) +{ + sVertDPI = (F32)llfloor(screen_dpi * y_scale); + sHorizDPI = (F32)llfloor(screen_dpi * x_scale); + sScaleX = x_scale; + sScaleY = y_scale; + sAppDir = app_dir; + + // Font registry init + if (!sFontRegistry) { - ext_width += (EXT_X_BEARING + getFontExtChar()->getWidthF32(label.c_str())) * sScaleX; + sFontRegistry = new LLFontRegistry(xui_paths, create_gl_textures); + sFontRegistry->parseFontInfo("fonts.xml"); + } + else + { + sFontRegistry->reset(); } +} - return (EXT_X_BEARING * sScaleX) + ext_width; +// Force standard fonts to get generated up front. +// This is primarily for error detection purposes. +// Don't do this during initClass because it can be slow and we want to get +// the viewer window on screen first. JC +// static +bool LLFontGL::loadDefaultFonts() +{ + bool succ = true; + succ &= (NULL != getFontSansSerifSmall()); + succ &= (NULL != getFontSansSerif()); + succ &= (NULL != getFontSansSerifBig()); + succ &= (NULL != getFontSansSerifHuge()); + succ &= (NULL != getFontSansSerifBold()); + succ &= (NULL != getFontMonospace()); + succ &= (NULL != getFontExtChar()); + return succ; } +// static +void LLFontGL::destroyDefaultFonts() +{ + // Remove the actual fonts. + delete sFontRegistry; + sFontRegistry = NULL; +} -void LLFontGL::clearEmbeddedChars() +//static +void LLFontGL::destroyAllGL() { - for_each(mEmbeddedChars.begin(), mEmbeddedChars.end(), DeletePairedPointer()); - mEmbeddedChars.clear(); + if (sFontRegistry) + { + sFontRegistry->destroyGL(); + } } -void LLFontGL::addEmbeddedChar( llwchar wc, LLTexture* image, const std::string& label ) const +// static +U8 LLFontGL::getStyleFromString(const std::string &style) { - LLWString wlabel = utf8str_to_wstring(label); - addEmbeddedChar(wc, image, wlabel); + S32 ret = 0; + if (style.find("NORMAL") != style.npos) + { + ret |= NORMAL; + } + if (style.find("BOLD") != style.npos) + { + ret |= BOLD; + } + if (style.find("ITALIC") != style.npos) + { + ret |= ITALIC; + } + if (style.find("UNDERLINE") != style.npos) + { + ret |= UNDERLINE; + } + return ret; } -void LLFontGL::addEmbeddedChar( llwchar wc, LLTexture* image, const LLWString& wlabel ) const +// static +std::string LLFontGL::nameFromFont(const LLFontGL* fontp) { - embedded_data_t* ext_data = new embedded_data_t(image->getGLTexture(), wlabel); - mEmbeddedChars[wc] = ext_data; + return fontp->mFontDescriptor.getName(); } -void LLFontGL::removeEmbeddedChar( llwchar wc ) const +// static +std::string LLFontGL::nameFromHAlign(LLFontGL::HAlign align) { - embedded_map_t::iterator iter = mEmbeddedChars.find(wc); + if (align == LEFT) return std::string("left"); + else if (align == RIGHT) return std::string("right"); + else if (align == HCENTER) return std::string("center"); + else return std::string(); +} + +// static +LLFontGL::HAlign LLFontGL::hAlignFromName(const std::string& name) +{ + LLFontGL::HAlign gl_hfont_align = LLFontGL::LEFT; + if (name == "left") + { + gl_hfont_align = LLFontGL::LEFT; + } + else if (name == "right") + { + gl_hfont_align = LLFontGL::RIGHT; + } + else if (name == "center") + { + gl_hfont_align = LLFontGL::HCENTER; + } + //else leave left + return gl_hfont_align; +} + +// static +std::string LLFontGL::nameFromVAlign(LLFontGL::VAlign align) +{ + if (align == TOP) return std::string("top"); + else if (align == VCENTER) return std::string("center"); + else if (align == BASELINE) return std::string("baseline"); + else if (align == BOTTOM) return std::string("bottom"); + else return std::string(); +} + +// static +LLFontGL::VAlign LLFontGL::vAlignFromName(const std::string& name) +{ + LLFontGL::VAlign gl_vfont_align = LLFontGL::BASELINE; + if (name == "top") + { + gl_vfont_align = LLFontGL::TOP; + } + else if (name == "center") + { + gl_vfont_align = LLFontGL::VCENTER; + } + else if (name == "baseline") + { + gl_vfont_align = LLFontGL::BASELINE; + } + else if (name == "bottom") + { + gl_vfont_align = LLFontGL::BOTTOM; + } + //else leave baseline + return gl_vfont_align; +} + +//static +LLFontGL* LLFontGL::getFontMonospace() +{ + return getFont(LLFontDescriptor("Monospace","Monospace",0)); +} + +//static +LLFontGL* LLFontGL::getFontSansSerifSmall() +{ + return getFont(LLFontDescriptor("SansSerif","Small",0)); +} + +//static +LLFontGL* LLFontGL::getFontSansSerif() +{ + return getFont(LLFontDescriptor("SansSerif","Medium",0)); +} + +//static +LLFontGL* LLFontGL::getFontSansSerifBig() +{ + return getFont(LLFontDescriptor("SansSerif","Large",0)); +} + +//static +LLFontGL* LLFontGL::getFontSansSerifHuge() +{ + return getFont(LLFontDescriptor("SansSerif","Huge",0)); +} + +//static +LLFontGL* LLFontGL::getFontSansSerifBold() +{ + return getFont(LLFontDescriptor("SansSerif","Medium",BOLD)); +} + +//static +LLFontGL* LLFontGL::getFontExtChar() +{ + return getFontSansSerif(); +} + +//static +LLFontGL* LLFontGL::getFont(const LLFontDescriptor& desc) +{ + return sFontRegistry->getFont(desc); +} + +//static +LLFontGL* LLFontGL::getFontByName(const std::string& name) +{ + // check for most common fonts first + if (name == "SANSSERIF") + { + return getFontSansSerif(); + } + else if (name == "SANSSERIF_SMALL") + { + return getFontSansSerifSmall(); + } + else if (name == "SANSSERIF_BIG") + { + return getFontSansSerifBig(); + } + else if (name == "SMALL" || name == "OCRA") + { + // *BUG: Should this be "MONOSPACE"? Do we use "OCRA" anymore? + // Does "SMALL" mean "SERIF"? + return getFontMonospace(); + } + else + { + return NULL; + } +} + +// static +std::string LLFontGL::getFontPathSystem() +{ + std::string system_path; + + // Try to figure out where the system's font files are stored. + char *system_root = NULL; +#if LL_WINDOWS + system_root = getenv("SystemRoot"); /* Flawfinder: ignore */ + if (!system_root) + { + llwarns << "SystemRoot not found, attempting to load fonts from default path." << llendl; + } +#endif + + if (system_root) + { + system_path = llformat("%s/fonts/", system_root); + } + else + { +#if LL_WINDOWS + // HACK for windows 98/Me + system_path = "/WINDOWS/FONTS/"; +#elif LL_DARWIN + // HACK for Mac OS X + system_path = "/System/Library/Fonts/"; +#endif + } + return system_path; +} + + +// static +std::string LLFontGL::getFontPathLocal() +{ + std::string local_path; + + // Backup files if we can't load from system fonts directory. + // We could store this in an end-user writable directory to allow + // end users to switch fonts. + if (LLFontGL::sAppDir.length()) + { + // use specified application dir to look for fonts + local_path = LLFontGL::sAppDir + "/fonts/"; + } + else + { + // assume working directory is executable directory + local_path = "./fonts/"; + } + return local_path; +} + +LLFontGL::LLFontGL(const LLFontGL &source) +{ + llerrs << "Not implemented!" << llendl; +} + +LLFontGL &LLFontGL::operator=(const LLFontGL &source) +{ + llerrs << "Not implemented" << llendl; + return *this; +} + +const LLFontGL::embedded_data_t* LLFontGL::getEmbeddedCharData(llwchar wch) const +{ + // Handle crappy embedded hack + embedded_map_t::const_iterator iter = mEmbeddedChars.find(wch); if (iter != mEmbeddedChars.end()) { - delete iter->second; - mEmbeddedChars.erase(wc); + return iter->second; } + return NULL; +} + +F32 LLFontGL::getEmbeddedCharAdvance(const embedded_data_t* ext_data) const +{ + const LLWString& label = ext_data->mLabel; + LLImageGL* ext_image = ext_data->mImage; + + F32 ext_width = (F32)ext_image->getWidth(); + if( !label.empty() ) + { + ext_width += (EXT_X_BEARING + getFontExtChar()->getWidthF32(label.c_str())) * sScaleX; + } + + return (EXT_X_BEARING * sScaleX) + ext_width; +} + +void LLFontGL::clearEmbeddedChars() +{ + for_each(mEmbeddedChars.begin(), mEmbeddedChars.end(), DeletePairedPointer()); + mEmbeddedChars.clear(); } @@ -1160,7 +1208,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 { 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); { @@ -1230,71 +1278,3 @@ void LLFontGL::drawGlyph(const LLRectf& screen_rect, const LLRectf& uv_rect, con } gGL.end(); } - -std::string LLFontGL::nameFromFont(const LLFontGL* fontp) -{ - return fontp->getFontDesc().getName(); -} - -// static -std::string LLFontGL::nameFromHAlign(LLFontGL::HAlign align) -{ - if (align == LEFT) return std::string("left"); - else if (align == RIGHT) return std::string("right"); - else if (align == HCENTER) return std::string("center"); - else return std::string(); -} - -// static -LLFontGL::HAlign LLFontGL::hAlignFromName(const std::string& name) -{ - LLFontGL::HAlign gl_hfont_align = LLFontGL::LEFT; - if (name == "left") - { - gl_hfont_align = LLFontGL::LEFT; - } - else if (name == "right") - { - gl_hfont_align = LLFontGL::RIGHT; - } - else if (name == "center") - { - gl_hfont_align = LLFontGL::HCENTER; - } - //else leave left - return gl_hfont_align; -} - -// static -std::string LLFontGL::nameFromVAlign(LLFontGL::VAlign align) -{ - if (align == TOP) return std::string("top"); - else if (align == VCENTER) return std::string("center"); - else if (align == BASELINE) return std::string("baseline"); - else if (align == BOTTOM) return std::string("bottom"); - else return std::string(); -} - -// static -LLFontGL::VAlign LLFontGL::vAlignFromName(const std::string& name) -{ - LLFontGL::VAlign gl_vfont_align = LLFontGL::BASELINE; - if (name == "top") - { - gl_vfont_align = LLFontGL::TOP; - } - else if (name == "center") - { - gl_vfont_align = LLFontGL::VCENTER; - } - else if (name == "baseline") - { - gl_vfont_align = LLFontGL::BASELINE; - } - else if (name == "bottom") - { - gl_vfont_align = LLFontGL::BOTTOM; - } - //else leave baseline - return gl_vfont_align; -} diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h index 2298db0ef3..42ed7a381f 100644 --- a/indra/llrender/llfontgl.h +++ b/indra/llrender/llfontgl.h @@ -35,21 +35,21 @@ #define LL_LLFONTGL_H #include "llcoord.h" -#include "llfont.h" #include "llfontregistry.h" +#include "llimagegl.h" #include "llpointer.h" #include "llrect.h" #include "v2math.h" class LLColor4; -class LLImageGL; // Key used to request a font. class LLFontDescriptor; +class LLFontFreetype; // Structure used to store previously requested fonts. class LLFontRegistry; -class LLFontGL : public LLFont +class LLFontGL { public: enum HAlign @@ -85,130 +85,72 @@ public: DROP_SHADOW, DROP_SHADOW_SOFT }; - - // Takes a string with potentially several flags, i.e. "NORMAL|BOLD|ITALIC" - static U8 getStyleFromString(const std::string &style); LLFontGL(); - LLFontGL(const LLFontGL &source); ~LLFontGL(); - void init(); // Internal init, or reinitialization - void reset(); // Reset a font after GL cleanup. ONLY works on an already loaded font. - LLFontGL &operator=(const LLFontGL &source); - - static void initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, - const std::string& app_dir, - const std::vector& xui_paths, - bool create_gl_textures = true); + void reset(); // Reset a font after GL cleanup. ONLY works on an already loaded font. - // Load sans-serif, sans-serif-small, etc. - // Slow, requires multiple seconds to load fonts. - static bool loadDefaultFonts(); - static void destroyDefaultFonts(); - static void destroyAllGL(); 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, 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, F32 x, F32 y, const LLColor4 &color, HAlign halign = LEFT, VAlign valign = BASELINE, U8 style = NORMAL, + ShadowType shadow = NO_SHADOW, S32 max_chars = S32_MAX, S32 max_pixels = S32_MAX, F32* right_x=NULL, BOOL use_embedded = FALSE, BOOL use_ellipses = FALSE) const; + S32 render(const LLWString &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color) const; - S32 renderUTF8(const std::string &text, const S32 begin_offset, - S32 x, S32 y, - const LLColor4 &color) const - { - return renderUTF8(text, begin_offset, (F32)x, (F32)y, color, - LEFT, BASELINE, NORMAL, NO_SHADOW, - S32_MAX, S32_MAX, NULL, FALSE); - } - - S32 renderUTF8(const std::string &text, const S32 begin_offset, - S32 x, S32 y, - const LLColor4 &color, - HAlign halign, VAlign valign, U8 style = NORMAL, ShadowType shadow = NO_SHADOW) const - { - return renderUTF8(text, begin_offset, (F32)x, (F32)y, color, - halign, valign, style, shadow, - S32_MAX, S32_MAX, NULL, FALSE); - } - // renderUTF8 does a conversion, so is slower! - S32 renderUTF8(const std::string &text, - S32 begin_offset, - F32 x, F32 y, - const LLColor4 &color, - HAlign halign, - VAlign valign, - U8 style, - ShadowType shadow, - S32 max_chars, - S32 max_pixels, - F32* right_x, - BOOL use_ellipses) const; - - S32 render(const LLWString &text, const S32 begin_offset, - F32 x, F32 y, - const LLColor4 &color) const - { - return render(text, begin_offset, x, y, color, - LEFT, BASELINE, NORMAL, NO_SHADOW, - S32_MAX, S32_MAX, NULL, FALSE, FALSE); - } - + S32 renderUTF8(const std::string &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, ShadowType shadow, S32 max_chars, S32 max_pixels, F32* right_x, BOOL use_ellipses) const; + S32 renderUTF8(const std::string &text, S32 begin_offset, S32 x, S32 y, const LLColor4 &color) 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; - S32 render(const LLWString &text, - S32 begin_offset, - F32 x, F32 y, - const LLColor4 &color, - HAlign halign = LEFT, - VAlign valign = BASELINE, - U8 style = NORMAL, - ShadowType shadow = NO_SHADOW, - S32 max_chars = S32_MAX, - S32 max_pixels = S32_MAX, - F32* right_x=NULL, - BOOL use_embedded = FALSE, - BOOL use_ellipses = FALSE) const; - - // font metrics - override for LLFont that returns units of virtual pixels - /*virtual*/ F32 getLineHeight() const { return (F32)llround(mLineHeight / sScaleY); } - /*virtual*/ F32 getAscenderHeight() const { return (F32)llround(mAscender / sScaleY); } - /*virtual*/ F32 getDescenderHeight() const { return (F32)llround(mDescender / sScaleY); } - - virtual S32 getWidth(const std::string& utf8text) const; - virtual S32 getWidth(const llwchar* wchars) const; - virtual S32 getWidth(const std::string& utf8text, const S32 offset, const S32 max_chars ) const; - virtual S32 getWidth(const llwchar* wchars, const S32 offset, const S32 max_chars, BOOL use_embedded = FALSE) const; + // font metrics - override for LLFontFreetype that returns units of virtual pixels + F32 getLineHeight() const; + F32 getAscenderHeight() const; + F32 getDescenderHeight() const; - virtual F32 getWidthF32(const std::string& utf8text) const; - virtual F32 getWidthF32(const llwchar* wchars) const; - virtual F32 getWidthF32(const std::string& text, const S32 offset, const S32 max_chars ) const; - virtual F32 getWidthF32(const llwchar* wchars, const S32 offset, const S32 max_chars, BOOL use_embedded = FALSE ) const; + S32 getWidth(const std::string& utf8text) const; + S32 getWidth(const llwchar* wchars) const; + S32 getWidth(const std::string& utf8text, S32 offset, S32 max_chars ) const; + S32 getWidth(const llwchar* wchars, S32 offset, S32 max_chars, BOOL use_embedded = FALSE) const; + + F32 getWidthF32(const std::string& utf8text) const; + F32 getWidthF32(const llwchar* wchars) const; + F32 getWidthF32(const std::string& text, S32 offset, S32 max_chars ) const; + F32 getWidthF32(const llwchar* wchars, S32 offset, S32 max_chars, BOOL use_embedded = FALSE ) const; // The following are called often, frequently with large buffers, so do not use a string interface // Returns the max number of complete characters from text (up to max_chars) that can be drawn in max_pixels - virtual S32 maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars = S32_MAX, - BOOL end_on_word_boundary = FALSE, const BOOL use_embedded = FALSE, - F32* drawn_pixels = NULL) const; + S32 maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_chars = S32_MAX, BOOL end_on_word_boundary = FALSE, BOOL use_embedded = FALSE, F32* drawn_pixels = NULL) const; // Returns the index of the first complete characters from text that can be drawn in max_pixels // given that the character at start_pos should be the last character (or as close to last as possible). - virtual S32 firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_len, S32 start_pos=S32_MAX, S32 max_chars = S32_MAX) const; + S32 firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_len, S32 start_pos=S32_MAX, S32 max_chars = S32_MAX) const; // Returns the index of the character closest to pixel position x (ignoring text to the right of max_pixels and max_chars) - virtual 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, S32 char_offset, F32 x, F32 max_pixels=F32_MAX, S32 max_chars = S32_MAX, BOOL round = TRUE, BOOL use_embedded = FALSE) const; + + void addEmbeddedChar( llwchar wc, LLTexture* image, const std::string& label) const; + void addEmbeddedChar( llwchar wc, LLTexture* image, const LLWString& label) const; + void removeEmbeddedChar( llwchar wc ) const; + BOOL addChar(const llwchar wch) const; - LLImageGL *getImageGL() const; + const LLFontDescriptor& getFontDesc() const; - void addEmbeddedChar( llwchar wc, LLTexture* image, const std::string& label) const; - void addEmbeddedChar( llwchar wc, LLTexture* image, const LLWString& label) const; - void removeEmbeddedChar( llwchar wc ) const; + + static void initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::string& app_dir, const std::vector& xui_paths, bool create_gl_textures = true); + + // Load sans-serif, sans-serif-small, etc. + // Slow, requires multiple seconds to load fonts. + static bool loadDefaultFonts(); + static void destroyDefaultFonts(); + static void destroyAllGL(); + + // Takes a string with potentially several flags, i.e. "NORMAL|BOLD|ITALIC" + static U8 getStyleFromString(const std::string &style); static std::string nameFromFont(const LLFontGL* fontp); @@ -218,28 +160,7 @@ public: static std::string nameFromVAlign(LLFontGL::VAlign align); static LLFontGL::VAlign vAlignFromName(const std::string& name); - static void setFontDisplay(BOOL flag) { sDisplayFont = flag ; } - -protected: - struct embedded_data_t - { - embedded_data_t(LLImageGL* image, const LLWString& label) : mImage(image), mLabel(label) {} - LLPointer mImage; - LLWString mLabel; - }; - const embedded_data_t* getEmbeddedCharData(const llwchar wch) const; - F32 getEmbeddedCharAdvance(const embedded_data_t* ext_data) const; - void clearEmbeddedChars(); - 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; - -public: - static F32 sVertDPI; - static F32 sHorizDPI; - static F32 sScaleX; - static F32 sScaleY; - static BOOL sDisplayFont ; - static std::string sAppDir; // For loading fonts + static void setFontDisplay(BOOL flag) { sDisplayFont = flag; } static LLFontGL* getFontMonospace(); static LLFontGL* getFontSansSerifSmall(); @@ -252,32 +173,50 @@ public: // Use with legacy names like "SANSSERIF_SMALL" or "OCRA" static LLFontGL* getFontByName(const std::string& name); + static std::string getFontPathLocal(); + static std::string getFontPathSystem(); + + static LLCoordFont sCurOrigin; + static std::vector sOriginStack; + static LLColor4 sShadowColor; + static F32 sVertDPI; + static F32 sHorizDPI; + static F32 sScaleX; + static F32 sScaleY; + static BOOL sDisplayFont ; + static std::string sAppDir; // For loading fonts + +private: + friend class LLFontRegistry; friend class LLTextBillboard; friend class LLHUDText; -protected: - /*virtual*/ BOOL addChar(const llwchar wch) const; + LLFontGL(const LLFontGL &source); + LLFontGL &operator=(const LLFontGL &source); -protected: - typedef std::map embedded_map_t; - mutable embedded_map_t mEmbeddedChars; - LLFontDescriptor mFontDescriptor; + LLPointer mFontFreetype; - // Registry holds all instantiated fonts. - static LLFontRegistry* sFontRegistry; + struct embedded_data_t + { + embedded_data_t(LLImageGL* image, const LLWString& label) : mImage(image), mLabel(label) {} + LLPointer mImage; + LLWString mLabel; + }; -public: - static std::string getFontPathLocal(); - static std::string getFontPathSystem(); + typedef std::map embedded_map_t; + mutable embedded_map_t mEmbeddedChars; - static LLCoordFont sCurOrigin; - static std::vector sOriginStack; + const embedded_data_t* getEmbeddedCharData(llwchar wch) const; + F32 getEmbeddedCharAdvance(const embedded_data_t* ext_data) const; + void clearEmbeddedChars(); + 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; - const LLFontDescriptor &getFontDesc() const { return mFontDescriptor; } - void setFontDesc(const LLFontDescriptor& font_desc) { mFontDescriptor = font_desc; } + // Registry holds all instantiated fonts. + static LLFontRegistry* sFontRegistry; }; #endif diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp index 3b5c62a5ea..553e7b8f9d 100644 --- a/indra/llrender/llfontregistry.cpp +++ b/indra/llrender/llfontregistry.cpp @@ -33,8 +33,9 @@ #include "linden_common.h" #include "llgl.h" -#include "llfontregistry.h" +#include "llfontfreetype.h" #include "llfontgl.h" +#include "llfontregistry.h" #include #include "llcontrol.h" #include "lldir.h" @@ -382,7 +383,14 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc) if (it != mFontMap.end()) { llinfos << "-- matching font exists: " << nearest_exact_desc.getName() << " size " << nearest_exact_desc.getSize() << " style " << ((S32) nearest_exact_desc.getStyle()) << llendl; - return it->second; + + // copying underlying Freetype font, and storing in LLFontGL with requested font descriptor + LLFontGL *font = new LLFontGL; + font->mFontDescriptor = desc; + font->mFontFreetype = it->second->mFontFreetype; + mFontMap[desc] = font; + + return font; } // Build list of font names to look for. @@ -410,10 +418,11 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc) llwarns << "createFont failed, no file names specified" << llendl; return NULL; } - LLFontList *fontlistp = new LLFontList; + + LLFontFreetype::font_vector_t fontlist; LLFontGL *result = NULL; - // Snarf all fonts we can into fontlistp. First will get pulled + // Snarf all fonts we can into fontlist. First will get pulled // off the list and become the "head" font, set to non-fallback. // Rest will consitute the fallback list. BOOL is_first_found = TRUE; @@ -455,23 +464,28 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc) is_first_found = false; } else - fontlistp->addAtEnd(fontp); + { + fontlist.push_back(fontp->mFontFreetype); + } } } - if (result && !fontlistp->empty()) + + if (result && !fontlist.empty()) { - result->setFallbackFont(fontlistp); + result->mFontFreetype->setFallbackFonts(fontlist); } - norm_desc.setStyle(match_desc->getStyle()); if (result) - result->setFontDesc(norm_desc); - - if (!result) + { + result->mFontFreetype->setStyle(match_desc->getStyle()); + result->mFontDescriptor = desc; + } + else { llwarns << "createFont failed in some way" << llendl; } - mFontMap[norm_desc] = result; + + mFontMap[desc] = result; return result; } @@ -511,21 +525,19 @@ void LLFontRegistry::destroyGL() } } -LLFontGL *LLFontRegistry::getFont(const LLFontDescriptor& orig_desc) +LLFontGL *LLFontRegistry::getFont(const LLFontDescriptor& desc) { - LLFontDescriptor norm_desc = orig_desc.normalize(); - - font_reg_map_t::iterator it = mFontMap.find(norm_desc); + font_reg_map_t::iterator it = mFontMap.find(desc); if (it != mFontMap.end()) return it->second; else { - LLFontGL *fontp = createFont(orig_desc); + LLFontGL *fontp = createFont(desc); if (!fontp) { - llwarns << "getFont failed, name " << orig_desc.getName() - <<" style=[" << ((S32) orig_desc.getStyle()) << "]" - << " size=[" << orig_desc.getSize() << "]" << llendl; + llwarns << "getFont failed, name " << desc.getName() + <<" style=[" << ((S32) desc.getStyle()) << "]" + << " size=[" << desc.getSize() << "]" << llendl; } return fontp; } @@ -653,3 +665,8 @@ void LLFontRegistry::dump() } } } + +const string_vec_t& LLFontRegistry::getUltimateFallbackList() const +{ + return mUltimateFallbackList; +} diff --git a/indra/llrender/llfontregistry.h b/indra/llrender/llfontregistry.h index 198ca0b920..4da4ca48bb 100644 --- a/indra/llrender/llfontregistry.h +++ b/indra/llrender/llfontregistry.h @@ -98,7 +98,7 @@ public: void dump(); - const string_vec_t& getUltimateFallbackList() const { return mUltimateFallbackList; } + const string_vec_t& getUltimateFallbackList() const; private: LLFontGL *createFont(const LLFontDescriptor& desc); -- cgit v1.2.3 From eb853f55c07ae4a3c3f2aa05fbabcf2e4b4dc115 Mon Sep 17 00:00:00 2001 From: Richard Nelson Date: Tue, 4 Aug 2009 01:12:59 +0000 Subject: svn merge -r 128442:129343 svn+ssh://svn.lindenlab.com/svn/linden/branches/skinning/skinning-18 into svn+ssh://svn.lindenlab.com/svn/linden/branches/viewer/viewer-2.0.0-3 --- indra/llrender/llfontfreetype.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llrender') diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp index 91a95cdd25..62534969b7 100644 --- a/indra/llrender/llfontfreetype.cpp +++ b/indra/llrender/llfontfreetype.cpp @@ -237,7 +237,7 @@ F32 LLFontFreetype::getXAdvance(llwchar wch) const if (mFTFace == NULL) return 0.0; - llassert(!mIsFallback); + //llassert(!mIsFallback); U32 glyph_index; // Return existing info only if it is current @@ -308,7 +308,7 @@ F32 LLFontFreetype::getXKerning(llwchar char_left, llwchar char_right) const if (mFTFace == NULL) return 0.0; - llassert(!mIsFallback); + //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. -- cgit v1.2.3