SL-10610 FIXED Floaters fails to display certain symbols. Added ability to load font collections.

meow-7.2.2
maxim_productengine 2019-03-19 11:16:24 +02:00
parent 9a2159a039
commit fd7b0e19da
7 changed files with 169 additions and 69 deletions

View File

@ -157,7 +157,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)
BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback, S32 face_n)
{
// Don't leak face objects. This is also needed to deal with
// changed font file names.
@ -168,40 +168,8 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v
}
int error;
#ifdef LL_WINDOWS
pFileStream = new llifstream(filename, std::ios::binary);
if (pFileStream->is_open())
{
std::streampos beg = pFileStream->tellg();
pFileStream->seekg(0, std::ios::end);
std::streampos end = pFileStream->tellg();
std::size_t file_size = end - beg;
pFileStream->seekg(0, std::ios::beg);
pFtStream = new LLFT_Stream();
pFtStream->base = 0;
pFtStream->pos = 0;
pFtStream->size = file_size;
pFtStream->descriptor.pointer = pFileStream;
pFtStream->read = ft_read_cb;
pFtStream->close = ft_close_cb;
FT_Open_Args args;
args.flags = FT_OPEN_STREAM;
args.stream = (FT_StreamRec*)pFtStream;
error = FT_Open_Face(gFTLibrary,
&args,
0,
&mFTFace);
}
else
{
delete pFileStream;
pFileStream = NULL;
return FALSE;
}
error = ftOpenFace(filename, face_n);
#else
error = FT_New_Face( gFTLibrary,
filename.c_str(),
@ -212,11 +180,7 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v
if (error)
{
#ifdef LL_WINDOWS
pFileStream->close();
delete pFileStream;
delete pFtStream;
pFileStream = NULL;
pFtStream = NULL;
clearFontStreams();
#endif
return FALSE;
}
@ -235,11 +199,7 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v
// Clean up freetype libs.
FT_Done_Face(mFTFace);
#ifdef LL_WINDOWS
pFileStream->close();
delete pFileStream;
delete pFtStream;
pFileStream = NULL;
pFtStream = NULL;
clearFontStreams();
#endif
mFTFace = NULL;
return FALSE;
@ -297,6 +257,78 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v
return TRUE;
}
S32 LLFontFreetype::getNumFaces(const std::string& filename)
{
if (mFTFace)
{
FT_Done_Face(mFTFace);
mFTFace = NULL;
}
S32 num_faces = 1;
#ifdef LL_WINDOWS
int error = ftOpenFace(filename, 0);
if (error)
{
return 0;
}
else
{
num_faces = mFTFace->num_faces;
}
FT_Done_Face(mFTFace);
clearFontStreams();
mFTFace = NULL;
#endif
return num_faces;
}
#ifdef LL_WINDOWS
S32 LLFontFreetype::ftOpenFace(const std::string& filename, S32 face_n)
{
S32 error = -1;
pFileStream = new llifstream(filename, std::ios::binary);
if (pFileStream->is_open())
{
std::streampos beg = pFileStream->tellg();
pFileStream->seekg(0, std::ios::end);
std::streampos end = pFileStream->tellg();
std::size_t file_size = end - beg;
pFileStream->seekg(0, std::ios::beg);
pFtStream = new LLFT_Stream();
pFtStream->base = 0;
pFtStream->pos = 0;
pFtStream->size = file_size;
pFtStream->descriptor.pointer = pFileStream;
pFtStream->read = ft_read_cb;
pFtStream->close = ft_close_cb;
FT_Open_Args args;
args.flags = FT_OPEN_STREAM;
args.stream = (FT_StreamRec*)pFtStream;
error = FT_Open_Face(gFTLibrary, &args, face_n, &mFTFace);
}
return error;
}
void LLFontFreetype::clearFontStreams()
{
if (pFileStream)
{
pFileStream->close();
}
delete pFileStream;
delete pFtStream;
pFileStream = NULL;
pFtStream = NULL;
}
#endif
void LLFontFreetype::setFallbackFonts(const font_vector_t &font)
{
mFallbackFonts = font;

View File

@ -84,7 +84,14 @@ 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);
BOOL loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback, S32 face_n = 0);
S32 getNumFaces(const std::string& filename);
#ifdef LL_WINDOWS
S32 ftOpenFace(const std::string& filename, S32 face_n);
void clearFontStreams();
#endif
typedef std::vector<LLPointer<LLFontFreetype> > font_vector_t;

View File

@ -89,14 +89,24 @@ 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)
BOOL LLFontGL::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, 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);
return mFontFreetype->loadFace(filename, point_size, vert_dpi, horz_dpi, components, is_fallback, face_n);
}
S32 LLFontGL::getNumFaces(const std::string& filename)
{
if (mFontFreetype == reinterpret_cast<LLFontFreetype*>(NULL))
{
mFontFreetype = new LLFontFreetype;
}
return mFontFreetype->getNumFaces(filename);
}
static LLTrace::BlockTimerStatHandle FTM_RENDER_FONTS("Fonts");

View File

@ -87,7 +87,9 @@ 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);
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);
S32 getNumFaces(const std::string& filename);
S32 render(const LLWString &text, S32 begin_offset,
const LLRect& rect,

View File

@ -62,6 +62,16 @@ LLFontDescriptor::LLFontDescriptor(const std::string& name,
{
}
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)
{
mFontCollectionsList = ft_collection_listections;
}
LLFontDescriptor::LLFontDescriptor(const std::string& name,
const std::string& size,
const U8 style):
@ -164,7 +174,7 @@ LLFontDescriptor LLFontDescriptor::normalize() const
if (removeSubString(new_name,"Italic"))
new_style |= LLFontGL::ITALIC;
return LLFontDescriptor(new_name,new_size,new_style,getFileNames());
return LLFontDescriptor(new_name,new_size,new_style,getFileNames(),getFontCollectionsList());
}
LLFontRegistry::LLFontRegistry(bool create_gl_textures)
@ -215,6 +225,7 @@ bool LLFontRegistry::parseFontInfo(const std::string& xml_filename)
success = success || init_succ;
}
}
//if (success)
// dump();
@ -262,6 +273,16 @@ bool font_desc_init_from_xml(LLXMLNodePtr node, LLFontDescriptor& desc)
{
std::string font_file_name = child->getTextContents();
desc.getFileNames().push_back(font_file_name);
if (child->hasAttribute("load_collection"))
{
BOOL col = FALSE;
child->getAttributeBOOL("load_collection", col);
if (col)
{
desc.getFontCollectionsList().push_back(font_file_name);
}
}
}
else if (child->hasName("os"))
{
@ -308,8 +329,15 @@ bool init_from_xml(LLFontRegistry* registry, LLXMLNodePtr node)
match_file_names.insert(match_file_names.begin(),
desc.getFileNames().begin(),
desc.getFileNames().end());
string_vec_t collections_list = match_desc->getFontCollectionsList();
collections_list.insert(collections_list.begin(),
desc.getFontCollectionsList().begin(),
desc.getFontCollectionsList().end());
LLFontDescriptor new_desc = *match_desc;
new_desc.getFileNames() = match_file_names;
new_desc.getFontCollectionsList() = collections_list;
registry->mFontMap.erase(*match_desc);
registry->mFontMap[new_desc] = NULL;
}
@ -395,6 +423,7 @@ 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;
LLFontDescriptor default_desc("default",s_template_string,0);
const LLFontDescriptor *match_default_desc = getMatchingFontDesc(default_desc);
@ -403,6 +432,9 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& 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());
}
// Add ultimate fallback list - generated dynamically on linux,
@ -435,13 +467,15 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
file_name_it != file_names.end();
++file_name_it)
{
LLFontGL *fontp = new LLFontGL;
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);
#endif
bool is_ft_collection = (std::find(ft_collection_list.begin(), ft_collection_list.end(), *file_name_it) != ft_collection_list.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;
@ -452,12 +486,37 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
font_paths_it != font_paths.end();
++font_paths_it)
{
if (fontp->loadFace(*font_paths_it, point_size_scale,
LLFontGL::sVertDPI, LLFontGL::sHorizDPI, 2, is_fallback))
fontp = new LLFontGL;
S32 num_faces = is_ft_collection ? fontp->getNumFaces(*font_paths_it) : 1;
for (S32 i = 0; i < num_faces; i++)
{
is_font_loaded = true;
break;
if (fontp == NULL)
{
fontp = new LLFontGL;
}
if (fontp->loadFace(*font_paths_it, point_size_scale,
LLFontGL::sVertDPI, LLFontGL::sHorizDPI, 2, is_fallback, i))
{
is_font_loaded = true;
if (is_first_found)
{
result = fontp;
is_first_found = false;
}
else
{
fontlist.push_back(fontp->mFontFreetype);
delete fontp;
fontp = NULL;
}
}
else
{
delete fontp;
fontp = NULL;
}
}
if (is_font_loaded) break;
}
if(!is_font_loaded)
{
@ -465,21 +524,6 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
delete fontp;
fontp = NULL;
}
if(fontp)
{
if (is_first_found)
{
result = fontp;
is_first_found = false;
}
else
{
fontlist.push_back(fontp->mFontFreetype);
delete fontp;
fontp = NULL;
}
}
}
if (result && !fontlist.empty())

View File

@ -40,6 +40,7 @@ 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 normalize() const;
bool operator<(const LLFontDescriptor& b) const;
@ -52,6 +53,8 @@ public:
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; }
const U8 getStyle() const { return mStyle; }
void setStyle(U8 style) { mStyle = style; }
@ -59,6 +62,7 @@ private:
std::string mName;
std::string mSize;
string_vec_t mFileNames;
string_vec_t mFontCollectionsList;
U8 mStyle;
};

View File

@ -10,6 +10,7 @@
<file>simhei.ttf</file>
<file>ArialUni.ttf</file>
<file>msyh.ttc</file>
<file load_collection="true">Cambria.ttc</file>
</os>
<os name="Mac">
<file>ヒラギノ角ゴシック W3.ttc</file>