some more clean up and removed CCStringTTF

This commit is contained in:
carlo morgantini 2013-08-07 16:36:04 -07:00
parent ef919aea91
commit 83b2377a76
12 changed files with 746 additions and 1761 deletions

View File

@ -1 +1 @@
e4abb5d1cb9dde319461fc8f0b800afe6490b185
f1f3f9509d1a7df5298606d8c099c5d3d85d4ff5

View File

@ -99,7 +99,7 @@ THE SOFTWARE.
#include "label_nodes/CCLabelAtlas.h"
#include "label_nodes/CCLabelTTF.h"
#include "label_nodes/CCLabelBMFont.h"
#include "label_nodes/CCStringTTF.h"
#include "label_nodes/CCLabel.h"
// layers_scenes_transitions_nodes
#include "layers_scenes_transitions_nodes/CCLayer.h"

View File

@ -28,6 +28,7 @@
#include "cocos2d.h"
#include "CCFontAtlas.h"
NS_CC_BEGIN
class CC_DLL FontAtlasFactory

View File

@ -23,6 +23,7 @@
****************************************************************************/
#include "cocos2d.h"
#include "CCFontDefinition.h"
NS_CC_BEGIN

View File

@ -7,6 +7,7 @@
//
#include "CCFontFNT.h"
#include "CCFontAtlas.h"
NS_CC_BEGIN

View File

@ -28,6 +28,7 @@
#include "CCFontFreeType.h"
#include "CCTextImage.h"
#include "CCFont.h"
#include "CCFontDefinition.h"
NS_CC_BEGIN

View File

@ -23,39 +23,43 @@
****************************************************************************/
#include "CCLabel.h"
#include "CCStringTTF.h"
#include "CCFontDefinition.h"
#include "CCFontCache.h"
#include "CCFontAtlasCache.h"
#include "CCLabelTextFormatter.h"
NS_CC_BEGIN
Label* Label::createWithTTF( const char* label, const char* tttFilePath, int fontSize, GlyphCollection glyphs, int lineSize, const char *customGlyphs )
{
FontAtlas *tempAtlas = FontAtlasCache::getFontAtlasTTF(tttFilePath, fontSize, glyphs, customGlyphs);
if (!tempAtlas)
return nullptr;
// create the actual label
StringTTF* templabel = StringTTF::create(tempAtlas, TextHAlignment::CENTER, lineSize);
Label* templabel = Label::create(tempAtlas, TextHAlignment::CENTER, lineSize);
if (templabel)
{
templabel->setText(label, lineSize, TextHAlignment::CENTER, false);
return templabel;
}
return nullptr;
return 0;
}
Label* Label::createWithBMFont( const char* label, const char* bmfontFilePath, int lineSize)
{
FontAtlas *tempAtlas = FontAtlasCache::getFontAtlasFNT(bmfontFilePath);
if (!tempAtlas)
return 0;
StringTTF* templabel = StringTTF::create(tempAtlas, TextHAlignment::CENTER, lineSize);
Label* templabel = Label::create(tempAtlas, TextHAlignment::CENTER, lineSize);
if (templabel)
{
@ -66,14 +70,640 @@ Label* Label::createWithBMFont( const char* label, const char* bmfontFilePath, i
{
return 0;
}
return 0;
}
Label::Label()
Label* Label::create(FontAtlas *pAtlas, TextHAlignment alignment, int lineSize)
{
Label *ret = new Label(pAtlas, alignment);
if (!ret)
return 0;
if( ret->init() )
{
ret->autorelease();
return ret;
}
else
{
delete ret;
return 0;
}
return ret;
}
Label::Label(FontAtlas *pAtlas, TextHAlignment alignment): _currentUTF8String(0),
_originalUTF8String(0),
_fontAtlas(pAtlas),
_alignment(alignment),
_lineBreakWithoutSpaces(false),
_advances(0),
_displayedColor(Color3B::WHITE),
_realColor(Color3B::WHITE),
_cascadeColorEnabled(true)
{
}
Label::~Label()
{
if (_currentUTF8String)
delete [] _currentUTF8String;
if (_advances)
delete [] _advances;
if (_fontAtlas)
FontAtlasCache::releaseFontAtlas(_fontAtlas);
}
bool Label::init()
{
return true;
}
void Label::setString(const char *stringToRender)
{
setText(stringToRender, 0, TextHAlignment::CENTER, false);
}
bool Label::setText(const char *stringToRender, float lineWidth, TextHAlignment alignment, bool lineBreakWithoutSpaces)
{
if (!_fontAtlas)
return false;
_width = lineWidth;
_alignment = alignment;
_lineBreakWithoutSpaces = lineBreakWithoutSpaces;
// release all the sprites
moveAllSpritesToCache();
// store locally common line height
_commonLineHeight = _fontAtlas->getCommonLineHeight();
if (_commonLineHeight <= 0)
return false;
int numLetter = 0;
unsigned short* utf16String = cc_utf8_to_utf16(stringToRender);
if(!utf16String)
return false;
numLetter = cc_wcslen(utf16String);
SpriteBatchNode::initWithTexture(&_fontAtlas->getTexture(0), numLetter);
_cascadeColorEnabled = true;
//
setCurrentString(utf16String);
setOriginalString(utf16String);
// align text
alignText();
// done here
return true;
}
void Label::setAlignment(TextHAlignment alignment)
{
// store the new alignment
if (alignment != _alignment)
{
// store
_alignment = alignment;
// reset the string
resetCurrentString();
// need to align text again
alignText();
}
}
void Label::setWidth(float width)
{
if (width != _width)
{
// store
_width = width;
// need to align text again
alignText();
}
}
void Label::setLineBreakWithoutSpace(bool breakWithoutSpace)
{
if (breakWithoutSpace != _lineBreakWithoutSpaces)
{
// store
_lineBreakWithoutSpaces = breakWithoutSpace;
// need to align text again
alignText();
}
}
void Label::setScale(float scale)
{
Node::setScale(scale);
alignText();
}
void Label::setScaleX(float scaleX)
{
Node::setScaleX(scaleX);
alignText();
}
void Label::setScaleY(float scaleY)
{
Node::setScaleY(scaleY);
alignText();
}
void Label::alignText()
{
hideAllLetters();
LabelTextFormatter::createStringSprites(this);
if( LabelTextFormatter::multilineText(this) )
{
hideAllLetters();
LabelTextFormatter::createStringSprites(this);
}
LabelTextFormatter::alignText(this);
}
void Label::hideAllLetters()
{
Object* Obj = NULL;
CCARRAY_FOREACH(&_spriteArray, Obj)
{
((Sprite *)Obj)->setVisible(false);
}
CCARRAY_FOREACH(&_spriteArrayCache, Obj)
{
((Sprite *)Obj)->setVisible(false);
}
}
bool Label::computeAdvancesForString(unsigned short int *stringToRender)
{
if (_advances)
{
delete [] _advances;
_advances = 0;
}
Font &theFont = _fontAtlas->getFont();
int letterCount = 0;
_advances = theFont.getAdvancesForTextUTF16(stringToRender, letterCount);
if(!_advances)
return false;
else
return true;
}
bool Label::setOriginalString(unsigned short *stringToSet)
{
if (_originalUTF8String)
{
delete [] _originalUTF8String;
_originalUTF8String = 0;
}
int newStringLenght = cc_wcslen(stringToSet);
_originalUTF8String = new unsigned short int [newStringLenght + 1];
memset(_originalUTF8String, 0, (newStringLenght + 1) * 2);
memcpy(_originalUTF8String, stringToSet, (newStringLenght * 2));
_originalUTF8String[newStringLenght] = 0;
return true;
}
bool Label::setCurrentString(unsigned short *stringToSet)
{
// set the new string
if (_currentUTF8String)
{
delete [] _currentUTF8String;
_currentUTF8String = 0;
}
//
_currentUTF8String = stringToSet;
// compute the advances
return computeAdvancesForString(stringToSet);
}
void Label::resetCurrentString()
{
// set the new string
if (_currentUTF8String)
{
delete [] _currentUTF8String;
_currentUTF8String = 0;
}
int stringLenght = cc_wcslen(_originalUTF8String);
_currentUTF8String = new unsigned short int [stringLenght + 1];
memcpy(_currentUTF8String, _originalUTF8String, stringLenght * 2);
_currentUTF8String[stringLenght] = 0;
}
Sprite * Label::createNewSpriteFromLetterDefinition(FontLetterDefinition &theDefinition, Texture2D *theTexture)
{
Rect uvRect;
uvRect.size.height = theDefinition.height;
uvRect.size.width = theDefinition.width;
uvRect.origin.x = theDefinition.U;
uvRect.origin.y = theDefinition.V;
SpriteFrame *pFrame = SpriteFrame::createWithTexture(theTexture, uvRect);
Sprite *tempSprite = getSprite();
if (!tempSprite)
return 0;
tempSprite->initWithSpriteFrame(pFrame);
tempSprite->setAnchorPoint(Point(theDefinition.anchorX, theDefinition.anchorY));
tempSprite->setBatchNode(this);
return tempSprite;
}
Sprite * Label::updateSpriteWithLetterDefinition(Sprite *spriteToUpdate, FontLetterDefinition &theDefinition, Texture2D *theTexture)
{
if (!spriteToUpdate)
{
return 0;
}
else
{
Rect uvRect;
uvRect.size.height = theDefinition.height;
uvRect.size.width = theDefinition.width;
uvRect.origin.x = theDefinition.U;
uvRect.origin.y = theDefinition.V;
SpriteFrame *frame = SpriteFrame::createWithTexture(theTexture, uvRect);
if (frame)
{
spriteToUpdate->setTexture(theTexture);
spriteToUpdate->setDisplayFrame(frame);
spriteToUpdate->setAnchorPoint(Point(theDefinition.anchorX, theDefinition.anchorY));
spriteToUpdate->setBatchNode(this);
}
return spriteToUpdate;
}
}
Sprite * Label::getSpriteForLetter(unsigned short int newLetter)
{
if (!_fontAtlas)
return 0;
FontLetterDefinition tempDefinition;
bool validDefinition = _fontAtlas->getLetterDefinitionForChar(newLetter, tempDefinition);
if (validDefinition)
{
Sprite *newSprite = createNewSpriteFromLetterDefinition(tempDefinition, &_fontAtlas->getTexture(tempDefinition.textureID) );
this->addChild(newSprite);
return newSprite;
}
else
{
return 0;
}
}
Sprite * Label::updateSpriteForLetter(Sprite *spriteToUpdate, unsigned short int newLetter)
{
if (!spriteToUpdate || !_fontAtlas)
return 0;
else
{
FontLetterDefinition tempDefinition;
bool validDefinition = _fontAtlas->getLetterDefinitionForChar(newLetter, tempDefinition);
if (validDefinition)
{
Sprite *pNewSprite = updateSpriteWithLetterDefinition(spriteToUpdate, tempDefinition, &_fontAtlas->getTexture(tempDefinition.textureID) );
return pNewSprite;
}
else
{
return 0;
}
}
}
void Label::moveAllSpritesToCache()
{
Object* pObj = NULL;
CCARRAY_FOREACH(&_spriteArray, pObj)
{
((Sprite *)pObj)->removeFromParent();
_spriteArrayCache.addObject(pObj);
}
_spriteArray.removeAllObjects();
}
Sprite * Label::getSprite()
{
if (_spriteArrayCache.count())
{
Sprite *retSprite = (Sprite *) _spriteArrayCache.lastObject();
_spriteArrayCache.removeLastObject();
return retSprite;
}
else
{
Sprite *retSprite = new Sprite;
return retSprite;
}
}
///// PROTOCOL STUFF
Sprite * Label::getSpriteChild(int ID)
{
Object* pObj = NULL;
CCARRAY_FOREACH(&_spriteArray, pObj)
{
Sprite *pSprite = (Sprite *)pObj;
if ( pSprite->getTag() == ID)
{
return pSprite;
}
}
return 0;
}
Array * Label::getChildrenLetters()
{
return &_spriteArray;
}
Sprite * Label::getSpriteForChar(unsigned short int theChar, int spriteIndexHint)
{
// ret sprite
Sprite *retSprite = 0;
// look for already existing sprites
retSprite = getSpriteChild(spriteIndexHint);
if (!retSprite)
{
retSprite = getSpriteForLetter(theChar);
if (!retSprite)
return 0;
if (retSprite)
retSprite->setTag(spriteIndexHint);
_spriteArray.addObject(retSprite);
}
// the sprite is now visible
retSprite->setVisible(true);
// set the right texture letter to the sprite
updateSpriteForLetter(retSprite, theChar);
// we are done here
return retSprite;
}
float Label::getLetterPosXLeft( Sprite* sp )
{
float scaleX = _scaleX;
return sp->getPosition().x * scaleX - (sp->getContentSize().width * scaleX * sp->getAnchorPoint().x);
}
float Label::getLetterPosXRight( Sprite* sp )
{
float scaleX = _scaleX;
return sp->getPosition().x * scaleX + (sp->getContentSize().width * scaleX * sp->getAnchorPoint().x);
}
int Label::getCommonLineHeight()
{
return _commonLineHeight;
}
int Label::getKerningForCharsPair(unsigned short first, unsigned short second)
{
return 0;
}
int Label::getXOffsetForChar(unsigned short c)
{
FontLetterDefinition tempDefinition;
bool validDefinition = _fontAtlas->getLetterDefinitionForChar(c, tempDefinition);
if (!validDefinition)
return -1;
return (tempDefinition.offsetX);
}
int Label::getYOffsetForChar(unsigned short c)
{
FontLetterDefinition tempDefinition;
bool validDefinition = _fontAtlas->getLetterDefinitionForChar(c, tempDefinition);
if (!validDefinition)
return -1;
return (tempDefinition.offsetY);
}
int Label::getAdvanceForChar(unsigned short c, int hintPositionInString)
{
if (_advances)
{
// not that advance contains the X offset already
FontLetterDefinition tempDefinition;
bool validDefinition = _fontAtlas->getLetterDefinitionForChar(c, tempDefinition);
if (!validDefinition)
return -1;
return (_advances[hintPositionInString].width - tempDefinition.offsetX);
}
else
{
return -1;
}
}
Rect Label::getRectForChar(unsigned short c)
{
return _fontAtlas->getFont().getRectForChar(c);
}
// string related stuff
int Label::getStringNumLines()
{
int quantityOfLines = 1;
unsigned int stringLen = _currentUTF8String ? cc_wcslen(_currentUTF8String) : 0;
if (stringLen == 0)
return (-1);
// count number of lines
for (unsigned int i = 0; i < stringLen - 1; ++i)
{
unsigned short c = _currentUTF8String[i];
if (c == '\n')
{
quantityOfLines++;
}
}
return quantityOfLines;
}
int Label::getStringLenght()
{
return _currentUTF8String ? cc_wcslen(_currentUTF8String) : 0;
}
unsigned short Label::getCharAtStringPosition(int position)
{
return _currentUTF8String[position];
}
unsigned short * Label::getUTF8String()
{
return _currentUTF8String;
}
void Label::assignNewUTF8String(unsigned short *newString)
{
setCurrentString(newString);
}
TextHAlignment Label::getTextAlignment()
{
return _alignment;
}
// label related stuff
float Label::getMaxLineWidth()
{
return _width;
}
bool Label::breakLineWithoutSpace()
{
return _lineBreakWithoutSpaces;
}
Size Label::getLabelContentSize()
{
return getContentSize();
}
void Label::setLabelContentSize(const Size &newSize)
{
setContentSize(newSize);
}
// RGBA protocol
bool Label::isOpacityModifyRGB() const
{
return false;
}
void Label::setOpacityModifyRGB(bool isOpacityModifyRGB)
{
}
unsigned char Label::getOpacity() const
{
return 0;
}
unsigned char Label::getDisplayedOpacity() const
{
return 0;
}
void Label::setOpacity(GLubyte opacity)
{
}
void Label::updateDisplayedOpacity(GLubyte parentOpacity)
{
}
bool Label::isCascadeOpacityEnabled() const
{
return false;
}
void Label::setCascadeOpacityEnabled(bool cascadeOpacityEnabled)
{
}
const Color3B& Label::getColor(void) const
{
return _realColor;
}
const Color3B& Label::getDisplayedColor() const
{
return _displayedColor;
}
void Label::setColor(const Color3B& color)
{
_displayedColor = _realColor = color;
if( _cascadeColorEnabled )
{
Color3B parentColor = Color3B::WHITE;
RGBAProtocol* pParent = dynamic_cast<RGBAProtocol*>(_parent);
if (pParent && pParent->isCascadeColorEnabled())
parentColor = pParent->getDisplayedColor();
updateDisplayedColor(parentColor);
}
}
void Label::updateDisplayedColor(const Color3B& parentColor)
{
_displayedColor.r = _realColor.r * parentColor.r/255.0;
_displayedColor.g = _realColor.g * parentColor.g/255.0;
_displayedColor.b = _realColor.b * parentColor.b/255.0;
Object* pObj;
CCARRAY_FOREACH(_children, pObj)
{
Sprite *item = static_cast<Sprite*>( pObj );
item->updateDisplayedColor(_displayedColor);
}
}
bool Label::isCascadeColorEnabled() const
{
return false;
}
void Label::setCascadeColorEnabled(bool cascadeColorEnabled)
{
_cascadeColorEnabled = cascadeColorEnabled;
}
NS_CC_END

View File

@ -27,6 +27,8 @@
#define _COCOS2D_CCLABEL_H_
#include "sprite_nodes/CCSpriteBatchNode.h"
#include "CCLabelTextFormatProtocol.h"
#include "ccTypes.h"
NS_CC_BEGIN
@ -39,28 +41,120 @@ enum class GlyphCollection {
};
class CC_DLL Label : public SpriteBatchNode, public LabelProtocol, public RGBAProtocol
//fwd
class FontLetterDefinition;
class FontAtlas;
class CC_DLL Label : public SpriteBatchNode, public LabelProtocol, public RGBAProtocol, public LabelTextFormatProtocol
{
public:
static Label* createWithTTF( const char* label, const char* tttFilePath, int fontSize, GlyphCollection glyphs = GlyphCollection::NEHE, int lineSize = 0, const char *customGlyphs = 0 );
static Label* createWithBMFont( const char* label, const char* bmfontFilePath, int lineSize = 0 );
virtual ~Label();
Label();
Label(FontAtlas *pAtlas, TextHAlignment alignment);
~Label();
bool setText(const char *stringToRender, float lineWidth, TextHAlignment alignment = TextHAlignment::LEFT, bool lineBreakWithoutSpaces = false);
void setString(const char *stringToRender);
virtual void setAlignment(TextHAlignment alignment);
virtual void setWidth(float width);
virtual void setLineBreakWithoutSpace(bool breakWithoutSpace);
virtual void setScale(float scale);
virtual void setScaleX(float scaleX);
virtual void setScaleY(float scaleY);
// carloX
const char * getString() const { return "not implemented"; }
// RGBAProtocol
virtual bool isOpacityModifyRGB() const;
virtual void setOpacityModifyRGB(bool isOpacityModifyRGB);
virtual void setOpacity(GLubyte opacity);
virtual void updateDisplayedOpacity(GLubyte parentOpacity);
virtual bool isCascadeOpacityEnabled() const;
virtual void setCascadeOpacityEnabled(bool cascadeOpacityEnabled);
virtual void setColor(const Color3B& color);
virtual void updateDisplayedColor(const Color3B& parentColor);
virtual bool isCascadeColorEnabled() const;
virtual void setCascadeColorEnabled(bool cascadeColorEnabled);
virtual const Color3B& getColor(void) const;
virtual const Color3B& getDisplayedColor() const;
virtual unsigned char getOpacity() const;
virtual unsigned char getDisplayedOpacity() const;
// CCLabelTextFormat protocol implementation
virtual Sprite * getSpriteChild(int ID);
virtual Array * getChildrenLetters();
virtual Sprite * getSpriteForChar(unsigned short int theChar, int spriteIndexHint);
virtual float getLetterPosXLeft( Sprite* sp );
virtual float getLetterPosXRight( Sprite* sp );
// font related stuff
virtual int getCommonLineHeight();
virtual int getKerningForCharsPair(unsigned short first, unsigned short second);
virtual int getXOffsetForChar(unsigned short c);
virtual int getYOffsetForChar(unsigned short c);
virtual int getAdvanceForChar(unsigned short c, int hintPositionInString);
virtual Rect getRectForChar(unsigned short c) ;
// string related stuff
virtual int getStringNumLines();
virtual int getStringLenght();
virtual unsigned short getCharAtStringPosition(int position);
virtual unsigned short * getUTF8String();
virtual void assignNewUTF8String(unsigned short *newString);
virtual TextHAlignment getTextAlignment();
// label related stuff
virtual float getMaxLineWidth() ;
virtual bool breakLineWithoutSpace();
virtual Size getLabelContentSize();
virtual void setLabelContentSize(const Size &newSize);
virtual void setAlignment(TextHAlignment alignment) = 0;
virtual void setWidth(float width) = 0;
virtual void setLineBreakWithoutSpace(bool breakWithoutSpace) = 0;
virtual void setScale(float scale) = 0;
virtual void setScaleX(float scaleX) = 0;
virtual void setScaleY(float scaleY) = 0;
private:
static Label* create(FontAtlas *pAtlas, TextHAlignment alignment = TextHAlignment::LEFT, int lineSize = 0);
bool init();
void alignText();
void hideAllLetters();
void moveAllSpritesToCache();
bool computeAdvancesForString(unsigned short int *stringToRender);
bool setCurrentString(unsigned short *stringToSet);
bool setOriginalString(unsigned short *stringToSet);
void resetCurrentString();
Sprite * getSprite();
Sprite * createNewSpriteFromLetterDefinition(FontLetterDefinition &theDefinition, Texture2D *theTexture);
Sprite * updateSpriteWithLetterDefinition(Sprite *spriteToUpdate, FontLetterDefinition &theDefinition, Texture2D *theTexture);
Sprite * getSpriteForLetter(unsigned short int newLetter);
Sprite * updateSpriteForLetter(Sprite *spriteToUpdate, unsigned short int newLetter);
Array _spriteArray;
Array _spriteArrayCache;
float _commonLineHeight;
bool _lineBreakWithoutSpaces;
float _width;
TextHAlignment _alignment;
unsigned short int * _currentUTF8String;
unsigned short int * _originalUTF8String;
Size * _advances;
FontAtlas * _fontAtlas;
Color3B _displayedColor;
Color3B _realColor;
bool _cascadeColorEnabled;
};
NS_CC_END
#endif /*__COCOS2D_CCLABEL_H */

View File

@ -1,733 +0,0 @@
/****************************************************************************
Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2008-2010 Ricardo Quesada
Copyright (c) 2011 Zynga Inc.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Use any of these editors to generate BMFonts:
http://glyphdesigner.71squared.com/ (Commercial, Mac OS X)
http://www.n4te.com/hiero/hiero.jnlp (Free, Java)
http://slick.cokeandcode.com/demos/hiero.jnlp (Free, Java)
http://www.angelcode.com/products/bmfont/ (Free, Windows only)
****************************************************************************/
#include "CCStringBMFont.h"
#include "cocoa/CCString.h"
#include "cocoa/CCDictionary.h"
#include "CCConfiguration.h"
#include "CCLabelTextFormatter.h"
#include "draw_nodes/CCDrawingPrimitives.h"
#include "sprite_nodes/CCSprite.h"
//#include "support/CCPointExtension.h"
#include "platform/CCFileUtils.h"
#include "CCDirector.h"
#include "textures/CCTextureCache.h"
#include "support/ccUTF8.h"
using namespace std;
NS_CC_BEGIN
// The return value needs to be deleted by CC_SAFE_DELETE_ARRAY.
static unsigned short* copyUTF16StringNN(unsigned short* str)
{
int length = str ? cc_wcslen(str) : 0;
unsigned short* ret = new unsigned short[length+1];
for (int i = 0; i < length; ++i) {
ret[i] = str[i];
}
ret[length] = 0;
return ret;
}
//
//CCLabelBMFont
//
//LabelBMFont - Purge Cache
void StringBMFont::purgeCachedData()
{
FNTConfigRemoveCache();
}
StringBMFont * StringBMFont::create()
{
StringBMFont * pRet = new StringBMFont();
if (pRet && pRet->init())
{
pRet->autorelease();
return pRet;
}
CC_SAFE_DELETE(pRet);
return NULL;
}
StringBMFont * StringBMFont::create(const char *str, const char *fntFile, float width, TextHAlignment alignment)
{
return StringBMFont::create(str, fntFile, width, alignment, Point::ZERO);
}
StringBMFont * StringBMFont::create(const char *str, const char *fntFile, float width)
{
return StringBMFont::create(str, fntFile, width, TextHAlignment::LEFT, Point::ZERO);
}
StringBMFont * StringBMFont::create(const char *str, const char *fntFile)
{
return StringBMFont::create(str, fntFile, kLabelAutomaticWidth, TextHAlignment::LEFT, Point::ZERO);
}
//LabelBMFont - Creation & Init
StringBMFont *StringBMFont::create(const char *str, const char *fntFile, float width/* = kLabelAutomaticWidth*/, TextHAlignment alignment/* = kTextAlignmentLeft*/, Point imageOffset/* = Point::ZERO*/)
{
StringBMFont *pRet = new StringBMFont();
if(pRet && pRet->initWithString(str, fntFile, width, alignment, imageOffset))
{
pRet->autorelease();
return pRet;
}
CC_SAFE_DELETE(pRet);
return NULL;
}
bool StringBMFont::init()
{
return initWithString(NULL, NULL, kLabelAutomaticWidth, TextHAlignment::LEFT, Point::ZERO);
}
bool StringBMFont::initWithString(const char *theString, const char *fntFile, float width/* = kLabelAutomaticWidth*/, TextHAlignment alignment/* = kTextAlignmentLeft*/, Point imageOffset/* = Point::ZERO*/)
{
CCAssert(!_configuration, "re-init is no longer supported");
CCAssert( (theString && fntFile) || (theString==NULL && fntFile==NULL), "Invalid params for StringBMFont");
Texture2D *texture = NULL;
if (fntFile)
{
CCBMFontConfiguration *newConf = FNTConfigLoadFile(fntFile);
if (!newConf)
{
CCLOG("cocos2d: WARNING. StringBMFont: Impossible to create font. Please check file: '%s'", fntFile);
release();
return false;
}
newConf->retain();
CC_SAFE_RELEASE(_configuration);
_configuration = newConf;
_fntFile = fntFile;
texture = TextureCache::getInstance()->addImage(_configuration->getAtlasName());
}
else
{
texture = new Texture2D();
texture->autorelease();
}
if (theString == NULL)
{
theString = "";
}
if (SpriteBatchNode::initWithTexture(texture, strlen(theString)))
{
_width = width;
_alignment = alignment;
_displayedOpacity = _realOpacity = 255;
_displayedColor = _realColor = Color3B::WHITE;
_cascadeOpacityEnabled = true;
_cascadeColorEnabled = true;
_contentSize = Size::ZERO;
_isOpacityModifyRGB = _textureAtlas->getTexture()->hasPremultipliedAlpha();
_anchorPoint = Point(0.5f, 0.5f);
_imageOffset = imageOffset;
_reusedChar = new Sprite();
_reusedChar->initWithTexture(_textureAtlas->getTexture(), Rect(0, 0, 0, 0), false);
_reusedChar->setBatchNode(this);
this->setString(theString);
return true;
}
return false;
}
StringBMFont::StringBMFont()
: _string(NULL)
, _initialString(NULL)
, _alignment(TextHAlignment::CENTER)
, _width(-1.0f)
, _configuration(NULL)
, _lineBreakWithoutSpaces(false)
, _imageOffset(Point::ZERO)
, _reusedChar(NULL)
, _displayedOpacity(255)
, _realOpacity(255)
, _displayedColor(Color3B::WHITE)
, _realColor(Color3B::WHITE)
, _cascadeColorEnabled(true)
, _cascadeOpacityEnabled(true)
, _isOpacityModifyRGB(false)
{
}
StringBMFont::~StringBMFont()
{
CC_SAFE_RELEASE(_reusedChar);
CC_SAFE_DELETE_ARRAY(_string);
CC_SAFE_DELETE_ARRAY(_initialString);
CC_SAFE_RELEASE(_configuration);
}
// StringBMFont - Atlas generation
int StringBMFont::kerningAmountForFirst(unsigned short first, unsigned short second)
{
int ret = 0;
unsigned int key = (first<<16) | (second & 0xffff);
if( _configuration->_kerningDictionary ) {
tKerningHashElement *element = NULL;
HASH_FIND_INT(_configuration->_kerningDictionary, &key, element);
if(element)
ret = element->amount;
}
return ret;
}
const char* StringBMFont::getString(void) const
{
return _initialStringUTF8.c_str();
}
//StringBMFont - RGBAProtocol protocol
const Color3B& StringBMFont::getColor() const
{
return _realColor;
}
const Color3B& StringBMFont::getDisplayedColor() const
{
return _displayedColor;
}
void StringBMFont::setColor(const Color3B& color)
{
_displayedColor = _realColor = color;
if( _cascadeColorEnabled ) {
Color3B parentColor = Color3B::WHITE;
RGBAProtocol* pParent = dynamic_cast<RGBAProtocol*>(_parent);
if (pParent && pParent->isCascadeColorEnabled())
{
parentColor = pParent->getDisplayedColor();
}
this->updateDisplayedColor(parentColor);
}
}
GLubyte StringBMFont::getOpacity(void) const
{
return _realOpacity;
}
GLubyte StringBMFont::getDisplayedOpacity(void) const
{
return _displayedOpacity;
}
/** Override synthesized setOpacity to recurse items */
void StringBMFont::setOpacity(GLubyte opacity)
{
_displayedOpacity = _realOpacity = opacity;
if( _cascadeOpacityEnabled ) {
GLubyte parentOpacity = 255;
RGBAProtocol* pParent = dynamic_cast<RGBAProtocol*>(_parent);
if (pParent && pParent->isCascadeOpacityEnabled())
{
parentOpacity = pParent->getDisplayedOpacity();
}
this->updateDisplayedOpacity(parentOpacity);
}
}
void StringBMFont::setOpacityModifyRGB(bool var)
{
_isOpacityModifyRGB = var;
if (_children && _children->count() != 0)
{
Object* child;
CCARRAY_FOREACH(_children, child)
{
Node* pNode = static_cast<Node*>( child );
if (pNode)
{
RGBAProtocol *pRGBAProtocol = dynamic_cast<RGBAProtocol*>(pNode);
if (pRGBAProtocol)
{
pRGBAProtocol->setOpacityModifyRGB(_isOpacityModifyRGB);
}
}
}
}
}
bool StringBMFont::isOpacityModifyRGB() const
{
return _isOpacityModifyRGB;
}
void StringBMFont::updateDisplayedOpacity(GLubyte parentOpacity)
{
_displayedOpacity = _realOpacity * parentOpacity/255.0;
Object* pObj;
CCARRAY_FOREACH(_children, pObj)
{
Sprite *item = static_cast<Sprite*>( pObj );
item->updateDisplayedOpacity(_displayedOpacity);
}
}
void StringBMFont::updateDisplayedColor(const Color3B& parentColor)
{
_displayedColor.r = _realColor.r * parentColor.r/255.0;
_displayedColor.g = _realColor.g * parentColor.g/255.0;
_displayedColor.b = _realColor.b * parentColor.b/255.0;
Object* pObj;
CCARRAY_FOREACH(_children, pObj)
{
Sprite *item = static_cast<Sprite*>( pObj );
item->updateDisplayedColor(_displayedColor);
}
}
bool StringBMFont::isCascadeColorEnabled() const
{
return false;
}
void StringBMFont::setCascadeColorEnabled(bool cascadeColorEnabled)
{
_cascadeColorEnabled = cascadeColorEnabled;
}
bool StringBMFont::isCascadeOpacityEnabled() const
{
return false;
}
void StringBMFont::setCascadeOpacityEnabled(bool cascadeOpacityEnabled)
{
_cascadeOpacityEnabled = cascadeOpacityEnabled;
}
// StringBMFont - AnchorPoint
void StringBMFont::setAnchorPoint(const Point& point)
{
if( ! point.equals(_anchorPoint))
{
SpriteBatchNode::setAnchorPoint(point);
updateLabel();
}
}
// StringBMFont - Alignment
void StringBMFont::setAlignment(TextHAlignment alignment)
{
this->_alignment = alignment;
updateLabel();
}
void StringBMFont::setWidth(float width)
{
this->_width = width;
updateLabel();
}
void StringBMFont::setLineBreakWithoutSpace( bool breakWithoutSpace )
{
_lineBreakWithoutSpaces = breakWithoutSpace;
updateLabel();
}
void StringBMFont::setScale(float scale)
{
SpriteBatchNode::setScale(scale);
updateLabel();
}
void StringBMFont::setScaleX(float scaleX)
{
SpriteBatchNode::setScaleX(scaleX);
updateLabel();
}
void StringBMFont::setScaleY(float scaleY)
{
SpriteBatchNode::setScaleY(scaleY);
updateLabel();
}
float StringBMFont::getLetterPosXLeft( Sprite* sp )
{
return sp->getPosition().x * _scaleX - (sp->getContentSize().width * _scaleX * sp->getAnchorPoint().x);
}
float StringBMFont::getLetterPosXRight( Sprite* sp )
{
return sp->getPosition().x * _scaleX + (sp->getContentSize().width * _scaleX * sp->getAnchorPoint().x);
}
// StringBMFont - FntFile
void StringBMFont::setFntFile(const char* fntFile)
{
if (fntFile != NULL && strcmp(fntFile, _fntFile.c_str()) != 0 )
{
CCBMFontConfiguration *newConf = FNTConfigLoadFile(fntFile);
CCAssert( newConf, "CCStringBMFont: Impossible to create font. Please check file");
_fntFile = fntFile;
CC_SAFE_RETAIN(newConf);
CC_SAFE_RELEASE(_configuration);
_configuration = newConf;
this->setTexture(TextureCache::getInstance()->addImage(_configuration->getAtlasName()));
LabelTextFormatter::createStringSprites(this);
}
}
const char* StringBMFont::getFntFile()
{
return _fntFile.c_str();
}
//StringBMFont - Debug draw
#if CC_LabelBMFontNew_DEBUG_DRAW
void StringBMFont::draw()
{
SpriteBatchNode::draw();
const Size& s = this->getContentSize();
Point vertices[4]={
ccp(0,0),ccp(s.width,0),
ccp(s.width,s.height),ccp(0,s.height),
};
ccDrawPoly(vertices, 4, true);
}
#endif // CC_LABELBMFONT_DEBUG_DRAW
int StringBMFont::getCommonLineHeight()
{
if (_configuration)
{
return _configuration->_commonHeight;
}
else
{
return -1;
}
}
int StringBMFont::getKerningForCharsPair(unsigned short first, unsigned short second)
{
return this->kerningAmountForFirst(first, second);
}
ccBMFontDef StringBMFont::getFontDefForChar(unsigned short int theChar)
{
ccBMFontDef fontDef;
tFontDefHashElement *element = NULL;
unsigned int key = theChar;
HASH_FIND_INT(_configuration->_fontDefDictionary, &key, element);
if (element)
{
fontDef = element->fontDef;
}
return fontDef;
}
// return a sprite for rendering one letter
Sprite * StringBMFont::getSpriteForChar(unsigned short int theChar, int spriteIndexHint)
{
Rect rect;
ccBMFontDef fontDef;
Sprite *pRetSprite = 0;
// unichar is a short, and an int is needed on HASH_FIND_INT
tFontDefHashElement *element = NULL;
unsigned int key = theChar;
HASH_FIND_INT(_configuration->_fontDefDictionary, &key, element);
if (! element)
{
return 0;
}
fontDef = element->fontDef;
rect = fontDef.rect;
rect = CC_RECT_PIXELS_TO_POINTS(rect);
rect.origin.x += _imageOffset.x;
rect.origin.y += _imageOffset.y;
//bool hasSprite = true;
pRetSprite = (Sprite*)(this->getChildByTag(spriteIndexHint));
if(pRetSprite )
{
// Reusing previous Sprite
pRetSprite->setVisible(true);
}
else
{
pRetSprite = new Sprite();
pRetSprite->initWithTexture(_textureAtlas->getTexture(), rect);
addChild(pRetSprite, spriteIndexHint, spriteIndexHint);
pRetSprite->release();
// Apply label properties
pRetSprite->setOpacityModifyRGB(_isOpacityModifyRGB);
// Color MUST be set before opacity, since opacity might change color if OpacityModifyRGB is on
pRetSprite->updateDisplayedColor(_displayedColor);
pRetSprite->updateDisplayedOpacity(_displayedOpacity);
}
// updating previous sprite
pRetSprite->setTextureRect(rect, false, rect.size);
return pRetSprite;
}
int StringBMFont::getStringNumLines()
{
int quantityOfLines = 1;
unsigned int stringLen = _string ? cc_wcslen(_string) : 0;
if (stringLen == 0)
return (-1);
// count number of lines
for (unsigned int i = 0; i < stringLen - 1; ++i)
{
unsigned short c = _string[i];
if (c == '\n')
{
quantityOfLines++;
}
}
return quantityOfLines;
}
// need cross implementation
int StringBMFont::getStringLenght()
{
return _string ? cc_wcslen(_string) : 0;
}
unsigned short StringBMFont::getCharAtStringPosition(int position)
{
return _string[position];
}
int StringBMFont::getXOffsetForChar(unsigned short c)
{
ccBMFontDef fontDef = getFontDefForChar(c);
return fontDef.xOffset;
}
int StringBMFont::getYOffsetForChar(unsigned short c)
{
ccBMFontDef fontDef = getFontDefForChar(c);
return fontDef.yOffset;
}
Rect StringBMFont::getRectForChar(unsigned short c)
{
ccBMFontDef fontDef = getFontDefForChar(c);
return fontDef.rect;
}
int StringBMFont::getAdvanceForChar(unsigned short c, int hintPositionInString)
{
ccBMFontDef fontDef = getFontDefForChar(c);
return fontDef.xAdvance;
}
void StringBMFont::setLabelContentSize(const Size &newSize)
{
setContentSize(newSize);
}
void StringBMFont::createStringSprites()
{
LabelTextFormatter::createStringSprites(this);
}
void StringBMFont::setString(const char *newString)
{
// store initial string in char8 format
_initialStringUTF8 = newString;
// update the initial string if needed
unsigned short* utf16String = cc_utf8_to_utf16(newString);
unsigned short* tmp = _initialString;
_initialString = copyUTF16StringNN(utf16String);
CC_SAFE_DELETE_ARRAY(tmp);
CC_SAFE_DELETE_ARRAY(utf16String);
// do the rest of the josb
updateLabel();
}
void StringBMFont::setCString(const char *label)
{
setString(label);
}
void StringBMFont::updateLabel()
{
if ( _initialString!=0 )
{
// set the new string
CC_SAFE_DELETE_ARRAY(_string);
_string = copyUTF16StringNN(_initialString);
// hide all the letters and create or recicle sprites for the new letters
updateLetterSprites();
// format the text on more than line
multilineText();
// align the text (left - center - right)
alignText();
}
}
void StringBMFont::updateLetterSprites()
{
// hide all the letters
hideStringSprites();
// create new letters sprites
createStringSprites();
}
void StringBMFont::hideStringSprites()
{
if (_children && _children->count() != 0)
{
Object* child;
CCARRAY_FOREACH(_children, child)
{
Node* pNode = (Node*) child;
if (pNode)
{
pNode->setVisible(false);
}
}
}
}
void StringBMFont::multilineText()
{
if (_width > 0)
{
// format on more than one line
LabelTextFormatter::multilineText(this);
// hide all the letter sprites and create/reclaim letters sprite with new position
updateLetterSprites();
}
}
void StringBMFont::alignText()
{
if (_alignment != TextHAlignment::LEFT)
{
LabelTextFormatter::alignText(this);
}
}
unsigned short * StringBMFont::getUTF8String()
{
return _string;
}
Sprite * StringBMFont::getSpriteChild(int ID)
{
return (Sprite*)this->getChildByTag(ID);
}
float StringBMFont::getMaxLineWidth()
{
return _width;
}
TextHAlignment StringBMFont::getTextAlignment()
{
return _alignment;
}
Array* StringBMFont::getChildrenLetters()
{
return _children;
}
void StringBMFont::assignNewUTF8String(unsigned short *newString)
{
CC_SAFE_DELETE_ARRAY(_string);
_string = newString;
}
Size StringBMFont::getLabelContentSize()
{
return getContentSize();
}
bool StringBMFont::breakLineWithoutSpace()
{
return _lineBreakWithoutSpaces;
}
NS_CC_END

View File

@ -1,204 +0,0 @@
/****************************************************************************
Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2008-2010 Ricardo Quesada
Copyright (c) 2011 Zynga Inc.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Use any of these editors to generate BMFonts:
http://glyphdesigner.71squared.com/ (Commercial, Mac OS X)
http://www.n4te.com/hiero/hiero.jnlp (Free, Java)
http://slick.cokeandcode.com/demos/hiero.jnlp (Free, Java)
http://www.angelcode.com/products/bmfont/ (Free, Windows only)
****************************************************************************/
#ifndef __CCBITMAP_FONT_ATLAS_H__NEW_
#define __CCBITMAP_FONT_ATLAS_H__NEW_
#include "sprite_nodes/CCSpriteBatchNode.h"
#include "support/data_support/uthash.h"
#include "CCLabelBMFont.h"
#include "CClabelTextFormatProtocol.h"
#include <map>
#include <sstream>
#include <iostream>
#include <vector>
#include "CCLabel.h"
NS_CC_BEGIN
class CC_DLL StringBMFont: public Label, public LabelTextFormatProtocol
{
public:
StringBMFont();
virtual ~StringBMFont();
/** Purges the cached data.
Removes from memory the cached configurations and the atlas name dictionary.
@since v0.99.3
*/
static void purgeCachedData();
/** creates a bitmap font atlas with an initial string and the FNT file */
static StringBMFont * create(const char *str, const char *fntFile, float width, TextHAlignment alignment, Point imageOffset);
static StringBMFont * create(const char *str, const char *fntFile, float width, TextHAlignment alignment);
static StringBMFont * create(const char *str, const char *fntFile, float width);
static StringBMFont * create(const char *str, const char *fntFile);
/** Creates an label.
*/
static StringBMFont * create();
bool init();
/** init a bitmap font atlas with an initial string and the FNT file */
bool initWithString(const char *str, const char *fntFile, float width = kLabelAutomaticWidth, TextHAlignment alignment = TextHAlignment::LEFT, Point imageOffset = Point::ZERO);
/** updates the font chars based on the string to render */
// super method
virtual void setString(const char *newString);
virtual const char* getString(void) const;
virtual void setCString(const char *label);
virtual void setAnchorPoint(const Point& var);
virtual void updateLabel();
virtual void setAlignment(TextHAlignment alignment);
virtual void setWidth(float width);
virtual void setLineBreakWithoutSpace(bool breakWithoutSpace);
virtual void setScale(float scale);
virtual void setScaleX(float scaleX);
virtual void setScaleY(float scaleY);
// RGBAProtocol
virtual bool isOpacityModifyRGB() const;
virtual void setOpacityModifyRGB(bool isOpacityModifyRGB);
virtual GLubyte getOpacity() const;
virtual GLubyte getDisplayedOpacity() const;
virtual void setOpacity(GLubyte opacity);
virtual void updateDisplayedOpacity(GLubyte parentOpacity);
virtual bool isCascadeOpacityEnabled() const;
virtual void setCascadeOpacityEnabled(bool cascadeOpacityEnabled);
virtual const Color3B& getColor(void) const;
virtual const Color3B& getDisplayedColor() const;
virtual void setColor(const Color3B& color);
virtual void updateDisplayedColor(const Color3B& parentColor);
virtual bool isCascadeColorEnabled() const;
virtual void setCascadeColorEnabled(bool cascadeColorEnabled);
// StringBMFont protocol stuff
virtual Sprite * getSpriteChild(int ID);
virtual Array * getChildrenLetters();
virtual Sprite * getSpriteForChar(unsigned short int theChar, int spriteIndexHint);
virtual int getCommonLineHeight();
virtual int getKerningForCharsPair(unsigned short first, unsigned short second);
virtual int getXOffsetForChar(unsigned short c);
virtual int getYOffsetForChar(unsigned short c);
virtual int getAdvanceForChar(unsigned short c, int hintPositionInString);
virtual Rect getRectForChar(unsigned short c);
float getLetterPosXLeft( Sprite* sp );
float getLetterPosXRight( Sprite* sp );
virtual int getStringNumLines();
virtual int getStringLenght();
virtual unsigned short getCharAtStringPosition(int position);
virtual unsigned short * getUTF8String();
virtual void assignNewUTF8String(unsigned short *newString);
virtual float getMaxLineWidth();
virtual bool breakLineWithoutSpace();
virtual TextHAlignment getTextAlignment();
virtual Size getLabelContentSize();
virtual void setLabelContentSize(const Size &newSize);
void setFntFile(const char* fntFile);
const char* getFntFile();
#if CC_LABELBMFONT_DEBUG_DRAW
virtual void draw();
#endif // CC_LABELBMFONT_DEBUG_DRAW
private:
char * atlasNameFromFntFile(const char *fntFile);
int kerningAmountForFirst(unsigned short first, unsigned short second);
// some more new stuff
void alignText();
void multilineText();
ccBMFontDef getFontDefForChar(unsigned short int theChar);
void createStringSprites();
void hideStringSprites();
void updateLetterSprites();
protected:
// string to render
unsigned short* _string;
// name of fntFile
std::string _fntFile;
// initial string without line breaks
unsigned short* _initialString;
std::string _initialStringUTF8;
// alignment of all lines
TextHAlignment _alignment;
// max width until a line break is added
float _width;
CCBMFontConfiguration *_configuration;
bool _lineBreakWithoutSpaces;
// offset of the texture atlas
Point _imageOffset;
// reused char
Sprite *_reusedChar;
// texture RGBA
GLubyte _displayedOpacity;
GLubyte _realOpacity;
Color3B _displayedColor;
Color3B _realColor;
bool _cascadeColorEnabled;
bool _cascadeOpacityEnabled;
/** conforms to RGBAProtocol protocol */
bool _isOpacityModifyRGB;
};
/** Free function that parses a FNT file a place it on the cache
*/
CC_DLL CCBMFontConfiguration * FNTConfigLoadFile( const char *file );
/** Purges the FNT config cache
*/
CC_DLL void FNTConfigRemoveCache( void );
// end of GUI group
/// @}
/// @}
NS_CC_END
#endif //__CCBITMAP_FONT_ATLAS_H__

View File

@ -1,664 +0,0 @@
/****************************************************************************
Copyright (c) 2013 Zynga Inc.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "cocos2d.h"
#include "CCStringTTF.h"
#include "CCFont.h"
#include "CCLabelTextFormatter.h"
#include "CCFontAtlasCache.h"
NS_CC_BEGIN
StringTTF::StringTTF(FontAtlas *pAtlas, TextHAlignment alignment): _currentUTF8String(0),
_originalUTF8String(0),
_fontAtlas(pAtlas),
_alignment(alignment),
_lineBreakWithoutSpaces(false),
_advances(0),
_displayedColor(Color3B::WHITE),
_realColor(Color3B::WHITE),
_cascadeColorEnabled(true)
{
}
StringTTF* StringTTF::create(FontAtlas *pAtlas, TextHAlignment alignment, int lineSize)
{
StringTTF *ret = new StringTTF(pAtlas, alignment);
if (!ret)
return 0;
if( ret->init() )
{
ret->autorelease();
return ret;
}
else
{
delete ret;
return 0;
}
return ret;
}
StringTTF::~StringTTF()
{
if (_currentUTF8String)
delete [] _currentUTF8String;
if (_advances)
delete [] _advances;
if (_fontAtlas)
FontAtlasCache::releaseFontAtlas(_fontAtlas);
}
bool StringTTF::init()
{
return true;
}
void StringTTF::setString(const char *stringToRender)
{
setText(stringToRender, 0, TextHAlignment::CENTER, false);
}
bool StringTTF::setText(const char *stringToRender, float lineWidth, TextHAlignment alignment, bool lineBreakWithoutSpaces)
{
if (!_fontAtlas)
return false;
_width = lineWidth;
_alignment = alignment;
_lineBreakWithoutSpaces = lineBreakWithoutSpaces;
// release all the sprites
moveAllSpritesToCache();
// store locally common line height
_commonLineHeight = _fontAtlas->getCommonLineHeight();
if (_commonLineHeight <= 0)
return false;
int numLetter = 0;
unsigned short* utf16String = cc_utf8_to_utf16(stringToRender);
if(!utf16String)
return false;
numLetter = cc_wcslen(utf16String);
SpriteBatchNode::initWithTexture(&_fontAtlas->getTexture(0), numLetter);
_cascadeColorEnabled = true;
//
setCurrentString(utf16String);
setOriginalString(utf16String);
// align text
alignText();
// done here
return true;
}
void StringTTF::setAlignment(TextHAlignment alignment)
{
// store the new alignment
if (alignment != _alignment)
{
// store
_alignment = alignment;
// reset the string
resetCurrentString();
// need to align text again
alignText();
}
}
void StringTTF::setWidth(float width)
{
if (width != _width)
{
// store
_width = width;
// need to align text again
alignText();
}
}
void StringTTF::setLineBreakWithoutSpace(bool breakWithoutSpace)
{
if (breakWithoutSpace != _lineBreakWithoutSpaces)
{
// store
_lineBreakWithoutSpaces = breakWithoutSpace;
// need to align text again
alignText();
}
}
void StringTTF::setScale(float scale)
{
Node::setScale(scale);
alignText();
}
void StringTTF::setScaleX(float scaleX)
{
Node::setScaleX(scaleX);
alignText();
}
void StringTTF::setScaleY(float scaleY)
{
Node::setScaleY(scaleY);
alignText();
}
void StringTTF::alignText()
{
hideAllLetters();
LabelTextFormatter::createStringSprites(this);
if( LabelTextFormatter::multilineText(this) )
{
hideAllLetters();
LabelTextFormatter::createStringSprites(this);
}
LabelTextFormatter::alignText(this);
}
void StringTTF::hideAllLetters()
{
Object* Obj = NULL;
CCARRAY_FOREACH(&_spriteArray, Obj)
{
((Sprite *)Obj)->setVisible(false);
}
CCARRAY_FOREACH(&_spriteArrayCache, Obj)
{
((Sprite *)Obj)->setVisible(false);
}
}
bool StringTTF::computeAdvancesForString(unsigned short int *stringToRender)
{
if (_advances)
{
delete [] _advances;
_advances = 0;
}
Font &theFont = _fontAtlas->getFont();
int letterCount = 0;
_advances = theFont.getAdvancesForTextUTF16(stringToRender, letterCount);
if(!_advances)
return false;
else
return true;
}
bool StringTTF::setOriginalString(unsigned short *stringToSet)
{
if (_originalUTF8String)
{
delete [] _originalUTF8String;
_originalUTF8String = 0;
}
int newStringLenght = cc_wcslen(stringToSet);
_originalUTF8String = new unsigned short int [newStringLenght + 1];
memset(_originalUTF8String, 0, (newStringLenght + 1) * 2);
memcpy(_originalUTF8String, stringToSet, (newStringLenght * 2));
_originalUTF8String[newStringLenght] = 0;
return true;
}
bool StringTTF::setCurrentString(unsigned short *stringToSet)
{
// set the new string
if (_currentUTF8String)
{
delete [] _currentUTF8String;
_currentUTF8String = 0;
}
//
_currentUTF8String = stringToSet;
// compute the advances
return computeAdvancesForString(stringToSet);
}
void StringTTF::resetCurrentString()
{
// set the new string
if (_currentUTF8String)
{
delete [] _currentUTF8String;
_currentUTF8String = 0;
}
int stringLenght = cc_wcslen(_originalUTF8String);
_currentUTF8String = new unsigned short int [stringLenght + 1];
memcpy(_currentUTF8String, _originalUTF8String, stringLenght * 2);
_currentUTF8String[stringLenght] = 0;
}
Sprite * StringTTF::createNewSpriteFromLetterDefinition(FontLetterDefinition &theDefinition, Texture2D *theTexture)
{
Rect uvRect;
uvRect.size.height = theDefinition.height;
uvRect.size.width = theDefinition.width;
uvRect.origin.x = theDefinition.U;
uvRect.origin.y = theDefinition.V;
SpriteFrame *pFrame = SpriteFrame::createWithTexture(theTexture, uvRect);
Sprite *tempSprite = getSprite();
if (!tempSprite)
return 0;
tempSprite->initWithSpriteFrame(pFrame);
tempSprite->setAnchorPoint(Point(theDefinition.anchorX, theDefinition.anchorY));
tempSprite->setBatchNode(this);
return tempSprite;
}
Sprite * StringTTF::updateSpriteWithLetterDefinition(Sprite *spriteToUpdate, FontLetterDefinition &theDefinition, Texture2D *theTexture)
{
if (!spriteToUpdate)
{
return 0;
}
else
{
Rect uvRect;
uvRect.size.height = theDefinition.height;
uvRect.size.width = theDefinition.width;
uvRect.origin.x = theDefinition.U;
uvRect.origin.y = theDefinition.V;
SpriteFrame *frame = SpriteFrame::createWithTexture(theTexture, uvRect);
if (frame)
{
spriteToUpdate->setTexture(theTexture);
spriteToUpdate->setDisplayFrame(frame);
spriteToUpdate->setAnchorPoint(Point(theDefinition.anchorX, theDefinition.anchorY));
spriteToUpdate->setBatchNode(this);
}
return spriteToUpdate;
}
}
Sprite * StringTTF::getSpriteForLetter(unsigned short int newLetter)
{
if (!_fontAtlas)
return 0;
FontLetterDefinition tempDefinition;
bool validDefinition = _fontAtlas->getLetterDefinitionForChar(newLetter, tempDefinition);
if (validDefinition)
{
Sprite *newSprite = createNewSpriteFromLetterDefinition(tempDefinition, &_fontAtlas->getTexture(tempDefinition.textureID) );
this->addChild(newSprite);
return newSprite;
}
else
{
return 0;
}
}
Sprite * StringTTF::updateSpriteForLetter(Sprite *spriteToUpdate, unsigned short int newLetter)
{
if (!spriteToUpdate || !_fontAtlas)
return 0;
else
{
FontLetterDefinition tempDefinition;
bool validDefinition = _fontAtlas->getLetterDefinitionForChar(newLetter, tempDefinition);
if (validDefinition)
{
Sprite *pNewSprite = updateSpriteWithLetterDefinition(spriteToUpdate, tempDefinition, &_fontAtlas->getTexture(tempDefinition.textureID) );
return pNewSprite;
}
else
{
return 0;
}
}
}
void StringTTF::moveAllSpritesToCache()
{
Object* pObj = NULL;
CCARRAY_FOREACH(&_spriteArray, pObj)
{
((Sprite *)pObj)->removeFromParent();
_spriteArrayCache.addObject(pObj);
}
_spriteArray.removeAllObjects();
}
Sprite * StringTTF::getSprite()
{
if (_spriteArrayCache.count())
{
Sprite *retSprite = (Sprite *) _spriteArrayCache.lastObject();
_spriteArrayCache.removeLastObject();
return retSprite;
}
else
{
Sprite *retSprite = new Sprite;
return retSprite;
}
}
///// PROTOCOL STUFF
Sprite * StringTTF::getSpriteChild(int ID)
{
Object* pObj = NULL;
CCARRAY_FOREACH(&_spriteArray, pObj)
{
Sprite *pSprite = (Sprite *)pObj;
if ( pSprite->getTag() == ID)
{
return pSprite;
}
}
return 0;
}
Array * StringTTF::getChildrenLetters()
{
return &_spriteArray;
}
Sprite * StringTTF::getSpriteForChar(unsigned short int theChar, int spriteIndexHint)
{
// ret sprite
Sprite *retSprite = 0;
// look for already existing sprites
retSprite = getSpriteChild(spriteIndexHint);
if (!retSprite)
{
retSprite = getSpriteForLetter(theChar);
if (!retSprite)
return 0;
if (retSprite)
retSprite->setTag(spriteIndexHint);
_spriteArray.addObject(retSprite);
}
// the sprite is now visible
retSprite->setVisible(true);
// set the right texture letter to the sprite
updateSpriteForLetter(retSprite, theChar);
// we are done here
return retSprite;
}
float StringTTF::getLetterPosXLeft( Sprite* sp )
{
float scaleX = _scaleX;
return sp->getPosition().x * scaleX - (sp->getContentSize().width * scaleX * sp->getAnchorPoint().x);
}
float StringTTF::getLetterPosXRight( Sprite* sp )
{
float scaleX = _scaleX;
return sp->getPosition().x * scaleX + (sp->getContentSize().width * scaleX * sp->getAnchorPoint().x);
}
int StringTTF::getCommonLineHeight()
{
return _commonLineHeight;
}
int StringTTF::getKerningForCharsPair(unsigned short first, unsigned short second)
{
return 0;
}
int StringTTF::getXOffsetForChar(unsigned short c)
{
FontLetterDefinition tempDefinition;
bool validDefinition = _fontAtlas->getLetterDefinitionForChar(c, tempDefinition);
if (!validDefinition)
return -1;
return (tempDefinition.offsetX);
}
int StringTTF::getYOffsetForChar(unsigned short c)
{
FontLetterDefinition tempDefinition;
bool validDefinition = _fontAtlas->getLetterDefinitionForChar(c, tempDefinition);
if (!validDefinition)
return -1;
return (tempDefinition.offsetY);
}
int StringTTF::getAdvanceForChar(unsigned short c, int hintPositionInString)
{
if (_advances)
{
// not that advance contains the X offset already
FontLetterDefinition tempDefinition;
bool validDefinition = _fontAtlas->getLetterDefinitionForChar(c, tempDefinition);
if (!validDefinition)
return -1;
return (_advances[hintPositionInString].width - tempDefinition.offsetX);
}
else
{
return -1;
}
}
Rect StringTTF::getRectForChar(unsigned short c)
{
return _fontAtlas->getFont().getRectForChar(c);
}
// string related stuff
int StringTTF::getStringNumLines()
{
int quantityOfLines = 1;
unsigned int stringLen = _currentUTF8String ? cc_wcslen(_currentUTF8String) : 0;
if (stringLen == 0)
return (-1);
// count number of lines
for (unsigned int i = 0; i < stringLen - 1; ++i)
{
unsigned short c = _currentUTF8String[i];
if (c == '\n')
{
quantityOfLines++;
}
}
return quantityOfLines;
}
int StringTTF::getStringLenght()
{
return _currentUTF8String ? cc_wcslen(_currentUTF8String) : 0;
}
unsigned short StringTTF::getCharAtStringPosition(int position)
{
return _currentUTF8String[position];
}
unsigned short * StringTTF::getUTF8String()
{
return _currentUTF8String;
}
void StringTTF::assignNewUTF8String(unsigned short *newString)
{
setCurrentString(newString);
}
TextHAlignment StringTTF::getTextAlignment()
{
return _alignment;
}
// label related stuff
float StringTTF::getMaxLineWidth()
{
return _width;
}
bool StringTTF::breakLineWithoutSpace()
{
return _lineBreakWithoutSpaces;
}
Size StringTTF::getLabelContentSize()
{
return getContentSize();
}
void StringTTF::setLabelContentSize(const Size &newSize)
{
setContentSize(newSize);
}
// RGBA protocol
bool StringTTF::isOpacityModifyRGB() const
{
return false;
}
void StringTTF::setOpacityModifyRGB(bool isOpacityModifyRGB)
{
}
unsigned char StringTTF::getOpacity() const
{
return 0;
}
unsigned char StringTTF::getDisplayedOpacity() const
{
return 0;
}
void StringTTF::setOpacity(GLubyte opacity)
{
}
void StringTTF::updateDisplayedOpacity(GLubyte parentOpacity)
{
}
bool StringTTF::isCascadeOpacityEnabled() const
{
return false;
}
void StringTTF::setCascadeOpacityEnabled(bool cascadeOpacityEnabled)
{
}
const Color3B& StringTTF::getColor(void) const
{
return _realColor;
}
const Color3B& StringTTF::getDisplayedColor() const
{
return _displayedColor;
}
void StringTTF::setColor(const Color3B& color)
{
_displayedColor = _realColor = color;
if( _cascadeColorEnabled )
{
Color3B parentColor = Color3B::WHITE;
RGBAProtocol* pParent = dynamic_cast<RGBAProtocol*>(_parent);
if (pParent && pParent->isCascadeColorEnabled())
parentColor = pParent->getDisplayedColor();
updateDisplayedColor(parentColor);
}
}
void StringTTF::updateDisplayedColor(const Color3B& parentColor)
{
_displayedColor.r = _realColor.r * parentColor.r/255.0;
_displayedColor.g = _realColor.g * parentColor.g/255.0;
_displayedColor.b = _realColor.b * parentColor.b/255.0;
Object* pObj;
CCARRAY_FOREACH(_children, pObj)
{
Sprite *item = static_cast<Sprite*>( pObj );
item->updateDisplayedColor(_displayedColor);
}
}
bool StringTTF::isCascadeColorEnabled() const
{
return false;
}
void StringTTF::setCascadeColorEnabled(bool cascadeColorEnabled)
{
_cascadeColorEnabled = cascadeColorEnabled;
}
NS_CC_END

View File

@ -1,142 +0,0 @@
/****************************************************************************
Copyright (c) 2013 Zynga Inc.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef _StringTTF_h
#define _StringTTF_h
#include "CCFontDefinition.h"
#include "CCLabelTextFormatProtocol.h"
#include "CCLabel.h"
#include "CCFontAtlas.h"
NS_CC_BEGIN
class CC_DLL StringTTF : public Label, public LabelTextFormatProtocol
{
public:
static StringTTF* create(FontAtlas *pAtlas, TextHAlignment alignment = TextHAlignment::LEFT, int lineSize = 0);
// main interface
bool setText(const char *stringToRender, float lineWidth, TextHAlignment alignment = TextHAlignment::LEFT, bool lineBreakWithoutSpaces = false);
void setString(const char *stringToRender);
virtual void setAlignment(TextHAlignment alignment);
virtual void setWidth(float width);
virtual void setLineBreakWithoutSpace(bool breakWithoutSpace);
virtual void setScale(float scale);
virtual void setScaleX(float scaleX);
virtual void setScaleY(float scaleY);
// carloX
const char * getString() const { return "not implemented"; }
// RGBAProtocol
virtual bool isOpacityModifyRGB() const;
virtual void setOpacityModifyRGB(bool isOpacityModifyRGB);
virtual void setOpacity(GLubyte opacity);
virtual void updateDisplayedOpacity(GLubyte parentOpacity);
virtual bool isCascadeOpacityEnabled() const;
virtual void setCascadeOpacityEnabled(bool cascadeOpacityEnabled);
virtual void setColor(const Color3B& color);
virtual void updateDisplayedColor(const Color3B& parentColor);
virtual bool isCascadeColorEnabled() const;
virtual void setCascadeColorEnabled(bool cascadeColorEnabled);
virtual const Color3B& getColor(void) const;
virtual const Color3B& getDisplayedColor() const;
virtual unsigned char getOpacity() const;
virtual unsigned char getDisplayedOpacity() const;
// CCLabelTextFormat protocol implementation
virtual Sprite * getSpriteChild(int ID);
virtual Array * getChildrenLetters();
virtual Sprite * getSpriteForChar(unsigned short int theChar, int spriteIndexHint);
virtual float getLetterPosXLeft( Sprite* sp );
virtual float getLetterPosXRight( Sprite* sp );
// font related stuff
virtual int getCommonLineHeight();
virtual int getKerningForCharsPair(unsigned short first, unsigned short second);
virtual int getXOffsetForChar(unsigned short c);
virtual int getYOffsetForChar(unsigned short c);
virtual int getAdvanceForChar(unsigned short c, int hintPositionInString);
virtual Rect getRectForChar(unsigned short c) ;
// string related stuff
virtual int getStringNumLines();
virtual int getStringLenght();
virtual unsigned short getCharAtStringPosition(int position);
virtual unsigned short * getUTF8String();
virtual void assignNewUTF8String(unsigned short *newString);
virtual TextHAlignment getTextAlignment();
// label related stuff
virtual float getMaxLineWidth() ;
virtual bool breakLineWithoutSpace();
virtual Size getLabelContentSize();
virtual void setLabelContentSize(const Size &newSize);
private:
//
StringTTF(FontAtlas *pAtlas, TextHAlignment alignment = TextHAlignment::LEFT);
~StringTTF();
bool init();
void alignText();
void hideAllLetters();
void moveAllSpritesToCache();
bool computeAdvancesForString(unsigned short int *stringToRender);
bool setCurrentString(unsigned short *stringToSet);
bool setOriginalString(unsigned short *stringToSet);
void resetCurrentString();
Sprite * getSprite();
Sprite * createNewSpriteFromLetterDefinition(FontLetterDefinition &theDefinition, Texture2D *theTexture);
Sprite * updateSpriteWithLetterDefinition(Sprite *spriteToUpdate, FontLetterDefinition &theDefinition, Texture2D *theTexture);
Sprite * getSpriteForLetter(unsigned short int newLetter);
Sprite * updateSpriteForLetter(Sprite *spriteToUpdate, unsigned short int newLetter);
Array _spriteArray;
Array _spriteArrayCache;
float _commonLineHeight;
bool _lineBreakWithoutSpaces;
float _width;
TextHAlignment _alignment;
unsigned short int * _currentUTF8String;
unsigned short int * _originalUTF8String;
Size * _advances;
FontAtlas * _fontAtlas;
Color3B _displayedColor;
Color3B _realColor;
bool _cascadeColorEnabled;
};
NS_CC_END
#endif