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.
****************************************************************************/
#include "CCLabelTTF.h"
#include "CCDirector.h"
#include "CCGLProgram.h"
#include "CCShaderCache.h"
#include "CCApplication.h"
#include "CCLabel.h"
#include "CCString.h"
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()
: _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()
@ -59,7 +47,7 @@ LabelTTF::~LabelTTF()
LabelTTF * LabelTTF::create()
{
LabelTTF * ret = new LabelTTF();
if (ret && ret->init())
if (ret)
{
ret->autorelease();
}
@ -70,18 +58,6 @@ LabelTTF * LabelTTF::create()
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,
const Size &dimensions, TextHAlignment hAlignment,
TextVAlignment vAlignment)
@ -108,449 +84,189 @@ LabelTTF * LabelTTF::createWithFontDefinition(const std::string& string, FontDef
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,
const cocos2d::Size &dimensions, TextHAlignment hAlignment,
TextVAlignment vAlignment)
{
if (Sprite::init())
{
// shader program
// this->setShaderProgram(ShaderCache::getInstance()->getProgram(SHADER_PROGRAM));
_renderLabel->setString(string);
_renderLabel->setFontSize(fontSize);
_renderLabel->setDimensions(dimensions.width,dimensions.height);
_renderLabel->setAlignment(hAlignment,vAlignment);
_renderLabel->setFontName(fontName);
this->setContentSize(_renderLabel->getContentSize());
_dimensions = Size(dimensions.width, dimensions.height);
_alignment = hAlignment;
_vAlignment = vAlignment;
_fontName = fontName;
_fontSize = fontSize;
this->setString(string);
return true;
}
return false;
return true;
}
bool LabelTTF::initWithStringAndTextDefinition(const std::string& string, FontDefinition &textDefinition)
{
if (Sprite::init())
{
// shader program
this->setShaderProgram(ShaderCache::getInstance()->getProgram(SHADER_PROGRAM));
// prepare everythin needed to render the label
_updateWithTextDefinition(textDefinition, false);
// set the string
this->setString(string);
//
return true;
}
else
{
return false;
}
_renderLabel->setFontDefinition(textDefinition);
_renderLabel->setString(string);
this->setContentSize(_renderLabel->getContentSize());
return true;
}
void LabelTTF::setString(const std::string &string)
{
if (_string.compare(string))
{
_string = string;
this->updateTexture();
}
_renderLabel->setString(string);
_contentDirty = true;
}
const std::string& LabelTTF::getString() const
{
return _string;
return _renderLabel->getString();
}
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
{
return _alignment;
return _renderLabel->getHorizontalAlignment();
}
void LabelTTF::setHorizontalAlignment(TextHAlignment alignment)
{
if (alignment != _alignment)
{
_alignment = alignment;
// Force update
if (_string.size() > 0)
{
this->updateTexture();
}
}
_renderLabel->setHorizontalAlignment(alignment);
_contentDirty = true;
}
TextVAlignment LabelTTF::getVerticalAlignment() const
{
return _vAlignment;
return _renderLabel->getVerticalAlignment();
}
void LabelTTF::setVerticalAlignment(TextVAlignment verticalAlignment)
{
if (verticalAlignment != _vAlignment)
{
_vAlignment = verticalAlignment;
// Force update
if (_string.size() > 0)
{
this->updateTexture();
}
}
_renderLabel->setVerticalAlignment(verticalAlignment);
_contentDirty = true;
}
const Size& LabelTTF::getDimensions() const
{
return _dimensions;
return _renderLabel->getDimensions();
}
void LabelTTF::setDimensions(const Size &dim)
{
// XXX: float comparison... very unreliable
if (dim.width != _dimensions.width || dim.height != _dimensions.height)
{
_dimensions = dim;
// Force update
if (_string.size() > 0)
{
this->updateTexture();
}
}
_renderLabel->setDimensions(dim.width,dim.height);
_contentDirty = true;
}
float LabelTTF::getFontSize() const
{
return _fontSize;
return _renderLabel->getFontSize();
}
void LabelTTF::setFontSize(float fontSize)
{
// XXX: float comparison... very unreliable
if (_fontSize != fontSize)
{
_fontSize = fontSize;
// Force update
if (_string.size() > 0)
{
this->updateTexture();
}
}
_renderLabel->setFontSize(fontSize);
_contentDirty = true;
}
const std::string& LabelTTF::getFontName() const
{
return _fontName;
return _renderLabel->getFontName();
}
void LabelTTF::setFontName(const std::string& fontName)
{
if (_fontName.compare(fontName))
{
_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;
_renderLabel->setFontName(fontName);
_contentDirty = true;
}
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)
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
_renderLabel->enableShadow(Color3B::BLACK,shadowOffset,shadowOpacity,shadowBlur);
_contentDirty = true;
}
void LabelTTF::disableShadow(bool updateTexture)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) || (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
if (_shadowEnabled)
{
_shadowEnabled = false;
if (updateTexture)
this->updateTexture();
}
#else
CCLOGERROR("Currently only supported on iOS and Android!");
#endif
_renderLabel->disableEffect();
this->setContentSize(_renderLabel->getContentSize());
}
void LabelTTF::enableStroke(const Color3B &strokeColor, float strokeSize, bool updateTexture)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) || (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
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
_renderLabel->enableOutline(Color4B(strokeColor),strokeSize);
_contentDirty = true;
}
void LabelTTF::disableStroke(bool updateTexture)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) || (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
if (_strokeEnabled)
{
_strokeEnabled = false;
if (updateTexture)
this->updateTexture();
}
#else
CCLOGERROR("Currently only supported on iOS and Android!");
#endif
_renderLabel->disableEffect();
this->setContentSize(_renderLabel->getContentSize());
}
void LabelTTF::setFontFillColor(const Color3B &tintColor, bool updateTexture)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) || (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
if (_textFillColor.r != tintColor.r || _textFillColor.g != tintColor.g || _textFillColor.b != tintColor.b)
{
_textFillColor = tintColor;
if (updateTexture)
this->updateTexture();
}
#else
CCLOGERROR("Currently only supported on iOS and Android!");
#endif
_renderLabel->setColor(tintColor);
this->setContentSize(_renderLabel->getContentSize());
}
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);
_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();
_renderLabel->setBlendFunc(blendFunc);
}
FontDefinition LabelTTF::_prepareTextDefinition(bool adjustForResolution)
const BlendFunc &LabelTTF::getBlendFunc() const
{
FontDefinition texDef;
if (adjustForResolution)
texDef._fontSize = _fontSize * CC_CONTENT_SCALE_FACTOR();
else
texDef._fontSize = _fontSize;
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 )
return _renderLabel->getBlendFunc();
}
void LabelTTF::setFlippedX(bool flippedX)
{
if (flippedX)
{
texDef._stroke._strokeEnabled = true;
texDef._stroke._strokeColor = _strokeColor;
if (adjustForResolution)
texDef._stroke._strokeSize = _strokeSize * CC_CONTENT_SCALE_FACTOR();
else
texDef._stroke._strokeSize = _strokeSize;
}
_renderLabel->setScaleX(-1.0f);
}
else
{
texDef._stroke._strokeEnabled = false;
_renderLabel->setScaleX(1.0f);
}
// shadow
if ( _shadowEnabled )
}
void LabelTTF::setFlippedY(bool flippedY)
{
if (flippedY)
{
texDef._shadow._shadowEnabled = true;
texDef._shadow._shadowBlur = _shadowBlur;
texDef._shadow._shadowOpacity = _shadowOpacity;
if (adjustForResolution)
texDef._shadow._shadowOffset = CC_SIZE_POINTS_TO_PIXELS(_shadowOffset);
else
texDef._shadow._shadowOffset = _shadowOffset;
}
_renderLabel->setScaleY(-1.0f);
}
else
{
texDef._shadow._shadowEnabled = false;
_renderLabel->setScaleY(1.0f);
}
// text tint
texDef._fontFillColor = _textFillColor;
return texDef;
}
void LabelTTF::visit(Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated)
{
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

View File

@ -26,11 +26,12 @@ THE SOFTWARE.
#ifndef __CCLABELTTF_H__
#define __CCLABELTTF_H__
#include "CCTexture2D.h"
#include "CCSprite.h"
#include "CCNode.h"
NS_CC_BEGIN
class Label;
/**
* @addtogroup GUI
* @{
@ -55,7 +56,7 @@ NS_CC_BEGIN
* @endcode
*
*/
class CC_DLL LabelTTF : public Sprite, public LabelProtocol
class CC_DLL LabelTTF : public Node, public LabelProtocol, public BlendProtocol
{
public:
/**
@ -68,39 +69,21 @@ public:
*/
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
@since v2.0.1
*/
static LabelTTF * create(const std::string& string, const std::string& fontName, float fontSize,
const Size& dimensions, TextHAlignment hAlignment,
TextVAlignment vAlignment);
const Size& dimensions = Size::ZERO, TextHAlignment hAlignment = TextHAlignment::CENTER,
TextVAlignment vAlignment = TextVAlignment::TOP);
/** Create a lable with string and a font definition*/
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 */
bool initWithString(const std::string& string, const std::string& fontName, float fontSize,
const Size& dimensions, TextHAlignment hAlignment);
/** 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);
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 initWithStringAndTextDefinition(const std::string& string, FontDefinition &textDefinition);
@ -109,7 +92,7 @@ public:
void setTextDefinition(const FontDefinition& theDefinition);
/** get the text definition used by this label */
FontDefinition getTextDefinition();
const FontDefinition& getTextDefinition() const;
@ -128,11 +111,6 @@ public:
/** set text tinting */
void setFontFillColor(const Color3B &tintColor, bool mustUpdateTexture = true);
/** initializes the LabelTTF */
bool init();
/** Creates an label.
*/
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
*/
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;
void setHorizontalAlignment(TextHAlignment alignment);
@ -158,46 +136,23 @@ public:
const std::string& getFontName() const;
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
* @lua NA
*/
virtual std::string getDescription() const override;
virtual void visit(Renderer *renderer, const kmMat4 &parentTransform, bool parentTransformUpdated) override;
virtual const Size& getContentSize() const override;
protected:
bool updateTexture();
/** 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;
Label* _renderLabel;
bool _contentDirty;
};