FreeType fix (thanks shevalie)

This commit is contained in:
Joshua Granick
2014-02-07 09:51:21 -08:00
parent 55f1cbf94b
commit edd0e7342d
2 changed files with 31 additions and 15 deletions

View File

@@ -154,6 +154,7 @@ Font::~Font()
{ {
for(int i=0;i<mSheets.size();i++) for(int i=0;i<mSheets.size();i++)
mSheets[i]->DecRef(); mSheets[i]->DecRef();
if (mFace) delete mFace;
} }

View File

@@ -46,8 +46,8 @@ FT_Library sgLibrary = 0;
class FreeTypeFont : public FontFace class FreeTypeFont : public FontFace
{ {
public: public:
FreeTypeFont(FT_Face inFace, int inPixelHeight, int inTransform) : FreeTypeFont(FT_Face inFace, int inPixelHeight, int inTransform, void* inBuffer) :
mFace(inFace), mPixelHeight(inPixelHeight),mTransform(inTransform) mFace(inFace), mPixelHeight(inPixelHeight),mTransform(inTransform), mBuffer(inBuffer)
{ {
} }
@@ -55,6 +55,7 @@ public:
~FreeTypeFont() ~FreeTypeFont()
{ {
FT_Done_Face(mFace); FT_Done_Face(mFace);
if (mBuffer) free(mBuffer);
} }
bool LoadBitmap(int inChar) bool LoadBitmap(int inChar)
@@ -155,16 +156,18 @@ public:
} }
} }
void* mBuffer;
FT_Face mFace; FT_Face mFace;
uint32 mTransform; uint32 mTransform;
int mPixelHeight; int mPixelHeight;
}; };
int MyNewFace(const std::string &inFace, int inIndex, FT_Face *outFace, AutoGCRoot *inBytes) int MyNewFace(const std::string &inFace, int inIndex, FT_Face *outFace, AutoGCRoot *inBytes, void** outBuffer)
{ {
*outFace = 0; *outFace = 0;
*outBuffer = 0;
int result = 0; int result = 0;
result = FT_New_Face(sgLibrary, inFace.c_str(), inIndex, outFace); result = FT_New_Face(sgLibrary, inFace.c_str(), inIndex, outFace);
if (*outFace==0) if (*outFace==0)
@@ -188,6 +191,7 @@ int MyNewFace(const std::string &inFace, int inIndex, FT_Face *outFace, AutoGCRo
// The font owns the bytes here - so we just leak (fonts are not actually cleaned) // The font owns the bytes here - so we just leak (fonts are not actually cleaned)
if (!*outFace) if (!*outFace)
free(buf); free(buf);
else *outBuffer = buf;
} }
} }
return result; return result;
@@ -197,10 +201,12 @@ int MyNewFace(const std::string &inFace, int inIndex, FT_Face *outFace, AutoGCRo
static FT_Face OpenFont(const std::string &inFace, unsigned int inFlags, AutoGCRoot *inBytes) static FT_Face OpenFont(const std::string &inFace, unsigned int inFlags, AutoGCRoot *inBytes, void** outBuffer)
{ {
*outBuffer = 0;
FT_Face face = 0; FT_Face face = 0;
MyNewFace(inFace.c_str(), 0, &face, inBytes); void* pBuffer = 0;
MyNewFace(inFace.c_str(), 0, &face, inBytes, &pBuffer);
if (face && inFlags!=0 && face->num_faces>1) if (face && inFlags!=0 && face->num_faces>1)
{ {
int n = face->num_faces; int n = face->num_faces;
@@ -208,10 +214,14 @@ static FT_Face OpenFont(const std::string &inFace, unsigned int inFlags, AutoGCR
for(int f=1;f<n;f++) for(int f=1;f<n;f++)
{ {
FT_Face test = 0; FT_Face test = 0;
MyNewFace(inFace.c_str(), f, &test, NULL); void* pTestBuffer = 0;
MyNewFace(inFace.c_str(), f, &test, NULL, &pTestBuffer);
if (test && test->style_flags == inFlags) if (test && test->style_flags == inFlags)
{ {
// A goodie! // A goodie!
FT_Done_Face(face);
if (pBuffer) free(pBuffer);
*outBuffer = pTestBuffer;
return test; return test;
} }
else if (test) else if (test)
@@ -219,6 +229,7 @@ static FT_Face OpenFont(const std::string &inFace, unsigned int inFlags, AutoGCR
} }
// The original face will have to do... // The original face will have to do...
} }
*outBuffer = pBuffer;
return face; return face;
} }
@@ -411,7 +422,7 @@ std::string ToAssetName(const std::string &inPath)
#endif #endif
} }
FT_Face FindFont(const std::string &inFontName, unsigned int inFlags, AutoGCRoot *inBytes) FT_Face FindFont(const std::string &inFontName, unsigned int inFlags, AutoGCRoot *inBytes, void** pBuffer)
{ {
std::string fname = inFontName; std::string fname = inFontName;
@@ -420,20 +431,20 @@ FT_Face FindFont(const std::string &inFontName, unsigned int inFlags, AutoGCRoot
fname += ".ttf"; fname += ".ttf";
#endif #endif
FT_Face font = OpenFont(fname,inFlags,inBytes); FT_Face font = OpenFont(fname,inFlags,inBytes, pBuffer);
if (font==0 && fname.find("\\")==std::string::npos && fname.find("/")==std::string::npos) if (font==0 && fname.find("\\")==std::string::npos && fname.find("/")==std::string::npos)
{ {
std::string file_name; std::string file_name;
#if HX_MACOS #if HX_MACOS
font = OpenFont(ToAssetName(fname).c_str(),inFlags,NULL); font = OpenFont(ToAssetName(fname).c_str(),inFlags,NULL,pBuffer);
#endif #endif
if (font==0 && GetFontFile(fname,file_name)) if (font==0 && GetFontFile(fname,file_name))
{ {
// printf("Found font in %s\n", file_name.c_str()); // printf("Found font in %s\n", file_name.c_str());
font = OpenFont(file_name.c_str(),inFlags,NULL); font = OpenFont(file_name.c_str(),inFlags,NULL,pBuffer);
// printf("Opened : %p\n", font); // printf("Opened : %p\n", font);
} }
@@ -461,8 +472,9 @@ FontFace *FontFace::CreateFreeType(const TextFormat &inFormat,double inScale,Aut
flags |= ffBold; flags |= ffBold;
if (inFormat.italic) if (inFormat.italic)
flags |= ffItalic; flags |= ffItalic;
face = FindFont(str,flags,inBytes); void* pBuffer = 0;
face = FindFont(str,flags,inBytes,&pBuffer);
if (!face) if (!face)
return 0; return 0;
@@ -475,7 +487,7 @@ FontFace *FontFace::CreateFreeType(const TextFormat &inFormat,double inScale,Aut
transform |= ffBold; transform |= ffBold;
if ( !(face->style_flags & ffItalic) && inFormat.italic ) if ( !(face->style_flags & ffItalic) && inFormat.italic )
transform |= ffItalic; transform |= ffItalic;
return new FreeTypeFont(face,height,transform); return new FreeTypeFont(face,height,transform,pBuffer);
} }
@@ -658,7 +670,8 @@ value freetype_import_font(value font_file, value char_vector, value em_size, va
AutoGCRoot *bytes = !val_is_null(inBytes) ? new AutoGCRoot(inBytes) : NULL; AutoGCRoot *bytes = !val_is_null(inBytes) ? new AutoGCRoot(inBytes) : NULL;
result = lime::MyNewFace(val_string(font_file), 0, &face, bytes); void* pBuffer = 0;
result = lime::MyNewFace(val_string(font_file), 0, &face, bytes, &pBuffer);
if (result == FT_Err_Unknown_File_Format) if (result == FT_Err_Unknown_File_Format)
{ {
@@ -674,6 +687,7 @@ value freetype_import_font(value font_file, value char_vector, value em_size, va
if (!FT_IS_SCALABLE(face)) if (!FT_IS_SCALABLE(face))
{ {
FT_Done_Face(face); FT_Done_Face(face);
if (pBuffer) free(pBuffer);
val_throw(alloc_string("Font is not scalable!")); val_throw(alloc_string("Font is not scalable!"));
return alloc_null(); return alloc_null();
@@ -843,6 +857,7 @@ value freetype_import_font(value font_file, value char_vector, value em_size, va
alloc_field(ret, val_id("kerning"), alloc_null()); alloc_field(ret, val_id("kerning"), alloc_null());
FT_Done_Face(face); FT_Done_Face(face);
if (pBuffer) free(pBuffer);
return ret; return ret;
} }