mirror of https://github.com/axmolengine/axmol.git
Merge pull request #4715 from SBKarr/develop
closed #3542: AngelCode binary file format support for LabelBMFont.
This commit is contained in:
commit
31e2b3d5c2
|
@ -183,10 +183,16 @@ void CCBMFontConfiguration::purgeFontDefDictionary()
|
|||
std::set<unsigned int>* CCBMFontConfiguration::parseConfigFile(const std::string& controlFile)
|
||||
{
|
||||
std::string fullpath = FileUtils::getInstance()->fullPathForFilename(controlFile);
|
||||
|
||||
std::string contents = FileUtils::getInstance()->getStringFromFile(fullpath);
|
||||
|
||||
CCASSERT(!contents.empty(), "CCBMFontConfiguration::parseConfigFile | Open file error.");
|
||||
|
||||
Data data = FileUtils::getInstance()->getDataFromFile(fullpath);
|
||||
CCASSERT((!data.isNull() && data.getSize() > 0), "CCBMFontConfiguration::parseConfigFile | Open file error.");
|
||||
|
||||
if (memcmp("BMF", data.getBytes(), 3) == 0) {
|
||||
std::set<unsigned int>* ret = parseBinaryConfigFile(data.getBytes(), data.getSize(), controlFile);
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string contents((const char*)data.getBytes(), data.getSize());
|
||||
|
||||
std::set<unsigned int> *validCharsString = new std::set<unsigned int>();
|
||||
|
||||
|
@ -260,6 +266,167 @@ std::set<unsigned int>* CCBMFontConfiguration::parseConfigFile(const std::string
|
|||
return validCharsString;
|
||||
}
|
||||
|
||||
std::set<unsigned int>* CCBMFontConfiguration::parseBinaryConfigFile(unsigned char* pData, unsigned long size, const std::string& controlFile)
|
||||
{
|
||||
/* based on http://www.angelcode.com/products/bmfont/doc/file_format.html file format */
|
||||
|
||||
set<unsigned int> *validCharsString = new set<unsigned int>();
|
||||
|
||||
unsigned long remains = size;
|
||||
|
||||
unsigned char version = pData[3];
|
||||
CCASSERT(version == 3, "Only version 3 is supported");
|
||||
|
||||
pData += 4; remains -= 4;
|
||||
|
||||
while (remains > 0)
|
||||
{
|
||||
unsigned char blockId = pData[0]; pData += 1; remains -= 1;
|
||||
uint32_t blockSize = 0; memcpy(&blockSize, pData, 4);
|
||||
|
||||
pData += 4; remains -= 4;
|
||||
|
||||
if (blockId == 1)
|
||||
{
|
||||
/*
|
||||
fontSize 2 int 0
|
||||
bitField 1 bits 2 bit 0: smooth, bit 1: unicode, bit 2: italic, bit 3: bold, bit 4: fixedHeigth, bits 5-7: reserved
|
||||
charSet 1 uint 3
|
||||
stretchH 2 uint 4
|
||||
aa 1 uint 6
|
||||
paddingUp 1 uint 7
|
||||
paddingRight 1 uint 8
|
||||
paddingDown 1 uint 9
|
||||
paddingLeft 1 uint 10
|
||||
spacingHoriz 1 uint 11
|
||||
spacingVert 1 uint 12
|
||||
outline 1 uint 13 added with version 2
|
||||
fontName n+1 string 14 null terminated string with length n
|
||||
*/
|
||||
|
||||
_padding.top = (unsigned char)pData[7];
|
||||
_padding.right = (unsigned char)pData[8];
|
||||
_padding.bottom = (unsigned char)pData[9];
|
||||
_padding.left = (unsigned char)pData[10];
|
||||
}
|
||||
else if (blockId == 2)
|
||||
{
|
||||
/*
|
||||
lineHeight 2 uint 0
|
||||
base 2 uint 2
|
||||
scaleW 2 uint 4
|
||||
scaleH 2 uint 6
|
||||
pages 2 uint 8
|
||||
bitField 1 bits 10 bits 0-6: reserved, bit 7: packed
|
||||
alphaChnl 1 uint 11
|
||||
redChnl 1 uint 12
|
||||
greenChnl 1 uint 13
|
||||
blueChnl 1 uint 14
|
||||
*/
|
||||
|
||||
uint16_t lineHeight = 0; memcpy(&lineHeight, pData, 2);
|
||||
_commonHeight = lineHeight;
|
||||
|
||||
uint16_t scaleW = 0; memcpy(&scaleW, pData + 4, 2);
|
||||
uint16_t scaleH = 0; memcpy(&scaleH, pData + 6, 2);
|
||||
|
||||
CCASSERT(scaleW <= Configuration::getInstance()->getMaxTextureSize() && scaleH <= Configuration::getInstance()->getMaxTextureSize(), "CCLabelBMFont: page can't be larger than supported");
|
||||
|
||||
uint16_t pages = 0; memcpy(&pages, pData + 8, 2);
|
||||
CCASSERT(pages == 1, "CCBitfontAtlas: only supports 1 page");
|
||||
}
|
||||
else if (blockId == 3)
|
||||
{
|
||||
/*
|
||||
pageNames p*(n+1) strings 0 p null terminated strings, each with length n
|
||||
*/
|
||||
|
||||
const char *value = (const char *)pData;
|
||||
size_t len = strlen(value);
|
||||
CCASSERT(len < blockSize, "Block size should be less then string");
|
||||
|
||||
_atlasName = FileUtils::getInstance()->fullPathFromRelativeFile(value, controlFile);
|
||||
}
|
||||
else if (blockId == 4)
|
||||
{
|
||||
/*
|
||||
id 4 uint 0+c*20 These fields are repeated until all characters have been described
|
||||
x 2 uint 4+c*20
|
||||
y 2 uint 6+c*20
|
||||
width 2 uint 8+c*20
|
||||
height 2 uint 10+c*20
|
||||
xoffset 2 int 12+c*20
|
||||
yoffset 2 int 14+c*20
|
||||
xadvance 2 int 16+c*20
|
||||
page 1 uint 18+c*20
|
||||
chnl 1 uint 19+c*20
|
||||
*/
|
||||
|
||||
unsigned long count = blockSize / 20;
|
||||
|
||||
for (unsigned long i = 0; i < count; i++)
|
||||
{
|
||||
tFontDefHashElement* element = (tFontDefHashElement*)malloc( sizeof(*element) );
|
||||
|
||||
uint32_t charId = 0; memcpy(&charId, pData + (i * 20), 4);
|
||||
element->fontDef.charID = charId;
|
||||
|
||||
uint16_t charX = 0; memcpy(&charX, pData + (i * 20) + 4, 2);
|
||||
element->fontDef.rect.origin.x = charX;
|
||||
|
||||
uint16_t charY = 0; memcpy(&charY, pData + (i * 20) + 6, 2);
|
||||
element->fontDef.rect.origin.y = charY;
|
||||
|
||||
uint16_t charWidth = 0; memcpy(&charWidth, pData + (i * 20) + 8, 2);
|
||||
element->fontDef.rect.size.width = charWidth;
|
||||
|
||||
uint16_t charHeight = 0; memcpy(&charHeight, pData + (i * 20) + 10, 2);
|
||||
element->fontDef.rect.size.height = charHeight;
|
||||
|
||||
int16_t xoffset = 0; memcpy(&xoffset, pData + (i * 20) + 12, 2);
|
||||
element->fontDef.xOffset = xoffset;
|
||||
|
||||
int16_t yoffset = 0; memcpy(&yoffset, pData + (i * 20) + 14, 2);
|
||||
element->fontDef.yOffset = yoffset;
|
||||
|
||||
int16_t xadvance = 0; memcpy(&xadvance, pData + (i * 20) + 16, 2);
|
||||
element->fontDef.xAdvance = xadvance;
|
||||
|
||||
element->key = element->fontDef.charID;
|
||||
HASH_ADD_INT(_fontDefDictionary, key, element);
|
||||
|
||||
validCharsString->insert(element->fontDef.charID);
|
||||
}
|
||||
}
|
||||
else if (blockId == 5) {
|
||||
/*
|
||||
first 4 uint 0+c*10 These fields are repeated until all kerning pairs have been described
|
||||
second 4 uint 4+c*10
|
||||
amount 2 int 8+c*10
|
||||
*/
|
||||
|
||||
unsigned long count = blockSize / 20;
|
||||
|
||||
for (unsigned long i = 0; i < count; i++)
|
||||
{
|
||||
|
||||
uint32_t first = 0; memcpy(&first, pData + (i * 10), 4);
|
||||
uint32_t second = 0; memcpy(&second, pData + (i * 10) + 4, 4);
|
||||
int16_t amount = 0; memcpy(&amount, pData + (i * 10) + 8, 2);
|
||||
|
||||
tKerningHashElement *element = (tKerningHashElement *)calloc( sizeof( *element ), 1 );
|
||||
element->amount = amount;
|
||||
element->key = (first<<16) | (second&0xffff);
|
||||
HASH_ADD_INT(_kerningDictionary,key, element);
|
||||
}
|
||||
}
|
||||
|
||||
pData += blockSize; remains -= blockSize;
|
||||
}
|
||||
|
||||
return validCharsString;
|
||||
}
|
||||
|
||||
void CCBMFontConfiguration::parseImageFileName(std::string line, const std::string& fntFile)
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -151,6 +151,7 @@ public:
|
|||
std::set<unsigned int>* getCharacterSet() const;
|
||||
private:
|
||||
std::set<unsigned int>* parseConfigFile(const std::string& controlFile);
|
||||
std::set<unsigned int>* parseBinaryConfigFile(unsigned char* pData, unsigned long size, const std::string& controlFile);
|
||||
void parseCharacterDefinition(std::string line, ccBMFontDef *characterDefinition);
|
||||
void parseInfoArguments(std::string line);
|
||||
void parseCommonArguments(std::string line);
|
||||
|
|
|
@ -74,6 +74,7 @@ static std::function<Layer*()> createFunctions[] =
|
|||
// should be moved to another test
|
||||
CL(Atlas1),
|
||||
CL(LabelBMFontCrashTest),
|
||||
CL(LabelBMFontBinaryFormat),
|
||||
};
|
||||
|
||||
#define MAX_LAYER (sizeof(createFunctions) / sizeof(createFunctions[0]))
|
||||
|
@ -1669,3 +1670,26 @@ std::string LabelBMFontCrashTest::subtitle() const
|
|||
{
|
||||
return "Should not crash.";
|
||||
}
|
||||
|
||||
// LabelBMFontBinaryFormat
|
||||
LabelBMFontBinaryFormat::LabelBMFontBinaryFormat()
|
||||
{
|
||||
auto s = Director::getInstance()->getWinSize();
|
||||
|
||||
auto bmFont = LabelBMFont::create();
|
||||
|
||||
bmFont->setFntFile("fonts/Roboto.bmf.fnt");
|
||||
bmFont->setString("It is working!");
|
||||
this->addChild(bmFont);
|
||||
bmFont->setPosition(Point(s.width/2,s.height/4*2));
|
||||
}
|
||||
|
||||
std::string LabelBMFontBinaryFormat::title() const
|
||||
{
|
||||
return "LabelBMFont Binary FNT File";
|
||||
}
|
||||
|
||||
std::string LabelBMFontBinaryFormat::subtitle() const
|
||||
{
|
||||
return "This label uses font file in AngelCode binary format";
|
||||
}
|
||||
|
|
|
@ -429,6 +429,17 @@ public:
|
|||
virtual std::string subtitle() const override;
|
||||
};
|
||||
|
||||
class LabelBMFontBinaryFormat : public AtlasDemo
|
||||
{
|
||||
public:
|
||||
CREATE_FUNC(LabelBMFontBinaryFormat);
|
||||
|
||||
LabelBMFontBinaryFormat();
|
||||
|
||||
virtual std::string title() const override;
|
||||
virtual std::string subtitle() const override;
|
||||
};
|
||||
|
||||
|
||||
// we don't support linebreak mode
|
||||
|
||||
|
|
Loading…
Reference in New Issue