SL-10610 FIXED Floaters fails to display certain symbols. Added ability to load font collections.
parent
9a2159a039
commit
fd7b0e19da
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
Loading…
Reference in New Issue