Merge pull request #5142 from Dhilan007/develop_label

close #3805:fix wrap error and alignment error.
This commit is contained in:
James Chen 2014-01-21 19:35:45 -08:00
commit 3aac0b32a2
13 changed files with 170 additions and 277 deletions

View File

@ -41,7 +41,7 @@ class CC_DLL Font : public Object
public:
virtual FontAtlas *createFontAtlas() = 0;
virtual Size* getAdvancesForTextUTF16(unsigned short *text, int &outNumLetters) const = 0;
virtual int* getHorizontalKerningForTextUTF16(unsigned short *text, int &outNumLetters) const = 0;
virtual const char* getCurrentGlyphCollection() const;
virtual int getLetterPadding() const { return 0; }

View File

@ -133,7 +133,7 @@ bool FontAtlas::prepareLetterDefinitions(unsigned short *utf16String)
tempDef.anchorX = 0.0f;
tempDef.anchorY = 1.0f;
if (!fontTTf->getBBOXFotChar(utf16String[i], tempRect))
if (!fontTTf->getBBOXFotChar(utf16String[i], tempRect,tempDef.xAdvance))
{
tempDef.validDefinition = false;
tempDef.letteCharUTF16 = utf16String[i];
@ -145,6 +145,7 @@ bool FontAtlas::prepareLetterDefinitions(unsigned short *utf16String)
tempDef.offsetX = 0;
tempDef.offsetY = 0;
tempDef.textureID = 0;
tempDef.xAdvance = 0;
}
else
{
@ -155,7 +156,6 @@ bool FontAtlas::prepareLetterDefinitions(unsigned short *utf16String)
tempDef.offsetX = tempRect.origin.x;
tempDef.offsetY = tempRect.origin.y;
tempDef.commonLineHeight = _currentPageLineHeight;
}
fontDefs[utf16String[i]] = tempDef;
}

View File

@ -49,6 +49,7 @@ struct FontLetterDefinition
float anchorX;
float anchorY;
bool validDefinition;
int xAdvance;
};
class CC_DLL FontAtlas : public Object

View File

@ -99,7 +99,7 @@ FontCharMap::~FontCharMap()
}
Size * FontCharMap::getAdvancesForTextUTF16(unsigned short *text, int &outNumLetters) const
int * FontCharMap::getHorizontalKerningForTextUTF16(unsigned short *text, int &outNumLetters) const
{
if (!text)
return 0;
@ -109,14 +109,13 @@ Size * FontCharMap::getAdvancesForTextUTF16(unsigned short *text, int &outNumLet
if (!outNumLetters)
return 0;
Size *sizes = new Size[outNumLetters];
int *sizes = new int[outNumLetters];
if (!sizes)
return 0;
int advance = _itemWidth * CC_CONTENT_SCALE_FACTOR();
for (int c = 0; c < outNumLetters; ++c)
{
sizes[c].width = advance;
sizes[c] = 0;
}
return sizes;
@ -149,10 +148,9 @@ FontAtlas * FontCharMap::createFontAtlas()
tempDefinition.validDefinition = true;
tempDefinition.width = _itemWidth;
tempDefinition.height = _itemHeight;
tempDefinition.xAdvance = _itemWidth * CC_CONTENT_SCALE_FACTOR();
int charId = _mapStartChar;
float itemWidthInPixels = _itemWidth * CC_CONTENT_SCALE_FACTOR();
float itemHeightInPixels = _itemHeight * CC_CONTENT_SCALE_FACTOR();
for (int row = 0; row < itemsPerColumn; ++row)
{
for (int col = 0; col < itemsPerRow; ++col)

View File

@ -37,7 +37,7 @@ public:
static FontCharMap * create(Texture2D* texture, int itemWidth, int itemHeight, int startCharMap);
static FontCharMap * create(const std::string& plistFile);
virtual Size* getAdvancesForTextUTF16(unsigned short *text, int &outNumLetters) const override;
virtual int* getHorizontalKerningForTextUTF16(unsigned short *text, int &outNumLetters) const override;
virtual Rect getRectForChar(unsigned short theChar) const override;
virtual FontAtlas *createFontAtlas() override;

View File

@ -62,7 +62,7 @@ FontFNT::~FontFNT()
}
Size * FontFNT::getAdvancesForTextUTF16(unsigned short *text, int &outNumLetters) const
int * FontFNT::getHorizontalKerningForTextUTF16(unsigned short *text, int &outNumLetters) const
{
if (!text)
return 0;
@ -72,39 +72,21 @@ Size * FontFNT::getAdvancesForTextUTF16(unsigned short *text, int &outNumLetters
if (!outNumLetters)
return 0;
Size *sizes = new Size[outNumLetters];
int *sizes = new int[outNumLetters];
if (!sizes)
return 0;
for (int c = 0; c < outNumLetters; ++c)
{
int advance = 0;
int kerning = 0;
advance = getAdvanceForChar(text[c]);
if (c < (outNumLetters-1))
kerning = getHorizontalKerningForChars(text[c], text[c+1]);
sizes[c].width = (advance + kerning);
sizes[c] = getHorizontalKerningForChars(text[c], text[c+1]);
else
sizes[c] = 0;
}
return sizes;
}
int FontFNT::getAdvanceForChar(unsigned short theChar) const
{
tFontDefHashElement *element = nullptr;
// unichar is a short, and an int is needed on HASH_FIND_INT
unsigned int key = theChar;
HASH_FIND_INT(_configuration->_fontDefDictionary, &key, element);
if (! element)
return -1;
return element->fontDef.xAdvance;
}
int FontFNT::getHorizontalKerningForChars(unsigned short firstChar, unsigned short secondChar) const
{
int ret = 0;
@ -194,9 +176,8 @@ FontAtlas * FontFNT::createFontAtlas()
//carloX: only one texture supported FOR NOW
tempDefinition.textureID = 0;
tempDefinition.anchorX = 0.5f;
tempDefinition.anchorY = 0.5f;
tempDefinition.validDefinition = true;
tempDefinition.xAdvance = fontDef.xAdvance;
// add the new definition
tempAtlas->addLetterDefinition(tempDefinition);
}

View File

@ -39,7 +39,7 @@ public:
static FontFNT * create(const std::string& fntFilePath);
virtual Size* getAdvancesForTextUTF16(unsigned short *text, int &outNumLetters) const override;
virtual int* getHorizontalKerningForTextUTF16(unsigned short *text, int &outNumLetters) const override;
virtual Rect getRectForChar(unsigned short theChar) const override;
virtual FontAtlas *createFontAtlas() override;
@ -55,7 +55,6 @@ protected:
private:
int getAdvanceForChar(unsigned short theChar) const;
int getHorizontalKerningForChars(unsigned short firstChar, unsigned short secondChar) const;
Rect getRectForCharInternal(unsigned short theChar) const;

View File

@ -143,7 +143,7 @@ FontAtlas * FontFreeType::createFontAtlas()
return atlas;
}
bool FontFreeType::getBBOXFotChar(unsigned short theChar, Rect &outRect) const
bool FontFreeType::getBBOXFotChar(unsigned short theChar, Rect &outRect, int &xAdvance) const
{
if (!_fontRef)
return false;
@ -164,10 +164,12 @@ bool FontFreeType::getBBOXFotChar(unsigned short theChar, Rect &outRect) const
outRect.size.width = (_fontRef->glyph->metrics.width >> 6);
outRect.size.height = (_fontRef->glyph->metrics.height >> 6);
xAdvance = (static_cast<int>(_fontRef->glyph->metrics.horiAdvance >> 6));
return true;
}
Size * FontFreeType::getAdvancesForTextUTF16(unsigned short *text, int &outNumLetters) const
int * FontFreeType::getHorizontalKerningForTextUTF16(unsigned short *text, int &outNumLetters) const
{
if (!text)
return 0;
@ -177,64 +179,21 @@ Size * FontFreeType::getAdvancesForTextUTF16(unsigned short *text, int &outNumLe
if (!outNumLetters)
return 0;
Size *sizes = new Size[outNumLetters];
int *sizes = new int[outNumLetters];
if (!sizes)
return 0;
for (int c = 0; c < outNumLetters; ++c)
{
int advance = 0;
int kerning = 0;
advance = getAdvanceForChar(text[c]);
if (c < (outNumLetters-1))
kerning = getHorizontalKerningForChars(text[c], text[c+1]);
sizes[c].width = (advance + kerning);
sizes[c] = getHorizontalKerningForChars(text[c], text[c+1]);
else
sizes[c] = 0;
}
return sizes;
}
int FontFreeType::getAdvanceForChar(unsigned short theChar) const
{
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;
// get to the advance for this glyph
return (static_cast<int>(_fontRef->glyph->metrics.horiAdvance >> 6));
}
int FontFreeType::getBearingXForChar(unsigned short theChar) const
{
if (!_fontRef)
return 0;
// get the ID to the char we need
int glyphIndex = FT_Get_Char_Index(_fontRef, theChar);
if (!glyphIndex)
return 0;
// load glyph infos
if (FT_Load_Glyph(_fontRef, glyphIndex, FT_LOAD_DEFAULT))
return 0;
return (static_cast<int>(_fontRef->glyph->metrics.horiBearingX >>6));
}
int FontFreeType::getHorizontalKerningForChars(unsigned short firstChar, unsigned short secondChar) const
{
if (!_fontRef)

View File

@ -50,13 +50,13 @@ public:
bool renderCharAt(unsigned short int charToRender, int posX, int posY, unsigned char *destMemory, int destSize);
virtual FontAtlas * createFontAtlas() override;
virtual Size * getAdvancesForTextUTF16(unsigned short *text, int &outNumLetters) const override;
virtual int * getHorizontalKerningForTextUTF16(unsigned short *text, int &outNumLetters) const override;
unsigned char * getGlyphBitmap(unsigned short theChar, int &outWidth, int &outHeight) const override;
virtual int getFontMaxHeight() const override;
virtual int getLetterPadding() const override;
bool getBBOXFotChar(unsigned short theChar, Rect &outRect) const;
bool getBBOXFotChar(unsigned short theChar, Rect &outRect,int &xAdvance) const;
protected:
@ -69,8 +69,6 @@ private:
bool initFreeType();
FT_Library getFTLibrary();
int getAdvanceForChar(unsigned short theChar) const;
int getBearingXForChar(unsigned short theChar) const;
int getHorizontalKerningForChars(unsigned short firstChar, unsigned short secondChar) const;
static FT_Library _FTlibrary;

View File

@ -193,7 +193,7 @@ Label::Label(FontAtlas *atlas, TextHAlignment alignment, bool useDistanceField,b
, _alignment(alignment)
, _currentUTF16String(nullptr)
, _originalUTF16String(nullptr)
, _advances(nullptr)
, _horizontalKernings(nullptr)
, _fontAtlas(atlas)
, _isOpacityModifyRGB(true)
, _useDistanceField(useDistanceField)
@ -208,7 +208,7 @@ Label::~Label()
{
delete [] _currentUTF16String;
delete [] _originalUTF16String;
delete [] _advances;
delete [] _horizontalKernings;
if (_fontAtlas)
FontAtlasCache::releaseFontAtlas(_fontAtlas);
@ -226,6 +226,7 @@ bool Label::init()
_reusedLetter = Sprite::createWithTexture(&_fontAtlas->getTexture(0));
_reusedLetter->setOpacityModifyRGB(_isOpacityModifyRGB);
_reusedLetter->retain();
_reusedLetter->setAnchorPoint(Point::ANCHOR_TOP_LEFT);
}
ret = SpriteBatchNode::initWithTexture(&_fontAtlas->getTexture(0), 30);
}
@ -474,18 +475,18 @@ void Label::alignText()
}
}
bool Label::computeAdvancesForString(unsigned short int *stringToRender)
bool Label::computeHorizontalKernings(unsigned short int *stringToRender)
{
if (_advances)
if (_horizontalKernings)
{
delete [] _advances;
_advances = 0;
delete [] _horizontalKernings;
_horizontalKernings = 0;
}
int letterCount = 0;
_advances = _fontAtlas->getFont()->getAdvancesForTextUTF16(stringToRender, letterCount);
_horizontalKernings = _fontAtlas->getFont()->getHorizontalKerningForTextUTF16(stringToRender, letterCount);
if(!_advances)
if(!_horizontalKernings)
return false;
else
return true;
@ -519,7 +520,7 @@ bool Label::setCurrentString(unsigned short *stringToSet)
//
_currentUTF16String = stringToSet;
// compute the advances
return computeAdvancesForString(stringToSet);
return computeHorizontalKernings(stringToSet);
}
void Label::resetCurrentString()
@ -558,10 +559,8 @@ Sprite * Label::updateSpriteWithLetterDefinition(Sprite *spriteToUpdate, const F
SpriteFrame *frame = SpriteFrame::createWithTexture(theTexture, uvRect);
if (frame)
{
spriteToUpdate->setBatchNode(this);
spriteToUpdate->setTexture(theTexture);
spriteToUpdate->setSpriteFrame(frame);
spriteToUpdate->setAnchorPoint(Point(theDefinition.anchorX, theDefinition.anchorY));
spriteToUpdate->setBatchNode(this);
spriteToUpdate->setSpriteFrame(frame);
}
return spriteToUpdate;
@ -692,8 +691,8 @@ Sprite * Label::getLetter(int ID)
sp = Sprite::createWithTexture(&_fontAtlas->getTexture(_lettersInfo[ID].def.textureID),uvRect);
sp->setBatchNode(this);
sp->setAnchorPoint(Point(_lettersInfo[ID].def.anchorX, _lettersInfo[ID].def.anchorY));
sp->setPosition(_lettersInfo[ID].position);
sp->setAnchorPoint(Point::ANCHOR_MIDDLE);
sp->setPosition(Point(_lettersInfo[ID].position.x+uvRect.size.width/2,_lettersInfo[ID].position.y-uvRect.size.height/2));
sp->setOpacity(_realOpacity);
this->addSpriteWithoutQuad(sp, ID, ID);
@ -706,12 +705,12 @@ Sprite * Label::getLetter(int ID)
float Label::getLetterPosXLeft( int index ) const
{
return _lettersInfo[index].position.x * _scaleX - (_lettersInfo[index].contentSize.width * _scaleX * _lettersInfo[index].def.anchorX);
return _lettersInfo[index].position.x * _scaleX;
}
float Label::getLetterPosXRight( int index ) const
{
return _lettersInfo[index].position.x * _scaleX + (_lettersInfo[index].contentSize.width * _scaleX * _lettersInfo[index].def.anchorX);
return (_lettersInfo[index].position.x + _lettersInfo[index].contentSize.width) * _scaleX;
}
int Label::getCommonLineHeight() const
@ -719,9 +718,16 @@ int Label::getCommonLineHeight() const
return _commonLineHeight;
}
int Label::getKerningForCharsPair(unsigned short first, unsigned short second) const
int Label::getKerningInString(int hintPositionInString) const
{
return 0;
if (_horizontalKernings)
{
return (_horizontalKernings[hintPositionInString]);
}
else
{
return -1;
}
}
int Label::getXOffsetForChar(unsigned short c) const
@ -746,7 +752,7 @@ int Label::getYOffsetForChar(unsigned short c) const
int Label::getAdvanceForChar(unsigned short c, int hintPositionInString) const
{
if (_advances)
if (_horizontalKernings)
{
// not that advance contains the X offset already
FontLetterDefinition tempDefinition;
@ -754,7 +760,7 @@ int Label::getAdvanceForChar(unsigned short c, int hintPositionInString) const
if (!validDefinition)
return -1;
return (_advances[hintPositionInString].width);
return tempDefinition.xAdvance;
}
else
{

View File

@ -123,7 +123,7 @@ public:
// font related stuff
virtual int getCommonLineHeight() const override;
virtual int getKerningForCharsPair(unsigned short first, unsigned short second) const override;
virtual int getKerningInString(int hintPositionInString) const override;
virtual int getXOffsetForChar(unsigned short c) const override;
virtual int getYOffsetForChar(unsigned short c) const override;
virtual int getAdvanceForChar(unsigned short c, int hintPositionInString) const override;
@ -170,7 +170,7 @@ private:
void alignText();
bool computeAdvancesForString(unsigned short int *stringToRender);
bool computeHorizontalKernings(unsigned short int *stringToRender);
bool setCurrentString(unsigned short *stringToSet);
bool setOriginalString(unsigned short *stringToSet);
void resetCurrentString();
@ -189,7 +189,7 @@ private:
TextHAlignment _alignment;
unsigned short int * _currentUTF16String;
unsigned short int * _originalUTF16String;
Size * _advances;
int * _horizontalKernings;
FontAtlas * _fontAtlas;
bool _isOpacityModifyRGB;

View File

@ -61,7 +61,7 @@ public:
// font related stuff
virtual int getCommonLineHeight() const = 0;
virtual int getKerningForCharsPair(unsigned short first, unsigned short second) const = 0;
virtual int getKerningInString(int hintPositionInString) const = 0;
virtual int getXOffsetForChar(unsigned short c) const = 0;
virtual int getYOffsetForChar(unsigned short c) const = 0;
virtual int getAdvanceForChar(unsigned short c, int hintPositionInString) const = 0;

View File

@ -35,70 +35,39 @@ NS_CC_BEGIN
bool LabelTextFormatter::multilineText(LabelTextFormatProtocol *theLabel)
{
// to do if (m_fWidth > 0)
if (theLabel->getMaxLineWidth())
{
// Step 1: Make multiline
vector<unsigned short> strWhole = cc_utf16_vec_from_utf16_str(theLabel->getUTF8String());
size_t stringLength = strWhole.size();
vector<unsigned short> multiline_string;
multiline_string.reserve( stringLength );
vector<unsigned short> last_word;
last_word.reserve( stringLength );
unsigned int line = 1, i = 0;
bool isStartOfLine = false, isStartOfWord = false;
float startOfLine = -1, startOfWord = -1;
int skip = 0;
int strLen = theLabel->getStringLenght();
std::vector<LetterInfo> *leterInfo = theLabel->getLettersInfo();
int tIndex = 0;
int strLen = theLabel->getStringLenght();
auto strWhole = theLabel->getUTF8String();
for (int j = 0; j+skip < strLen; j++)
{
LetterInfo* info = &leterInfo->at(j+skip);
vector<unsigned short> multiline_string;
multiline_string.reserve( strLen );
unsigned int justSkipped = 0;
while (info->def.validDefinition == false)
{
justSkipped++;
tIndex = j+skip+justSkipped;
if(tIndex < strLen)
info = &leterInfo->at( tIndex );
else
break;
}
skip += justSkipped;
tIndex = j + skip;
if (tIndex >= stringLength)
break;
unsigned short character = strWhole[tIndex];
if (!isStartOfWord)
{
startOfWord = theLabel->getLetterPosXLeft( tIndex );
isStartOfWord = true;
}
if (!isStartOfLine)
{
startOfLine = startOfWord;
isStartOfLine = true;
}
// Newline.
if (character == '\n')
vector<unsigned short> last_word;
last_word.reserve( strLen );
unsigned int line = 1;
bool isStartOfLine = false, isStartOfWord = false;
float startOfLine = -1, startOfWord = -1;
int skip = 0;
std::vector<LetterInfo> *leterInfo = theLabel->getLettersInfo();
int tIndex = 0;
for (int j = 0; j+skip < strLen; j++)
{
LetterInfo* info = &leterInfo->at(j+skip);
unsigned int justSkipped = 0;
while (info->def.validDefinition == false)
{
justSkipped++;
tIndex = j+skip+justSkipped;
if (strWhole[tIndex-1] == '\n')
{
cc_utf8_trim_ws(&last_word);
last_word.push_back('\n');
multiline_string.insert(multiline_string.end(), last_word.begin(), last_word.end());
last_word.clear();
@ -106,119 +75,102 @@ bool LabelTextFormatter::multilineText(LabelTextFormatProtocol *theLabel)
isStartOfLine = false;
startOfWord = -1;
startOfLine = -1;
i += justSkipped;
++line;
if (i >= stringLength)
break;
character = strWhole[i];
if (!startOfWord)
{
startOfWord = theLabel->getLetterPosXLeft( tIndex );
isStartOfWord = true;
}
if (!startOfLine)
{
startOfLine = startOfWord;
isStartOfLine = true;
}
}
// Whitespace.
if (isspace_unicode(character))
if(tIndex < strLen)
{
info = &leterInfo->at( tIndex );
}
else
break;
}
skip += justSkipped;
tIndex = j + skip;
if (tIndex >= strLen)
break;
unsigned short character = strWhole[tIndex];
if (!isStartOfWord)
{
startOfWord = theLabel->getLetterPosXLeft( tIndex );
isStartOfWord = true;
}
if (!isStartOfLine)
{
startOfLine = startOfWord;
isStartOfLine = true;
}
// Whitespace.
if (isspace_unicode(character))
{
last_word.push_back(character);
multiline_string.insert(multiline_string.end(), last_word.begin(), last_word.end());
last_word.clear();
isStartOfWord = false;
startOfWord = -1;
continue;
}
// Out of bounds.
if (theLabel->getLetterPosXRight( tIndex ) - startOfLine > theLabel->getMaxLineWidth())
{
if (!theLabel->breakLineWithoutSpace())
{
last_word.push_back(character);
multiline_string.insert(multiline_string.end(), last_word.begin(), last_word.end());
last_word.clear();
isStartOfWord = false;
startOfWord = -1;
++i;
continue;
}
// Out of bounds.
if (theLabel->getLetterPosXRight( tIndex ) - startOfLine > theLabel->getMaxLineWidth())
{
if (!theLabel->breakLineWithoutSpace())
{
last_word.push_back(character);
int found = cc_utf8_find_last_not_char(multiline_string, ' ');
if (found != -1)
cc_utf8_trim_ws(&multiline_string);
else
multiline_string.clear();
if (multiline_string.size() > 0)
multiline_string.push_back('\n');
++line;
isStartOfLine = false;
startOfLine = -1;
++i;
}
int found = cc_utf8_find_last_not_char(multiline_string, ' ');
if (found != -1)
cc_utf8_trim_ws(&multiline_string);
else
{
cc_utf8_trim_ws(&last_word);
last_word.push_back('\n');
multiline_string.insert(multiline_string.end(), last_word.begin(), last_word.end());
last_word.clear();
isStartOfWord = false;
isStartOfLine = false;
startOfWord = -1;
startOfLine = -1;
++line;
if (i >= stringLength)
break;
if (!startOfWord)
{
startOfWord = theLabel->getLetterPosXLeft( tIndex );
isStartOfWord = true;
}
if (!startOfLine)
{
startOfLine = startOfWord;
isStartOfLine = true;
}
--j;
}
continue;
multiline_string.clear();
if (multiline_string.size() > 0)
multiline_string.push_back('\n');
++line;
isStartOfLine = false;
startOfLine = -1;
}
else
{
// Character is normal.
last_word.push_back(character);
++i;
continue;
cc_utf8_trim_ws(&last_word);
last_word.push_back('\n');
multiline_string.insert(multiline_string.end(), last_word.begin(), last_word.end());
last_word.clear();
isStartOfWord = false;
isStartOfLine = false;
startOfWord = -1;
startOfLine = -1;
++line;
--j;
}
}
multiline_string.insert(multiline_string.end(), last_word.begin(), last_word.end());
size_t size = multiline_string.size();
unsigned short* strNew = new unsigned short[size + 1];
for (size_t j = 0; j < size; ++j)
else
{
strNew[j] = multiline_string[j];
// Character is normal.
last_word.push_back(character);
}
strNew[size] = 0;
theLabel->assignNewUTF8String(strNew);
return true;
}
else
multiline_string.insert(multiline_string.end(), last_word.begin(), last_word.end());
size_t size = multiline_string.size();
unsigned short* strNew = new unsigned short[size + 1];
for (size_t j = 0; j < size; ++j)
{
return false;
strNew[j] = multiline_string[j];
}
strNew[size] = 0;
theLabel->assignNewUTF8String(strNew);
return true;
}
bool LabelTextFormatter::alignText(LabelTextFormatProtocol *theLabel)
@ -337,7 +289,7 @@ bool LabelTextFormatter::createStringSprites(LabelTextFormatProtocol *theLabel)
charAdvance = theLabel->getAdvanceForChar(c, i);
charRect = theLabel->getRectForChar(c);
int kerningAmount = theLabel->getKerningForCharsPair(prev, c);
int kerningAmount = theLabel->getKerningInString(i);
if (c == '\n')
{
@ -351,9 +303,8 @@ bool LabelTextFormatter::createStringSprites(LabelTextFormatProtocol *theLabel)
// See issue 1343. cast( signed short + unsigned integer ) == unsigned integer (sign is lost!)
int yOffset = commonLineHeight - charYOffset;
Point fontPos = Point((float)nextFontPositionX + charXOffset + charRect.size.width * 0.5f + kerningAmount,
(float)nextFontPositionY + yOffset - charRect.size.height * 0.5f);
Point fontPos = Point((float)nextFontPositionX + charXOffset + kerningAmount,
(float)nextFontPositionY + yOffset);
if( theLabel->recordLetterInfo(CC_POINT_PIXELS_TO_POINTS(fontPos),c,i) == false)
{