From fadb3792caa5279d3521dcaad44a6211bfa4bfad Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Tue, 9 Jan 2018 20:31:21 +0200
Subject: [PATCH] MAINT-8146 Fixed Installing viewer to non default path
 results in incorrect fonts loading

---
 indra/llrender/llfontfreetype.cpp | 64 ++++++++++++++++++++++++++++++-
 indra/llrender/llfontfreetype.h   |  2 +
 indra/llrender/llfontregistry.cpp |  2 +-
 3 files changed, 65 insertions(+), 3 deletions(-)

diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp
index de26d19efc1..5c1f4ff8b34 100644
--- a/indra/llrender/llfontfreetype.cpp
+++ b/indra/llrender/llfontfreetype.cpp
@@ -106,6 +106,8 @@ LLFontFreetype::LLFontFreetype()
 	mAscender(0.f),
 	mDescender(0.f),
 	mLineHeight(0.f),
+	pFontBuffer(NULL),
+	mBufferSize(0),
 	mIsFallback(FALSE),
 	mFTFace(NULL),
 	mRenderGlyphCount(0),
@@ -128,6 +130,8 @@ LLFontFreetype::~LLFontFreetype()
 	mCharGlyphInfoMap.clear();
 
 	delete mFontBitmapCachep;
+	delete pFontBuffer;
+	disclaimMem(mBufferSize);
 	// mFallbackFonts cleaned up by LLPointer destructor
 }
 
@@ -143,13 +147,64 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v
 	
 	int error;
 
+#ifdef LL_WINDOWS
+
+	if (mBufferSize > 0)
+	{
+		delete pFontBuffer;
+		disclaimMem(mBufferSize);
+		pFontBuffer = NULL;
+		mBufferSize = 0;
+	}
+
+	S32 file_size = 0;
+	LLFILE* file = LLFile::fopen(filename, "rb");
+	if (!file)
+	{
+		return FALSE;
+	}
+
+	if (!fseek(file, 0, SEEK_END))
+	{
+		file_size = ftell(file);
+		fseek(file, 0, SEEK_SET);
+	}
+
+	// Don't delete before FT_Done_Face
+	pFontBuffer = new(std::nothrow) U8[file_size];
+	if (!pFontBuffer)
+	{
+		fclose(file);
+		return FALSE;
+	}
+
+	mBufferSize = fread(pFontBuffer, 1, file_size, file);
+	fclose(file);
+
+	if (mBufferSize != file_size)
+	{
+		delete pFontBuffer;
+		mBufferSize = 0;
+		return FALSE;
+	}
+
+	error = FT_New_Memory_Face( gFTLibrary,
+								(FT_Byte*) pFontBuffer,
+								mBufferSize,
+								0,
+								&mFTFace);
+#else
 	error = FT_New_Face( gFTLibrary,
 						 filename.c_str(),
 						 0,
-						 &mFTFace );
+						 &mFTFace);
+#endif
 
-    if (error)
+	if (error)
 	{
+		delete pFontBuffer;
+		pFontBuffer = NULL;
+		mBufferSize = 0;
 		return FALSE;
 	}
 
@@ -166,10 +221,15 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v
 	{
 		// Clean up freetype libs.
 		FT_Done_Face(mFTFace);
+		delete pFontBuffer;
+		pFontBuffer = NULL;
+		mBufferSize = 0;
 		mFTFace = NULL;
 		return FALSE;
 	}
 
+	claimMem(mBufferSize);
+
 	F32 y_max, y_min, x_max, x_min;
 	F32 ems_per_unit = 1.f/ mFTFace->units_per_EM;
 	F32 pixels_per_unit = pixels_per_em * ems_per_unit;
diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h
index a5ece42b885..26ba6954180 100644
--- a/indra/llrender/llfontfreetype.h
+++ b/indra/llrender/llfontfreetype.h
@@ -158,6 +158,8 @@ class LLFontFreetype : public LLRefCount, public LLTrace::MemTrackable<LLFontFre
 	F32 mLineHeight;
 
 	LLFT_Face mFTFace;
+	U8* pFontBuffer;
+	S32 mBufferSize;
 
 	BOOL mIsFallback;
 	font_vector_t mFallbackFonts; // A list of fallback fonts to look for glyphs in (for Unicode chars)
diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp
index d0036874153..3c829596ce5 100644
--- a/indra/llrender/llfontregistry.cpp
+++ b/indra/llrender/llfontregistry.cpp
@@ -447,7 +447,7 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
 			if (!fontp->loadFace(font_path, extra_scale * point_size,
 								 LLFontGL::sVertDPI, LLFontGL::sHorizDPI, 2, is_fallback))
 			{
-				LL_INFOS_ONCE("LLFontRegistry") << "Couldn't load font " << *file_name_it << LL_ENDL;
+				LL_INFOS_ONCE("LLFontRegistry") << "Couldn't load font " << *file_name_it << " from path " << local_path << LL_ENDL;
 				delete fontp;
 				fontp = NULL;
 			}
-- 
GitLab