summaryrefslogtreecommitdiff
path: root/indra/llrender/llfontfreetype.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llrender/llfontfreetype.cpp')
-rw-r--r--indra/llrender/llfontfreetype.cpp47
1 files changed, 44 insertions, 3 deletions
diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp
index 19326d301e..5c1b82b230 100644
--- a/indra/llrender/llfontfreetype.cpp
+++ b/indra/llrender/llfontfreetype.cpp
@@ -52,6 +52,7 @@
//#include "imdebug.h"
#include "llfontbitmapcache.h"
#include "llgl.h"
+#include "llwindow.h"
#define ENABLE_OT_SVG_SUPPORT
@@ -188,7 +189,7 @@ bool LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v
return false;
openArgs.flags = FT_OPEN_MEMORY;
- int error = FT_Open_Face( gFTLibrary, &openArgs, 0, &mFTFace );
+ int error = FT_Open_Face( gFTLibrary, &openArgs, face_n, &mFTFace );
if (error)
return false;
@@ -197,6 +198,9 @@ bool LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v
mHinting = hinting;
mFontFlags = flags;
mWeight = weight;
+ mFaceIndex = face_n;
+ mVertDPI = vert_dpi;
+ mHorzDPI = horz_dpi;
bool variable_font = false;
if (weight >= 0)
@@ -314,7 +318,7 @@ S32 LLFontFreetype::getNumFaces(const std::string& filename)
}
void LLFontFreetype::addFallbackFont(const LLPointer<LLFontFreetype>& fallback_font,
- const char_functor_t& functor)
+ const char_functor_t& functor) const
{
mFallbackFonts.emplace_back(fallback_font, functor);
}
@@ -419,6 +423,18 @@ bool LLFontFreetype::hasGlyph(llwchar wch) const
return(mCharGlyphInfoMap.find(wch) != mCharGlyphInfoMap.end());
}
+bool LLFontFreetype::hasFallbackPath(const std::string& path) const
+{
+ for (const fallback_font_t& pair : mFallbackFonts)
+ {
+ if (pair.first->getName() == path)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
LLFontGlyphInfo* LLFontFreetype::addGlyph(llwchar wch, EFontGlyphType glyph_type) const
{
if (!mFTFace)
@@ -501,6 +517,31 @@ LLFontGlyphInfo* LLFontFreetype::addGlyph(llwchar wch, EFontGlyphType glyph_type
glyph_type);
}
}
+
+ // Nothing above covers this char: ask the OS for a font that does,
+ // load it and attach it.
+ if (mAttemptedFallbackChars.insert(wch).second)
+ {
+ LLFontFallbackMatch match = LLWindow::findFallbackFontForChar(wch);
+ if (!match.mPath.empty() && !hasFallbackPath(match.mPath))
+ {
+ LLPointer<LLFontFreetype> fallback = new LLFontFreetype;
+ if (fallback->loadFace(match.mPath, mPointSize, mVertDPI, mHorzDPI,
+ /*weight*/ -1, /*is_fallback*/ true,
+ match.mFaceIndex, mHinting, mFontFlags))
+ {
+ glyph_index = FT_Get_Char_Index(fallback->mFTFace, wch);
+ if (glyph_index)
+ {
+ LL_DEBUGS("Font") << "Lazy OS fallback for U+" << std::hex << (U32)wch << std::dec
+ << ": " << match.mPath << " (face " << match.mFaceIndex << ")" << LL_ENDL;
+ addFallbackFont(fallback, nullptr);
+ return addGlyphFromFont(fallback, wch, glyph_index, glyph_type);
+ }
+ // Matched font doesn't actually cover wch: discard it.
+ }
+ }
+ }
}
auto range_it = mCharGlyphInfoMap.equal_range(wch);
@@ -728,7 +769,7 @@ void LLFontFreetype::renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index, ll
void LLFontFreetype::reset(F32 vert_dpi, F32 horz_dpi)
{
resetBitmapCache();
- loadFace(mName, mPointSize, vert_dpi ,horz_dpi, mWeight, mIsFallback, 0, mHinting, mFontFlags);
+ loadFace(mName, mPointSize, vert_dpi ,horz_dpi, mWeight, mIsFallback, mFaceIndex, mHinting, mFontFlags);
if (!mIsFallback)
{
// This is the head of the list - need to rebuild ourself and all fallbacks.