rendering using free type. This commit is a work in progress and should NOT be used

This commit is contained in:
carlo morgantini 2013-07-17 17:31:28 -07:00
parent 9cfe1b7823
commit 80247d409b
12 changed files with 744 additions and 57 deletions

View File

@ -20,15 +20,22 @@ class Font
public:
virtual ~Font() {}
virtual bool createFontObject(const std::string &fontName, int fontSize) = 0;
virtual GlyphDef * getGlyphsForText(const char *pText, int &outNumGlyphs) = 0;
virtual Size * getAdvancesForText(const char *pText, int &outNumLetters) = 0;
virtual Size * getAdvancesForTextUTF8(unsigned short *pText, int &outNumLetters) = 0;
virtual unsigned short int * getUTF8Text(const char *pText, int &outNumLetters) = 0;
virtual const char * trimUTF8Text(const char *pText, int newBegin, int newEnd) = 0;
virtual Size getTextWidthAndHeight(const char *pText) = 0;
virtual int getUTF8TextLenght(const char *pText) = 0;
virtual int getLetterPadding() { return 0;}
virtual unsigned char * getGlyphBitmap(unsigned short theChar, int &outWidth, int &outHeight) { return 0; }
virtual GlyphDef * getGlyphsForText(const char *pText, int &outNumGlyphs, bool UTF16text = false) = 0;
virtual Size * getAdvancesForText(const char *pText, int &outNumLetters, bool UTF16text = false) = 0;
virtual Size getTextWidthAndHeight(const char *pText, bool UTF16text = false) = 0;
virtual Size * getAdvancesForTextUTF8(unsigned short *pText, int &outNumLetters) = 0;
virtual unsigned short int * getUTF8Text(const char *pText, int &outNumLetters) = 0;
virtual const char * trimUTF8Text(const char *pText, int newBegin, int newEnd) = 0;
virtual int getUTF8TextLenght(const char *pText) = 0;
virtual int getLetterPadding() { return 0; }
virtual unsigned char * getGlyphBitmap(unsigned short theChar, int &outWidth, int &outHeight) { return 0; }
virtual unsigned short int * trimUTF16Text(unsigned short int *pText, int newBegin, int newEnd) { return 0; }
virtual int getUTF16TextLenght(unsigned short int *pText) { return 0; }
};
NS_CC_END

View File

@ -24,12 +24,173 @@ LabelFontDefinition::~LabelFontDefinition()
}
}
bool LabelFontDefinition::createFontDefinition(char *fontName, int fontSize, char *letters, int textureSize, bool debugOutput)
bool LabelFontDefinition::prepareLetterDefinitions(TextFontPagesDef *pageDefs)
{
// constants
float LINE_PADDING = 1.9;
float PIXEL_PADDING = 1.0;
// get all the pages
TextFontPagesDef *pPages = pageDefs;
if (!pPages)
return (false);
float maxLineHeight = -1;
// loops all the pages
for (int cPages = 0; cPages<pPages->getNumPages(); ++cPages)
{
// loops all the lines in this page
for (int cLines = 0; cLines<pPages->getPageAt(cPages)->getNumLines(); ++cLines)
{
float posXUV = 0.0;
float posYUV = pPages->getPageAt(cPages)->getLineAt(cLines)->getY();
int charsCounter = 0;
for (int c = 0; c < pPages->getPageAt(cPages)->getLineAt(cLines)->getNumGlyph(); ++c)
{
// the current glyph
GlyphDef currentGlyph = pPages->getPageAt(cPages)->getLineAt(cLines)->getGlyphAt(c);
// letter width
float letterWidth = currentGlyph.getRect().size.width;
// letter height
float letterHeight = pPages->getPageAt(cPages)->getLineAt(cLines)->getHeight();
// add this letter definition
LetterDefinition tempDef;
tempDef.letteCharUTF8 = currentGlyph.getUTF8Letter();
tempDef.width = letterWidth + PIXEL_PADDING;
tempDef.height = letterHeight;
tempDef.U = posXUV + LINE_PADDING - PIXEL_PADDING;
tempDef.V = posYUV;
tempDef.offsetX = currentGlyph.getRect().origin.x;
tempDef.textureID = cPages;
tempDef.commonLineHeight = currentGlyph.getCommonHeight();
// take from pixels to points
tempDef.width = tempDef.width / CC_CONTENT_SCALE_FACTOR();
tempDef.height = tempDef.height / CC_CONTENT_SCALE_FACTOR();
tempDef.U = tempDef.U / CC_CONTENT_SCALE_FACTOR();
tempDef.V = tempDef.V / CC_CONTENT_SCALE_FACTOR();
if (tempDef.commonLineHeight>maxLineHeight)
maxLineHeight = tempDef.commonLineHeight;
// add this definition
addLetterDef(tempDef);
// move bounding box to the next letter
posXUV += letterWidth + currentGlyph.getPadding();
// next char in the string
++charsCounter;
}
}
}
// store the common line height
_commonLineHeight = maxLineHeight;
return true;
}
bool LabelFontDefinition::prepareLetterDefinitionsNew(TextFontPagesDef *pageDefs)
{
// get all the pages
TextFontPagesDef *pPages = pageDefs;
if (!pPages)
return (false);
float maxLineHeight = -1;
// loops all the pages
for (int cPages = 0; cPages<pPages->getNumPages(); ++cPages)
{
// loops all the lines in this page
for (int cLines = 0; cLines<pPages->getPageAt(cPages)->getNumLines(); ++cLines)
{
float posXUV = 0.0;
float posYUV = pPages->getPageAt(cPages)->getLineAt(cLines)->getY();
int charsCounter = 0;
for (int c = 0; c < pPages->getPageAt(cPages)->getLineAt(cLines)->getNumGlyph(); ++c)
{
// the current glyph
GlyphDef currentGlyph = pPages->getPageAt(cPages)->getLineAt(cLines)->getGlyphAt(c);
// letter width
float letterWidth = currentGlyph.getRect().size.width;
// letter height
float letterHeight = pPages->getPageAt(cPages)->getLineAt(cLines)->getHeight();
// add this letter definition
LetterDefinition tempDef;
// little hack (this should be done outside the loop)
if (posXUV == 0.0)
posXUV = currentGlyph.getPadding();
int daMeno = 1;
tempDef.letteCharUTF8 = currentGlyph.getUTF8Letter();
tempDef.width = letterWidth + currentGlyph.getPadding();
tempDef.height = letterHeight - daMeno;
tempDef.U = posXUV - daMeno;
tempDef.V = posYUV;
tempDef.offsetX = currentGlyph.getRect().origin.x;
tempDef.offsetY = currentGlyph.getRect().origin.y;
tempDef.textureID = cPages;
tempDef.commonLineHeight = currentGlyph.getCommonHeight();
// take from pixels to points
tempDef.width = tempDef.width / CC_CONTENT_SCALE_FACTOR();
tempDef.height = tempDef.height / CC_CONTENT_SCALE_FACTOR();
tempDef.U = tempDef.U / CC_CONTENT_SCALE_FACTOR();
tempDef.V = tempDef.V / CC_CONTENT_SCALE_FACTOR();
if (tempDef.commonLineHeight>maxLineHeight)
maxLineHeight = tempDef.commonLineHeight;
// add this definition
addLetterDefNew(tempDef);
// move bounding box to the next letter
posXUV += letterWidth + currentGlyph.getPadding();
// next char in the string
++charsCounter;
}
}
}
// store the common line height
_commonLineHeightNew = maxLineHeight;
return true;
}
bool LabelFontDefinition::createFontDefinition(char *fontName, int fontSize, char *letters, int textureSize, bool debugOutput)
{
debugUseFreetype = true;
// constants
//float LINE_PADDING = 1.9;
//float PIXEL_PADDING = 1.0;
// preare texture/image stuff
_textImages = new TextImage();
@ -46,6 +207,14 @@ bool LabelFontDefinition::createFontDefinition(char *fontName, int fontSize, cha
if ( debugOutput )
_textImages->debugSaveToFile("debugFontDef.png", false);
// prepare the new letter definition
prepareLetterDefinitionsNew(_textImages->getPagesNew());
// prepare the letter definitions
return prepareLetterDefinitions(_textImages->getPages());
/*
// get all the pages
TextFontPagesDef *pPages = _textImages->getPages();
if (!pPages)
@ -114,6 +283,7 @@ bool LabelFontDefinition::createFontDefinition(char *fontName, int fontSize, cha
_commonLineHeight = maxLineHeight;
return true;
*/
}
void LabelFontDefinition::addLetterDef(LetterDefinition &defToAdd)
@ -124,14 +294,34 @@ void LabelFontDefinition::addLetterDef(LetterDefinition &defToAdd)
}
}
void LabelFontDefinition::addLetterDefNew(LetterDefinition &defToAdd)
{
if (_fontLettersDefinitionUTF16.find(defToAdd.letteCharUTF8) == _fontLettersDefinitionUTF16.end())
{
_fontLettersDefinitionUTF16[defToAdd.letteCharUTF8] = defToAdd;
}
}
LetterDefinition & LabelFontDefinition::getLetterDefinition(unsigned short int theLetter)
{
return _fontLettersDefinitionUTF8[theLetter];
if (debugUseFreetype)
return _fontLettersDefinitionUTF16[theLetter];
else
return _fontLettersDefinitionUTF8[theLetter];
}
Texture2D * LabelFontDefinition::getTexture(int index)
{
TextFontPagesDef *pPages = _textImages->getPages();
TextFontPagesDef *pPages = 0;
if ( debugUseFreetype )
{
pPages = _textImages->getPagesNew();
}
else
{
pPages = _textImages->getPages();
}
if (!pPages)
return (false);

View File

@ -38,7 +38,9 @@ struct LetterDefinition
float V;
float width;
float height;
float offset;
float offsetX;
float offsetY;
int textureID;
float commonLineHeight;
};
@ -51,19 +53,34 @@ public:
~LabelFontDefinition();
bool createFontDefinition(char *fontName, int fontSize, char *letters, int textureSize = 512, bool debugOutput = false);
LetterDefinition & getLetterDefinition(unsigned short int theLetter);
Texture2D * getTexture(int index);
Font * getFont() { return _textImages->getFont(); }
float getCommonLineHeight() { return _commonLineHeight; }
Font * getFont() { if (debugUseFreetype) return _textImages->getFontNew(); else return _textImages->getFont(); }
float getCommonLineHeight() { if (debugUseFreetype) return _commonLineHeightNew; else return _commonLineHeight; }
private:
void addLetterDef(LetterDefinition &defToAdd);
bool prepareLetterDefinitions(TextFontPagesDef *pageDefs);
// carloX
bool prepareLetterDefinitionsNew(TextFontPagesDef *pageDefs);
void addLetterDefNew(LetterDefinition &defToAdd);
std::map<unsigned short, LetterDefinition> _fontLettersDefinitionUTF16;
float _commonLineHeightNew;
void addLetterDef(LetterDefinition &defToAdd);
TextImage * _textImages;
float _commonLineHeight;
std::map<unsigned short, LetterDefinition> _fontLettersDefinitionUTF8;
bool debugUseFreetype;
};
NS_CC_END

View File

@ -102,8 +102,19 @@ bool FontFreeType::getBBOXFotChar(unsigned short theChar, Rect &outRect)
if (FT_Load_Glyph(_fontRef, glyph_index, FT_LOAD_DEFAULT))
return false;
// store result in the passed rectangle
outRect.origin.x = 0;
// hack carloX //////////////////////////////////////////
FT_Render_Glyph( _fontRef->glyph, FT_RENDER_MODE_NORMAL );
int testCarloX = _fontRef->glyph->bitmap.width;
int testCarloX2 = (_fontRef->glyph->metrics.horiBearingX >>6);
/////////////////////////////////////////////////////////
outRect.origin.y = - (_fontRef->glyph->metrics.horiBearingY >> 6);
outRect.size.width = (_fontRef->glyph->metrics.width >> 6);
outRect.size.height = (_fontRef->glyph->metrics.height >> 6);
@ -111,9 +122,23 @@ bool FontFreeType::getBBOXFotChar(unsigned short theChar, Rect &outRect)
return true;
}
GlyphDef * FontFreeType::getGlyphsForText(const char *pText, int &outNumGlyphs)
int FontFreeType::getUTF16TextLenght(unsigned short int *pText)
{
unsigned short* utf16String = cc_utf8_to_utf16(pText);
return cc_wcslen(pText);
}
GlyphDef * FontFreeType::getGlyphsForText(const char *pText, int &outNumGlyphs, bool UTF16text)
{
unsigned short* utf16String = 0;
if (UTF16text)
{
utf16String = (unsigned short*) pText;
}
else
{
utf16String = cc_utf8_to_utf16(pText);
}
//
if (!utf16String)
@ -126,7 +151,8 @@ GlyphDef * FontFreeType::getGlyphsForText(const char *pText, int &outNumGlyphs)
// allocate the needed Glyphs
GlyphDef *pGlyphs = new GlyphDef[numChar];
assert( pGlyphs != NULL );
return 0;
if (!pGlyphs)
return 0;
// sore result as CCRect
for (int c=0; c<numChar; ++c)
@ -146,7 +172,8 @@ GlyphDef * FontFreeType::getGlyphsForText(const char *pText, int &outNumGlyphs)
outNumGlyphs = numChar;
// free memory
delete [] utf16String;
if (!UTF16text)
delete [] utf16String;
// done
return pGlyphs;
@ -171,7 +198,7 @@ Size * FontFreeType::getAdvancesForTextUTF8(unsigned short *pText, int &outNumLe
int advance = 0;
int kerning = 0;
advance = getAdvanceFotChar(pText[c]);
advance = getAdvanceForChar(pText[c]) - getBearingXForChar(pText[c]);
if ( c < (outNumLetters-1) )
kerning = getHorizontalKerningForChars(pText[c], pText[c+1]);
@ -182,66 +209,116 @@ Size * FontFreeType::getAdvancesForTextUTF8(unsigned short *pText, int &outNumLe
return pSizes;
}
int FontFreeType::getAdvanceFotChar(unsigned short theChar)
int FontFreeType::getAdvanceForChar(unsigned short theChar)
{
if (!_fontRef)
return false;
return 0;
// get the ID to the char we need
int glyph_index = FT_Get_Char_Index(_fontRef, theChar);
if (!glyph_index)
return false;
return 0;
// load glyph infos
if (FT_Load_Glyph(_fontRef, glyph_index, FT_LOAD_DEFAULT))
return false;
return 0;
// carloX //// hack to be moved somewhere eles ///////////////
FT_Render_Glyph( _fontRef->glyph, FT_RENDER_MODE_NORMAL );
int testBMP = _fontRef->glyph->bitmap_left;
// end hack/////////////////////////////////////////////////////
// get to the advance for this glyph
return (_fontRef->glyph->advance.x >> 6);
//return (_fontRef->glyph->advance.x >> 6) + testBMP;
}
int FontFreeType::getBearingXForChar(unsigned short theChar)
{
if (!_fontRef)
return 0;
// get the ID to the char we need
int glyph_index = FT_Get_Char_Index(_fontRef, theChar);
if (!glyph_index)
return 0;
// load glyph infos
if (FT_Load_Glyph(_fontRef, glyph_index, FT_LOAD_DEFAULT))
return 0;
return (_fontRef->glyph->metrics.horiBearingX >>6);
}
int FontFreeType::getHorizontalKerningForChars(unsigned short firstChar, unsigned short secondChar)
{
if (!_fontRef)
return -1;
return 0;
bool hasKerning = FT_HAS_KERNING( _fontRef );
if (!hasKerning)
return 0;
// get the ID to the char we need
int glyph_index1 = FT_Get_Char_Index(_fontRef, firstChar);
if (!glyph_index1)
return -1;
return 0;
// get the ID to the char we need
int glyph_index2 = FT_Get_Char_Index(_fontRef, secondChar);
if (!glyph_index2)
return -1;
return 0;
FT_Vector kerning;
if (FT_Get_Kerning( _fontRef, glyph_index1, glyph_index2, FT_KERNING_DEFAULT, &kerning ))
return -1;
return 0;
return ( kerning.x >> 6 );
}
Size * FontFreeType::getAdvancesForText(const char *pText, int &outNumLetters)
Size * FontFreeType::getAdvancesForText(const char *pText, int &outNumLetters, bool UTF16text)
{
unsigned short* utf16String = cc_utf8_to_utf16(pText);
unsigned short* utf16String = 0;
if (UTF16text)
{
utf16String = (unsigned short* )pText;
}
else
{
utf16String = cc_utf8_to_utf16(pText);
}
Size *ret = getAdvancesForTextUTF8(utf16String, outNumLetters);
delete [] utf16String;
if (!UTF16text)
delete [] utf16String;
return ret;
}
Size FontFreeType::getTextWidthAndHeight(const char *pText)
Size FontFreeType::getTextWidthAndHeight(const char *pText, bool UTF16text)
{
Size retSize;
retSize.width = 0;
retSize.height = 0;
int numLetters;
Size *tempSizes = getAdvancesForText(pText, numLetters);
Size *tempSizes = getAdvancesForText(pText, numLetters, UTF16text);
for (int c = 0; c<numLetters; ++c)
{
@ -322,6 +399,33 @@ const char * FontFreeType::trimUTF8Text(const char *pText, int newBegin, int new
return (const char *)trimmedString;
}
unsigned short int * FontFreeType::trimUTF16Text(unsigned short int *pText, int newBegin, int newEnd)
{
if ( newBegin<0 || newEnd<=0 )
return 0;
if ( newBegin>=newEnd )
return 0;
if (newEnd >= cc_wcslen(pText))
return 0;
int newLenght = newEnd - newBegin + 2;
unsigned short* trimmedString = new unsigned short[newLenght];
for(int c = 0; c < (newLenght-1); ++c)
{
trimmedString[c] = pText[newBegin + c];
}
// last char
trimmedString[newLenght-1] = 0x0000;
// done
return trimmedString;
}
int FontFreeType::getUTF8TextLenght(const char *pText)
{
unsigned short* utf16String = cc_utf8_to_utf16(pText);
@ -329,6 +433,7 @@ int FontFreeType::getUTF8TextLenght(const char *pText)
return -1;
int outNumLetters = cc_wcslen(utf16String);
delete [] utf16String;
return outNumLetters;
}

View File

@ -26,23 +26,30 @@ public:
virtual ~FontFreeType();
virtual bool createFontObject(const std::string &fontName, int fontSize);
virtual GlyphDef * getGlyphsForText(const char *pText, int &outNumGlyphs, bool UTF16text = false);
virtual Size * getAdvancesForText(const char *pText, int &outNumLetters, bool UTF16text = false);
virtual Size getTextWidthAndHeight(const char *pText, bool UTF16text = false);
virtual int getUTF8TextLenght(const char *pText);
virtual Size getTextWidthAndHeight(const char *pText);
virtual GlyphDef * getGlyphsForText(const char *pText, int &outNumGlyphs);
virtual Size * getAdvancesForText(const char *pText, int &outNumLetters);
virtual Size * getAdvancesForTextUTF8(unsigned short *pText, int &outNumLetters);
virtual unsigned short int * getUTF8Text(const char *pText, int &outNumLetters);
virtual const char * trimUTF8Text(const char *pText, int newBegin, int newEnd);
virtual int getLetterPadding() { return _letterPadding;}
unsigned char * getGlyphBitmap(unsigned short theChar, int &outWidth, int &outHeight);
virtual unsigned short int * trimUTF16Text(unsigned short int *pText, int newBegin, int newEnd);
virtual int getUTF16TextLenght(unsigned short int *pText);
private:
bool initFreeType();
void shutdownFreeType();
FT_Library getFTLibrary();
bool getBBOXFotChar(unsigned short theChar, Rect &outRect);
int getAdvanceFotChar(unsigned short theChar);
int getAdvanceForChar(unsigned short theChar);
int getBearingXForChar(unsigned short theChar);
int getHorizontalKerningForChars(unsigned short firstChar, unsigned short secondChar);
static FT_Library _FTlibrary;

View File

@ -21,10 +21,13 @@ public:
virtual ~FontIOS();
virtual bool createFontObject(const std::string &fontName, int fontSize);
virtual GlyphDef * getGlyphsForText(const char *pText, int &outNumGlyphs, bool UTF16text = false);
virtual Size * getAdvancesForText(const char *pText, int &outNumLetters, bool UTF16text = false);
virtual Size getTextWidthAndHeight(const char *pText, bool UTF16text = false);
virtual int getUTF8TextLenght(const char *pText);
virtual Size getTextWidthAndHeight(const char *pText);
virtual GlyphDef * getGlyphsForText(const char *pText, int &outNumGlyphs);
virtual Size * getAdvancesForText(const char *pText, int &outNumLetters);
virtual Size * getAdvancesForTextUTF8(unsigned short *pText, int &outNumLetters);
virtual unsigned short int * getUTF8Text(const char *pText, int &outNumLetters);
virtual const char * trimUTF8Text(const char *pText, int newBegin, int newEnd);

View File

@ -41,7 +41,7 @@ FontIOS::~FontIOS()
// TO DO
}
GlyphDef * FontIOS::getGlyphsForText(const char *pText, int &outNumGlyphs)
GlyphDef * FontIOS::getGlyphsForText(const char *pText, int &outNumGlyphs, bool UTF16text)
{
float CHAR_PADDING = 10.0f;
@ -171,7 +171,7 @@ Size * FontIOS::getAdvancesForTextUTF8(unsigned short *pText, int &outNumLetters
return pCCSizes;
}
Size * FontIOS::getAdvancesForText(const char *pText, int &outNumLetters)
Size * FontIOS::getAdvancesForText(const char *pText, int &outNumLetters, bool UTF16text)
{
unsigned short int *utf8Text = FontIOS::getUTF8Text(pText, outNumLetters);
if (utf8Text)
@ -186,7 +186,7 @@ Size * FontIOS::getAdvancesForText(const char *pText, int &outNumLetters)
}
}
Size FontIOS::getTextWidthAndHeight(const char *pText)
Size FontIOS::getTextWidthAndHeight(const char *pText, bool UTF16text)
{
Size retSize;
NSString * str = [NSString stringWithUTF8String:pText];

View File

@ -237,7 +237,7 @@ unsigned char * FontRenderFreeType::preparePageGlyphData(TextPageDef *thePage, c
if (!thePage)
return 0;
if (_font)
if (!_font)
return 0;
if (thePage->getNumLines() == 0)

View File

@ -378,7 +378,12 @@ int StringTTF::getXOffsetForChar(unsigned short c)
int StringTTF::getYOffsetForChar(unsigned short c)
{
return 0;
LetterDefinition tempDefinition = _fontDef->getLetterDefinition(c);
return (tempDefinition.offsetY);
// carloX return 0;
}
int StringTTF::getAdvanceForChar(unsigned short c, int hintPositionInString)
@ -387,7 +392,7 @@ int StringTTF::getAdvanceForChar(unsigned short c, int hintPositionInString)
{
// not that advance contains the X offset already
LetterDefinition tempDefinition = _fontDef->getLetterDefinition(c);
return (_advances[hintPositionInString].width - tempDefinition.offset);
return (_advances[hintPositionInString].width - tempDefinition.offsetX);
}
else
{

View File

@ -16,6 +16,9 @@
#include "CCTextImage.h"
#include "CCFontRenderIOS.h"
// new stuff CarloX
#include "CCFontFreeType.h"
NS_CC_BEGIN
@ -123,10 +126,38 @@ TextFontPagesDef::~TextFontPagesDef()
}
}
int _getNumGlyphsFittingInSize(std::map<unsigned short int, GlyphDef> &glyphDefs, unsigned short int *strUTF8, Font *pFont, Size *constrainSize, int &outNewSize)
{
if (!strUTF8)
return NULL;
float widthWithBBX = 0.0f;
float lastWidth = 0.0f;
// get the string to UTF8
int numChar = cc_wcslen(strUTF8);
for (int c = 0; c<numChar; ++c)
{
widthWithBBX+= (glyphDefs[strUTF8[c]].getRect().size.width + glyphDefs[strUTF8[c]].getPadding());
if (widthWithBBX >= constrainSize->width)
{
outNewSize = lastWidth;
return c;
}
lastWidth = widthWithBBX;
}
outNewSize = constrainSize->width;
return numChar;
}
const char * _getStringInBoundsUsingGlyphSize(std::map<unsigned short int, GlyphDef> &glyphDefs, const char *str, Font *pFont, Size *constrainSize)
{
Size tmp = pFont->getTextWidthAndHeight(str);
Size tmp = pFont->getTextWidthAndHeight(str);
float widthWithBBX = 0.0f;
// get the string to UTF8
@ -162,7 +193,7 @@ const char * _getStringInBoundsUsingGlyphSize(std::map<unsigned short int, Glyph
}
}
TextImage::TextImage(): _font(0), _fontRender(0)
TextImage::TextImage(): _font(0), _fontRender(0), _fontNew(0), _fontRenderNew(0)
{
}
@ -179,6 +210,146 @@ TextImage::~TextImage()
}
}
bool TextImage::initWithStringNew(const char * pText, int nWidth, int nHeight, const char * pFontName, int nSize, bool textIsUTF16, bool releaseRAWData)
{
CGSize constrainSize;
unsigned short int *strUTF16 = 0;
int stringNumChars;
if ( textIsUTF16 )
{
strUTF16 = (unsigned short int *)pText;
stringNumChars = cc_wcslen(strUTF16);
}
else
{
// string needs to go to unicode
strUTF16 = _fontNew->getUTF8Text(pText, stringNumChars);
}
// tell if the string has been trimmed at least one
bool stringTrimmedOnce = false;
constrainSize.width = nWidth;
constrainSize.height = nHeight;
// pointer to the original input stream
//const char *inputString = pText;
int delta = 0;
int currentPage = 0;
float currentY = 0.0;
//carloX
float lineHeight = _fontNew->getTextWidthAndHeight(pText).height;
// check if at least one line will fit in the texture
if ( lineHeight > constrainSize.height )
{
// we can't even fit one line in this texture
return false;
}
// create pages for the font
_fontPagesNew = new TextFontPagesDef((char *)pFontName, nSize);
if (!_fontPagesNew)
return false;
// create the first page (ther is going to be at least one page)
TextPageDef *currentPageDef = new TextPageDef(currentPage, nWidth, nHeight);
if ( !currentPageDef )
return false;
// add the current page
_fontPagesNew->addPage(currentPageDef);
do {
// choose texture page
if ( ( currentY + lineHeight ) > constrainSize.height )
{
currentY = 0;
currentPage += 1;
// create a new page and add
currentPageDef = new TextPageDef(currentPage, nWidth, nHeight);
if ( !currentPageDef )
return false;
_fontPagesNew->addPage(currentPageDef);
}
// get the new fitting string
Size tempSize;
tempSize.width = constrainSize.width;
tempSize.height = constrainSize.height;
//const char *pNewString = _getStringInBoundsUsingGlyphSizeNew(_textGlyphsNew, inputString, _fontNew, &tempSize);
// figure out how many glyphs fit in this line
int newLineSize = 0;
int numFittingChar = _getNumGlyphsFittingInSize(_textGlyphsNew, strUTF16, _fontNew, &tempSize, newLineSize);
// crete the temporary new string
unsigned short int *pTempString = 0;
pTempString = _fontNew->trimUTF16Text(strUTF16, 0, (numFittingChar - 1));
// create the new line and add to the current page
TextLineDef *newLine = new TextLineDef(0.0, currentY, newLineSize, lineHeight);
if ( !newLine )
return false;
// add all the glyphs to this line
addGlyphsToLineNew(newLine, (const char *)pTempString, true);
// add the line the to current page
currentPageDef->addLine(newLine);
// can now release the string
delete [] pTempString;
// create the new string
int stringLenght = _fontNew->getUTF16TextLenght(strUTF16);
delta = (stringLenght - numFittingChar);
// there is still some leftover, need to work on it
if ( delta )
{
// create the new string
unsigned short int *tempS = _fontNew->trimUTF16Text(strUTF16, numFittingChar, (stringLenght - 1));
// a copy of the string has been created
stringTrimmedOnce = true;
// release the old one
delete [] strUTF16;
// assign pointer
strUTF16 = tempS;
}
// go to next line
currentY += lineHeight;
} while( delta );
if (!textIsUTF16 || stringTrimmedOnce)
delete [] strUTF16;
// actually create the needed images
return createImageDataFromPagesNew(_fontPagesNew, releaseRAWData);
return true;
}
bool TextImage::initWithString(const char * pText, int nWidth, int nHeight, const char * pFontName, int nSize, bool releaseRAWData)
{
// create the reference to the system font
@ -189,6 +360,14 @@ bool TextImage::initWithString(const char * pText, int nWidth, int nHeight, cons
if ( !generateTextGlyphs(pText) )
return false;
// carloX new stuff
initWithStringNew(pText, nWidth, nHeight, pFontName, nSize, false, releaseRAWData);
// end new stuff
CGSize constrainSize;
constrainSize.width = nWidth;
constrainSize.height = nHeight;
@ -285,7 +464,23 @@ bool TextImage::initWithString(const char * pText, int nWidth, int nHeight, cons
bool TextImage::createFontRef(const char *fontName, int fontSize)
{
//carloX new stuff
//_font
if (_fontNew)
{
delete _fontNew;
_fontNew = 0;
}
_fontNew = new FontFreeType();
if (!_fontNew)
return false;
// fixed font name for now, to be changed
//if( !_fontNew->createFontObject("fonts/Marker Felt.ttf", 20))
if( !_fontNew->createFontObject("fonts/arial.ttf", 26))
return false;
// end carloX new stuff
@ -307,6 +502,25 @@ bool TextImage::createFontRef(const char *fontName, int fontSize)
return false;
}
bool TextImage::createFontRenderNew()
{
if (!_fontNew)
return false;
if (_fontRenderNew)
{
delete _fontRenderNew;
_fontRenderNew = 0;
}
_fontRenderNew = new FontRenderFreeType(_fontNew);
if (!_fontRenderNew)
return false;
return true;
}
bool TextImage::createFontRender()
{
if (_fontRender)
@ -321,29 +535,97 @@ bool TextImage::createFontRender()
return true;
}
bool TextImage::addGlyphsToLine(TextLineDef *line, const char *lineText)
bool TextImage::addGlyphsToLineNew(TextLineDef *line, const char *lineText, bool textIsUTF16)
{
if (!_font)
return false;
int numLetters = 0;
unsigned short int *UTF8string = _font->getUTF8Text(lineText, numLetters);
int numLetters = 0;
unsigned short int *UTF16string = 0;
if (textIsUTF16)
{
UTF16string = (unsigned short int *) lineText;
numLetters = cc_wcslen(UTF16string);
}
else
{
UTF16string = _fontNew->getUTF8Text(lineText, numLetters);
}
for (int c=0; c<numLetters; ++c)
{
_textGlyphs[UTF8string[c]].setCommonHeight(line->getHeight());
line->addGlyph(_textGlyphs[UTF8string[c]] );
_textGlyphsNew[UTF16string[c]].setCommonHeight(line->getHeight());
line->addGlyph(_textGlyphsNew[UTF16string[c]] );
}
if(!textIsUTF16)
delete [] UTF16string;
return true;
}
bool TextImage::addGlyphsToLine(TextLineDef *line, const char *lineText, bool textIsUTF16)
{
if (!_font)
return false;
int numLetters = 0;
unsigned short int *UTF16string = 0;
if (textIsUTF16)
{
UTF16string = (unsigned short int *) lineText;
numLetters = cc_wcslen(UTF16string);
}
else
{
UTF16string = _font->getUTF8Text(lineText, numLetters);
}
for (int c=0; c<numLetters; ++c)
{
_textGlyphs[UTF16string[c]].setCommonHeight(line->getHeight());
line->addGlyph(_textGlyphs[UTF16string[c]] );
}
if(!textIsUTF16)
delete [] UTF16string;
return true;
}
bool TextImage::generateTextGlyphs(const char * pText)
{
int numGlyphs = 0;
// carloX new stuff
if(!_fontNew)
return false;
GlyphDef *pNewGlyphs = _fontNew->getGlyphsForText(pText, numGlyphs);
if (!pNewGlyphs)
return false;
for (int c=0; c < numGlyphs; ++c)
{
_textGlyphsNew[pNewGlyphs[c].getUTF8Letter()] = pNewGlyphs[c];
}
delete [] pNewGlyphs;
// end new stuff
if (!_font)
return false;
int numGlyphs = 0;
GlyphDef *pGlyphs = _font->getGlyphsForText(pText, numGlyphs);
if (!pGlyphs || !numGlyphs)
@ -358,6 +640,36 @@ bool TextImage::generateTextGlyphs(const char * pText)
return true;
}
bool TextImage::createImageDataFromPagesNew(TextFontPagesDef *thePages, bool releaseRAWData)
{
int numPages = thePages->getNumPages();
if (!numPages)
return false;
for (int c = 0; c < numPages; ++c)
{
unsigned char *pPageData = 0;
pPageData = preparePageGlyphDataNew(thePages->getPageAt(c), thePages->getFontName(), thePages->getFontSize());
if (pPageData)
{
// set the page data
thePages->getPageAt(c)->setPageData(pPageData);
// crete page texture and relase RAW data
thePages->getPageAt(c)->preparePageTexture(releaseRAWData);
}
else
{
return false;
}
}
return true;
}
bool TextImage::createImageDataFromPages(TextFontPagesDef *thePages, bool releaseRAWData)
{
int numPages = thePages->getNumPages();
@ -386,6 +698,23 @@ bool TextImage::createImageDataFromPages(TextFontPagesDef *thePages, bool releas
return true;
}
unsigned char * TextImage::preparePageGlyphDataNew(TextPageDef *thePage, char *fontName, int fontSize)
{
if ( !_fontRenderNew )
{
createFontRenderNew();
}
if (_fontRenderNew)
{
return _fontRenderNew->preparePageGlyphData(thePage, fontName, fontSize);
}
else
{
return 0;
}
}
unsigned char * TextImage::preparePageGlyphData(TextPageDef *thePage, char *fontName, int fontSize)
{
// crate the font renderer if needed

View File

@ -163,12 +163,22 @@ public:
bool initWithString(const char *pText, int nWidth, int nHeight, const char * pFontName, int nSize, bool releaseRAWData = true);
// carloX
bool initWithStringNew(const char *pText, int nWidth, int nHeight, const char * pFontName, int nSize, bool textIsUTF16 = false, bool releaseRAWData = true);
TextFontPagesDef * getPagesNew() { return _fontPagesNew; }
Font * getFontNew() { return _fontNew; }
TextFontPagesDef * getPages() { return _fontPages; }
Font * getFont() { return _font; }
// debug only (this will go)
bool debugSaveToFile(const char *pszFilePath, bool bIsToRGB);
private:
bool createImageDataFromPages(TextFontPagesDef *thePages, bool releaseRAWData = true);
@ -176,7 +186,17 @@ private:
bool createFontRender();
bool generateTextGlyphs(const char * pText);
unsigned char * preparePageGlyphData(TextPageDef *thePage, char *fontName, int fontSize);
bool addGlyphsToLine(TextLineDef *line, const char *lineText);
bool addGlyphsToLine(TextLineDef *line, const char *lineText, bool textIsUTF16 = false);
// carloX
unsigned char * preparePageGlyphDataNew(TextPageDef *thePage, char *fontName, int fontSize);
bool createImageDataFromPagesNew(TextFontPagesDef *thePages, bool releaseRAWData = true);
bool createFontRenderNew();
bool addGlyphsToLineNew(TextLineDef *line, const char *lineText, bool textIsUTF16 = false);
std::map<unsigned short int, GlyphDef> _textGlyphs;
@ -186,6 +206,8 @@ private:
// carloX new stuff
std::map<unsigned short int, GlyphDef> _textGlyphsNew;
TextFontPagesDef * _fontPagesNew;
Font * _fontNew;
FontRender * _fontRenderNew;

View File

@ -1124,6 +1124,7 @@ string LabelBMFontChinese::title()
/// BitmapFontMultiLineAlignment
#define LongSentencesExample "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
//#define LongSentencesExample "psps"
#define LineBreaksExample "Lorem ipsum dolor\nsit amet\nconsectetur adipisicing elit\nblah\nblah"
#define MixedExample "ABC\nLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt\nDEF"
@ -1661,6 +1662,7 @@ LabelDyamicTest::LabelDyamicTest()
const char *pFontName = "MarkerFelt-Thin";
const char *pFontGlyphs = "abcdefghilmnopqrstuvzxywABCDEFGHILMNOPQRSTUVZXYW0123456789,. ";
//const char *pFontGlyphs = "ps";
LabelFontDefinition *pDef = new LabelFontDefinition;
pDef->createFontDefinition((char *)pFontName, 30, (char *) pFontGlyphs);