summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandreykproductengine <andreykproductengine@lindenlab.com>2018-02-12 19:31:53 +0200
committerandreykproductengine <andreykproductengine@lindenlab.com>2018-02-12 19:31:53 +0200
commite394c0623d5b015ba5495b3c80559a7420186c5b (patch)
tree195017649dab11492a5fd716ea345d75718b6359
parent2714ff8f25972c28d6667c83b834f189b0427f2d (diff)
MAINT-8146 Remade fix with streams to save memory
-rw-r--r--indra/llrender/llfontfreetype.cpp114
-rw-r--r--indra/llrender/llfontfreetype.h9
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)