From fadb3792caa5279d3521dcaad44a6211bfa4bfad Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Tue, 9 Jan 2018 20:31:21 +0200 Subject: MAINT-8146 Fixed Installing viewer to non default path results in incorrect fonts loading --- indra/llrender/llfontfreetype.cpp | 64 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 2 deletions(-) (limited to 'indra/llrender/llfontfreetype.cpp') diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp index de26d19efc..5c1f4ff8b3 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; -- cgit v1.2.3 From e394c0623d5b015ba5495b3c80559a7420186c5b Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Mon, 12 Feb 2018 19:31:53 +0200 Subject: MAINT-8146 Remade fix with streams to save memory --- indra/llrender/llfontfreetype.cpp | 114 +++++++++++++++++++++----------------- 1 file changed, 62 insertions(+), 52 deletions(-) (limited to 'indra/llrender/llfontfreetype.cpp') diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp index 5c1f4ff8b3..bd2eef7fd3 100644 --- a/indra/llrender/llfontfreetype.cpp +++ b/indra/llrender/llfontfreetype.cpp @@ -31,6 +31,9 @@ // Freetype stuff #include +#ifdef LL_WINDOWS +#include +#endif // For some reason, this won't work if it's not wrapped in the ifdef #ifdef FT_FREETYPE_H @@ -106,8 +109,10 @@ LLFontFreetype::LLFontFreetype() mAscender(0.f), mDescender(0.f), mLineHeight(0.f), - pFontBuffer(NULL), - mBufferSize(0), +#ifdef LL_WINDOWS + pFileStream(NULL), + pFtStream(NULL), +#endif mIsFallback(FALSE), mFTFace(NULL), mRenderGlyphCount(0), @@ -129,12 +134,29 @@ LLFontFreetype::~LLFontFreetype() std::for_each(mCharGlyphInfoMap.begin(), mCharGlyphInfoMap.end(), DeletePairedPointer()); mCharGlyphInfoMap.clear(); +#ifdef LL_WINDOWS + delete pFileStream; // closed by FT_Done_Face + delete pFtStream; +#endif delete mFontBitmapCachep; - delete pFontBuffer; - disclaimMem(mBufferSize); // mFallbackFonts cleaned up by LLPointer destructor } +#ifdef LL_WINDOWS +unsigned long ft_read_cb(FT_Stream stream, unsigned long offset, unsigned char *buffer, unsigned long count) { + if (count <= 0) return count; + llifstream *file_stream = static_cast(stream->descriptor.pointer); + file_stream->seekg(offset, std::ios::beg); + file_stream->read((char*)buffer, count); + return file_stream->gcount(); +} + +void ft_close_cb(FT_Stream stream) { + llifstream *file_stream = static_cast(stream->descriptor.pointer); + file_stream->close(); +} +#endif + BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback) { // Don't leak face objects. This is also needed to deal with @@ -148,51 +170,37 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v int error; #ifdef LL_WINDOWS - - if (mBufferSize > 0) + pFileStream = new llifstream(filename, std::ios::binary); + if (pFileStream->is_open()) { - delete pFontBuffer; - disclaimMem(mBufferSize); - pFontBuffer = NULL; - mBufferSize = 0; - } - - S32 file_size = 0; - LLFILE* file = LLFile::fopen(filename, "rb"); - if (!file) - { - return FALSE; + 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); } - - 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) + else { - delete pFontBuffer; - mBufferSize = 0; + delete pFileStream; return FALSE; } - - error = FT_New_Memory_Face( gFTLibrary, - (FT_Byte*) pFontBuffer, - mBufferSize, - 0, - &mFTFace); #else error = FT_New_Face( gFTLibrary, filename.c_str(), @@ -202,9 +210,11 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v if (error) { - delete pFontBuffer; - pFontBuffer = NULL; - mBufferSize = 0; +#ifdef LL_WINDOWS + pFileStream->close(); + delete pFileStream; + delete pFtStream; +#endif return FALSE; } @@ -219,17 +229,17 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v if (error) { +#ifdef LL_WINDOWS + pFileStream->close(); + delete pFileStream; + delete pFtStream; +#endif // 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; -- cgit v1.2.3 From 8f65593786a4302a1ef7c95ce048bd658367a220 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Tue, 13 Feb 2018 14:45:09 +0200 Subject: MAINT-8146 Clearing pointers --- indra/llrender/llfontfreetype.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'indra/llrender/llfontfreetype.cpp') diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp index bd2eef7fd3..ab668dc192 100644 --- a/indra/llrender/llfontfreetype.cpp +++ b/indra/llrender/llfontfreetype.cpp @@ -199,6 +199,7 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v else { delete pFileStream; + pFileStream = NULL; return FALSE; } #else @@ -214,6 +215,8 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v pFileStream->close(); delete pFileStream; delete pFtStream; + pFileStream = NULL; + pFtStream = NULL; #endif return FALSE; } @@ -229,13 +232,15 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v if (error) { + // Clean up freetype libs. + FT_Done_Face(mFTFace); #ifdef LL_WINDOWS pFileStream->close(); delete pFileStream; delete pFtStream; + pFileStream = NULL; + pFtStream = NULL; #endif - // Clean up freetype libs. - FT_Done_Face(mFTFace); mFTFace = NULL; return FALSE; } -- cgit v1.2.3