FreeType fix (thanks shevalie)
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user