Merge branch 'contribution/emoji'
commit
5440464a9c
|
|
@ -46,6 +46,7 @@ indra/newview/dbghelp.dll
|
|||
indra/newview/filters.xml
|
||||
indra/newview/fmod.dll
|
||||
indra/newview/fmod.log
|
||||
indra/newview/fonts
|
||||
indra/newview/mozilla-theme
|
||||
indra/newview/mozilla-universal-darwin.tgz
|
||||
indra/newview/pilot.txt
|
||||
|
|
|
|||
128
autobuild.xml
128
autobuild.xml
|
|
@ -807,6 +807,36 @@
|
|||
<key>version</key>
|
||||
<string>2.01.07.555883</string>
|
||||
</map>
|
||||
<key>fonts</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
<string>Copyright various</string>
|
||||
<key>description</key>
|
||||
<string>Viewer fonts</string>
|
||||
<key>license</key>
|
||||
<string>Various open source</string>
|
||||
<key>license_file</key>
|
||||
<string>LICENSES/fonts.txt</string>
|
||||
<key>name</key>
|
||||
<string>fonts</string>
|
||||
<key>platforms</key>
|
||||
<map>
|
||||
<key>common</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>65b89f06d9b698b376e1736216dd5623</string>
|
||||
<key>url</key>
|
||||
<string>viewer_fonts-1.0-1.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>common</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>1.0</string>
|
||||
</map>
|
||||
<key>fontconfig</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
|
|
@ -916,9 +946,9 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>7ee200d6b5fa282c7f973ade5615aa86</string>
|
||||
<string>d8f5b352176d5c582d91ce936a700b2c</string>
|
||||
<key>url</key>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78594/744011/freetype-2.4.4.557047-windows-557047.tar.bz2</string>
|
||||
<string>freetype-2.10.1.0-windows-72.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows</string>
|
||||
|
|
@ -928,9 +958,9 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>69307aaba16ac71531c9c4d930ace993</string>
|
||||
<string>aa8be83cdfcd5cda0343ea72e7d662ca</string>
|
||||
<key>url</key>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/78593/744010/freetype-2.4.4.557047-windows64-557047.tar.bz2</string>
|
||||
<string>freetype-2.10.1.0-windows64-72.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
|
|
@ -1401,6 +1431,96 @@
|
|||
<key>version</key>
|
||||
<string>2012.1-2</string>
|
||||
</map>
|
||||
<key>icu4c</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
<string>Copyright (c) 1995-2011 International Business Machines Corporation and others <http://source.icu-project.org></string>
|
||||
<key>description</key>
|
||||
<string>ICU is a mature, widely used set of C/C++ and Java libraries providing Unicode and Globalization support for software applications. ICU is widely portable and gives applications the same results on all platforms and between C/C++ and Java software.</string>
|
||||
<key>license</key>
|
||||
<string>ICU, permissive non-copyleft free software license</string>
|
||||
<key>license_file</key>
|
||||
<string>LICENSES/icu.txt</string>
|
||||
<key>name</key>
|
||||
<string>icu4c</string>
|
||||
<key>platforms</key>
|
||||
<map>
|
||||
<key>darwin</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>910edfc0b936389bc8804c42d1008aa8</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/icu4c_3p-update-icu4c/rev/295486/arch/Darwin/installer/icu4c-4.8.1-darwin-295486.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
</map>
|
||||
<key>darwin64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>2c34cb4e62d1f155d5dad798e69d03c8</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/466/1005/icu4c-4.8.1-darwin64-500388.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
</map>
|
||||
<key>linux</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>0a4423cfd26409f33ae81fb9806a9972</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/p64_3p-icu4c/rev/314152/arch/Linux/installer/icu4c-4.8.1-linux-314152.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
</map>
|
||||
<key>linux64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>b327031733c36efe2eee4582aefb2d66</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/462/995/icu4c-4.8.1-linux64-500388.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
</map>
|
||||
<key>windows</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>af354f6ab6d2cecf266c79031977e3e0</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/492/1078/icu4c-4.8.1-windows-500388.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
</map>
|
||||
<key>windows64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>e8b20cea748b90ea18bb63dfba06e059</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/491/1075/icu4c-4.8.1-windows64-500388.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>4.8.1</string>
|
||||
</map>
|
||||
<key>jpeglib</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ set(cmake_SOURCE_FILES
|
|||
FindBerkeleyDB.cmake
|
||||
FindGLH.cmake
|
||||
FindHUNSPELL.cmake
|
||||
FindICU4C.cmake
|
||||
FindJsonCpp.cmake
|
||||
FindNDOF.cmake
|
||||
FindOpenJPEG.cmake
|
||||
|
|
@ -45,6 +46,7 @@ set(cmake_SOURCE_FILES
|
|||
GoogleMock.cmake
|
||||
Havok.cmake
|
||||
Hunspell.cmake
|
||||
ICU4C.cmake
|
||||
JPEG.cmake
|
||||
JsonCpp.cmake
|
||||
LLAddBuildTest.cmake
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
# -*- cmake -*-
|
||||
|
||||
# - Find ICU4C
|
||||
# This module defines
|
||||
# ICU4C_INCLUDE_DIR, where to find headers
|
||||
# ICU4C_LIBRARY, the library needed to use ICU4C.
|
||||
# ICU4C_FOUND, If false, do not try to use ICU4C.
|
||||
|
||||
find_path(ICU4C_INCLUDE_DIR uchar.h
|
||||
PATH_SUFFIXES unicode
|
||||
)
|
||||
|
||||
set(ICU4C_NAMES ${ICU4C_NAMES} icuuc)
|
||||
find_library(ICU4C_LIBRARY
|
||||
NAMES ${ICU4C_NAMES}
|
||||
)
|
||||
|
||||
if (ICU4C_LIBRARY AND ICU4C_INCLUDE_DIR)
|
||||
set(ICU4C_FOUND "YES")
|
||||
else (ICU4C_LIBRARY AND ICU4C_INCLUDE_DIR)
|
||||
set(ICU4C_FOUND "NO")
|
||||
endif (ICU4C_LIBRARY AND ICU4C_INCLUDE_DIR)
|
||||
|
||||
if (ICU4C_FOUND)
|
||||
message(STATUS "Found ICU4C: Library in '${ICU4C_LIBRARY}' and header in '${ICU4C_INCLUDE_DIR}' ")
|
||||
else (ICU4C_FOUND)
|
||||
message(FATAL_ERROR " * * *\nCould not find ICU4C library! * * *")
|
||||
endif (ICU4C_FOUND)
|
||||
|
||||
mark_as_advanced(
|
||||
ICU4C_LIBRARY
|
||||
ICU4C_INCLUDE_DIR
|
||||
)
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
# -*- cmake -*-
|
||||
include(Prebuilt)
|
||||
|
||||
set(ICU4C_FIND_QUIETLY ON)
|
||||
set(ICU4C_FIND_REQUIRED ON)
|
||||
|
||||
if (USESYSTEMLIBS)
|
||||
include(FindICU4C)
|
||||
else (USESYSTEMLIBS)
|
||||
use_prebuilt_binary(icu4c)
|
||||
if (WINDOWS)
|
||||
set(ICU4C_LIBRARY icuuc)
|
||||
#elseif(DARWIN)
|
||||
# set(ICU4C_LIBRARY ...)
|
||||
#elseif(LINUX)
|
||||
# set(ICU4C_LIBRARY ...)
|
||||
else()
|
||||
message(FATAL_ERROR "Invalid platform")
|
||||
endif()
|
||||
set(ICU4C_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/unicode)
|
||||
use_prebuilt_binary(dictionaries)
|
||||
endif (USESYSTEMLIBS)
|
||||
|
|
@ -10,3 +10,4 @@ if (NOT USESYSTEMLIBS)
|
|||
use_prebuilt_binary(slvoice)
|
||||
endif(NOT USESYSTEMLIBS)
|
||||
|
||||
use_prebuilt_binary(fonts)
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
project(llcommon)
|
||||
|
||||
include(00-Common)
|
||||
include(ICU4C)
|
||||
include(LLCommon)
|
||||
include(bugsplat)
|
||||
include(Linking)
|
||||
|
|
@ -289,6 +290,7 @@ target_link_libraries(
|
|||
${APRUTIL_LIBRARIES}
|
||||
${APR_LIBRARIES}
|
||||
${EXPAT_LIBRARIES}
|
||||
${ICU4C_LIBRARY}
|
||||
${JSONCPP_LIBRARIES}
|
||||
${ZLIB_LIBRARIES}
|
||||
${WINDOWS_LIBRARIES}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include "llerror.h"
|
||||
#include "llfasttimer.h"
|
||||
#include "llsd.h"
|
||||
#include <unicode/uchar.h>
|
||||
#include <vector>
|
||||
|
||||
#if LL_WINDOWS
|
||||
|
|
@ -872,6 +873,31 @@ std::string LLStringOps::sDayFormat;
|
|||
std::string LLStringOps::sAM;
|
||||
std::string LLStringOps::sPM;
|
||||
|
||||
// static
|
||||
bool LLStringOps::isEmoji(llwchar wch)
|
||||
{
|
||||
switch (ublock_getCode(wch))
|
||||
{
|
||||
case UBLOCK_MISCELLANEOUS_SYMBOLS:
|
||||
case UBLOCK_DINGBATS:
|
||||
case UBLOCK_MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS:
|
||||
case UBLOCK_EMOTICONS:
|
||||
case UBLOCK_TRANSPORT_AND_MAP_SYMBOLS:
|
||||
#if U_ICU_VERSION_MAJOR_NUM > 56
|
||||
// Boost uses ICU so we can't update it independently
|
||||
case UBLOCK_SUPPLEMENTAL_SYMBOLS_AND_PICTOGRAPHS:
|
||||
#endif // U_ICU_VERSION_MAJOR_NUM > 56
|
||||
return true;
|
||||
default:
|
||||
#if U_ICU_VERSION_MAJOR_NUM > 56
|
||||
return false;
|
||||
#else
|
||||
// See https://en.wikipedia.org/wiki/Supplemental_Symbols_and_Pictographs
|
||||
return wch >= 0x1F900 && wch <= 0x1F9FF;
|
||||
#endif // U_ICU_VERSION_MAJOR_NUM > 56
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
S32 LLStringOps::collate(const llwchar* a, const llwchar* b)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -187,6 +187,8 @@ public:
|
|||
static bool isAlnum(char a) { return isalnum((unsigned char)a) != 0; }
|
||||
static bool isAlnum(llwchar a) { return iswalnum(a) != 0; }
|
||||
|
||||
static bool isEmoji(llwchar wch);
|
||||
|
||||
static S32 collate(const char* a, const char* b) { return strcoll(a, b); }
|
||||
static S32 collate(const llwchar* a, const llwchar* b);
|
||||
|
||||
|
|
|
|||
|
|
@ -30,152 +30,165 @@
|
|||
#include "llfontbitmapcache.h"
|
||||
|
||||
LLFontBitmapCache::LLFontBitmapCache()
|
||||
: LLTrace::MemTrackable<LLFontBitmapCache>("LLFontBitmapCache"),
|
||||
mNumComponents(0),
|
||||
mBitmapWidth(0),
|
||||
mBitmapHeight(0),
|
||||
mBitmapNum(-1),
|
||||
mMaxCharWidth(0),
|
||||
mMaxCharHeight(0),
|
||||
mCurrentOffsetX(1),
|
||||
mCurrentOffsetY(1)
|
||||
: LLTrace::MemTrackable<LLFontBitmapCache>("LLFontBitmapCache")
|
||||
, mBitmapWidth(0)
|
||||
, mBitmapHeight(0)
|
||||
, mMaxCharWidth(0)
|
||||
, mMaxCharHeight(0)
|
||||
{
|
||||
// *TODO: simplify with initializer after VS2017
|
||||
for (U32 idx = 0, cnt = static_cast<U32>(EFontGlyphType::Count); idx < cnt; idx++)
|
||||
{
|
||||
mCurrentOffsetX[idx] = 1;
|
||||
mCurrentOffsetY[idx] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
LLFontBitmapCache::~LLFontBitmapCache()
|
||||
{
|
||||
}
|
||||
|
||||
void LLFontBitmapCache::init(S32 num_components,
|
||||
S32 max_char_width,
|
||||
void LLFontBitmapCache::init(S32 max_char_width,
|
||||
S32 max_char_height)
|
||||
{
|
||||
reset();
|
||||
|
||||
mNumComponents = num_components;
|
||||
mMaxCharWidth = max_char_width;
|
||||
mMaxCharHeight = max_char_height;
|
||||
}
|
||||
|
||||
LLImageRaw *LLFontBitmapCache::getImageRaw(U32 bitmap_num) const
|
||||
{
|
||||
if (bitmap_num >= mImageRawVec.size())
|
||||
return NULL;
|
||||
|
||||
return mImageRawVec[bitmap_num];
|
||||
}
|
||||
|
||||
LLImageGL *LLFontBitmapCache::getImageGL(U32 bitmap_num) const
|
||||
{
|
||||
if (bitmap_num >= mImageGLVec.size())
|
||||
return NULL;
|
||||
|
||||
return mImageGLVec[bitmap_num];
|
||||
}
|
||||
|
||||
|
||||
BOOL LLFontBitmapCache::nextOpenPos(S32 width, S32 &pos_x, S32 &pos_y, S32& bitmap_num)
|
||||
{
|
||||
if ((mBitmapNum<0) || (mCurrentOffsetX + width + 1) > mBitmapWidth)
|
||||
S32 image_width = mMaxCharWidth * 20;
|
||||
S32 pow_iw = 2;
|
||||
while (pow_iw < image_width)
|
||||
{
|
||||
if ((mBitmapNum<0) || (mCurrentOffsetY + 2*mMaxCharHeight + 2) > mBitmapHeight)
|
||||
pow_iw <<= 1;
|
||||
}
|
||||
image_width = pow_iw;
|
||||
image_width = llmin(512, image_width); // Don't make bigger than 512x512, ever.
|
||||
|
||||
mBitmapWidth = image_width;
|
||||
mBitmapHeight = image_width;
|
||||
}
|
||||
|
||||
LLImageRaw *LLFontBitmapCache::getImageRaw(EFontGlyphType bitmap_type, U32 bitmap_num) const
|
||||
{
|
||||
const U32 bitmap_idx = static_cast<U32>(bitmap_type);
|
||||
if (bitmap_type >= EFontGlyphType::Count || bitmap_num >= mImageRawVec[bitmap_idx].size())
|
||||
return nullptr;
|
||||
|
||||
return mImageRawVec[bitmap_idx][bitmap_num];
|
||||
}
|
||||
|
||||
LLImageGL *LLFontBitmapCache::getImageGL(EFontGlyphType bitmap_type, U32 bitmap_num) const
|
||||
{
|
||||
const U32 bitmap_idx = static_cast<U32>(bitmap_type);
|
||||
if (bitmap_type >= EFontGlyphType::Count || bitmap_num >= mImageGLVec[bitmap_idx].size())
|
||||
return nullptr;
|
||||
|
||||
return mImageGLVec[bitmap_idx][bitmap_num];
|
||||
}
|
||||
|
||||
|
||||
BOOL LLFontBitmapCache::nextOpenPos(S32 width, S32& pos_x, S32& pos_y, EFontGlyphType bitmap_type, U32& bitmap_num)
|
||||
{
|
||||
if (bitmap_type >= EFontGlyphType::Count)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
const U32 bitmap_idx = static_cast<U32>(bitmap_type);
|
||||
if (mImageRawVec[bitmap_idx].empty() || (mCurrentOffsetX[bitmap_idx] + width + 1) > mBitmapWidth)
|
||||
{
|
||||
if ((mImageRawVec[bitmap_idx].empty()) || (mCurrentOffsetY[bitmap_idx] + 2*mMaxCharHeight + 2) > mBitmapHeight)
|
||||
{
|
||||
// We're out of space in the current image, or no image
|
||||
// has been allocated yet. Make a new one.
|
||||
|
||||
mImageRawVec.push_back(new LLImageRaw);
|
||||
mBitmapNum = mImageRawVec.size()-1;
|
||||
LLImageRaw *image_raw = getImageRaw(mBitmapNum);
|
||||
S32 num_components = getNumComponents(bitmap_type);
|
||||
mImageRawVec[bitmap_idx].push_back(new LLImageRaw(mBitmapWidth, mBitmapHeight, num_components));
|
||||
bitmap_num = mImageRawVec[bitmap_idx].size() - 1;
|
||||
|
||||
LLImageRaw* image_raw = getImageRaw(bitmap_type, bitmap_num);
|
||||
if (EFontGlyphType::Grayscale == bitmap_type)
|
||||
{
|
||||
image_raw->clear(255, 0);
|
||||
}
|
||||
|
||||
// Make corresponding GL image.
|
||||
mImageGLVec.push_back(new LLImageGL(FALSE));
|
||||
LLImageGL *image_gl = getImageGL(mBitmapNum);
|
||||
|
||||
S32 image_width = mMaxCharWidth * 20;
|
||||
S32 pow_iw = 2;
|
||||
while (pow_iw < image_width)
|
||||
{
|
||||
pow_iw *= 2;
|
||||
}
|
||||
image_width = pow_iw;
|
||||
image_width = llmin(512, image_width); // Don't make bigger than 512x512, ever.
|
||||
S32 image_height = image_width;
|
||||
|
||||
image_raw->resize(image_width, image_height, mNumComponents);
|
||||
|
||||
mBitmapWidth = image_width;
|
||||
mBitmapHeight = image_height;
|
||||
|
||||
switch (mNumComponents)
|
||||
{
|
||||
case 1:
|
||||
image_raw->clear();
|
||||
break;
|
||||
case 2:
|
||||
image_raw->clear(255, 0);
|
||||
break;
|
||||
}
|
||||
mImageGLVec[bitmap_idx].push_back(new LLImageGL(image_raw, false));
|
||||
LLImageGL* image_gl = getImageGL(bitmap_type, bitmap_num);
|
||||
|
||||
// Start at beginning of the new image.
|
||||
mCurrentOffsetX = 1;
|
||||
mCurrentOffsetY = 1;
|
||||
mCurrentOffsetX[bitmap_idx] = 1;
|
||||
mCurrentOffsetY[bitmap_idx] = 1;
|
||||
|
||||
// Attach corresponding GL texture.
|
||||
image_gl->createGLTexture(0, image_raw);
|
||||
// Attach corresponding GL texture. (*TODO: is this needed?)
|
||||
gGL.getTexUnit(0)->bind(image_gl);
|
||||
image_gl->setFilteringOption(LLTexUnit::TFO_POINT); // was setMipFilterNearest(TRUE, TRUE);
|
||||
|
||||
claimMem(image_raw);
|
||||
claimMem(image_gl);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Move to next row in current image.
|
||||
mCurrentOffsetX = 1;
|
||||
mCurrentOffsetY += mMaxCharHeight + 1;
|
||||
mCurrentOffsetX[bitmap_idx] = 1;
|
||||
mCurrentOffsetY[bitmap_idx] += mMaxCharHeight + 1;
|
||||
}
|
||||
}
|
||||
|
||||
pos_x = mCurrentOffsetX;
|
||||
pos_y = mCurrentOffsetY;
|
||||
bitmap_num = mBitmapNum;
|
||||
pos_x = mCurrentOffsetX[bitmap_idx];
|
||||
pos_y = mCurrentOffsetY[bitmap_idx];
|
||||
bitmap_num = getNumBitmaps(bitmap_type) - 1;
|
||||
|
||||
mCurrentOffsetX += width + 1;
|
||||
mCurrentOffsetX[bitmap_idx] += width + 1;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLFontBitmapCache::destroyGL()
|
||||
{
|
||||
for (std::vector<LLPointer<LLImageGL> >::iterator it = mImageGLVec.begin();
|
||||
it != mImageGLVec.end(); ++it)
|
||||
for (U32 idx = 0, cnt = static_cast<U32>(EFontGlyphType::Count); idx < cnt; idx++)
|
||||
{
|
||||
(*it)->destroyGLTexture();
|
||||
for (std::vector<LLPointer<LLImageGL> >::iterator it = mImageGLVec[idx].begin(); it != mImageGLVec[idx].end(); ++it)
|
||||
{
|
||||
(*it)->destroyGLTexture();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLFontBitmapCache::reset()
|
||||
{
|
||||
for (std::vector<LLPointer<LLImageRaw> >::iterator it = mImageRawVec.begin(), end_it = mImageRawVec.end();
|
||||
it != end_it;
|
||||
++it)
|
||||
for (U32 idx = 0, cnt = static_cast<U32>(EFontGlyphType::Count); idx < cnt; idx++)
|
||||
{
|
||||
disclaimMem(**it);
|
||||
for (std::vector<LLPointer<LLImageRaw> >::iterator it = mImageRawVec[idx].begin(), end_it = mImageRawVec[idx].end(); it != end_it; ++it)
|
||||
{
|
||||
disclaimMem(**it);
|
||||
}
|
||||
mImageRawVec[idx].clear();
|
||||
}
|
||||
mImageRawVec.clear();
|
||||
|
||||
for (std::vector<LLPointer<LLImageGL> >::iterator it = mImageGLVec.begin(), end_it = mImageGLVec.end();
|
||||
it != end_it;
|
||||
++it)
|
||||
for (U32 idx = 0, cnt = static_cast<U32>(EFontGlyphType::Count); idx < cnt; idx++)
|
||||
{
|
||||
disclaimMem(**it);
|
||||
for (std::vector<LLPointer<LLImageGL> >::iterator it = mImageGLVec[idx].begin(), end_it = mImageGLVec[idx].end(); it != end_it; ++it)
|
||||
{
|
||||
disclaimMem(**it);
|
||||
}
|
||||
mImageGLVec[idx].clear();
|
||||
mCurrentOffsetX[idx] = 1;
|
||||
mCurrentOffsetY[idx] = 1;
|
||||
}
|
||||
mImageGLVec.clear();
|
||||
|
||||
mBitmapWidth = 0;
|
||||
mBitmapHeight = 0;
|
||||
mBitmapNum = -1;
|
||||
mCurrentOffsetX = 1;
|
||||
mCurrentOffsetY = 1;
|
||||
}
|
||||
|
||||
//static
|
||||
U32 LLFontBitmapCache::getNumComponents(EFontGlyphType bitmap_type)
|
||||
{
|
||||
switch (bitmap_type)
|
||||
{
|
||||
case EFontGlyphType::Grayscale:
|
||||
return 2;
|
||||
case EFontGlyphType::Color:
|
||||
return 4;
|
||||
default:
|
||||
llassert(false);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,14 @@
|
|||
#include <vector>
|
||||
#include "lltrace.h"
|
||||
|
||||
enum class EFontGlyphType : U32
|
||||
{
|
||||
Grayscale = 0,
|
||||
Color,
|
||||
Count,
|
||||
Unspecified,
|
||||
};
|
||||
|
||||
// Maintain a collection of bitmaps containing rendered glyphs.
|
||||
// Generalizes the single-bitmap logic from LLFontFreetype and LLFontGL.
|
||||
class LLFontBitmapCache : public LLTrace::MemTrackable<LLFontBitmapCache>
|
||||
|
|
@ -39,35 +47,35 @@ public:
|
|||
~LLFontBitmapCache();
|
||||
|
||||
// Need to call this once, before caching any glyphs.
|
||||
void init(S32 num_components,
|
||||
S32 max_char_width,
|
||||
void init(S32 max_char_width,
|
||||
S32 max_char_height);
|
||||
|
||||
void reset();
|
||||
|
||||
BOOL nextOpenPos(S32 width, S32 &posX, S32 &posY, S32 &bitmapNum);
|
||||
BOOL nextOpenPos(S32 width, S32& posX, S32& posY, EFontGlyphType bitmapType, U32& bitmapNum);
|
||||
|
||||
void destroyGL();
|
||||
|
||||
LLImageRaw *getImageRaw(U32 bitmapNum = 0) const;
|
||||
LLImageGL *getImageGL(U32 bitmapNum = 0) const;
|
||||
|
||||
LLImageRaw* getImageRaw(EFontGlyphType bitmapType, U32 bitmapNum) const;
|
||||
LLImageGL* getImageGL(EFontGlyphType bitmapType, U32 bitmapNum) const;
|
||||
|
||||
S32 getMaxCharWidth() const { return mMaxCharWidth; }
|
||||
S32 getNumComponents() const { return mNumComponents; }
|
||||
U32 getNumBitmaps(EFontGlyphType bitmapType) const { return (bitmapType < EFontGlyphType::Count) ? mImageRawVec[static_cast<U32>(bitmapType)].size() : 0; }
|
||||
S32 getBitmapWidth() const { return mBitmapWidth; }
|
||||
S32 getBitmapHeight() const { return mBitmapHeight; }
|
||||
|
||||
protected:
|
||||
static U32 getNumComponents(EFontGlyphType bitmap_type);
|
||||
|
||||
private:
|
||||
S32 mNumComponents;
|
||||
S32 mBitmapWidth;
|
||||
S32 mBitmapHeight;
|
||||
S32 mBitmapNum;
|
||||
S32 mCurrentOffsetX[static_cast<U32>(EFontGlyphType::Count)];
|
||||
S32 mCurrentOffsetY[static_cast<U32>(EFontGlyphType::Count)];
|
||||
S32 mMaxCharWidth;
|
||||
S32 mMaxCharHeight;
|
||||
S32 mCurrentOffsetX;
|
||||
S32 mCurrentOffsetY;
|
||||
std::vector<LLPointer<LLImageRaw> > mImageRawVec;
|
||||
std::vector<LLPointer<LLImageGL> > mImageGLVec;
|
||||
std::vector<LLPointer<LLImageRaw>> mImageRawVec[static_cast<U32>(EFontGlyphType::Count)];
|
||||
std::vector<LLPointer<LLImageGL>> mImageGLVec[static_cast<U32>(EFontGlyphType::Count)];
|
||||
};
|
||||
|
||||
#endif //LL_LLFONTBITMAPCACHE_H
|
||||
|
|
|
|||
|
|
@ -40,8 +40,10 @@
|
|||
#include FT_FREETYPE_H
|
||||
#endif
|
||||
|
||||
#include "lldir.h"
|
||||
#include "llerror.h"
|
||||
#include "llimage.h"
|
||||
#include "llimagepng.h"
|
||||
//#include "llimagej2c.h"
|
||||
#include "llmath.h" // Linden math
|
||||
#include "llstring.h"
|
||||
|
|
@ -89,8 +91,9 @@ LLFontManager::~LLFontManager()
|
|||
}
|
||||
|
||||
|
||||
LLFontGlyphInfo::LLFontGlyphInfo(U32 index)
|
||||
LLFontGlyphInfo::LLFontGlyphInfo(U32 index, EFontGlyphType glyph_type)
|
||||
: mGlyphIndex(index),
|
||||
mGlyphType(glyph_type),
|
||||
mWidth(0), // In pixels
|
||||
mHeight(0), // In pixels
|
||||
mXAdvance(0.f), // In pixels
|
||||
|
|
@ -99,10 +102,25 @@ LLFontGlyphInfo::LLFontGlyphInfo(U32 index)
|
|||
mYBitmapOffset(0), // Offset to the origin in the bitmap
|
||||
mXBearing(0), // Distance from baseline to left in pixels
|
||||
mYBearing(0), // Distance from baseline to top in pixels
|
||||
mBitmapNum(0) // Which bitmap in the bitmap cache contains this glyph
|
||||
mBitmapEntry(std::make_pair(EFontGlyphType::Unspecified, -1)) // Which bitmap in the bitmap cache contains this glyph
|
||||
{
|
||||
}
|
||||
|
||||
LLFontGlyphInfo::LLFontGlyphInfo(const LLFontGlyphInfo& fgi)
|
||||
: mGlyphIndex(fgi.mGlyphIndex)
|
||||
, mGlyphType(fgi.mGlyphType)
|
||||
, mWidth(fgi.mWidth)
|
||||
, mHeight(fgi.mHeight)
|
||||
, mXAdvance(fgi.mXAdvance)
|
||||
, mYAdvance(fgi.mYAdvance)
|
||||
, mXBitmapOffset(fgi.mXBitmapOffset)
|
||||
, mYBitmapOffset(fgi.mYBitmapOffset)
|
||||
, mXBearing(fgi.mXBearing)
|
||||
, mYBearing(fgi.mYBearing)
|
||||
{
|
||||
mBitmapEntry = fgi.mBitmapEntry;
|
||||
}
|
||||
|
||||
LLFontFreetype::LLFontFreetype()
|
||||
: LLTrace::MemTrackable<LLFontFreetype>("LLFontFreetype"),
|
||||
mFontBitmapCachep(new LLFontBitmapCache),
|
||||
|
|
@ -157,7 +175,7 @@ void ft_close_cb(FT_Stream stream) {
|
|||
}
|
||||
#endif
|
||||
|
||||
BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback, S32 face_n)
|
||||
BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, bool is_fallback, S32 face_n)
|
||||
{
|
||||
// Don't leak face objects. This is also needed to deal with
|
||||
// changed font file names.
|
||||
|
|
@ -221,7 +239,7 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v
|
|||
S32 max_char_width = ll_round(0.5f + (x_max - x_min));
|
||||
S32 max_char_height = ll_round(0.5f + (y_max - y_min));
|
||||
|
||||
mFontBitmapCachep->init(components, max_char_width, max_char_height);
|
||||
mFontBitmapCachep->init(max_char_width, max_char_height);
|
||||
claimMem(mFontBitmapCachep);
|
||||
|
||||
|
||||
|
|
@ -234,7 +252,7 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v
|
|||
if (!mIsFallback)
|
||||
{
|
||||
// Add the default glyph
|
||||
addGlyphFromFont(this, 0, 0);
|
||||
addGlyphFromFont(this, 0, 0, EFontGlyphType::Grayscale);
|
||||
}
|
||||
|
||||
mName = filename;
|
||||
|
|
@ -327,14 +345,11 @@ void LLFontFreetype::clearFontStreams()
|
|||
}
|
||||
#endif
|
||||
|
||||
void LLFontFreetype::setFallbackFonts(const font_vector_t &font)
|
||||
void LLFontFreetype::addFallbackFont(const LLPointer<LLFontFreetype>& fallback_font, const char_functor_t& functor)
|
||||
{
|
||||
mFallbackFonts = font;
|
||||
}
|
||||
|
||||
const LLFontFreetype::font_vector_t &LLFontFreetype::getFallbackFonts() const
|
||||
{
|
||||
return mFallbackFonts;
|
||||
// Insert functor fallbacks before generic fallbacks
|
||||
mFallbackFonts.insert((functor) ? std::find_if(mFallbackFonts.begin(), mFallbackFonts.end(), [](const fallback_font_t& fe) { return !fe.second; }) : mFallbackFonts.end(),
|
||||
std::make_pair(fallback_font, functor));
|
||||
}
|
||||
|
||||
F32 LLFontFreetype::getLineHeight() const
|
||||
|
|
@ -358,7 +373,7 @@ F32 LLFontFreetype::getXAdvance(llwchar wch) const
|
|||
return 0.0;
|
||||
|
||||
// Return existing info only if it is current
|
||||
LLFontGlyphInfo* gi = getGlyphInfo(wch);
|
||||
LLFontGlyphInfo* gi = getGlyphInfo(wch, EFontGlyphType::Unspecified);
|
||||
if (gi)
|
||||
{
|
||||
return gi->mXAdvance;
|
||||
|
|
@ -390,10 +405,10 @@ F32 LLFontFreetype::getXKerning(llwchar char_left, llwchar char_right) const
|
|||
return 0.0;
|
||||
|
||||
//llassert(!mIsFallback);
|
||||
LLFontGlyphInfo* left_glyph_info = getGlyphInfo(char_left);;
|
||||
LLFontGlyphInfo* left_glyph_info = getGlyphInfo(char_left, EFontGlyphType::Unspecified);;
|
||||
U32 left_glyph = left_glyph_info ? left_glyph_info->mGlyphIndex : 0;
|
||||
// Kern this puppy.
|
||||
LLFontGlyphInfo* right_glyph_info = getGlyphInfo(char_right);
|
||||
LLFontGlyphInfo* right_glyph_info = getGlyphInfo(char_right, EFontGlyphType::Unspecified);
|
||||
U32 right_glyph = right_glyph_info ? right_glyph_info->mGlyphIndex : 0;
|
||||
|
||||
FT_Vector delta;
|
||||
|
|
@ -424,59 +439,90 @@ BOOL LLFontFreetype::hasGlyph(llwchar wch) const
|
|||
return(mCharGlyphInfoMap.find(wch) != mCharGlyphInfoMap.end());
|
||||
}
|
||||
|
||||
LLFontGlyphInfo* LLFontFreetype::addGlyph(llwchar wch) const
|
||||
LLFontGlyphInfo* LLFontFreetype::addGlyph(llwchar wch, EFontGlyphType glyph_type) const
|
||||
{
|
||||
if (mFTFace == NULL)
|
||||
return FALSE;
|
||||
|
||||
llassert(!mIsFallback);
|
||||
llassert(glyph_type < EFontGlyphType::Count);
|
||||
//LL_DEBUGS() << "Adding new glyph for " << wch << " to font" << LL_ENDL;
|
||||
|
||||
FT_UInt glyph_index;
|
||||
|
||||
// Fallback fonts with a functor have precedence over everything else
|
||||
fallback_font_vector_t::const_iterator it_fallback = mFallbackFonts.cbegin();
|
||||
for (; it_fallback != mFallbackFonts.cend() && it_fallback->second; ++it_fallback)
|
||||
{
|
||||
if (it_fallback->second(wch))
|
||||
{
|
||||
glyph_index = FT_Get_Char_Index(it_fallback->first->mFTFace, wch);
|
||||
if (glyph_index)
|
||||
{
|
||||
return addGlyphFromFont(it_fallback->first, wch, glyph_index, glyph_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize char to glyph map
|
||||
glyph_index = FT_Get_Char_Index(mFTFace, wch);
|
||||
if (glyph_index == 0)
|
||||
{
|
||||
//LL_INFOS() << "Trying to add glyph from fallback font!" << LL_ENDL;
|
||||
font_vector_t::const_iterator iter;
|
||||
for(iter = mFallbackFonts.begin(); iter != mFallbackFonts.end(); iter++)
|
||||
for (; it_fallback != mFallbackFonts.cend(); ++it_fallback)
|
||||
{
|
||||
glyph_index = FT_Get_Char_Index((*iter)->mFTFace, wch);
|
||||
glyph_index = FT_Get_Char_Index(it_fallback->first->mFTFace, wch);
|
||||
if (glyph_index)
|
||||
{
|
||||
return addGlyphFromFont(*iter, wch, glyph_index);
|
||||
return addGlyphFromFont(it_fallback->first, wch, glyph_index, glyph_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char_glyph_info_map_t::iterator iter = mCharGlyphInfoMap.find(wch);
|
||||
if (iter == mCharGlyphInfoMap.end())
|
||||
std::pair<char_glyph_info_map_t::iterator, char_glyph_info_map_t::iterator> range_it = mCharGlyphInfoMap.equal_range(wch);
|
||||
char_glyph_info_map_t::iterator iter =
|
||||
std::find_if(range_it.first, range_it.second, [&glyph_type](const char_glyph_info_map_t::value_type& entry) { return entry.second->mGlyphType == glyph_type; });
|
||||
if (iter == range_it.second)
|
||||
{
|
||||
return addGlyphFromFont(this, wch, glyph_index);
|
||||
return addGlyphFromFont(this, wch, glyph_index, glyph_type);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LLFontGlyphInfo* LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index) const
|
||||
LLFontGlyphInfo* LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index, EFontGlyphType requested_glyph_type) const
|
||||
{
|
||||
if (mFTFace == NULL)
|
||||
return NULL;
|
||||
|
||||
llassert(!mIsFallback);
|
||||
fontp->renderGlyph(glyph_index);
|
||||
fontp->renderGlyph(requested_glyph_type, glyph_index);
|
||||
|
||||
EFontGlyphType bitmap_glyph_type = EFontGlyphType::Unspecified;
|
||||
switch (fontp->mFTFace->glyph->bitmap.pixel_mode)
|
||||
{
|
||||
case FT_PIXEL_MODE_MONO:
|
||||
case FT_PIXEL_MODE_GRAY:
|
||||
bitmap_glyph_type = EFontGlyphType::Grayscale;
|
||||
break;
|
||||
case FT_PIXEL_MODE_BGRA:
|
||||
bitmap_glyph_type = EFontGlyphType::Color;
|
||||
break;
|
||||
default:
|
||||
llassert_always(true);
|
||||
break;
|
||||
}
|
||||
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);
|
||||
U32 bitmap_num;
|
||||
mFontBitmapCachep->nextOpenPos(width, pos_x, pos_y, bitmap_glyph_type, bitmap_num);
|
||||
mAddGlyphCount++;
|
||||
|
||||
LLFontGlyphInfo* gi = new LLFontGlyphInfo(glyph_index);
|
||||
LLFontGlyphInfo* gi = new LLFontGlyphInfo(glyph_index, requested_glyph_type);
|
||||
gi->mXBitmapOffset = pos_x;
|
||||
gi->mYBitmapOffset = pos_y;
|
||||
gi->mBitmapNum = bitmap_num;
|
||||
gi->mBitmapEntry = std::make_pair(bitmap_glyph_type, bitmap_num);
|
||||
gi->mWidth = width;
|
||||
gi->mHeight = height;
|
||||
gi->mXBearing = fontp->mFTFace->glyph->bitmap_left;
|
||||
|
|
@ -487,8 +533,12 @@ LLFontGlyphInfo* LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, l
|
|||
|
||||
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 (requested_glyph_type != bitmap_glyph_type)
|
||||
{
|
||||
LLFontGlyphInfo* gi_temp = new LLFontGlyphInfo(*gi);
|
||||
gi_temp->mGlyphType = bitmap_glyph_type;
|
||||
insertGlyphInfo(wch, gi_temp);
|
||||
}
|
||||
|
||||
if (fontp->mFTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO
|
||||
|| fontp->mFTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY)
|
||||
|
|
@ -523,62 +573,63 @@ LLFontGlyphInfo* LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, l
|
|||
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;
|
||||
}
|
||||
setSubImageLuminanceAlpha(pos_x,
|
||||
pos_y,
|
||||
bitmap_num,
|
||||
width,
|
||||
height,
|
||||
buffer_data,
|
||||
buffer_row_stride);
|
||||
|
||||
if (tmp_graydata)
|
||||
delete[] tmp_graydata;
|
||||
}
|
||||
else if (fontp->mFTFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA)
|
||||
{
|
||||
setSubImageBGRA(pos_x,
|
||||
pos_y,
|
||||
bitmap_num,
|
||||
fontp->mFTFace->glyph->bitmap.width,
|
||||
fontp->mFTFace->glyph->bitmap.rows,
|
||||
fontp->mFTFace->glyph->bitmap.buffer,
|
||||
llabs(fontp->mFTFace->glyph->bitmap.pitch));
|
||||
} else {
|
||||
// we don't know how to handle this pixel format from FreeType;
|
||||
// omit it from the font-image.
|
||||
llassert(false);
|
||||
}
|
||||
|
||||
LLImageGL *image_gl = mFontBitmapCachep->getImageGL(bitmap_num);
|
||||
LLImageRaw *image_raw = mFontBitmapCachep->getImageRaw(bitmap_num);
|
||||
LLImageGL *image_gl = mFontBitmapCachep->getImageGL(bitmap_glyph_type, bitmap_num);
|
||||
LLImageRaw *image_raw = mFontBitmapCachep->getImageRaw(bitmap_glyph_type, bitmap_num);
|
||||
image_gl->setSubImage(image_raw, 0, 0, image_gl->getWidth(), image_gl->getHeight());
|
||||
|
||||
return gi;
|
||||
}
|
||||
|
||||
LLFontGlyphInfo* LLFontFreetype::getGlyphInfo(llwchar wch) const
|
||||
LLFontGlyphInfo* LLFontFreetype::getGlyphInfo(llwchar wch, EFontGlyphType glyph_type) const
|
||||
{
|
||||
char_glyph_info_map_t::iterator iter = mCharGlyphInfoMap.find(wch);
|
||||
if (iter != mCharGlyphInfoMap.end())
|
||||
std::pair<char_glyph_info_map_t::iterator, char_glyph_info_map_t::iterator> range_it = mCharGlyphInfoMap.equal_range(wch);
|
||||
|
||||
char_glyph_info_map_t::iterator iter = (EFontGlyphType::Unspecified != glyph_type)
|
||||
? std::find_if(range_it.first, range_it.second, [&glyph_type](const char_glyph_info_map_t::value_type& entry) { return entry.second->mGlyphType == glyph_type; })
|
||||
: range_it.first;
|
||||
if (iter != range_it.second)
|
||||
{
|
||||
return iter->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
// this glyph doesn't yet exist, so render it and return the result
|
||||
return addGlyph(wch);
|
||||
return addGlyph(wch, (EFontGlyphType::Unspecified != glyph_type) ? glyph_type : EFontGlyphType::Grayscale);
|
||||
}
|
||||
}
|
||||
|
||||
void LLFontFreetype::insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const
|
||||
{
|
||||
char_glyph_info_map_t::iterator iter = mCharGlyphInfoMap.find(wch);
|
||||
if (iter != mCharGlyphInfoMap.end())
|
||||
llassert(gi->mGlyphType < EFontGlyphType::Count);
|
||||
std::pair<char_glyph_info_map_t::iterator, char_glyph_info_map_t::iterator> range_it = mCharGlyphInfoMap.equal_range(wch);
|
||||
|
||||
char_glyph_info_map_t::iterator iter =
|
||||
std::find_if(range_it.first, range_it.second, [&gi](const char_glyph_info_map_t::value_type& entry) { return entry.second->mGlyphType == gi->mGlyphType; });
|
||||
if (iter != range_it.second)
|
||||
{
|
||||
delete iter->second;
|
||||
iter->second = gi;
|
||||
|
|
@ -586,16 +637,23 @@ void LLFontFreetype::insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const
|
|||
else
|
||||
{
|
||||
claimMem(gi);
|
||||
mCharGlyphInfoMap[wch] = gi;
|
||||
mCharGlyphInfoMap.insert(std::make_pair(wch, gi));
|
||||
}
|
||||
}
|
||||
|
||||
void LLFontFreetype::renderGlyph(U32 glyph_index) const
|
||||
void LLFontFreetype::renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index) const
|
||||
{
|
||||
if (mFTFace == NULL)
|
||||
return;
|
||||
|
||||
llassert_always(! FT_Load_Glyph(mFTFace, glyph_index, FT_LOAD_FORCE_AUTOHINT) );
|
||||
FT_Int32 load_flags = FT_LOAD_FORCE_AUTOHINT;
|
||||
if (EFontGlyphType::Color == bitmap_type)
|
||||
{
|
||||
// We may not actually get a color render so our caller should always examine mFTFace->glyph->bitmap.pixel_mode
|
||||
load_flags |= FT_LOAD_COLOR;
|
||||
}
|
||||
|
||||
llassert_always(! FT_Load_Glyph(mFTFace, glyph_index, load_flags) );
|
||||
|
||||
llassert_always(! FT_Render_Glyph(mFTFace->glyph, gFontRenderMode) );
|
||||
|
||||
|
|
@ -605,7 +663,7 @@ void LLFontFreetype::renderGlyph(U32 glyph_index) const
|
|||
void LLFontFreetype::reset(F32 vert_dpi, F32 horz_dpi)
|
||||
{
|
||||
resetBitmapCache();
|
||||
loadFace(mName, mPointSize, vert_dpi ,horz_dpi, mFontBitmapCachep->getNumComponents(), mIsFallback);
|
||||
loadFace(mName, mPointSize, vert_dpi ,horz_dpi, mIsFallback, 0);
|
||||
if (!mIsFallback)
|
||||
{
|
||||
// This is the head of the list - need to rebuild ourself and all fallbacks.
|
||||
|
|
@ -615,11 +673,9 @@ void LLFontFreetype::reset(F32 vert_dpi, F32 horz_dpi)
|
|||
}
|
||||
else
|
||||
{
|
||||
for(font_vector_t::iterator it = mFallbackFonts.begin();
|
||||
it != mFallbackFonts.end();
|
||||
++it)
|
||||
for (fallback_font_vector_t::iterator it = mFallbackFonts.begin(); it != mFallbackFonts.end(); ++it)
|
||||
{
|
||||
(*it)->reset(vert_dpi, horz_dpi);
|
||||
it->first->reset(vert_dpi, horz_dpi);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -643,7 +699,7 @@ void LLFontFreetype::resetBitmapCache()
|
|||
if(!mIsFallback)
|
||||
{
|
||||
// Add the empty glyph
|
||||
addGlyphFromFont(this, 0, 0);
|
||||
addGlyphFromFont(this, 0, 0, EFontGlyphType::Grayscale);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -657,6 +713,34 @@ const std::string &LLFontFreetype::getName() const
|
|||
return mName;
|
||||
}
|
||||
|
||||
static void dumpFontBitmap(const LLImageRaw* image_raw, const std::string& file_name)
|
||||
{
|
||||
LLPointer<LLImagePNG> tmpImage = new LLImagePNG();
|
||||
if ( (tmpImage->encode(image_raw, 0.0f)) && (tmpImage->save(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, file_name))) )
|
||||
{
|
||||
LL_INFOS("Font") << "Successfully saved " << file_name << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("Font") << "Failed to save " << file_name << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
void LLFontFreetype::dumpFontBitmaps() const
|
||||
{
|
||||
// Dump all the regular bitmaps (if any)
|
||||
for (int idx = 0, cnt = mFontBitmapCachep->getNumBitmaps(EFontGlyphType::Grayscale); idx < cnt; idx++)
|
||||
{
|
||||
dumpFontBitmap(mFontBitmapCachep->getImageRaw(EFontGlyphType::Grayscale, idx), llformat("%s_%d_%d_%d.png", mFTFace->family_name, (int)(mPointSize * 10), mStyle, idx));
|
||||
}
|
||||
|
||||
// Dump all the color bitmaps (if any)
|
||||
for (int idx = 0, cnt = mFontBitmapCachep->getNumBitmaps(EFontGlyphType::Color); idx < cnt; idx++)
|
||||
{
|
||||
dumpFontBitmap(mFontBitmapCachep->getImageRaw(EFontGlyphType::Color, idx), llformat("%s_%d_%d_%d_clr.png", mFTFace->family_name, (int)(mPointSize * 10), mStyle, idx));
|
||||
}
|
||||
}
|
||||
|
||||
const LLFontBitmapCache* LLFontFreetype::getFontBitmapCache() const
|
||||
{
|
||||
return mFontBitmapCachep;
|
||||
|
|
@ -672,9 +756,38 @@ U8 LLFontFreetype::getStyle() const
|
|||
return mStyle;
|
||||
}
|
||||
|
||||
bool LLFontFreetype::setSubImageBGRA(U32 x, U32 y, U32 bitmap_num, U16 width, U16 height, const U8* data, U32 stride) const
|
||||
{
|
||||
LLImageRaw* image_raw = mFontBitmapCachep->getImageRaw(EFontGlyphType::Color, bitmap_num);
|
||||
llassert(!mIsFallback);
|
||||
llassert(image_raw && (image_raw->getComponents() == 4));
|
||||
|
||||
// NOTE: inspired by LLImageRaw::setSubImage()
|
||||
U32* image_data = (U32*)image_raw->getData();
|
||||
if (!image_data)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (U32 idxRow = 0; idxRow < height; idxRow++)
|
||||
{
|
||||
const U32 nSrcRow = height - 1 - idxRow;
|
||||
const U32 nSrcOffset = nSrcRow * width * image_raw->getComponents();
|
||||
const U32 nDstOffset = (y + idxRow) * image_raw->getWidth() + x;
|
||||
|
||||
for (U32 idxCol = 0; idxCol < width; idxCol++)
|
||||
{
|
||||
U32 nTemp = nSrcOffset + idxCol * 4;
|
||||
image_data[nDstOffset + idxCol] = data[nTemp + 3] << 24 | data[nTemp] << 16 | data[nTemp + 1] << 8 | data[nTemp + 2];
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
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);
|
||||
LLImageRaw *image_raw = mFontBitmapCachep->getImageRaw(EFontGlyphType::Grayscale, bitmap_num);
|
||||
|
||||
llassert(!mIsFallback);
|
||||
llassert(image_raw && (image_raw->getComponents() == 2));
|
||||
|
|
|
|||
|
|
@ -56,9 +56,11 @@ private:
|
|||
|
||||
struct LLFontGlyphInfo
|
||||
{
|
||||
LLFontGlyphInfo(U32 index);
|
||||
LLFontGlyphInfo(U32 index, EFontGlyphType glyph_type);
|
||||
LLFontGlyphInfo(const LLFontGlyphInfo& fgi);
|
||||
|
||||
U32 mGlyphIndex;
|
||||
EFontGlyphType mGlyphType;
|
||||
|
||||
// Metrics
|
||||
S32 mWidth; // In pixels
|
||||
|
|
@ -71,7 +73,7 @@ struct LLFontGlyphInfo
|
|||
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
|
||||
std::pair<EFontGlyphType, S32> mBitmapEntry; // Which bitmap in the bitmap cache contains this glyph
|
||||
};
|
||||
|
||||
extern LLFontManager *gFontManagerp;
|
||||
|
|
@ -84,7 +86,7 @@ public:
|
|||
|
||||
// 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, S32 face_n = 0);
|
||||
BOOL loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, bool is_fallback, S32 face_n);
|
||||
|
||||
S32 getNumFaces(const std::string& filename);
|
||||
|
||||
|
|
@ -93,10 +95,8 @@ public:
|
|||
void clearFontStreams();
|
||||
#endif
|
||||
|
||||
typedef std::vector<LLPointer<LLFontFreetype> > font_vector_t;
|
||||
|
||||
void setFallbackFonts(const font_vector_t &font);
|
||||
const font_vector_t &getFallbackFonts() const;
|
||||
typedef std::function<bool(llwchar)> char_functor_t;
|
||||
void addFallbackFont(const LLPointer<LLFontFreetype>& fallback_font, const char_functor_t& functor = nullptr);
|
||||
|
||||
// Global font metrics - in units of pixels
|
||||
F32 getLineHeight() const;
|
||||
|
|
@ -135,7 +135,7 @@ public:
|
|||
F32 getXKerning(llwchar char_left, llwchar char_right) const; // Get the kerning between the two characters
|
||||
F32 getXKerning(const LLFontGlyphInfo* left_glyph_info, const LLFontGlyphInfo* right_glyph_info) const; // Get the kerning between the two characters
|
||||
|
||||
LLFontGlyphInfo* getGlyphInfo(llwchar wch) const;
|
||||
LLFontGlyphInfo* getGlyphInfo(llwchar wch, EFontGlyphType glyph_type) const;
|
||||
|
||||
void reset(F32 vert_dpi, F32 horz_dpi);
|
||||
|
||||
|
|
@ -143,6 +143,7 @@ public:
|
|||
|
||||
const std::string& getName() const;
|
||||
|
||||
void dumpFontBitmaps() const;
|
||||
const LLFontBitmapCache* getFontBitmapCache() const;
|
||||
|
||||
void setStyle(U8 style);
|
||||
|
|
@ -151,10 +152,11 @@ public:
|
|||
private:
|
||||
void resetBitmapCache();
|
||||
void setSubImageLuminanceAlpha(U32 x, U32 y, U32 bitmap_num, U32 width, U32 height, U8 *data, S32 stride = 0) const;
|
||||
bool setSubImageBGRA(U32 x, U32 y, U32 bitmap_num, U16 width, U16 height, const U8* data, U32 stride) const;
|
||||
BOOL hasGlyph(llwchar wch) const; // Has a glyph for this character
|
||||
LLFontGlyphInfo* addGlyph(llwchar wch) const; // Add a new character to the font if necessary
|
||||
LLFontGlyphInfo* 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)
|
||||
void renderGlyph(U32 glyph_index) const;
|
||||
LLFontGlyphInfo* addGlyph(llwchar wch, EFontGlyphType glyph_type) const; // Add a new character to the font if necessary
|
||||
LLFontGlyphInfo* addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index, EFontGlyphType bitmap_type) const; // Add a glyph from this font to the other (returns the glyph_index, 0 if not found)
|
||||
void renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index) const;
|
||||
void insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const;
|
||||
|
||||
std::string mName;
|
||||
|
|
@ -174,9 +176,12 @@ private:
|
|||
#endif
|
||||
|
||||
BOOL mIsFallback;
|
||||
font_vector_t mFallbackFonts; // A list of fallback fonts to look for glyphs in (for Unicode chars)
|
||||
typedef std::pair<LLPointer<LLFontFreetype>, char_functor_t> fallback_font_t;
|
||||
typedef std::vector<fallback_font_t> fallback_font_vector_t;
|
||||
fallback_font_vector_t mFallbackFonts; // A list of fallback fonts to look for glyphs in (for Unicode chars)
|
||||
|
||||
typedef boost::unordered_map<llwchar, LLFontGlyphInfo*> char_glyph_info_map_t;
|
||||
// *NOTE: the same glyph can be present with multiple representations (but the pointer is always unique)
|
||||
typedef boost::unordered_multimap<llwchar, LLFontGlyphInfo*> char_glyph_info_map_t;
|
||||
mutable char_glyph_info_map_t mCharGlyphInfoMap; // Information about glyph location in bitmap
|
||||
|
||||
mutable LLFontBitmapCache* mFontBitmapCachep;
|
||||
|
|
|
|||
|
|
@ -89,14 +89,14 @@ void LLFontGL::destroyGL()
|
|||
mFontFreetype->destroyGL();
|
||||
}
|
||||
|
||||
BOOL LLFontGL::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback, S32 face_n)
|
||||
BOOL LLFontGL::loadFace(const std::string& filename, F32 point_size, const F32 vert_dpi, const F32 horz_dpi, bool is_fallback, S32 face_n)
|
||||
{
|
||||
if(mFontFreetype == reinterpret_cast<LLFontFreetype*>(NULL))
|
||||
{
|
||||
mFontFreetype = new LLFontFreetype;
|
||||
}
|
||||
|
||||
return mFontFreetype->loadFace(filename, point_size, vert_dpi, horz_dpi, components, is_fallback, face_n);
|
||||
return mFontFreetype->loadFace(filename, point_size, vert_dpi, horz_dpi, is_fallback, face_n);
|
||||
}
|
||||
|
||||
S32 LLFontGL::getNumFaces(const std::string& filename)
|
||||
|
|
@ -112,14 +112,14 @@ S32 LLFontGL::getNumFaces(const std::string& filename)
|
|||
static LLTrace::BlockTimerStatHandle FTM_RENDER_FONTS("Fonts");
|
||||
|
||||
S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, const LLRect& rect, const LLColor4 &color, HAlign halign, VAlign valign, U8 style,
|
||||
ShadowType shadow, S32 max_chars, F32* right_x, BOOL use_ellipses) const
|
||||
ShadowType shadow, S32 max_chars, F32* right_x, BOOL use_ellipses, BOOL use_color) const
|
||||
{
|
||||
LLRectf rect_float(rect.mLeft, rect.mTop, rect.mRight, rect.mBottom);
|
||||
return render(wstr, begin_offset, rect_float, color, halign, valign, style, shadow, max_chars, right_x, use_ellipses);
|
||||
return render(wstr, begin_offset, rect_float, color, halign, valign, style, shadow, max_chars, right_x, use_ellipses, use_color);
|
||||
}
|
||||
|
||||
S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, const LLRectf& rect, const LLColor4 &color, HAlign halign, VAlign valign, U8 style,
|
||||
ShadowType shadow, S32 max_chars, F32* right_x, BOOL use_ellipses) const
|
||||
ShadowType shadow, S32 max_chars, F32* right_x, BOOL use_ellipses, BOOL use_color) const
|
||||
{
|
||||
F32 x = rect.mLeft;
|
||||
F32 y = 0.f;
|
||||
|
|
@ -140,12 +140,12 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, const LLRectf& rec
|
|||
y = rect.mBottom;
|
||||
break;
|
||||
}
|
||||
return render(wstr, begin_offset, x, y, color, halign, valign, style, shadow, max_chars, rect.getWidth(), right_x, use_ellipses);
|
||||
return render(wstr, begin_offset, x, y, color, halign, valign, style, shadow, max_chars, rect.getWidth(), right_x, use_ellipses, use_color);
|
||||
}
|
||||
|
||||
|
||||
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_ellipses) const
|
||||
ShadowType shadow, S32 max_chars, S32 max_pixels, F32* right_x, BOOL use_ellipses, BOOL use_color) const
|
||||
{
|
||||
LL_RECORD_BLOCK_TIME(FTM_RENDER_FONTS);
|
||||
|
||||
|
|
@ -280,7 +280,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
|||
|
||||
LLColor4U text_color(color);
|
||||
|
||||
S32 bitmap_num = -1;
|
||||
std::pair<EFontGlyphType, S32> bitmap_entry = std::make_pair(EFontGlyphType::Grayscale, -1);
|
||||
S32 glyph_count = 0;
|
||||
for (i = begin_offset; i < begin_offset + length; i++)
|
||||
{
|
||||
|
|
@ -290,7 +290,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
|||
next_glyph = NULL;
|
||||
if(!fgi)
|
||||
{
|
||||
fgi = mFontFreetype->getGlyphInfo(wch);
|
||||
fgi = mFontFreetype->getGlyphInfo(wch, (!use_color) ? EFontGlyphType::Grayscale : EFontGlyphType::Color);
|
||||
}
|
||||
if (!fgi)
|
||||
{
|
||||
|
|
@ -298,8 +298,8 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
|||
break;
|
||||
}
|
||||
// Per-glyph bitmap texture.
|
||||
S32 next_bitmap_num = fgi->mBitmapNum;
|
||||
if (next_bitmap_num != bitmap_num)
|
||||
std::pair<EFontGlyphType, S32> next_bitmap_entry = fgi->mBitmapEntry;
|
||||
if (next_bitmap_entry != bitmap_entry)
|
||||
{
|
||||
// Actually draw the queued glyphs before switching their texture;
|
||||
// otherwise the queued glyphs will be taken from wrong textures.
|
||||
|
|
@ -313,8 +313,8 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
|||
glyph_count = 0;
|
||||
}
|
||||
|
||||
bitmap_num = next_bitmap_num;
|
||||
LLImageGL *font_image = font_bitmap_cache->getImageGL(bitmap_num);
|
||||
bitmap_entry = next_bitmap_entry;
|
||||
LLImageGL* font_image = font_bitmap_cache->getImageGL(bitmap_entry.first, bitmap_entry.second);
|
||||
gGL.getTexUnit(0)->bind(font_image);
|
||||
}
|
||||
|
||||
|
|
@ -347,7 +347,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
|||
glyph_count = 0;
|
||||
}
|
||||
|
||||
drawGlyph(glyph_count, vertices, uvs, colors, screen_rect, uv_rect, text_color, style_to_add, shadow, drop_shadow_strength);
|
||||
drawGlyph(glyph_count, vertices, uvs, colors, screen_rect, uv_rect, (bitmap_entry.first == EFontGlyphType::Grayscale) ? text_color : LLColor4U::white, style_to_add, shadow, drop_shadow_strength);
|
||||
|
||||
chars_drawn++;
|
||||
cur_x += fgi->mXAdvance;
|
||||
|
|
@ -357,7 +357,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
|||
if (next_char && (next_char < LAST_CHARACTER))
|
||||
{
|
||||
// Kern this puppy.
|
||||
next_glyph = mFontFreetype->getGlyphInfo(next_char);
|
||||
next_glyph = mFontFreetype->getGlyphInfo(next_char, (!use_color) ? EFontGlyphType::Grayscale : EFontGlyphType::Color);
|
||||
cur_x += mFontFreetype->getXKerning(fgi, next_glyph);
|
||||
}
|
||||
|
||||
|
|
@ -411,7 +411,8 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
|
|||
shadow,
|
||||
S32_MAX, max_pixels,
|
||||
right_x,
|
||||
FALSE);
|
||||
FALSE,
|
||||
use_color);
|
||||
gGL.popUIMatrix();
|
||||
}
|
||||
|
||||
|
|
@ -425,19 +426,19 @@ S32 LLFontGL::render(const LLWString &text, S32 begin_offset, F32 x, F32 y, cons
|
|||
return render(text, begin_offset, x, y, color, LEFT, BASELINE, NORMAL, NO_SHADOW, S32_MAX, S32_MAX, NULL, 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
|
||||
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, BOOL use_color) const
|
||||
{
|
||||
return render(utf8str_to_wstring(text), begin_offset, x, y, color, halign, valign, style, shadow, max_chars, max_pixels, right_x, use_ellipses);
|
||||
return render(utf8str_to_wstring(text), begin_offset, x, y, color, halign, valign, style, shadow, max_chars, max_pixels, right_x, use_ellipses, use_color);
|
||||
}
|
||||
|
||||
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);
|
||||
return renderUTF8(text, begin_offset, (F32)x, (F32)y, color, LEFT, BASELINE, NORMAL, NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE, 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);
|
||||
return renderUTF8(text, begin_offset, (F32)x, (F32)y, color, halign, valign, style, shadow, S32_MAX, S32_MAX, NULL, FALSE, FALSE);
|
||||
}
|
||||
|
||||
// font metrics - override for LLFontFreetype that returns units of virtual pixels
|
||||
|
|
@ -514,7 +515,7 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars
|
|||
next_glyph = NULL;
|
||||
if(!fgi)
|
||||
{
|
||||
fgi = mFontFreetype->getGlyphInfo(wch);
|
||||
fgi = mFontFreetype->getGlyphInfo(wch, EFontGlyphType::Unspecified);
|
||||
}
|
||||
|
||||
F32 advance = mFontFreetype->getXAdvance(fgi);
|
||||
|
|
@ -534,7 +535,7 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars
|
|||
&& (next_char < LAST_CHARACTER))
|
||||
{
|
||||
// Kern this puppy.
|
||||
next_glyph = mFontFreetype->getGlyphInfo(next_char);
|
||||
next_glyph = mFontFreetype->getGlyphInfo(next_char, EFontGlyphType::Unspecified);
|
||||
cur_x += mFontFreetype->getXKerning(fgi, next_glyph);
|
||||
}
|
||||
// Round after kerning.
|
||||
|
|
@ -616,7 +617,7 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
|
|||
next_glyph = NULL;
|
||||
if(!fgi)
|
||||
{
|
||||
fgi = mFontFreetype->getGlyphInfo(wch);
|
||||
fgi = mFontFreetype->getGlyphInfo(wch, EFontGlyphType::Unspecified);
|
||||
|
||||
if (NULL == fgi)
|
||||
{
|
||||
|
|
@ -641,7 +642,7 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
|
|||
if (((i+1) < max_chars) && wchars[i+1])
|
||||
{
|
||||
// Kern this puppy.
|
||||
next_glyph = mFontFreetype->getGlyphInfo(wchars[i+1]);
|
||||
next_glyph = mFontFreetype->getGlyphInfo(wchars[i+1], EFontGlyphType::Unspecified);
|
||||
cur_x += mFontFreetype->getXKerning(fgi, next_glyph);
|
||||
}
|
||||
|
||||
|
|
@ -688,7 +689,7 @@ S32 LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_
|
|||
{
|
||||
llwchar wch = wchars[i];
|
||||
|
||||
const LLFontGlyphInfo* fgi= mFontFreetype->getGlyphInfo(wch);
|
||||
const LLFontGlyphInfo* fgi= mFontFreetype->getGlyphInfo(wch, EFontGlyphType::Unspecified);
|
||||
|
||||
// last character uses character width, since the whole character needs to be visible
|
||||
// other characters just use advance
|
||||
|
|
@ -763,7 +764,7 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, S32 begin_offset, F32 t
|
|||
next_glyph = NULL;
|
||||
if(!glyph)
|
||||
{
|
||||
glyph = mFontFreetype->getGlyphInfo(wch);
|
||||
glyph = mFontFreetype->getGlyphInfo(wch, EFontGlyphType::Unspecified);
|
||||
}
|
||||
|
||||
F32 char_width = mFontFreetype->getXAdvance(glyph);
|
||||
|
|
@ -793,7 +794,7 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, S32 begin_offset, F32 t
|
|||
&& (wchars[(pos + 1)]))
|
||||
{
|
||||
// Kern this puppy.
|
||||
next_glyph = mFontFreetype->getGlyphInfo(wchars[pos + 1]);
|
||||
next_glyph = mFontFreetype->getGlyphInfo(wchars[pos + 1], EFontGlyphType::Unspecified);
|
||||
cur_x += mFontFreetype->getXKerning(glyph, next_glyph);
|
||||
}
|
||||
|
||||
|
|
@ -831,6 +832,26 @@ void LLFontGL::initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::st
|
|||
}
|
||||
}
|
||||
|
||||
void LLFontGL::dumpTextures()
|
||||
{
|
||||
if (mFontFreetype.notNull())
|
||||
{
|
||||
mFontFreetype->dumpFontBitmaps();
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFontGL::dumpFonts()
|
||||
{
|
||||
sFontRegistry->dump();
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFontGL::dumpFontTextures()
|
||||
{
|
||||
sFontRegistry->dumpTextures();
|
||||
}
|
||||
|
||||
// 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
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ public:
|
|||
|
||||
void destroyGL();
|
||||
|
||||
BOOL loadFace(const std::string& filename, F32 point_size, const F32 vert_dpi, const F32 horz_dpi, const S32 components, BOOL is_fallback, S32 face_n = 0);
|
||||
BOOL loadFace(const std::string& filename, F32 point_size, const F32 vert_dpi, const F32 horz_dpi, bool is_fallback, S32 face_n);
|
||||
|
||||
S32 getNumFaces(const std::string& filename);
|
||||
|
||||
|
|
@ -98,7 +98,8 @@ public:
|
|||
U8 style = NORMAL, ShadowType shadow = NO_SHADOW,
|
||||
S32 max_chars = S32_MAX,
|
||||
F32* right_x=NULL,
|
||||
BOOL use_ellipses = FALSE) const;
|
||||
BOOL use_ellipses = FALSE,
|
||||
BOOL use_color = FALSE) const;
|
||||
|
||||
S32 render(const LLWString &text, S32 begin_offset,
|
||||
const LLRectf& rect,
|
||||
|
|
@ -107,7 +108,8 @@ public:
|
|||
U8 style = NORMAL, ShadowType shadow = NO_SHADOW,
|
||||
S32 max_chars = S32_MAX,
|
||||
F32* right_x=NULL,
|
||||
BOOL use_ellipses = FALSE) const;
|
||||
BOOL use_ellipses = FALSE,
|
||||
BOOL use_color = FALSE) const;
|
||||
|
||||
S32 render(const LLWString &text, S32 begin_offset,
|
||||
F32 x, F32 y,
|
||||
|
|
@ -116,12 +118,13 @@ public:
|
|||
U8 style = NORMAL, ShadowType shadow = NO_SHADOW,
|
||||
S32 max_chars = S32_MAX, S32 max_pixels = S32_MAX,
|
||||
F32* right_x=NULL,
|
||||
BOOL use_ellipses = FALSE) const;
|
||||
BOOL use_ellipses = FALSE,
|
||||
BOOL use_color = FALSE) const;
|
||||
|
||||
S32 render(const LLWString &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color) const;
|
||||
|
||||
// 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 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, BOOL use_color) 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;
|
||||
|
||||
|
|
@ -163,6 +166,10 @@ public:
|
|||
|
||||
static void initClass(F32 screen_dpi, F32 x_scale, F32 y_scale, const std::string& app_dir, bool create_gl_textures = true);
|
||||
|
||||
void dumpTextures();
|
||||
static void dumpFonts();
|
||||
static void dumpFontTextures();
|
||||
|
||||
// Load sans-serif, sans-serif-small, etc.
|
||||
// Slow, requires multiple seconds to load fonts.
|
||||
static bool loadDefaultFonts();
|
||||
|
|
|
|||
|
|
@ -47,6 +47,10 @@ bool init_from_xml(LLFontRegistry* registry, LLXMLNodePtr node);
|
|||
const std::string MACOSX_FONT_PATH_LIBRARY = "/Library/Fonts/";
|
||||
const std::string MACOSX_FONT_SUPPLEMENTAL = "Supplemental/";
|
||||
|
||||
LLFontDescriptor::char_functor_map_t LLFontDescriptor::mCharFunctors({
|
||||
{ "is_emoji", LLStringOps::isEmoji }
|
||||
});
|
||||
|
||||
LLFontDescriptor::LLFontDescriptor():
|
||||
mStyle(0)
|
||||
{
|
||||
|
|
@ -55,22 +59,22 @@ LLFontDescriptor::LLFontDescriptor():
|
|||
LLFontDescriptor::LLFontDescriptor(const std::string& name,
|
||||
const std::string& size,
|
||||
const U8 style,
|
||||
const string_vec_t& file_names):
|
||||
const font_file_info_vec_t& font_files):
|
||||
mName(name),
|
||||
mSize(size),
|
||||
mStyle(style),
|
||||
mFileNames(file_names)
|
||||
mFontFiles(font_files)
|
||||
{
|
||||
}
|
||||
|
||||
LLFontDescriptor::LLFontDescriptor(const std::string& name,
|
||||
const std::string& size,
|
||||
const U8 style,
|
||||
const string_vec_t& file_names,
|
||||
const string_vec_t& ft_collection_listections) :
|
||||
LLFontDescriptor(name, size, style, file_names)
|
||||
const font_file_info_vec_t& font_list,
|
||||
const font_file_info_vec_t& font_collection_files) :
|
||||
LLFontDescriptor(name, size, style, font_list)
|
||||
{
|
||||
mFontCollectionsList = ft_collection_listections;
|
||||
mFontCollectionFiles = font_collection_files;
|
||||
}
|
||||
|
||||
LLFontDescriptor::LLFontDescriptor(const std::string& name,
|
||||
|
|
@ -82,7 +86,6 @@ LLFontDescriptor::LLFontDescriptor(const std::string& name,
|
|||
{
|
||||
}
|
||||
|
||||
|
||||
bool LLFontDescriptor::operator<(const LLFontDescriptor& b) const
|
||||
{
|
||||
if (mName < b.mName)
|
||||
|
|
@ -175,7 +178,19 @@ LLFontDescriptor LLFontDescriptor::normalize() const
|
|||
if (removeSubString(new_name,"Italic"))
|
||||
new_style |= LLFontGL::ITALIC;
|
||||
|
||||
return LLFontDescriptor(new_name,new_size,new_style,getFileNames(),getFontCollectionsList());
|
||||
return LLFontDescriptor(new_name,new_size,new_style, getFontFiles(), getFontCollectionFiles());
|
||||
}
|
||||
|
||||
void LLFontDescriptor::addFontFile(const std::string& file_name, const std::string& char_functor)
|
||||
{
|
||||
char_functor_map_t::const_iterator it = mCharFunctors.find(char_functor);
|
||||
mFontFiles.push_back(LLFontFileInfo(file_name, (mCharFunctors.end() != it) ? it->second : nullptr));
|
||||
}
|
||||
|
||||
void LLFontDescriptor::addFontCollectionFile(const std::string& file_name, const std::string& char_functor)
|
||||
{
|
||||
char_functor_map_t::const_iterator it = mCharFunctors.find(char_functor);
|
||||
mFontCollectionFiles.push_back(LLFontFileInfo(file_name, (mCharFunctors.end() != it) ? it->second : nullptr));
|
||||
}
|
||||
|
||||
LLFontRegistry::LLFontRegistry(bool create_gl_textures)
|
||||
|
|
@ -273,17 +288,24 @@ bool font_desc_init_from_xml(LLXMLNodePtr node, LLFontDescriptor& desc)
|
|||
if (child->hasName("file"))
|
||||
{
|
||||
std::string font_file_name = child->getTextContents();
|
||||
desc.getFileNames().push_back(font_file_name);
|
||||
|
||||
std::string char_functor;
|
||||
|
||||
if (child->hasAttribute("functor"))
|
||||
{
|
||||
child->getAttributeString("functor", char_functor);
|
||||
}
|
||||
|
||||
if (child->hasAttribute("load_collection"))
|
||||
{
|
||||
BOOL col = FALSE;
|
||||
child->getAttributeBOOL("load_collection", col);
|
||||
if (col)
|
||||
{
|
||||
desc.getFontCollectionsList().push_back(font_file_name);
|
||||
desc.addFontCollectionFile(font_file_name, char_functor);
|
||||
}
|
||||
}
|
||||
|
||||
desc.addFontFile(font_file_name, char_functor);
|
||||
}
|
||||
else if (child->hasName("os"))
|
||||
{
|
||||
|
|
@ -326,19 +348,19 @@ bool init_from_xml(LLFontRegistry* registry, LLXMLNodePtr node)
|
|||
// A little roundabout because the map key is const,
|
||||
// so we have to fetch it, make a new map key, and
|
||||
// replace the old entry.
|
||||
string_vec_t match_file_names = match_desc->getFileNames();
|
||||
match_file_names.insert(match_file_names.begin(),
|
||||
desc.getFileNames().begin(),
|
||||
desc.getFileNames().end());
|
||||
font_file_info_vec_t font_files = match_desc->getFontFiles();
|
||||
font_files.insert(font_files.begin(),
|
||||
desc.getFontFiles().begin(),
|
||||
desc.getFontFiles().end());
|
||||
|
||||
string_vec_t collections_list = match_desc->getFontCollectionsList();
|
||||
collections_list.insert(collections_list.begin(),
|
||||
desc.getFontCollectionsList().begin(),
|
||||
desc.getFontCollectionsList().end());
|
||||
font_file_info_vec_t font_collection_files = match_desc->getFontCollectionFiles();
|
||||
font_collection_files.insert(font_collection_files.begin(),
|
||||
desc.getFontCollectionFiles().begin(),
|
||||
desc.getFontCollectionFiles().end());
|
||||
|
||||
LLFontDescriptor new_desc = *match_desc;
|
||||
new_desc.getFileNames() = match_file_names;
|
||||
new_desc.getFontCollectionsList() = collections_list;
|
||||
new_desc.setFontFiles(font_files);
|
||||
new_desc.setFontCollectionFiles(font_collection_files);
|
||||
registry->mFontMap.erase(*match_desc);
|
||||
registry->mFontMap[new_desc] = NULL;
|
||||
}
|
||||
|
|
@ -423,82 +445,80 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
|
|||
|
||||
// Build list of font names to look for.
|
||||
// Files specified for this font come first, followed by those from the default descriptor.
|
||||
string_vec_t file_names = match_desc->getFileNames();
|
||||
string_vec_t ft_collection_list = match_desc->getFontCollectionsList();
|
||||
string_vec_t default_file_names;
|
||||
font_file_info_vec_t font_files = match_desc->getFontFiles();
|
||||
font_file_info_vec_t font_collection_files = match_desc->getFontCollectionFiles();
|
||||
LLFontDescriptor default_desc("default",s_template_string,0);
|
||||
const LLFontDescriptor *match_default_desc = getMatchingFontDesc(default_desc);
|
||||
if (match_default_desc)
|
||||
{
|
||||
file_names.insert(file_names.end(),
|
||||
match_default_desc->getFileNames().begin(),
|
||||
match_default_desc->getFileNames().end());
|
||||
ft_collection_list.insert(ft_collection_list.end(),
|
||||
match_default_desc->getFontCollectionsList().begin(),
|
||||
match_default_desc->getFontCollectionsList().end());
|
||||
font_files.insert(font_files.end(),
|
||||
match_default_desc->getFontFiles().begin(),
|
||||
match_default_desc->getFontFiles().end());
|
||||
font_collection_files.insert(font_collection_files.end(),
|
||||
match_default_desc->getFontCollectionFiles().begin(),
|
||||
match_default_desc->getFontCollectionFiles().end());
|
||||
}
|
||||
|
||||
// Add ultimate fallback list - generated dynamically on linux,
|
||||
// null elsewhere.
|
||||
file_names.insert(file_names.end(),
|
||||
getUltimateFallbackList().begin(),
|
||||
getUltimateFallbackList().end());
|
||||
std::transform(getUltimateFallbackList().begin(), getUltimateFallbackList().end(), std::back_inserter(font_files),
|
||||
[](const std::string& file_name) { return LLFontFileInfo(file_name); });
|
||||
|
||||
// Load fonts based on names.
|
||||
if (file_names.empty())
|
||||
if (font_files.empty())
|
||||
{
|
||||
LL_WARNS() << "createFont failed, no file names specified" << LL_ENDL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LLFontFreetype::font_vector_t fontlist;
|
||||
LLFontGL *result = NULL;
|
||||
|
||||
// Snarf all fonts we can into fontlist. First will get pulled
|
||||
// off the list and become the "head" font, set to non-fallback.
|
||||
// The first font will get pulled will be the "head" font, set to non-fallback.
|
||||
// Rest will consitute the fallback list.
|
||||
BOOL is_first_found = TRUE;
|
||||
|
||||
std::string local_path = LLFontGL::getFontPathLocal();
|
||||
std::string sys_path = LLFontGL::getFontPathSystem();
|
||||
|
||||
string_vec_t font_search_paths;
|
||||
font_search_paths.push_back(LLFontGL::getFontPathLocal());
|
||||
font_search_paths.push_back(LLFontGL::getFontPathSystem());
|
||||
#if LL_DARWIN
|
||||
font_search_paths.push_back(MACOSX_FONT_PATH_LIBRARY);
|
||||
#endif
|
||||
|
||||
// The fontname string may contain multiple font file names separated by semicolons.
|
||||
// Break it apart and try loading each one, in order.
|
||||
for(string_vec_t::iterator file_name_it = file_names.begin();
|
||||
file_name_it != file_names.end();
|
||||
++file_name_it)
|
||||
for(font_file_info_vec_t::iterator font_file_it = font_files.begin();
|
||||
font_file_it != font_files.end();
|
||||
++font_file_it)
|
||||
{
|
||||
LLFontGL *fontp = NULL;
|
||||
string_vec_t font_paths;
|
||||
font_paths.push_back(local_path + *file_name_it);
|
||||
font_paths.push_back(sys_path + *file_name_it);
|
||||
#if LL_DARWIN
|
||||
font_paths.push_back(MACOSX_FONT_PATH_LIBRARY + *file_name_it);
|
||||
font_paths.push_back(MACOSX_FONT_PATH_LIBRARY + MACOSX_FONT_SUPPLEMENTAL + *file_name_it);
|
||||
font_paths.push_back(sys_path + MACOSX_FONT_SUPPLEMENTAL + *file_name_it);
|
||||
#endif
|
||||
|
||||
bool is_ft_collection = (std::find(ft_collection_list.begin(), ft_collection_list.end(), *file_name_it) != ft_collection_list.end());
|
||||
|
||||
bool is_ft_collection = (std::find_if(font_collection_files.begin(), font_collection_files.end(),
|
||||
[&font_file_it](const LLFontFileInfo& ffi) { return font_file_it->FileName == ffi.FileName; }) != font_collection_files.end());
|
||||
|
||||
// *HACK: Fallback fonts don't render, so we can use that to suppress
|
||||
// creation of OpenGL textures for test apps. JC
|
||||
BOOL is_fallback = !is_first_found || !mCreateGLTextures;
|
||||
F32 extra_scale = (is_fallback)?fallback_scale:1.0;
|
||||
F32 point_size_scale = extra_scale * point_size;
|
||||
bool is_font_loaded = false;
|
||||
for(string_vec_t::iterator font_paths_it = font_paths.begin();
|
||||
font_paths_it != font_paths.end();
|
||||
++font_paths_it)
|
||||
for(string_vec_t::iterator font_search_path_it = font_search_paths.begin();
|
||||
font_search_path_it != font_search_paths.end();
|
||||
++font_search_path_it)
|
||||
{
|
||||
const std::string font_path = *font_search_path_it + font_file_it->FileName;
|
||||
|
||||
fontp = new LLFontGL;
|
||||
S32 num_faces = is_ft_collection ? fontp->getNumFaces(*font_paths_it) : 1;
|
||||
S32 num_faces = is_ft_collection ? fontp->getNumFaces(font_path) : 1;
|
||||
for (S32 i = 0; i < num_faces; i++)
|
||||
{
|
||||
if (fontp == NULL)
|
||||
{
|
||||
fontp = new LLFontGL;
|
||||
}
|
||||
if (fontp->loadFace(*font_paths_it, point_size_scale,
|
||||
LLFontGL::sVertDPI, LLFontGL::sHorizDPI, 2, is_fallback, i))
|
||||
if (fontp->loadFace(font_path, point_size_scale,
|
||||
LLFontGL::sVertDPI, LLFontGL::sHorizDPI, is_fallback, i))
|
||||
{
|
||||
is_font_loaded = true;
|
||||
if (is_first_found)
|
||||
|
|
@ -508,7 +528,8 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
|
|||
}
|
||||
else
|
||||
{
|
||||
fontlist.push_back(fontp->mFontFreetype);
|
||||
result->mFontFreetype->addFallbackFont(fontp->mFontFreetype, font_file_it->CharFunctor);
|
||||
|
||||
delete fontp;
|
||||
fontp = NULL;
|
||||
}
|
||||
|
|
@ -523,17 +544,12 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
|
|||
}
|
||||
if(!is_font_loaded)
|
||||
{
|
||||
LL_INFOS_ONCE("LLFontRegistry") << "Couldn't load font " << *file_name_it << LL_ENDL;
|
||||
LL_INFOS_ONCE("LLFontRegistry") << "Couldn't load font " << font_file_it->FileName << LL_ENDL;
|
||||
delete fontp;
|
||||
fontp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (result && !fontlist.empty())
|
||||
{
|
||||
result->mFontFreetype->setFallbackFonts(fontlist);
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
result->mFontDescriptor = desc;
|
||||
|
|
@ -715,11 +731,22 @@ void LLFontRegistry::dump()
|
|||
<< " size=[" << desc.getSize() << "]"
|
||||
<< " fileNames="
|
||||
<< LL_ENDL;
|
||||
for (string_vec_t::const_iterator file_it=desc.getFileNames().begin();
|
||||
file_it != desc.getFileNames().end();
|
||||
for (font_file_info_vec_t::const_iterator file_it=desc.getFontFiles().begin();
|
||||
file_it != desc.getFontFiles().end();
|
||||
++file_it)
|
||||
{
|
||||
LL_INFOS() << " file: " << *file_it <<LL_ENDL;
|
||||
LL_INFOS() << " file: " << file_it->FileName << LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLFontRegistry::dumpTextures()
|
||||
{
|
||||
for (const auto& fontEntry : mFontMap)
|
||||
{
|
||||
if (fontEntry.second)
|
||||
{
|
||||
fontEntry.second->dumpTextures();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,13 +34,32 @@ class LLFontGL;
|
|||
|
||||
typedef std::vector<std::string> string_vec_t;
|
||||
|
||||
struct LLFontFileInfo
|
||||
{
|
||||
LLFontFileInfo(const std::string& file_name, const std::function<bool(llwchar)>& char_functor = nullptr)
|
||||
: FileName(file_name)
|
||||
, CharFunctor(char_functor)
|
||||
{
|
||||
}
|
||||
|
||||
LLFontFileInfo(const LLFontFileInfo& ffi)
|
||||
: FileName(ffi.FileName)
|
||||
, CharFunctor(ffi.CharFunctor)
|
||||
{
|
||||
}
|
||||
|
||||
std::string FileName;
|
||||
std::function<bool(llwchar)> CharFunctor;
|
||||
};
|
||||
typedef std::vector<LLFontFileInfo> font_file_info_vec_t;
|
||||
|
||||
class LLFontDescriptor
|
||||
{
|
||||
public:
|
||||
LLFontDescriptor();
|
||||
LLFontDescriptor(const std::string& name, const std::string& size, const U8 style);
|
||||
LLFontDescriptor(const std::string& name, const std::string& size, const U8 style, const string_vec_t& file_names);
|
||||
LLFontDescriptor(const std::string& name, const std::string& size, const U8 style, const string_vec_t& file_names, const string_vec_t& font_collections);
|
||||
LLFontDescriptor(const std::string& name, const std::string& size, const U8 style, const font_file_info_vec_t& font_list);
|
||||
LLFontDescriptor(const std::string& name, const std::string& size, const U8 style, const font_file_info_vec_t& font_list, const font_file_info_vec_t& font_collection_list);
|
||||
LLFontDescriptor normalize() const;
|
||||
|
||||
bool operator<(const LLFontDescriptor& b) const;
|
||||
|
|
@ -51,19 +70,26 @@ public:
|
|||
void setName(const std::string& name) { mName = name; }
|
||||
const std::string& getSize() const { return mSize; }
|
||||
void setSize(const std::string& size) { mSize = size; }
|
||||
const std::vector<std::string>& getFileNames() const { return mFileNames; }
|
||||
std::vector<std::string>& getFileNames() { return mFileNames; }
|
||||
const std::vector<std::string>& getFontCollectionsList() const { return mFontCollectionsList; }
|
||||
std::vector<std::string>& getFontCollectionsList() { return mFontCollectionsList; }
|
||||
|
||||
void addFontFile(const std::string& file_name, const std::string& char_functor = LLStringUtil::null);
|
||||
const font_file_info_vec_t & getFontFiles() const { return mFontFiles; }
|
||||
void setFontFiles(const font_file_info_vec_t& font_files) { mFontFiles = font_files; }
|
||||
void addFontCollectionFile(const std::string& file_name, const std::string& char_functor = LLStringUtil::null);
|
||||
const font_file_info_vec_t& getFontCollectionFiles() const { return mFontCollectionFiles; }
|
||||
void setFontCollectionFiles(const font_file_info_vec_t& font_collection_files) { mFontCollectionFiles = font_collection_files; }
|
||||
|
||||
const U8 getStyle() const { return mStyle; }
|
||||
void setStyle(U8 style) { mStyle = style; }
|
||||
|
||||
private:
|
||||
std::string mName;
|
||||
std::string mSize;
|
||||
string_vec_t mFileNames;
|
||||
string_vec_t mFontCollectionsList;
|
||||
font_file_info_vec_t mFontFiles;
|
||||
font_file_info_vec_t mFontCollectionFiles;
|
||||
U8 mStyle;
|
||||
|
||||
typedef std::map<std::string, std::function<bool(llwchar)>> char_functor_map_t;
|
||||
static char_functor_map_t mCharFunctors;
|
||||
};
|
||||
|
||||
class LLFontRegistry
|
||||
|
|
@ -94,6 +120,7 @@ public:
|
|||
bool nameToSize(const std::string& size_name, F32& size);
|
||||
|
||||
void dump();
|
||||
void dumpTextures();
|
||||
|
||||
const string_vec_t& getUltimateFallbackList() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -875,7 +875,7 @@ void LLFolderViewItem::drawLabel(const LLFontGL * font, const F32 x, const F32 y
|
|||
//
|
||||
font->renderUTF8(mLabel, 0, x, y, color,
|
||||
LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
|
||||
S32_MAX, getRect().getWidth() - (S32) x - mLabelPaddingRight, &right_x, TRUE);
|
||||
S32_MAX, getRect().getWidth() - (S32) x - mLabelPaddingRight, &right_x, /*use_ellipses*/TRUE, /*use_color*/FALSE);
|
||||
}
|
||||
|
||||
void LLFolderViewItem::draw()
|
||||
|
|
@ -954,7 +954,7 @@ void LLFolderViewItem::draw()
|
|||
{
|
||||
font->renderUTF8( mLabelSuffix, 0, right_x, y, isFadeItem() ? color : (LLColor4)sSuffixColor,
|
||||
LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
|
||||
S32_MAX, S32_MAX, &right_x, FALSE );
|
||||
S32_MAX, S32_MAX, &right_x, /*use_ellipses*/FALSE, /*use_color*/FALSE );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------//
|
||||
|
|
@ -967,7 +967,7 @@ void LLFolderViewItem::draw()
|
|||
F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)mTextPad - (F32)TOP_PAD;
|
||||
font->renderUTF8( combined_string, filter_offset, match_string_left, yy,
|
||||
sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
|
||||
filter_string_length, S32_MAX, &right_x, FALSE );
|
||||
filter_string_length, S32_MAX, &right_x, /*use_ellipses*/FALSE, /*use_color*/FALSE );
|
||||
}
|
||||
|
||||
//Gilbert Linden 9-20-2012: Although this should be legal, removing it because it causes the mLabelSuffix rendering to
|
||||
|
|
|
|||
|
|
@ -161,9 +161,11 @@ LLTextBase::Params::Params()
|
|||
line_spacing("line_spacing"),
|
||||
max_text_length("max_length", 255),
|
||||
font_shadow("font_shadow"),
|
||||
text_valign("text_valign"),
|
||||
wrap("wrap"),
|
||||
trusted_content("trusted_content", true),
|
||||
use_ellipses("use_ellipses", false),
|
||||
use_color("use_color", false),
|
||||
parse_urls("parse_urls", false),
|
||||
force_urls_external("force_urls_external", false),
|
||||
parse_highlights("parse_highlights", false)
|
||||
|
|
@ -206,6 +208,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
|
|||
mVPad(p.v_pad),
|
||||
mHAlign(p.font_halign),
|
||||
mVAlign(p.font_valign),
|
||||
mTextVAlign(p.text_valign.isProvided() ? p.text_valign : p.font_valign),
|
||||
mLineSpacingMult(p.line_spacing.multiple),
|
||||
mLineSpacingPixels(p.line_spacing.pixels),
|
||||
mClip(p.clip),
|
||||
|
|
@ -219,6 +222,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
|
|||
mPlainText ( p.plain_text ),
|
||||
mWordWrap(p.wrap),
|
||||
mUseEllipses( p.use_ellipses ),
|
||||
mUseColor(p.use_color),
|
||||
mParseHTML(p.parse_urls),
|
||||
mForceUrlsExternal(p.force_urls_external),
|
||||
mParseHighlights(p.parse_highlights),
|
||||
|
|
@ -515,7 +519,7 @@ void LLTextBase::drawCursor()
|
|||
fontp = segmentp->getStyle()->getFont();
|
||||
fontp->render(text, mCursorPos, cursor_rect,
|
||||
LLColor4(1.f - text_color.mV[VRED], 1.f - text_color.mV[VGREEN], 1.f - text_color.mV[VBLUE], alpha),
|
||||
LLFontGL::LEFT, mVAlign,
|
||||
LLFontGL::LEFT, mTextVAlign,
|
||||
LLFontGL::NORMAL,
|
||||
LLFontGL::NO_SHADOW,
|
||||
1);
|
||||
|
|
@ -1920,8 +1924,6 @@ LLTextBase::segment_set_t::iterator LLTextBase::getSegIterContaining(S32 index)
|
|||
text_len = mLabel.getWString().length();
|
||||
}
|
||||
|
||||
if (index > text_len) { return mSegments.end(); }
|
||||
|
||||
// when there are no segments, we return the end iterator, which must be checked by caller
|
||||
if (mSegments.size() <= 1) { return mSegments.begin(); }
|
||||
|
||||
|
|
@ -1945,8 +1947,6 @@ LLTextBase::segment_set_t::const_iterator LLTextBase::getSegIterContaining(S32 i
|
|||
text_len = mLabel.getWString().length();
|
||||
}
|
||||
|
||||
if (index > text_len) { return mSegments.end(); }
|
||||
|
||||
// when there are no segments, we return the end iterator, which must be checked by caller
|
||||
if (mSegments.size() <= 1) { return mSegments.begin(); }
|
||||
|
||||
|
|
@ -3239,12 +3239,13 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele
|
|||
font->render(text, start,
|
||||
rect,
|
||||
color,
|
||||
LLFontGL::LEFT, mEditor.mVAlign,
|
||||
LLFontGL::LEFT, mEditor.mTextVAlign,
|
||||
LLFontGL::NORMAL,
|
||||
mStyle->getShadowType(),
|
||||
length,
|
||||
&right_x,
|
||||
mEditor.getUseEllipses());
|
||||
mEditor.getUseEllipses(),
|
||||
mEditor.getUseColor());
|
||||
}
|
||||
rect.mLeft = right_x;
|
||||
|
||||
|
|
@ -3258,12 +3259,13 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele
|
|||
font->render(text, start,
|
||||
rect,
|
||||
mStyle->getSelectedColor().get(),
|
||||
LLFontGL::LEFT, mEditor.mVAlign,
|
||||
LLFontGL::LEFT, mEditor.mTextVAlign,
|
||||
LLFontGL::NORMAL,
|
||||
LLFontGL::NO_SHADOW,
|
||||
length,
|
||||
&right_x,
|
||||
mEditor.getUseEllipses());
|
||||
mEditor.getUseEllipses(),
|
||||
mEditor.getUseColor());
|
||||
}
|
||||
rect.mLeft = right_x;
|
||||
if( selection_end < seg_end )
|
||||
|
|
@ -3275,12 +3277,13 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele
|
|||
font->render(text, start,
|
||||
rect,
|
||||
color,
|
||||
LLFontGL::LEFT, mEditor.mVAlign,
|
||||
LLFontGL::LEFT, mEditor.mTextVAlign,
|
||||
LLFontGL::NORMAL,
|
||||
mStyle->getShadowType(),
|
||||
length,
|
||||
&right_x,
|
||||
mEditor.getUseEllipses());
|
||||
mEditor.getUseEllipses(),
|
||||
mEditor.getUseColor());
|
||||
}
|
||||
return right_x;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -316,6 +316,7 @@ public:
|
|||
plain_text,
|
||||
wrap,
|
||||
use_ellipses,
|
||||
use_color,
|
||||
parse_urls,
|
||||
force_urls_external,
|
||||
parse_highlights,
|
||||
|
|
@ -334,6 +335,8 @@ public:
|
|||
|
||||
Optional<LLFontGL::ShadowType> font_shadow;
|
||||
|
||||
Optional<LLFontGL::VAlign> text_valign;
|
||||
|
||||
Params();
|
||||
};
|
||||
|
||||
|
|
@ -391,6 +394,7 @@ public:
|
|||
// used by LLTextSegment layout code
|
||||
bool getWordWrap() { return mWordWrap; }
|
||||
bool getUseEllipses() { return mUseEllipses; }
|
||||
bool getUseColor() { return mUseColor; }
|
||||
bool truncate(); // returns true of truncation occurred
|
||||
|
||||
bool isContentTrusted() {return mTrustedContent;}
|
||||
|
|
@ -680,8 +684,9 @@ protected:
|
|||
// configuration
|
||||
S32 mHPad; // padding on left of text
|
||||
S32 mVPad; // padding above text
|
||||
LLFontGL::HAlign mHAlign;
|
||||
LLFontGL::VAlign mVAlign;
|
||||
LLFontGL::HAlign mHAlign; // horizontal alignment of the document in its entirety
|
||||
LLFontGL::VAlign mVAlign; // vertical alignment of the document in its entirety
|
||||
LLFontGL::VAlign mTextVAlign; // vertical alignment of a text segment within a single line of text
|
||||
F32 mLineSpacingMult; // multiple of line height used as space for a single line of text (e.g. 1.5 to get 50% padding)
|
||||
S32 mLineSpacingPixels; // padding between lines
|
||||
bool mBorderVisible;
|
||||
|
|
@ -690,6 +695,7 @@ protected:
|
|||
bool mParseHighlights; // highlight user-defined keywords
|
||||
bool mWordWrap;
|
||||
bool mUseEllipses;
|
||||
bool mUseColor;
|
||||
bool mTrackEnd; // if true, keeps scroll position at end of document during resize
|
||||
bool mReadOnly;
|
||||
bool mBGVisible; // render background?
|
||||
|
|
|
|||
|
|
@ -1325,7 +1325,7 @@ void LLView::drawDebugRect()
|
|||
debug_rect.getWidth(), debug_rect.getHeight());
|
||||
LLFontGL::getFontSansSerifSmall()->renderUTF8(debug_text, 0, (F32)x, (F32)y, border_color,
|
||||
LLFontGL::HCENTER, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
|
||||
S32_MAX, S32_MAX, NULL, FALSE);
|
||||
S32_MAX, S32_MAX, NULL, /*use_ellipses*/FALSE, /*use_color*/FALSE);
|
||||
}
|
||||
}
|
||||
LLUI::popMatrix();
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ include(EXPAT)
|
|||
include(FMODSTUDIO)
|
||||
include(GLOD)
|
||||
include(Hunspell)
|
||||
include(ICU4C)
|
||||
include(JsonCpp)
|
||||
include(LLAppearance)
|
||||
include(LLAudio)
|
||||
|
|
@ -1497,6 +1498,12 @@ if (WINDOWS)
|
|||
set(viewer_SOURCE_FILES "${viewer_SOURCE_FILES}" llviewerprecompiledheaders.cpp)
|
||||
endif(USE_PRECOMPILED_HEADERS)
|
||||
|
||||
message("Copying fonts")
|
||||
file(GLOB FONT_FILE_GLOB_LIST
|
||||
"${AUTOBUILD_INSTALL_DIR}/fonts/*"
|
||||
)
|
||||
file(COPY ${FONT_FILE_GLOB_LIST} DESTINATION "${CMAKE_CURRENT_SOURCE_DIR}/fonts")
|
||||
|
||||
# Replace the icons with the appropriate ones for the channel
|
||||
# ('test' is the default)
|
||||
set(ICON_PATH "test")
|
||||
|
|
@ -2042,6 +2049,7 @@ target_link_libraries(${VIEWER_BINARY_NAME}
|
|||
${NDOF_LIBRARY}
|
||||
${NVAPI_LIBRARY}
|
||||
${HUNSPELL_LIBRARY}
|
||||
${ICU4C_LIBRARY}
|
||||
${viewer_LIBRARIES}
|
||||
${BOOST_PROGRAM_OPTIONS_LIBRARY}
|
||||
${BOOST_REGEX_LIBRARY}
|
||||
|
|
|
|||
|
|
@ -1,99 +0,0 @@
|
|||
Fonts are (c) Bitstream (see below). DejaVu changes are in public domain.
|
||||
Glyphs imported from Arev fonts are (c) Tavmjong Bah (see below)
|
||||
|
||||
Bitstream Vera Fonts Copyright
|
||||
------------------------------
|
||||
|
||||
Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is
|
||||
a trademark of Bitstream, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of the fonts accompanying this license ("Fonts") and associated
|
||||
documentation files (the "Font Software"), to reproduce and distribute the
|
||||
Font Software, including without limitation the rights to use, copy, merge,
|
||||
publish, distribute, and/or sell copies of the Font Software, and to permit
|
||||
persons to whom the Font Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright and trademark notices and this permission notice shall
|
||||
be included in all copies of one or more of the Font Software typefaces.
|
||||
|
||||
The Font Software may be modified, altered, or added to, and in particular
|
||||
the designs of glyphs or characters in the Fonts may be modified and
|
||||
additional glyphs or characters may be added to the Fonts, only if the fonts
|
||||
are renamed to names not containing either the words "Bitstream" or the word
|
||||
"Vera".
|
||||
|
||||
This License becomes null and void to the extent applicable to Fonts or Font
|
||||
Software that has been modified and is distributed under the "Bitstream
|
||||
Vera" names.
|
||||
|
||||
The Font Software may be sold as part of a larger software package but no
|
||||
copy of one or more of the Font Software typefaces may be sold by itself.
|
||||
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT,
|
||||
TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME
|
||||
FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING
|
||||
ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE
|
||||
FONT SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the names of Gnome, the Gnome
|
||||
Foundation, and Bitstream Inc., shall not be used in advertising or
|
||||
otherwise to promote the sale, use or other dealings in this Font Software
|
||||
without prior written authorization from the Gnome Foundation or Bitstream
|
||||
Inc., respectively. For further information, contact: fonts at gnome dot
|
||||
org.
|
||||
|
||||
Arev Fonts Copyright
|
||||
------------------------------
|
||||
|
||||
Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the fonts accompanying this license ("Fonts") and
|
||||
associated documentation files (the "Font Software"), to reproduce
|
||||
and distribute the modifications to the Bitstream Vera Font Software,
|
||||
including without limitation the rights to use, copy, merge, publish,
|
||||
distribute, and/or sell copies of the Font Software, and to permit
|
||||
persons to whom the Font Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright and trademark notices and this permission notice
|
||||
shall be included in all copies of one or more of the Font Software
|
||||
typefaces.
|
||||
|
||||
The Font Software may be modified, altered, or added to, and in
|
||||
particular the designs of glyphs or characters in the Fonts may be
|
||||
modified and additional glyphs or characters may be added to the
|
||||
Fonts, only if the fonts are renamed to names not containing either
|
||||
the words "Tavmjong Bah" or the word "Arev".
|
||||
|
||||
This License becomes null and void to the extent applicable to Fonts
|
||||
or Font Software that has been modified and is distributed under the
|
||||
"Tavmjong Bah Arev" names.
|
||||
|
||||
The Font Software may be sold as part of a larger software package but
|
||||
no copy of one or more of the Font Software typefaces may be sold by
|
||||
itself.
|
||||
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL
|
||||
TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of Tavmjong Bah shall not
|
||||
be used in advertising or otherwise to promote the sale, use or other
|
||||
dealings in this Font Software without prior written authorization
|
||||
from Tavmjong Bah. For further information, contact: tavmjong @ free
|
||||
. fr.
|
||||
|
||||
$Id: LICENSE 2133 2007-11-28 02:46:28Z lechimp $
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -88,7 +88,7 @@ public:
|
|||
mStyle->getShadowType(),
|
||||
end - start, draw_rect.getWidth(),
|
||||
&right_x,
|
||||
mEditor.getUseEllipses());
|
||||
mEditor.getUseEllipses(), mEditor.getUseColor());
|
||||
return right_x;
|
||||
}
|
||||
/*virtual*/ bool canEdit() const { return false; }
|
||||
|
|
|
|||
|
|
@ -1601,7 +1601,7 @@ void LLOverlapPanel::draw()
|
|||
LLUI::translate(5,getRect().getHeight()-20); // translate to top-5,left-5
|
||||
LLView::sDrawPreviewHighlights = FALSE;
|
||||
LLFontGL::getFontSansSerifSmall()->renderUTF8(current_selection_text, 0, 0, 0, text_color,
|
||||
LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE);
|
||||
LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, /*use_ellipses*/FALSE, /*use_color*/FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1619,7 +1619,7 @@ void LLOverlapPanel::draw()
|
|||
std::string current_selection = std::string(current_selection_text + LLView::sPreviewClickedElement->getName() + " (no elements overlap)");
|
||||
S32 text_width = LLFontGL::getFontSansSerifSmall()->getWidth(current_selection) + 10;
|
||||
LLFontGL::getFontSansSerifSmall()->renderUTF8(current_selection, 0, 0, 0, text_color,
|
||||
LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE);
|
||||
LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, /*use_ellipses*/FALSE, /*use_color*/FALSE);
|
||||
// widen panel enough to fit this text
|
||||
LLRect rect = getRect();
|
||||
setRect(LLRect(rect.mLeft,rect.mTop,rect.getWidth() < text_width ? rect.mLeft + text_width : rect.mRight,rect.mTop));
|
||||
|
|
@ -1685,7 +1685,7 @@ void LLOverlapPanel::draw()
|
|||
// draw currently-selected element at top of overlappers
|
||||
LLUI::translate(0,-mSpacing);
|
||||
LLFontGL::getFontSansSerifSmall()->renderUTF8(current_selection_text + LLView::sPreviewClickedElement->getName(), 0, 0, 0, text_color,
|
||||
LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE);
|
||||
LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, /*use_ellipses*/FALSE, /*use_color*/FALSE);
|
||||
LLUI::translate(0,-mSpacing-LLView::sPreviewClickedElement->getRect().getHeight()); // skip spacing distance + height
|
||||
LLView::sPreviewClickedElement->draw();
|
||||
|
||||
|
|
@ -1700,7 +1700,7 @@ void LLOverlapPanel::draw()
|
|||
// draw name
|
||||
LLUI::translate(0,-mSpacing);
|
||||
LLFontGL::getFontSansSerifSmall()->renderUTF8(overlapper_text + viewp->getName(), 0, 0, 0, text_color,
|
||||
LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE);
|
||||
LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, /*use_ellipses*/FALSE, /*use_color*/FALSE);
|
||||
|
||||
// draw element
|
||||
LLUI::translate(0,-mSpacing-viewp->getRect().getHeight()); // skip spacing distance + height
|
||||
|
|
|
|||
|
|
@ -612,7 +612,7 @@ void LLGLTexMemBar::draw()
|
|||
LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*3,
|
||||
text_color, LLFontGL::LEFT, LLFontGL::TOP,
|
||||
LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX,
|
||||
&x_right, FALSE);
|
||||
&x_right, /*use_ellipses*/FALSE, /*use_color*/FALSE);
|
||||
|
||||
F32Kilobits bandwidth(LLAppViewer::getTextureFetch()->getTextureBandwidth());
|
||||
F32Kilobits max_bandwidth(gSavedSettings.getF32("ThrottleBandwidthKBPS"));
|
||||
|
|
|
|||
|
|
@ -9302,6 +9302,10 @@ void initialize_menus()
|
|||
//Develop (clear cache immediately)
|
||||
commit.add("Develop.ClearCache", boost::bind(&handle_cache_clear_immediately) );
|
||||
|
||||
// Develop (Fonts debugging)
|
||||
commit.add("Develop.Fonts.Dump", boost::bind(&LLFontGL::dumpFonts));
|
||||
commit.add("Develop.Fonts.DumpTextures", boost::bind(&LLFontGL::dumpFontTextures));
|
||||
|
||||
// Admin >Object
|
||||
view_listener_t::addMenu(new LLAdminForceTakeCopy(), "Admin.ForceTakeCopy");
|
||||
view_listener_t::addMenu(new LLAdminHandleObjectOwnerSelf(), "Admin.HandleObjectOwnerSelf");
|
||||
|
|
|
|||
|
|
@ -1007,7 +1007,7 @@ public:
|
|||
const Line& line = *iter;
|
||||
LLFontGL::getFontMonospace()->renderUTF8(line.text, 0, (F32)line.x, (F32)line.y, mTextColor,
|
||||
LLFontGL::LEFT, LLFontGL::TOP,
|
||||
LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE);
|
||||
LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, /*use_ellipses*/FALSE, /*use_color*/FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -469,7 +469,8 @@ void LLWorldMapView::draw()
|
|||
S32_MAX, //max_chars
|
||||
sMapScale, //max_pixels
|
||||
NULL,
|
||||
TRUE); //use ellipses
|
||||
/*use_ellipses*/TRUE,
|
||||
/*use_color*/FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
<font name="default" comment="default font files (global fallbacks)">
|
||||
<file>DejaVuSans.ttf</file>
|
||||
<file functor="is_emoji">Twemoji.ttf</file>
|
||||
<os name="Windows">
|
||||
<file>meiryo.TTC</file>
|
||||
<file>MSGOTHIC.TTC</file>
|
||||
|
|
|
|||
|
|
@ -159,6 +159,32 @@
|
|||
parameter="ui_preview" />
|
||||
</menu_item_call>
|
||||
<menu_item_separator />
|
||||
<menu
|
||||
create_jump_keys="true"
|
||||
label="Fonts"
|
||||
name="Fonts"
|
||||
tear_off="true">
|
||||
<menu_item_call
|
||||
label="Show Font Test"
|
||||
name="Show Font Test">
|
||||
<menu_item_call.on_click
|
||||
function="Floater.Show"
|
||||
parameter="font_test" />
|
||||
</menu_item_call>
|
||||
<menu_item_separator />
|
||||
<menu_item_call
|
||||
label="Dump Fonts"
|
||||
name="Dump Fonts">
|
||||
<menu_item_call.on_click
|
||||
function="Develop.Fonts.Dump" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Dump Font Textures"
|
||||
name="Dump Font Textures">
|
||||
<menu_item_call.on_click
|
||||
function="Develop.Fonts.DumpTextures" />
|
||||
</menu_item_call>
|
||||
</menu>
|
||||
<menu
|
||||
create_jump_keys="true"
|
||||
label="UI Tests"
|
||||
|
|
|
|||
|
|
@ -3448,6 +3448,18 @@ function="World.EnvPreset"
|
|||
function="Advanced.WebContentTest"
|
||||
parameter="https://cryptic-ridge-1632.herokuapp.com/"/>
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Dump Fonts"
|
||||
name="Dump Fonts">
|
||||
<menu_item_call.on_click
|
||||
function="Develop.Fonts.Dump" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Dump Font Textures"
|
||||
name="Dump Font Textures">
|
||||
<menu_item_call.on_click
|
||||
function="Develop.Fonts.DumpTextures" />
|
||||
</menu_item_call>
|
||||
<menu_item_call
|
||||
label="Dump SelectMgr"
|
||||
name="Dump SelectMgr">
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ class ViewerManifest(LLManifest):
|
|||
self.path("*.tga")
|
||||
|
||||
# Include our fonts
|
||||
with self.prefix(src_dst="fonts"):
|
||||
with self.prefix(src="../packages/fonts"):
|
||||
self.path("*.ttf")
|
||||
self.path("*.txt")
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue