[linux] use fontconfig to select system fonts

This patch removes the hardcoded font paths
from the linux project and uses fontconfig
to find the best match for a given font-family
The implementation also adds the possibility
to load a font file from the applications
resource directory
This commit is contained in:
Andre Rudlaff 2012-09-18 00:48:52 +02:00
parent 3be86f8b85
commit 44ccc40269
2 changed files with 42 additions and 37 deletions

View File

@ -3,12 +3,14 @@
#include <vector> #include <vector>
#include <string> #include <string>
#include <sstream> #include <sstream>
#include <fontconfig/fontconfig.h>
#include "platform/CCFileUtils.h" #include "platform/CCFileUtils.h"
#include "platform/CCPlatformMacros.h" #include "platform/CCPlatformMacros.h"
#define __CC_PLATFORM_IMAGE_CPP__ #define __CC_PLATFORM_IMAGE_CPP__
#include "platform/CCImageCommon_cpp.h" #include "platform/CCImageCommon_cpp.h"
#include "platform/CCImage.h" #include "platform/CCImage.h"
#include "platform/linux/CCApplication.h"
#include "ft2build.h" #include "ft2build.h"
#include "CCStdC.h" #include "CCStdC.h"
@ -26,27 +28,13 @@ struct TextLine {
wchar_t* text; wchar_t* text;
}; };
struct FontTableItem {
char* family_name;
char* style_name;
char* filename;
};
const int fontTableItems = 4;
const char* fontPath = "/usr/share/fonts/truetype/";
FontTableItem fontsTable[fontTableItems] = {
{ "Serif", "Medium", "freefont/FreeSerif.ttf" },
{ "Sans", "Medium", "freefont/FreeSans.ttf" },
{ "WenQuanYi Micro Hei", "Regular", "wqy/wqy-microhei.ttc" },
{ "WenQuanYi Zen Hei", "Regular", "wqy/wqy-zenhei.ttc" },
};
NS_CC_BEGIN NS_CC_BEGIN
class BitmapDC class BitmapDC
{ {
public: public:
BitmapDC() { BitmapDC() {
libError = FT_Init_FreeType( &library ); libError = FT_Init_FreeType( &library );
FcInit();
iInterval = szFont_kenning; iInterval = szFont_kenning;
m_pData = NULL; m_pData = NULL;
reset(); reset();
@ -54,6 +42,7 @@ public:
~BitmapDC() { ~BitmapDC() {
FT_Done_FreeType(library); FT_Done_FreeType(library);
FcFini();
//data will be deleted by CCImage //data will be deleted by CCImage
// if (m_pData) { // if (m_pData) {
// delete m_pData; // delete m_pData;
@ -238,27 +227,42 @@ public:
return iRet; return iRet;
} }
char* getFontFile(const char* family_name) { std::string getFontFile(const char* family_name) {
char* ret = NULL; std::string fontPath = family_name;
for (int i=0; i<fontTableItems; ++i) {
FontTableItem* item = &fontsTable[i]; // check if the parameter is a font file shipped with the application
if (strcmp(item->family_name, family_name) == 0) { if ( fontPath.find(".ttf") != std::string::npos ) {
size_t len = strlen(fontPath) + strlen(item->filename) + 1; fontPath = cocos2d::CCApplication::sharedApplication()->getResourceRootPath() + std::string("/") + fontPath;
ret = (char*) malloc(len);
snprintf(ret, len, "%s%s", fontPath, item->filename); FILE *f = fopen(fontPath.c_str(), "r");
break; if ( f ) {
fclose(f);
return fontPath;
} }
} }
// Return a default font , if font is not found // use fontconfig to match the parameter against the fonts installed on the system
if (ret == NULL) { FcPattern *pattern = FcPatternBuild (0, FC_FAMILY, FcTypeString, family_name, (char *) 0);
FontTableItem* item = &fontsTable[0]; FcConfigSubstitute(0, pattern, FcMatchPattern);
size_t len = strlen(fontPath) + strlen(item->filename) + 1; FcDefaultSubstitute(pattern);
ret = (char*) malloc(len);
snprintf(ret, len, "%s%s", fontPath, item->filename);
}
return ret; FcResult result;
FcPattern *font = FcFontMatch(0, pattern, &result);
if ( font ) {
FcChar8 *s = NULL;
if ( FcPatternGetString(font, FC_FILE, 0, &s) == FcResultMatch ) {
fontPath = (const char*)s;
FcPatternDestroy(font);
FcPatternDestroy(pattern);
return fontPath;
}
FcPatternDestroy(font);
}
FcPatternDestroy(pattern);
return family_name;
} }
bool getBitmap(const char *text, int nWidth, int nHeight, CCImage::ETextAlign eAlignMask, const char * pFontName, float fontSize) { bool getBitmap(const char *text, int nWidth, int nHeight, CCImage::ETextAlign eAlignMask, const char * pFontName, float fontSize) {
@ -276,9 +280,8 @@ public:
return false; return false;
} }
do { do {
char* fontfile = getFontFile(pFontName); std::string fontfile = getFontFile(pFontName);
iError = FT_New_Face( library, fontfile, 0, &face ); iError = FT_New_Face( library, fontfile.c_str(), 0, &face );
free(fontfile);
if (iError) { if (iError) {
//no valid font found use default //no valid font found use default
@ -393,6 +396,7 @@ public:
} }
public: public:
FT_Library library; FT_Library library;
unsigned char *m_pData; unsigned char *m_pData;
int libError; int libError;
vector<TextLine> vLines; vector<TextLine> vLines;

View File

@ -79,6 +79,7 @@
<option defaultValue="true" id="gnu.cpp.link.option.shared.1563119377" name="Shared (-shared)" superClass="gnu.cpp.link.option.shared" value="true" valueType="boolean"/> <option defaultValue="true" id="gnu.cpp.link.option.shared.1563119377" name="Shared (-shared)" superClass="gnu.cpp.link.option.shared" value="true" valueType="boolean"/>
<option id="gnu.cpp.link.option.libs.1265275896" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" valueType="libs"> <option id="gnu.cpp.link.option.libs.1265275896" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" valueType="libs">
<listOptionValue builtIn="false" value="glfw"/> <listOptionValue builtIn="false" value="glfw"/>
<listOptionValue builtIn="false" value="fontconfig"/>
<listOptionValue builtIn="false" value="GL"/> <listOptionValue builtIn="false" value="GL"/>
<listOptionValue builtIn="false" value="GLEW"/> <listOptionValue builtIn="false" value="GLEW"/>
</option> </option>