diff options
author | andreykproductengine <andreykproductengine@lindenlab.com> | 2018-02-12 19:31:53 +0200 |
---|---|---|
committer | andreykproductengine <andreykproductengine@lindenlab.com> | 2018-02-12 19:31:53 +0200 |
commit | e394c0623d5b015ba5495b3c80559a7420186c5b (patch) | |
tree | 195017649dab11492a5fd716ea345d75718b6359 | |
parent | 2714ff8f25972c28d6667c83b834f189b0427f2d (diff) |
MAINT-8146 Remade fix with streams to save memory
-rw-r--r-- | indra/llrender/llfontfreetype.cpp | 114 | ||||
-rw-r--r-- | indra/llrender/llfontfreetype.h | 9 |
2 files changed, 69 insertions, 54 deletions
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 <ft2build.h> +#ifdef LL_WINDOWS +#include <freetype2\freetype\ftsystem.h> +#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<llifstream *>(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<llifstream *>(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; diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h index 26ba695418..aadebf5e70 100644 --- a/indra/llrender/llfontfreetype.h +++ b/indra/llrender/llfontfreetype.h @@ -40,6 +40,8 @@ // We'll forward declare the struct here. JC struct FT_FaceRec_; typedef struct FT_FaceRec_* LLFT_Face; +struct FT_StreamRec_; +typedef struct FT_StreamRec_ LLFT_Stream; class LLFontManager { @@ -158,8 +160,11 @@ private: F32 mLineHeight; LLFT_Face mFTFace; - U8* pFontBuffer; - S32 mBufferSize; + +#ifdef LL_WINDOWS + llifstream *pFileStream; + LLFT_Stream *pFtStream; +#endif BOOL mIsFallback; font_vector_t mFallbackFonts; // A list of fallback fonts to look for glyphs in (for Unicode chars) |