issue #3821:LabelTTF re-implemented as a wrapper of Label.

This commit is contained in:
Dhilan007 2014-03-12 10:19:33 +08:00
parent 04fb80fed4
commit bc7e39283f
2 changed files with 112 additions and 441 deletions

View File

@ -24,32 +24,20 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
****************************************************************************/ ****************************************************************************/
#include "CCLabelTTF.h" #include "CCLabelTTF.h"
#include "CCDirector.h" #include "CCLabel.h"
#include "CCGLProgram.h" #include "CCString.h"
#include "CCShaderCache.h"
#include "CCApplication.h"
NS_CC_BEGIN NS_CC_BEGIN
#if CC_USE_LA88_LABELS
#define SHADER_PROGRAM GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR
#else
#define SHADER_PROGRAM GLProgram::SHADER_NAME_POSITION_TEXTUREA8Color
#endif
//
//CCLabelTTF
//
LabelTTF::LabelTTF() LabelTTF::LabelTTF()
: _alignment(TextHAlignment::CENTER)
, _vAlignment(TextVAlignment::TOP)
, _fontName("")
, _fontSize(0.0)
, _string("")
, _shadowEnabled(false)
, _strokeEnabled(false)
, _textFillColor(Color3B::WHITE)
{ {
_renderLabel = Label::create();
this->addChild(_renderLabel);
this->setAnchorPoint(Point::ANCHOR_MIDDLE);
_contentDirty = false;
_cascadeColorEnabled = true;
_cascadeOpacityEnabled = true;
} }
LabelTTF::~LabelTTF() LabelTTF::~LabelTTF()
@ -59,7 +47,7 @@ LabelTTF::~LabelTTF()
LabelTTF * LabelTTF::create() LabelTTF * LabelTTF::create()
{ {
LabelTTF * ret = new LabelTTF(); LabelTTF * ret = new LabelTTF();
if (ret && ret->init()) if (ret)
{ {
ret->autorelease(); ret->autorelease();
} }
@ -70,18 +58,6 @@ LabelTTF * LabelTTF::create()
return ret; return ret;
} }
LabelTTF * LabelTTF::create(const std::string& string, const std::string& fontName, float fontSize)
{
return LabelTTF::create(string, fontName, fontSize,
Size::ZERO, TextHAlignment::CENTER, TextVAlignment::TOP);
}
LabelTTF * LabelTTF::create(const std::string& string, const std::string& fontName, float fontSize,
const Size& dimensions, TextHAlignment hAlignment)
{
return LabelTTF::create(string, fontName, fontSize, dimensions, hAlignment, TextVAlignment::TOP);
}
LabelTTF* LabelTTF::create(const std::string& string, const std::string& fontName, float fontSize, LabelTTF* LabelTTF::create(const std::string& string, const std::string& fontName, float fontSize,
const Size &dimensions, TextHAlignment hAlignment, const Size &dimensions, TextHAlignment hAlignment,
TextVAlignment vAlignment) TextVAlignment vAlignment)
@ -108,449 +84,189 @@ LabelTTF * LabelTTF::createWithFontDefinition(const std::string& string, FontDef
return nullptr; return nullptr;
} }
bool LabelTTF::init()
{
return this->initWithString("", "Helvetica", 12);
}
bool LabelTTF::initWithString(const std::string& label, const std::string& fontName, float fontSize,
const Size& dimensions, TextHAlignment alignment)
{
return this->initWithString(label, fontName, fontSize, dimensions, alignment, TextVAlignment::TOP);
}
bool LabelTTF::initWithString(const std::string& label, const std::string& fontName, float fontSize)
{
return this->initWithString(label, fontName, fontSize,
Size::ZERO, TextHAlignment::LEFT, TextVAlignment::TOP);
}
bool LabelTTF::initWithString(const std::string& string, const std::string& fontName, float fontSize, bool LabelTTF::initWithString(const std::string& string, const std::string& fontName, float fontSize,
const cocos2d::Size &dimensions, TextHAlignment hAlignment, const cocos2d::Size &dimensions, TextHAlignment hAlignment,
TextVAlignment vAlignment) TextVAlignment vAlignment)
{ {
if (Sprite::init()) _renderLabel->setString(string);
{ _renderLabel->setFontSize(fontSize);
// shader program _renderLabel->setDimensions(dimensions.width,dimensions.height);
// this->setShaderProgram(ShaderCache::getInstance()->getProgram(SHADER_PROGRAM)); _renderLabel->setAlignment(hAlignment,vAlignment);
_renderLabel->setFontName(fontName);
this->setContentSize(_renderLabel->getContentSize());
_dimensions = Size(dimensions.width, dimensions.height); return true;
_alignment = hAlignment;
_vAlignment = vAlignment;
_fontName = fontName;
_fontSize = fontSize;
this->setString(string);
return true;
}
return false;
} }
bool LabelTTF::initWithStringAndTextDefinition(const std::string& string, FontDefinition &textDefinition) bool LabelTTF::initWithStringAndTextDefinition(const std::string& string, FontDefinition &textDefinition)
{ {
if (Sprite::init()) _renderLabel->setFontDefinition(textDefinition);
{ _renderLabel->setString(string);
// shader program this->setContentSize(_renderLabel->getContentSize());
this->setShaderProgram(ShaderCache::getInstance()->getProgram(SHADER_PROGRAM));
return true;
// prepare everythin needed to render the label
_updateWithTextDefinition(textDefinition, false);
// set the string
this->setString(string);
//
return true;
}
else
{
return false;
}
} }
void LabelTTF::setString(const std::string &string) void LabelTTF::setString(const std::string &string)
{ {
if (_string.compare(string)) _renderLabel->setString(string);
{ _contentDirty = true;
_string = string;
this->updateTexture();
}
} }
const std::string& LabelTTF::getString() const const std::string& LabelTTF::getString() const
{ {
return _string; return _renderLabel->getString();
} }
std::string LabelTTF::getDescription() const std::string LabelTTF::getDescription() const
{ {
return StringUtils::format("<LabelTTF | FontName = %s, FontSize = %.1f, Label = '%s'>", _fontName.c_str(), _fontSize, _string.c_str()); return StringUtils::format("<LabelTTF | FontName = %s, FontSize = %.1f, Label = '%s'>", _renderLabel->getFontName().c_str(), _renderLabel->getFontSize(), _renderLabel->getString().c_str());
} }
TextHAlignment LabelTTF::getHorizontalAlignment() const TextHAlignment LabelTTF::getHorizontalAlignment() const
{ {
return _alignment; return _renderLabel->getHorizontalAlignment();
} }
void LabelTTF::setHorizontalAlignment(TextHAlignment alignment) void LabelTTF::setHorizontalAlignment(TextHAlignment alignment)
{ {
if (alignment != _alignment) _renderLabel->setHorizontalAlignment(alignment);
{ _contentDirty = true;
_alignment = alignment;
// Force update
if (_string.size() > 0)
{
this->updateTexture();
}
}
} }
TextVAlignment LabelTTF::getVerticalAlignment() const TextVAlignment LabelTTF::getVerticalAlignment() const
{ {
return _vAlignment; return _renderLabel->getVerticalAlignment();
} }
void LabelTTF::setVerticalAlignment(TextVAlignment verticalAlignment) void LabelTTF::setVerticalAlignment(TextVAlignment verticalAlignment)
{ {
if (verticalAlignment != _vAlignment) _renderLabel->setVerticalAlignment(verticalAlignment);
{ _contentDirty = true;
_vAlignment = verticalAlignment;
// Force update
if (_string.size() > 0)
{
this->updateTexture();
}
}
} }
const Size& LabelTTF::getDimensions() const const Size& LabelTTF::getDimensions() const
{ {
return _dimensions; return _renderLabel->getDimensions();
} }
void LabelTTF::setDimensions(const Size &dim) void LabelTTF::setDimensions(const Size &dim)
{ {
// XXX: float comparison... very unreliable _renderLabel->setDimensions(dim.width,dim.height);
if (dim.width != _dimensions.width || dim.height != _dimensions.height) _contentDirty = true;
{
_dimensions = dim;
// Force update
if (_string.size() > 0)
{
this->updateTexture();
}
}
} }
float LabelTTF::getFontSize() const float LabelTTF::getFontSize() const
{ {
return _fontSize; return _renderLabel->getFontSize();
} }
void LabelTTF::setFontSize(float fontSize) void LabelTTF::setFontSize(float fontSize)
{ {
// XXX: float comparison... very unreliable _renderLabel->setFontSize(fontSize);
if (_fontSize != fontSize) _contentDirty = true;
{
_fontSize = fontSize;
// Force update
if (_string.size() > 0)
{
this->updateTexture();
}
}
} }
const std::string& LabelTTF::getFontName() const const std::string& LabelTTF::getFontName() const
{ {
return _fontName; return _renderLabel->getFontName();
} }
void LabelTTF::setFontName(const std::string& fontName) void LabelTTF::setFontName(const std::string& fontName)
{ {
if (_fontName.compare(fontName)) _renderLabel->setFontName(fontName);
{ _contentDirty = true;
_fontName = fontName;
// Force update
if (_string.size() > 0)
{
this->updateTexture();
}
}
}
// Helper
bool LabelTTF::updateTexture()
{
Texture2D *tex;
tex = new Texture2D();
if (!tex)
return false;
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) || (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
FontDefinition texDef = _prepareTextDefinition(true);
tex->initWithString( _string.c_str(), texDef );
#else
tex->initWithString( _string.c_str(),
_fontName.c_str(),
_fontSize * CC_CONTENT_SCALE_FACTOR(),
CC_SIZE_POINTS_TO_PIXELS(_dimensions),
_alignment,
_vAlignment);
#endif
// set the texture
this->setTexture(tex);
// release it
tex->release();
// set the size in the sprite
Rect rect =Rect::ZERO;
rect.size = _texture->getContentSize();
this->setTextureRect(rect);
//ok
return true;
} }
void LabelTTF::enableShadow(const Size &shadowOffset, float shadowOpacity, float shadowBlur, bool updateTexture) void LabelTTF::enableShadow(const Size &shadowOffset, float shadowOpacity, float shadowBlur, bool updateTexture)
{ {
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) || (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) _renderLabel->enableShadow(Color3B::BLACK,shadowOffset,shadowOpacity,shadowBlur);
_contentDirty = true;
bool valueChanged = false;
if (false == _shadowEnabled)
{
_shadowEnabled = true;
valueChanged = true;
}
if ( (_shadowOffset.width != shadowOffset.width) || (_shadowOffset.height!=shadowOffset.height) )
{
_shadowOffset.width = shadowOffset.width;
_shadowOffset.height = shadowOffset.height;
valueChanged = true;
}
if (_shadowOpacity != shadowOpacity )
{
_shadowOpacity = shadowOpacity;
valueChanged = true;
}
if (_shadowBlur != shadowBlur)
{
_shadowBlur = shadowBlur;
valueChanged = true;
}
if ( valueChanged && updateTexture )
{
this->updateTexture();
}
#else
CCLOGERROR("Currently only supported on iOS and Android!");
#endif
} }
void LabelTTF::disableShadow(bool updateTexture) void LabelTTF::disableShadow(bool updateTexture)
{ {
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) || (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) _renderLabel->disableEffect();
this->setContentSize(_renderLabel->getContentSize());
if (_shadowEnabled)
{
_shadowEnabled = false;
if (updateTexture)
this->updateTexture();
}
#else
CCLOGERROR("Currently only supported on iOS and Android!");
#endif
} }
void LabelTTF::enableStroke(const Color3B &strokeColor, float strokeSize, bool updateTexture) void LabelTTF::enableStroke(const Color3B &strokeColor, float strokeSize, bool updateTexture)
{ {
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) || (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) _renderLabel->enableOutline(Color4B(strokeColor),strokeSize);
_contentDirty = true;
bool valueChanged = false;
if(_strokeEnabled == false)
{
_strokeEnabled = true;
valueChanged = true;
}
if ( (_strokeColor.r != strokeColor.r) || (_strokeColor.g != strokeColor.g) || (_strokeColor.b != strokeColor.b) )
{
_strokeColor = strokeColor;
valueChanged = true;
}
if (_strokeSize!=strokeSize)
{
_strokeSize = strokeSize;
valueChanged = true;
}
if ( valueChanged && updateTexture )
{
this->updateTexture();
}
#else
CCLOGERROR("Currently only supported on iOS and Android!");
#endif
} }
void LabelTTF::disableStroke(bool updateTexture) void LabelTTF::disableStroke(bool updateTexture)
{ {
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) || (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) _renderLabel->disableEffect();
this->setContentSize(_renderLabel->getContentSize());
if (_strokeEnabled)
{
_strokeEnabled = false;
if (updateTexture)
this->updateTexture();
}
#else
CCLOGERROR("Currently only supported on iOS and Android!");
#endif
} }
void LabelTTF::setFontFillColor(const Color3B &tintColor, bool updateTexture) void LabelTTF::setFontFillColor(const Color3B &tintColor, bool updateTexture)
{ {
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) || (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) _renderLabel->setColor(tintColor);
if (_textFillColor.r != tintColor.r || _textFillColor.g != tintColor.g || _textFillColor.b != tintColor.b) this->setContentSize(_renderLabel->getContentSize());
{
_textFillColor = tintColor;
if (updateTexture)
this->updateTexture();
}
#else
CCLOGERROR("Currently only supported on iOS and Android!");
#endif
} }
void LabelTTF::setTextDefinition(const FontDefinition& theDefinition) void LabelTTF::setTextDefinition(const FontDefinition& theDefinition)
{ {
_updateWithTextDefinition(theDefinition, true); _renderLabel->setFontDefinition(theDefinition);
_contentDirty = true;
} }
FontDefinition LabelTTF::getTextDefinition() const FontDefinition& LabelTTF::getTextDefinition() const
{ {
return _prepareTextDefinition(false); return _renderLabel->getFontDefinition();
} }
void LabelTTF::_updateWithTextDefinition(const FontDefinition& textDefinition, bool mustUpdateTexture) void LabelTTF::setBlendFunc(const BlendFunc &blendFunc)
{ {
_dimensions = Size(textDefinition._dimensions.width, textDefinition._dimensions.height); _renderLabel->setBlendFunc(blendFunc);
_alignment = textDefinition._alignment;
_vAlignment = textDefinition._vertAlignment;
_fontName = textDefinition._fontName;
_fontSize = textDefinition._fontSize;
// shadow
if ( textDefinition._shadow._shadowEnabled )
{
enableShadow(textDefinition._shadow._shadowOffset, textDefinition._shadow._shadowOpacity, textDefinition._shadow._shadowBlur, false);
}
// stroke
if ( textDefinition._stroke._strokeEnabled )
{
enableStroke(textDefinition._stroke._strokeColor, textDefinition._stroke._strokeSize, false);
}
// fill color
setFontFillColor(textDefinition._fontFillColor, false);
if (mustUpdateTexture)
updateTexture();
} }
FontDefinition LabelTTF::_prepareTextDefinition(bool adjustForResolution) const BlendFunc &LabelTTF::getBlendFunc() const
{ {
FontDefinition texDef; return _renderLabel->getBlendFunc();
}
if (adjustForResolution)
texDef._fontSize = _fontSize * CC_CONTENT_SCALE_FACTOR(); void LabelTTF::setFlippedX(bool flippedX)
else {
texDef._fontSize = _fontSize; if (flippedX)
texDef._fontName = _fontName;
texDef._alignment = _alignment;
texDef._vertAlignment = _vAlignment;
if (adjustForResolution)
texDef._dimensions = CC_SIZE_POINTS_TO_PIXELS(_dimensions);
else
texDef._dimensions = _dimensions;
// stroke
if ( _strokeEnabled )
{ {
texDef._stroke._strokeEnabled = true; _renderLabel->setScaleX(-1.0f);
texDef._stroke._strokeColor = _strokeColor; }
if (adjustForResolution)
texDef._stroke._strokeSize = _strokeSize * CC_CONTENT_SCALE_FACTOR();
else
texDef._stroke._strokeSize = _strokeSize;
}
else else
{ {
texDef._stroke._strokeEnabled = false; _renderLabel->setScaleX(1.0f);
} }
}
// shadow
if ( _shadowEnabled ) void LabelTTF::setFlippedY(bool flippedY)
{
if (flippedY)
{ {
texDef._shadow._shadowEnabled = true; _renderLabel->setScaleY(-1.0f);
texDef._shadow._shadowBlur = _shadowBlur; }
texDef._shadow._shadowOpacity = _shadowOpacity;
if (adjustForResolution)
texDef._shadow._shadowOffset = CC_SIZE_POINTS_TO_PIXELS(_shadowOffset);
else
texDef._shadow._shadowOffset = _shadowOffset;
}
else else
{ {
texDef._shadow._shadowEnabled = false; _renderLabel->setScaleY(1.0f);
} }
}
// text tint
texDef._fontFillColor = _textFillColor; void LabelTTF::visit(Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated)
{
return texDef; if (_contentDirty)
{
this->setContentSize(_renderLabel->getContentSize());
_contentDirty = false;
}
Node::visit(renderer,parentTransform,parentTransformUpdated);
}
const Size& LabelTTF::getContentSize() const
{
const_cast<LabelTTF*>(this)->setContentSize(_renderLabel->getContentSize());
return _contentSize;
} }
NS_CC_END NS_CC_END

View File

@ -26,11 +26,12 @@ THE SOFTWARE.
#ifndef __CCLABELTTF_H__ #ifndef __CCLABELTTF_H__
#define __CCLABELTTF_H__ #define __CCLABELTTF_H__
#include "CCTexture2D.h" #include "CCNode.h"
#include "CCSprite.h"
NS_CC_BEGIN NS_CC_BEGIN
class Label;
/** /**
* @addtogroup GUI * @addtogroup GUI
* @{ * @{
@ -55,7 +56,7 @@ NS_CC_BEGIN
* @endcode * @endcode
* *
*/ */
class CC_DLL LabelTTF : public Sprite, public LabelProtocol class CC_DLL LabelTTF : public Node, public LabelProtocol, public BlendProtocol
{ {
public: public:
/** /**
@ -68,39 +69,21 @@ public:
*/ */
virtual ~LabelTTF(); virtual ~LabelTTF();
/** creates a LabelTTF with a font name and font size in points
@since v2.0.1
*/
static LabelTTF * create(const std::string& string, const std::string& fontName, float fontSize);
/** creates a LabelTTF from a fontname, horizontal alignment, dimension in points, and font size in points.
@since v2.0.1
*/
static LabelTTF * create(const std::string& string, const std::string& fontName, float fontSize,
const Size& dimensions, TextHAlignment hAlignment);
/** creates a Label from a fontname, alignment, dimension in points and font size in points /** creates a Label from a fontname, alignment, dimension in points and font size in points
@since v2.0.1 @since v2.0.1
*/ */
static LabelTTF * create(const std::string& string, const std::string& fontName, float fontSize, static LabelTTF * create(const std::string& string, const std::string& fontName, float fontSize,
const Size& dimensions, TextHAlignment hAlignment, const Size& dimensions = Size::ZERO, TextHAlignment hAlignment = TextHAlignment::CENTER,
TextVAlignment vAlignment); TextVAlignment vAlignment = TextVAlignment::TOP);
/** Create a lable with string and a font definition*/ /** Create a lable with string and a font definition*/
static LabelTTF * createWithFontDefinition(const std::string& string, FontDefinition &textDefinition); static LabelTTF * createWithFontDefinition(const std::string& string, FontDefinition &textDefinition);
/** initializes the LabelTTF with a font name and font size */
bool initWithString(const std::string& string, const std::string& fontName, float fontSize);
/** initializes the LabelTTF with a font name, alignment, dimension and font size */ /** initializes the LabelTTF with a font name, alignment, dimension and font size */
bool initWithString(const std::string& string, const std::string& fontName, float fontSize, bool initWithString(const std::string& string, const std::string& fontName, float fontSize,
const Size& dimensions, TextHAlignment hAlignment); const Size& dimensions = Size::ZERO, TextHAlignment hAlignment = TextHAlignment::LEFT,
TextVAlignment vAlignment = TextVAlignment::TOP);
/** initializes the LabelTTF with a font name, alignment, dimension and font size */
bool initWithString(const std::string& string, const std::string& fontName, float fontSize,
const Size& dimensions, TextHAlignment hAlignment,
TextVAlignment vAlignment);
/** initializes the LabelTTF with a font name, alignment, dimension and font size */ /** initializes the LabelTTF with a font name, alignment, dimension and font size */
bool initWithStringAndTextDefinition(const std::string& string, FontDefinition &textDefinition); bool initWithStringAndTextDefinition(const std::string& string, FontDefinition &textDefinition);
@ -109,7 +92,7 @@ public:
void setTextDefinition(const FontDefinition& theDefinition); void setTextDefinition(const FontDefinition& theDefinition);
/** get the text definition used by this label */ /** get the text definition used by this label */
FontDefinition getTextDefinition(); const FontDefinition& getTextDefinition() const;
@ -128,11 +111,6 @@ public:
/** set text tinting */ /** set text tinting */
void setFontFillColor(const Color3B &tintColor, bool mustUpdateTexture = true); void setFontFillColor(const Color3B &tintColor, bool mustUpdateTexture = true);
/** initializes the LabelTTF */
bool init();
/** Creates an label. /** Creates an label.
*/ */
static LabelTTF * create(); static LabelTTF * create();
@ -141,7 +119,7 @@ public:
* @warning Changing the string is as expensive as creating a new LabelTTF. To obtain better performance use LabelAtlas * @warning Changing the string is as expensive as creating a new LabelTTF. To obtain better performance use LabelAtlas
*/ */
virtual void setString(const std::string &label) override; virtual void setString(const std::string &label) override;
virtual const std::string& getString(void) const override; virtual const std::string& getString(void) const override ;
TextHAlignment getHorizontalAlignment() const; TextHAlignment getHorizontalAlignment() const;
void setHorizontalAlignment(TextHAlignment alignment); void setHorizontalAlignment(TextHAlignment alignment);
@ -158,46 +136,23 @@ public:
const std::string& getFontName() const; const std::string& getFontName() const;
void setFontName(const std::string& fontName); void setFontName(const std::string& fontName);
virtual void setBlendFunc(const BlendFunc &blendFunc) override;
virtual const BlendFunc &getBlendFunc() const override;
virtual void setFlippedX(bool flippedX);
virtual void setFlippedY(bool flippedY);
/** /**
* @js NA * @js NA
* @lua NA * @lua NA
*/ */
virtual std::string getDescription() const override; virtual std::string getDescription() const override;
virtual void visit(Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated) override;
virtual const Size& getContentSize() const override;
protected: protected:
bool updateTexture(); Label* _renderLabel;
bool _contentDirty;
/** set the text definition for this label */
void _updateWithTextDefinition(const FontDefinition& textDefinition, bool mustUpdateTexture = true);
FontDefinition _prepareTextDefinition(bool adjustForResolution = false);
/** Dimensions of the label in Points */
Size _dimensions;
/** The alignment of the label */
TextHAlignment _alignment;
/** The vertical alignment of the label */
TextVAlignment _vAlignment;
/** Font name used in the label */
std::string _fontName;
/** Font size of the label */
float _fontSize;
/** label's string */
std::string _string;
/** font shadow */
bool _shadowEnabled;
Size _shadowOffset;
float _shadowOpacity;
float _shadowBlur;
/** font stroke */
bool _strokeEnabled;
Color3B _strokeColor;
float _strokeSize;
/** font tint */
Color3B _textFillColor;
}; };