Sprite fixes: color + polygon (#17135)

* fixes issue #17119

and sanitizes the code a little bit

* more fixes

* fixes issue #17116

* restore xcode "none" sign profile

* code is cleaner

add more documentation in CCSprite.h

* missing assets

* anchor point works with batchnodes again
This commit is contained in:
Ricardo Quesada 2017-01-09 23:28:47 -08:00 committed by minggo
parent 5d41d3c65e
commit e100d02dff
10 changed files with 871 additions and 47 deletions

View File

@ -249,6 +249,7 @@ bool Sprite::initWithPolygon(const cocos2d::PolygonInfo &info)
if(texture && initWithTexture(texture)) if(texture && initWithTexture(texture))
{ {
_polyInfo = info; _polyInfo = info;
_renderMode = RenderMode::POLYGON;
Node::setContentSize(_polyInfo.getRect().size / _director->getContentScaleFactor()); Node::setContentSize(_polyInfo.getRect().size / _director->getContentScaleFactor());
ret = true; ret = true;
} }
@ -312,7 +313,7 @@ Sprite::Sprite(void)
, _spriteFrame(nullptr) , _spriteFrame(nullptr)
, _insideBounds(true) , _insideBounds(true)
, _centerRectNormalized(0,0,1,1) , _centerRectNormalized(0,0,1,1)
, _numberOfSlices(1) , _renderMode(Sprite::RenderMode::QUAD)
, _trianglesVertex(nullptr) , _trianglesVertex(nullptr)
, _trianglesIndex(nullptr) , _trianglesIndex(nullptr)
, _strechFactor(Vec2::ONE) , _strechFactor(Vec2::ONE)
@ -395,7 +396,7 @@ void Sprite::setTexture(Texture2D *texture)
} }
} }
if (!_batchNode && _texture != texture) if ((_renderMode != RenderMode::BATCHNODE) && (_texture != texture))
{ {
CC_SAFE_RETAIN(texture); CC_SAFE_RETAIN(texture);
CC_SAFE_RELEASE(_texture); CC_SAFE_RELEASE(_texture);
@ -439,7 +440,7 @@ void Sprite::updatePoly()
// the texture is streched to the content size // the texture is streched to the content size
// C) 9-sliced, streched // C) 9-sliced, streched
// the sprite is 9-sliced and streched. // the sprite is 9-sliced and streched.
if (_numberOfSlices == 1) { if (_renderMode == RenderMode::QUAD || _renderMode == RenderMode::BATCHNODE) {
Rect copyRect; Rect copyRect;
if (_strechEnabled) { if (_strechEnabled) {
// case B) // case B)
@ -455,13 +456,10 @@ void Sprite::updatePoly()
setTextureCoords(_rect, &_quad); setTextureCoords(_rect, &_quad);
setVertexCoords(copyRect, &_quad); setVertexCoords(copyRect, &_quad);
_polyInfo.setQuad(&_quad); _polyInfo.setQuad(&_quad);
} else {
} else if (_renderMode == RenderMode::SLICE9) {
// case C) // case C)
// in theory it can support 3 or 6 slices as well, but let's stick to 9 only
CCASSERT(_numberOfSlices == 9, "Invalid number of slices");
// How the texture is split // How the texture is split
// //
// u,v: are the texture coordinates // u,v: are the texture coordinates
@ -652,7 +650,7 @@ void Sprite::updatePoly()
// needed in order to get color from "_quad" // needed in order to get color from "_quad"
V3F_C4B_T2F_Quad tmpQuad = _quad; V3F_C4B_T2F_Quad tmpQuad = _quad;
for (int i=0; i<_numberOfSlices; ++i) { for (int i=0; i<9; ++i) {
setTextureCoords(texRects[i], &tmpQuad); setTextureCoords(texRects[i], &tmpQuad);
setVertexCoords(verticesRects[i], &tmpQuad); setVertexCoords(verticesRects[i], &tmpQuad);
populateTriangle(i, tmpQuad); populateTriangle(i, tmpQuad);
@ -671,6 +669,8 @@ void Sprite::updatePoly()
void Sprite::setCenterRectNormalized(const cocos2d::Rect &rectTopLeft) void Sprite::setCenterRectNormalized(const cocos2d::Rect &rectTopLeft)
{ {
CCASSERT(_renderMode == RenderMode::QUAD || _renderMode == RenderMode::SLICE9, "centerRect can only be used with SLICE9 or QUAD render modes");
// FIMXE: Rect is has origin on top-left (like text coordinate). // FIMXE: Rect is has origin on top-left (like text coordinate).
// but all the logic has been done using bottom-left as origin. So it is easier to invert Y // but all the logic has been done using bottom-left as origin. So it is easier to invert Y
// here, than in the rest of the places... but it is not as clean. // here, than in the rest of the places... but it is not as clean.
@ -678,9 +678,9 @@ void Sprite::setCenterRectNormalized(const cocos2d::Rect &rectTopLeft)
if (!_centerRectNormalized.equals(rect)) { if (!_centerRectNormalized.equals(rect)) {
_centerRectNormalized = rect; _centerRectNormalized = rect;
// convert it to 1-slice // convert it to 1-slice when the centerRect is not present.
if (rect.equals(Rect(0,0,1,1))) { if (rect.equals(Rect(0,0,1,1))) {
_numberOfSlices = 1; _renderMode = RenderMode::QUAD;
free(_trianglesVertex); free(_trianglesVertex);
free(_trianglesIndex); free(_trianglesIndex);
_trianglesVertex = nullptr; _trianglesVertex = nullptr;
@ -689,8 +689,8 @@ void Sprite::setCenterRectNormalized(const cocos2d::Rect &rectTopLeft)
else else
{ {
// convert it to 9-slice if it isn't already // convert it to 9-slice if it isn't already
if (_numberOfSlices != 9) { if (_renderMode != RenderMode::SLICE9) {
_numberOfSlices = 9; _renderMode = RenderMode::SLICE9;
// 9 quads + 7 exterior points = 16 // 9 quads + 7 exterior points = 16
_trianglesVertex = (V3F_C4B_T2F*) malloc(sizeof(*_trianglesVertex) * (9 + 3 + 4)); _trianglesVertex = (V3F_C4B_T2F*) malloc(sizeof(*_trianglesVertex) * (9 + 3 + 4));
// 9 quads, each needs 6 vertices = 54 // 9 quads, each needs 6 vertices = 54
@ -716,6 +716,8 @@ void Sprite::setCenterRectNormalized(const cocos2d::Rect &rectTopLeft)
void Sprite::setCenterRect(const cocos2d::Rect &rectInPoints) void Sprite::setCenterRect(const cocos2d::Rect &rectInPoints)
{ {
CCASSERT(_renderMode == RenderMode::QUAD || _renderMode == RenderMode::SLICE9, "centerRect can only be used with SLICE9 or QUAD render modes");
if (!_originalContentSize.equals(Size::ZERO)) if (!_originalContentSize.equals(Size::ZERO))
{ {
Rect rect = rectInPoints; Rect rect = rectInPoints;
@ -761,7 +763,7 @@ void Sprite::setTextureCoords(const Rect& rectInPoints)
void Sprite::setTextureCoords(const Rect& rectInPoints, V3F_C4B_T2F_Quad* outQuad) void Sprite::setTextureCoords(const Rect& rectInPoints, V3F_C4B_T2F_Quad* outQuad)
{ {
Texture2D *tex = _batchNode ? _textureAtlas->getTexture() : _texture; Texture2D *tex = (_renderMode == RenderMode::BATCHNODE) ? _textureAtlas->getTexture() : _texture;
if (tex == nullptr) if (tex == nullptr)
{ {
return; return;
@ -855,13 +857,13 @@ void Sprite::setVertexCoords(const Rect& rect, V3F_C4B_T2F_Quad* outQuad)
// FIXME: Streching should be applied to the "offset" as well // FIXME: Streching should be applied to the "offset" as well
// but probably it should be calculated in the caller function. It will be tidier // but probably it should be calculated in the caller function. It will be tidier
if (_numberOfSlices == 1) { if (_renderMode == RenderMode::QUAD) {
_offsetPosition.x *= _strechFactor.x; _offsetPosition.x *= _strechFactor.x;
_offsetPosition.y *= _strechFactor.y; _offsetPosition.y *= _strechFactor.y;
} }
// rendering using batch node // rendering using batch node
if (_batchNode) if (_renderMode == RenderMode::BATCHNODE)
{ {
// update dirty_, don't update recursiveDirty_ // update dirty_, don't update recursiveDirty_
setDirty(true); setDirty(true);
@ -944,7 +946,7 @@ void Sprite::populateTriangle(int quadIndex, const V3F_C4B_T2F_Quad& quad)
void Sprite::updateTransform(void) void Sprite::updateTransform(void)
{ {
CCASSERT(_batchNode, "updateTransform is only valid when Sprite is being rendered using an SpriteBatchNode"); CCASSERT(_renderMode == RenderMode::BATCHNODE, "updateTransform is only valid when Sprite is being rendered using an SpriteBatchNode");
// recalculate matrix only if it is dirty // recalculate matrix only if it is dirty
if( isDirty() ) { if( isDirty() ) {
@ -1102,7 +1104,7 @@ void Sprite::addChild(Node *child, int zOrder, int tag)
return; return;
} }
if (_batchNode) if (_renderMode == RenderMode::BATCHNODE)
{ {
Sprite* childSprite = dynamic_cast<Sprite*>(child); Sprite* childSprite = dynamic_cast<Sprite*>(child);
CCASSERT( childSprite, "CCSprite only supports Sprites as children when using SpriteBatchNode"); CCASSERT( childSprite, "CCSprite only supports Sprites as children when using SpriteBatchNode");
@ -1127,7 +1129,7 @@ void Sprite::addChild(Node *child, int zOrder, const std::string &name)
return; return;
} }
if (_batchNode) if (_renderMode == RenderMode::BATCHNODE)
{ {
Sprite* childSprite = dynamic_cast<Sprite*>(child); Sprite* childSprite = dynamic_cast<Sprite*>(child);
CCASSERT( childSprite, "CCSprite only supports Sprites as children when using SpriteBatchNode"); CCASSERT( childSprite, "CCSprite only supports Sprites as children when using SpriteBatchNode");
@ -1150,7 +1152,7 @@ void Sprite::reorderChild(Node *child, int zOrder)
CCASSERT(child != nullptr, "child must be non null"); CCASSERT(child != nullptr, "child must be non null");
CCASSERT(_children.contains(child), "child does not belong to this"); CCASSERT(_children.contains(child), "child does not belong to this");
if( _batchNode && ! _reorderChildDirty) if ((_renderMode == RenderMode::BATCHNODE) && ! _reorderChildDirty)
{ {
setReorderChildDirtyRecursively(); setReorderChildDirtyRecursively();
_batchNode->reorderBatch(true); _batchNode->reorderBatch(true);
@ -1161,7 +1163,7 @@ void Sprite::reorderChild(Node *child, int zOrder)
void Sprite::removeChild(Node *child, bool cleanup) void Sprite::removeChild(Node *child, bool cleanup)
{ {
if (_batchNode) if (_renderMode == RenderMode::BATCHNODE)
{ {
_batchNode->removeSpriteFromAtlas((Sprite*)(child)); _batchNode->removeSpriteFromAtlas((Sprite*)(child));
} }
@ -1171,7 +1173,7 @@ void Sprite::removeChild(Node *child, bool cleanup)
void Sprite::removeAllChildrenWithCleanup(bool cleanup) void Sprite::removeAllChildrenWithCleanup(bool cleanup)
{ {
if (_batchNode) if (_renderMode == RenderMode::BATCHNODE)
{ {
for(const auto &child : _children) { for(const auto &child : _children) {
Sprite* sprite = dynamic_cast<Sprite*>(child); Sprite* sprite = dynamic_cast<Sprite*>(child);
@ -1191,7 +1193,7 @@ void Sprite::sortAllChildren()
{ {
sortNodes(_children); sortNodes(_children);
if ( _batchNode) if (_renderMode == RenderMode::BATCHNODE)
{ {
for(const auto &child : _children) for(const auto &child : _children)
child->sortAllChildren(); child->sortAllChildren();
@ -1326,7 +1328,7 @@ void Sprite::setAnchorPoint(const Vec2& anchor)
void Sprite::setIgnoreAnchorPointForPosition(bool value) void Sprite::setIgnoreAnchorPointForPosition(bool value)
{ {
CCASSERT(! _batchNode, "setIgnoreAnchorPointForPosition is invalid in Sprite"); CCASSERT(_renderMode != RenderMode::BATCHNODE, "setIgnoreAnchorPointForPosition is invalid in Sprite");
Node::setIgnoreAnchorPointForPosition(value); Node::setIgnoreAnchorPointForPosition(value);
} }
@ -1338,6 +1340,9 @@ void Sprite::setVisible(bool bVisible)
void Sprite::setContentSize(const Size& size) void Sprite::setContentSize(const Size& size)
{ {
if (_renderMode == RenderMode::BATCHNODE || _renderMode == RenderMode::POLYGON)
CCLOGWARN("Sprite::setContentSize() doesn't strech the sprite when using BATCHNODE or POLYGON render modes");
Node::setContentSize(size); Node::setContentSize(size);
updateStretchFactor(); updateStretchFactor();
@ -1367,16 +1372,17 @@ void Sprite::updateStretchFactor()
{ {
const Size size = getContentSize(); const Size size = getContentSize();
float x_factor, y_factor; if (_renderMode == RenderMode::QUAD)
if (_numberOfSlices == 1)
{ {
// If strech is disabled, calculate the strech anyway // If strech is disabled, calculate the strech anyway
// since it is needed to calculate the offset // since it is needed to calculate the offset
x_factor = size.width / _originalContentSize.width; const float x_factor = size.width / _originalContentSize.width;
y_factor = size.height / _originalContentSize.height; const float y_factor = size.height / _originalContentSize.height;
_strechFactor = Vec2(std::max(0.0f, x_factor),
std::max(0.0f, y_factor));
} }
else else if (_renderMode == RenderMode::SLICE9)
{ {
const float x1 = _rect.size.width * _centerRectNormalized.origin.x; const float x1 = _rect.size.width * _centerRectNormalized.origin.x;
const float x2 = _rect.size.width * _centerRectNormalized.size.width; const float x2 = _rect.size.width * _centerRectNormalized.size.width;
@ -1390,25 +1396,37 @@ void Sprite::updateStretchFactor()
const float adjustedWidth = size.width - (_originalContentSize.width - _rect.size.width); const float adjustedWidth = size.width - (_originalContentSize.width - _rect.size.width);
const float adjustedHeight = size.height - (_originalContentSize.height - _rect.size.height); const float adjustedHeight = size.height - (_originalContentSize.height - _rect.size.height);
x_factor = (adjustedWidth - x1 - x3) / x2; const float x_factor = (adjustedWidth - x1 - x3) / x2;
y_factor = (adjustedHeight - y1 - y3) / y2; const float y_factor = (adjustedHeight - y1 - y3) / y2;
}
// sanity check:
_strechFactor = Vec2(std::max(0.0f, x_factor), _strechFactor = Vec2(std::max(0.0f, x_factor),
std::max(0.0f, y_factor)); std::max(0.0f, y_factor));
} }
// else:
// Do nothing if renderMode is Polygon
}
void Sprite::setFlippedX(bool flippedX) void Sprite::setFlippedX(bool flippedX)
{ {
if (_flippedX != flippedX) if (_flippedX != flippedX)
{ {
_flippedX = flippedX; _flippedX = flippedX;
if (_batchNode) { if (_renderMode == RenderMode::BATCHNODE)
{
setDirty(true); setDirty(true);
} else { }
else if (_renderMode == RenderMode::POLYGON)
{
for (ssize_t i = 0; i < _polyInfo.triangles.vertCount; i++) {
auto& v = _polyInfo.triangles.verts[i].vertices;
v.x = _contentSize.width -v.x;
}
}
else
{
// RenderMode:: Quad or Slice9
updatePoly(); updatePoly();
} }
} }
@ -1425,9 +1443,20 @@ void Sprite::setFlippedY(bool flippedY)
{ {
_flippedY = flippedY; _flippedY = flippedY;
if (_batchNode) { if (_renderMode == RenderMode::BATCHNODE)
{
setDirty(true); setDirty(true);
} else { }
else if (_renderMode == RenderMode::POLYGON)
{
for (ssize_t i = 0; i < _polyInfo.triangles.vertCount; i++) {
auto& v = _polyInfo.triangles.verts[i].vertices;
v.y = _contentSize.height -v.y;
}
}
else
{
// RenderMode:: Quad or Slice9
updatePoly(); updatePoly();
} }
} }
@ -1458,8 +1487,13 @@ void Sprite::updateColor(void)
_polyInfo.triangles.verts[i].colors = color4; _polyInfo.triangles.verts[i].colors = color4;
} }
// related to issue #17116
// when switching from Quad to Slice9, the color will be obtained from _quad
// so it is important to update _quad colors as well.
_quad.bl.colors = _quad.tl.colors = _quad.br.colors = _quad.tr.colors = color4;
// renders using batch node // renders using batch node
if (_batchNode) if (_renderMode == RenderMode::BATCHNODE)
{ {
if (_atlasIndex != INDEX_NOT_INITIALIZED) if (_atlasIndex != INDEX_NOT_INITIALIZED)
{ {
@ -1535,6 +1569,7 @@ void Sprite::setSpriteFrame(SpriteFrame *spriteFrame)
if (spriteFrame->hasPolygonInfo()) if (spriteFrame->hasPolygonInfo())
{ {
_polyInfo = spriteFrame->getPolygonInfo(); _polyInfo = spriteFrame->getPolygonInfo();
_renderMode = RenderMode::POLYGON;
} }
if (spriteFrame->hasAnchorPoint()) if (spriteFrame->hasAnchorPoint())
{ {
@ -1598,6 +1633,7 @@ void Sprite::setBatchNode(SpriteBatchNode *spriteBatchNode)
// self render // self render
if( ! _batchNode ) { if( ! _batchNode ) {
_renderMode = RenderMode::QUAD;
_atlasIndex = INDEX_NOT_INITIALIZED; _atlasIndex = INDEX_NOT_INITIALIZED;
setTextureAtlas(nullptr); setTextureAtlas(nullptr);
_recursiveDirty = false; _recursiveDirty = false;
@ -1613,8 +1649,8 @@ void Sprite::setBatchNode(SpriteBatchNode *spriteBatchNode)
_quad.tr.vertices.set(x2, y2, 0); _quad.tr.vertices.set(x2, y2, 0);
} else { } else {
// using batch // using batch
_renderMode = RenderMode::BATCHNODE;
_transformToBatch = Mat4::IDENTITY; _transformToBatch = Mat4::IDENTITY;
setTextureAtlas(_batchNode->getTextureAtlas()); // weak ref setTextureAtlas(_batchNode->getTextureAtlas()); // weak ref
} }
@ -1624,7 +1660,7 @@ void Sprite::setBatchNode(SpriteBatchNode *spriteBatchNode)
void Sprite::updateBlendFunc(void) void Sprite::updateBlendFunc(void)
{ {
CCASSERT(! _batchNode, "CCSprite: updateBlendFunc doesn't work when the sprite is rendered using a SpriteBatchNode"); CCASSERT(_renderMode != RenderMode::BATCHNODE, "CCSprite: updateBlendFunc doesn't work when the sprite is rendered using a SpriteBatchNode");
// it is possible to have an untextured sprite // it is possible to have an untextured sprite
if (! _texture || ! _texture->hasPremultipliedAlpha()) if (! _texture || ! _texture->hasPremultipliedAlpha())
@ -1642,7 +1678,7 @@ void Sprite::updateBlendFunc(void)
std::string Sprite::getDescription() const std::string Sprite::getDescription() const
{ {
int texture_id = -1; int texture_id = -1;
if( _batchNode ) if (_renderMode == RenderMode::BATCHNODE)
texture_id = _batchNode->getTextureAtlas()->getTexture()->getName(); texture_id = _batchNode->getTextureAtlas()->getTexture()->getName();
else else
texture_id = _texture->getName(); texture_id = _texture->getName();
@ -1657,6 +1693,7 @@ const PolygonInfo& Sprite::getPolygonInfo() const
void Sprite::setPolygonInfo(const PolygonInfo& info) void Sprite::setPolygonInfo(const PolygonInfo& info)
{ {
_polyInfo = info; _polyInfo = info;
_renderMode = RenderMode::POLYGON;
} }
NS_CC_END NS_CC_END

View File

@ -72,8 +72,18 @@ struct transformValues_;
* - Use the same blending function for all your sprites. * - Use the same blending function for all your sprites.
* - ...and the Renderer will automatically "batch" your sprites (will draw all of them in one OpenGL call). * - ...and the Renderer will automatically "batch" your sprites (will draw all of them in one OpenGL call).
* *
* To gain an additional 5% ~ 10% more in the rendering, you can parent your sprites into a `SpriteBatchNode`. * Sprite has 4 types or rendering modes:
* But doing so carries the following limitations: *
* - `QUAD`: Renders the sprite using 2 triangles: uses small memory, but renders empty pixels (slow)
* - `POLYGON`: Renders the sprite using many triangles (depending on the setting). Uses more memory, but doesn't render so much empty pixels (faster)
* - `SLICE9`: Renders the sprite using 9 quads (18 triangles). Useful to to scale buttons an other rectangular sprites
* - `BATCHNODE`: Renders the sprite using an static batch, which has some limitations (see below):
*
* By default, the sprite uses `QUAD` mode. But can be changed to `POLYGON` when calling `setPolygonInfo()`. To use `SLICE9` call `setCenterRect()` or
* `serCenterRectNormalized()`. To use `BATCHNODE` parent the sprite to a `SpriteBatchNode` object.
*
*
* `BATCHNODE` limitations:
* *
* - The Alias/Antialias property belongs to `SpriteBatchNode`, so you can't individually set the aliased property. * - The Alias/Antialias property belongs to `SpriteBatchNode`, so you can't individually set the aliased property.
* - The Blending function property belongs to `SpriteBatchNode`, so you can't individually set the blending function property. * - The Blending function property belongs to `SpriteBatchNode`, so you can't individually set the blending function property.
@ -85,6 +95,12 @@ struct transformValues_;
class CC_DLL Sprite : public Node, public TextureProtocol class CC_DLL Sprite : public Node, public TextureProtocol
{ {
public: public:
enum class RenderMode {
QUAD,
POLYGON,
SLICE9,
BATCHNODE
};
/** Sprite invalid index on the SpriteBatchNode. */ /** Sprite invalid index on the SpriteBatchNode. */
static const int INDEX_NOT_INITIALIZED = -1; static const int INDEX_NOT_INITIALIZED = -1;
@ -670,7 +686,7 @@ protected:
bool _rectRotated; /// Whether the texture is rotated bool _rectRotated; /// Whether the texture is rotated
Rect _centerRectNormalized; /// Rectangle to implement "slice 9" Rect _centerRectNormalized; /// Rectangle to implement "slice 9"
int _numberOfSlices; /// how many sprite slices: 1 or 9 RenderMode _renderMode; /// how many sprite slices: 1 or 9
Vec2 _strechFactor; /// strech factor to match the contentSize. for 1- and 9- slice sprites Vec2 _strechFactor; /// strech factor to match the contentSize. for 1- and 9- slice sprites
Size _originalContentSize; /// original content size Size _originalContentSize; /// original content size

View File

@ -135,6 +135,7 @@ SpriteTests::SpriteTests()
ADD_TEST_CASE(SpriteSlice9Test8); ADD_TEST_CASE(SpriteSlice9Test8);
ADD_TEST_CASE(SpriteSlice9Test9); ADD_TEST_CASE(SpriteSlice9Test9);
ADD_TEST_CASE(SpriteSlice9Test10); ADD_TEST_CASE(SpriteSlice9Test10);
ADD_TEST_CASE(Issue17119);
}; };
//------------------------------------------------------------------ //------------------------------------------------------------------
@ -1975,7 +1976,7 @@ void SpriteFramesFromFileContent::onEnter()
// Animation using Sprite BatchNode // Animation using Sprite BatchNode
// //
Sprite * sprite = Sprite::createWithSpriteFrameName("grossini_dance_01.png"); Sprite * sprite = Sprite::createWithSpriteFrameName("grossini_dance_01.png");
sprite->setPosition( Vec2( s.width/2-80, s.height/2) ); sprite->setPosition( Vec2( s.width/2, s.height/2) );
addChild(sprite); addChild(sprite);
Vector<SpriteFrame*> animFrames(15); Vector<SpriteFrame*> animFrames(15);
@ -5725,3 +5726,77 @@ SpriteSlice9Test10::SpriteSlice9Test10()
s3->setContentSize(s3->getContentSize()*1.5); s3->setContentSize(s3->getContentSize()*1.5);
s3->setFlippedY(true); s3->setFlippedY(true);
} }
//------------------------------------------------------------------
//
// Issue 17119
//
//------------------------------------------------------------------
Issue17119::Issue17119()
: _accum(0)
{
Size s = Director::getInstance()->getVisibleSize();
SpriteFrameCache::getInstance()->addSpriteFramesWithFile("Images/issue_17119.plist");
SpriteFrameCache::getInstance()->addSpriteFramesWithFile("Images/blocks9ss.plist");
auto s1 = Sprite::createWithSpriteFrameName("firstPic.png");
addChild(s1);
s1->setPosition(s.width/2-s.width/3, s.height/2);
s1->setScale(0.25f);
auto p1 = Sprite::create("Images/r1.png");
p1->setScale(0.25f);
p1->setPosition(s1->getPosition());
addChild(p1, 10);
auto s2 = Sprite::createWithSpriteFrameName("blocks9r.png");
addChild(s2);
s2->setPosition(s.width/2, s.height/2);
s2->setCenterRectNormalized(Rect(1/3.f, 1/3.f, 1/3.f, 1/3.f));
s2->setContentSize(s2->getContentSize()*1.5);
auto p2 = Sprite::create("Images/r1.png");
p2->setScale(0.25f);
p2->setPosition(s2->getPosition());
addChild(p2, 10);
auto s3 = Sprite::create("Images/grossini.png");
addChild(s3);
s3->setPosition(s.width/2+s.width/3, s.height/2+s.height/3);
s3->setContentSize(s3->getContentSize()*1.5);
auto p3 = Sprite::create("Images/r1.png");
p3->setScale(0.25f);
p3->setPosition(s3->getPosition());
addChild(p3, 10);
auto s4 = Sprite::create("Images/grossini.png");
addChild(s4);
s4->setPosition(s.width/2+s.width/3, s.height/2-s.height/3);
s4->setContentSize(s2->getContentSize()*1.5);
s4->setStrechEnabled(false);
auto p4 = Sprite::create("Images/r1.png");
p4->setScale(0.25f);
p4->setPosition(s3->getPosition());
addChild(p4, 10);
_s1 = s1;
_s2 = s2;
_s3 = s3;
_s4 = s4;
scheduleUpdate();
}
void Issue17119::update(float dt)
{
_accum += dt;
if (_accum > 0.5) {
_accum = 0;
auto flipped = _s1->isFlippedX();
_s1->setFlippedX(!flipped);
_s2->setFlippedX(!flipped);
_s3->setFlippedX(!flipped);
_s4->setFlippedX(!flipped);
}
}

View File

@ -915,4 +915,21 @@ public:
virtual std::string subtitle() const override { return "setting after getting should be the same"; } virtual std::string subtitle() const override { return "setting after getting should be the same"; }
}; };
class Issue17119 : public SpriteTestDemo
{
public:
CREATE_FUNC(Issue17119);
Issue17119();
virtual std::string title() const override { return "Issue 17119"; };
virtual std::string subtitle() const override { return "flipping should work ok"; }
virtual void update(float dt) override;
protected:
float _accum;
cocos2d::Sprite* _s1;
cocos2d::Sprite* _s2;
cocos2d::Sprite* _s3;
cocos2d::Sprite* _s4;
};
#endif #endif

View File

@ -21,6 +21,7 @@ UIButtonTests::UIButtonTests()
ADD_TEST_CASE(UIButtonDisableDefaultTest); ADD_TEST_CASE(UIButtonDisableDefaultTest);
ADD_TEST_CASE(UIButtonCloneTest); ADD_TEST_CASE(UIButtonCloneTest);
ADD_TEST_CASE(Issue12249); ADD_TEST_CASE(Issue12249);
ADD_TEST_CASE(Issue17116);
} }
// UIButtonTest // UIButtonTest
@ -1189,3 +1190,25 @@ bool Issue12249::init()
} }
return false; return false;
} }
// https://github.com/cocos2d/cocos2d-x/issues/17116
Issue17116::Issue17116()
{
}
bool Issue17116::init()
{
if (UIScene::init())
{
auto visibleSize = Director::getInstance()->getVisibleSize();
SpriteFrameCache::getInstance()->addSpriteFramesWithFile("Images/issue_17116.plist");
auto button = ui::Button::create();
button->loadTextureNormal("buttons/play-big", ui::Widget::TextureResType::PLIST);
button->setPosition(Vec2(visibleSize.width/2, visibleSize.height/2));
button->setOpacity(100);
addChild(button);
return true;
}
return false;
}

View File

@ -262,4 +262,14 @@ protected:
cocos2d::ui::Text* _displayValueLabel; cocos2d::ui::Text* _displayValueLabel;
}; };
class Issue17116: public UIScene
{
public:
CREATE_FUNC(Issue17116);
Issue17116();
virtual bool init() override;
};
#endif /* defined(__TestCpp__UIButtonTest__) */ #endif /* defined(__TestCpp__UIButtonTest__) */

View File

@ -0,0 +1,578 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>frames</key>
<dict>
<key>buttons/back</key>
<dict>
<key>aliases</key>
<array/>
<key>anchor</key>
<string>{0.5,0.5}</string>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{60,60}</string>
<key>spriteSourceSize</key>
<string>{60,60}</string>
<key>textureRect</key>
<string>{{152,1},{60,60}}</string>
<key>textureRotated</key>
<false/>
<key>triangles</key>
<string>3 4 5 2 3 5 0 1 2 0 2 5</string>
<key>vertices</key>
<string>60 16 60 60 17 60 0 43 0 0 44 0</string>
<key>verticesUV</key>
<string>212 17 212 61 169 61 152 44 152 1 196 1</string>
</dict>
<key>buttons/icons/achievements</key>
<dict>
<key>aliases</key>
<array/>
<key>anchor</key>
<string>{0.5,0.5}</string>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{23,23}</string>
<key>spriteSourceSize</key>
<string>{23,23}</string>
<key>textureRect</key>
<string>{{214,97},{23,23}}</string>
<key>textureRotated</key>
<false/>
<key>triangles</key>
<string>1 2 3 0 1 3</string>
<key>vertices</key>
<string>23 23 0 23 0 0 23 0</string>
<key>verticesUV</key>
<string>237 120 214 120 214 97 237 97</string>
</dict>
<key>buttons/icons/clear-level</key>
<dict>
<key>aliases</key>
<array/>
<key>anchor</key>
<string>{0.5,0.5}</string>
<key>spriteOffset</key>
<string>{1,0}</string>
<key>spriteSize</key>
<string>{28,28}</string>
<key>spriteSourceSize</key>
<string>{30,30}</string>
<key>textureRect</key>
<string>{{214,36},{28,28}}</string>
<key>textureRotated</key>
<false/>
<key>triangles</key>
<string>0 3 4 0 1 2 0 2 3</string>
<key>vertices</key>
<string>30 9 26 29 2 29 2 1 25 1</string>
<key>verticesUV</key>
<string>242 44 238 64 214 64 214 36 237 36</string>
</dict>
<key>buttons/icons/conditions</key>
<dict>
<key>aliases</key>
<array/>
<key>anchor</key>
<string>{0.5,0.5}</string>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{28,33}</string>
<key>spriteSourceSize</key>
<string>{28,33}</string>
<key>textureRect</key>
<string>{{214,1},{28,33}}</string>
<key>textureRotated</key>
<false/>
<key>triangles</key>
<string>0 4 5 2 3 4 0 2 4 0 1 2</string>
<key>vertices</key>
<string>28 33 0 33 0 13 5 3 11 0 28 0</string>
<key>verticesUV</key>
<string>242 34 214 34 214 14 219 4 225 1 242 1</string>
</dict>
<key>buttons/icons/leaderboard</key>
<dict>
<key>aliases</key>
<array/>
<key>anchor</key>
<string>{0.5,0.5}</string>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{26,23}</string>
<key>spriteSourceSize</key>
<string>{26,23}</string>
<key>textureRect</key>
<string>{{98,463},{26,23}}</string>
<key>textureRotated</key>
<true/>
<key>triangles</key>
<string>1 2 3 0 1 3</string>
<key>vertices</key>
<string>26 23 0 23 0 0 26 0</string>
<key>verticesUV</key>
<string>98 489 98 463 121 463 121 489</string>
</dict>
<key>buttons/icons/objectives</key>
<dict>
<key>aliases</key>
<array/>
<key>anchor</key>
<string>{0.5,0.5}</string>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{29,29}</string>
<key>spriteSourceSize</key>
<string>{29,29}</string>
<key>textureRect</key>
<string>{{67,463},{29,29}}</string>
<key>textureRotated</key>
<false/>
<key>triangles</key>
<string>1 2 3 0 1 3</string>
<key>vertices</key>
<string>29 29 0 29 0 0 29 0</string>
<key>verticesUV</key>
<string>96 492 67 492 67 463 96 463</string>
</dict>
<key>buttons/icons/sound</key>
<dict>
<key>aliases</key>
<array/>
<key>anchor</key>
<string>{0.5,0.5}</string>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{27,23}</string>
<key>spriteSourceSize</key>
<string>{27,23}</string>
<key>textureRect</key>
<string>{{123,341},{27,23}}</string>
<key>textureRotated</key>
<false/>
<key>triangles</key>
<string>1 2 3 0 1 3</string>
<key>vertices</key>
<string>27 23 0 23 0 0 27 0</string>
<key>verticesUV</key>
<string>150 364 123 364 123 341 150 341</string>
</dict>
<key>buttons/icons/time</key>
<dict>
<key>aliases</key>
<array/>
<key>anchor</key>
<string>{0.5,0.5}</string>
<key>spriteOffset</key>
<string>{0,-0.5}</string>
<key>spriteSize</key>
<string>{18,29}</string>
<key>spriteSourceSize</key>
<string>{30,30}</string>
<key>textureRect</key>
<string>{{214,66},{18,29}}</string>
<key>textureRotated</key>
<false/>
<key>triangles</key>
<string>1 2 3 0 1 3</string>
<key>vertices</key>
<string>24 30 6 30 6 1 24 1</string>
<key>verticesUV</key>
<string>232 95 214 95 214 66 232 66</string>
</dict>
<key>buttons/icons/tutorial</key>
<dict>
<key>aliases</key>
<array/>
<key>anchor</key>
<string>{0.5,0.5}</string>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{10,23}</string>
<key>spriteSourceSize</key>
<string>{10,23}</string>
<key>textureRect</key>
<string>{{214,122},{10,23}}</string>
<key>textureRotated</key>
<false/>
<key>triangles</key>
<string>1 2 3 0 1 3</string>
<key>vertices</key>
<string>10 23 0 23 0 0 10 0</string>
<key>verticesUV</key>
<string>224 145 214 145 214 122 224 122</string>
</dict>
<key>buttons/info-small</key>
<dict>
<key>aliases</key>
<array/>
<key>anchor</key>
<string>{0.5,0.5}</string>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{30,30}</string>
<key>spriteSourceSize</key>
<string>{30,30}</string>
<key>textureRect</key>
<string>{{35,463},{30,30}}</string>
<key>textureRotated</key>
<false/>
<key>triangles</key>
<string>1 2 3 0 1 3</string>
<key>vertices</key>
<string>30 30 0 30 0 0 30 0</string>
<key>verticesUV</key>
<string>65 493 35 493 35 463 65 463</string>
</dict>
<key>buttons/menu/disabled</key>
<dict>
<key>aliases</key>
<array/>
<key>anchor</key>
<string>{0.5,0.5}</string>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{60,60}</string>
<key>spriteSourceSize</key>
<string>{60,60}</string>
<key>textureRect</key>
<string>{{152,63},{60,60}}</string>
<key>textureRotated</key>
<false/>
<key>triangles</key>
<string>1 2 3 0 1 3</string>
<key>vertices</key>
<string>60 60 0 60 0 0 60 0</string>
<key>verticesUV</key>
<string>212 123 152 123 152 63 212 63</string>
</dict>
<key>buttons/menu/normal</key>
<dict>
<key>aliases</key>
<array/>
<key>anchor</key>
<string>{0.5,0.5}</string>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{60,60}</string>
<key>spriteSourceSize</key>
<string>{60,60}</string>
<key>textureRect</key>
<string>{{152,125},{60,60}}</string>
<key>textureRotated</key>
<false/>
<key>triangles</key>
<string>1 2 3 0 1 3</string>
<key>vertices</key>
<string>60 60 0 60 0 0 60 0</string>
<key>verticesUV</key>
<string>212 185 152 185 152 125 212 125</string>
</dict>
<key>buttons/menu/selected</key>
<dict>
<key>aliases</key>
<array/>
<key>anchor</key>
<string>{0.5,0.5}</string>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{60,60}</string>
<key>spriteSourceSize</key>
<string>{60,60}</string>
<key>textureRect</key>
<string>{{152,187},{60,60}}</string>
<key>textureRotated</key>
<false/>
<key>triangles</key>
<string>1 2 3 0 1 3</string>
<key>vertices</key>
<string>60 60 0 60 0 0 60 0</string>
<key>verticesUV</key>
<string>212 247 152 247 152 187 212 187</string>
</dict>
<key>buttons/music</key>
<dict>
<key>aliases</key>
<array/>
<key>anchor</key>
<string>{0.5,0.5}</string>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{60,60}</string>
<key>spriteSourceSize</key>
<string>{60,60}</string>
<key>textureRect</key>
<string>{{152,249},{60,60}}</string>
<key>textureRotated</key>
<false/>
<key>triangles</key>
<string>3 4 5 2 3 5 0 1 2 0 2 5</string>
<key>vertices</key>
<string>60 16 60 60 17 60 0 43 0 0 44 0</string>
<key>verticesUV</key>
<string>212 265 212 309 169 309 152 292 152 249 196 249</string>
</dict>
<key>buttons/play</key>
<dict>
<key>aliases</key>
<array/>
<key>anchor</key>
<string>{0.5,0.5}</string>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{60,60}</string>
<key>spriteSourceSize</key>
<string>{60,60}</string>
<key>textureRect</key>
<string>{{152,311},{60,60}}</string>
<key>textureRotated</key>
<false/>
<key>triangles</key>
<string>3 4 5 2 3 5 0 1 2 0 2 5</string>
<key>vertices</key>
<string>60 16 60 60 17 60 0 43 0 0 44 0</string>
<key>verticesUV</key>
<string>212 327 212 371 169 371 152 354 152 311 196 311</string>
</dict>
<key>buttons/play-big</key>
<dict>
<key>aliases</key>
<array/>
<key>anchor</key>
<string>{0.5,0.5}</string>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{120,120}</string>
<key>spriteSourceSize</key>
<string>{120,120}</string>
<key>textureRect</key>
<string>{{1,341},{120,120}}</string>
<key>textureRotated</key>
<false/>
<key>triangles</key>
<string>5 6 7 4 5 7 1 4 7 1 2 3 1 3 4 0 1 7</string>
<key>vertices</key>
<string>120 24 120 82 97 120 34 120 0 86 0 33 33 0 82 0</string>
<key>verticesUV</key>
<string>121 365 121 423 98 461 35 461 1 427 1 374 34 341 83 341</string>
</dict>
<key>buttons/rating</key>
<dict>
<key>aliases</key>
<array/>
<key>anchor</key>
<string>{0.5,0.5}</string>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{60,60}</string>
<key>spriteSourceSize</key>
<string>{60,60}</string>
<key>textureRect</key>
<string>{{123,373},{60,60}}</string>
<key>textureRotated</key>
<false/>
<key>triangles</key>
<string>3 4 5 2 3 5 0 1 2 0 2 5</string>
<key>vertices</key>
<string>60 16 60 60 17 60 0 43 0 0 44 0</string>
<key>verticesUV</key>
<string>183 389 183 433 140 433 123 416 123 373 167 373</string>
</dict>
<key>buttons/ray</key>
<dict>
<key>aliases</key>
<array/>
<key>anchor</key>
<string>{0.5,0.5}</string>
<key>spriteOffset</key>
<string>{-2.5,-8}</string>
<key>spriteSize</key>
<string>{149,338}</string>
<key>spriteSourceSize</key>
<string>{180,360}</string>
<key>textureRect</key>
<string>{{1,1},{149,338}}</string>
<key>textureRotated</key>
<false/>
<key>triangles</key>
<string>1 7 8 5 6 7 1 5 7 4 5 2 4 2 3 1 2 5 0 1 8</string>
<key>vertices</key>
<string>158 33 162 72 118 351 85 357 63 346 28 152 13 36 37 20 141 19</string>
<key>verticesUV</key>
<string>146 15 150 54 106 333 73 339 51 328 16 134 1 18 25 2 129 1</string>
</dict>
<key>buttons/sfx</key>
<dict>
<key>aliases</key>
<array/>
<key>anchor</key>
<string>{0.5,0.5}</string>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{60,60}</string>
<key>spriteSourceSize</key>
<string>{60,60}</string>
<key>textureRect</key>
<string>{{123,435},{60,60}}</string>
<key>textureRotated</key>
<false/>
<key>triangles</key>
<string>3 4 5 2 3 5 0 1 2 0 2 5</string>
<key>vertices</key>
<string>60 16 60 60 17 60 0 43 0 0 44 0</string>
<key>verticesUV</key>
<string>183 451 183 495 140 495 123 478 123 435 167 435</string>
</dict>
<key>buttons/star-off-big</key>
<dict>
<key>aliases</key>
<array/>
<key>anchor</key>
<string>{0.5,0.5}</string>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{60,57}</string>
<key>spriteSourceSize</key>
<string>{60,57}</string>
<key>textureRect</key>
<string>{{185,373},{60,57}}</string>
<key>textureRotated</key>
<true/>
<key>triangles</key>
<string>0 8 9 7 5 6 7 8 5 0 3 5 3 4 5 0 1 2 0 2 3 0 5 8</string>
<key>vertices</key>
<string>41 19 60 21 60 23 49 57 11 57 11 34 0 23 0 21 28 0 31 0</string>
<key>verticesUV</key>
<string>223 414 221 433 219 433 185 422 185 384 208 384 219 373 221 373 242 401 242 404</string>
</dict>
<key>buttons/star-off-small</key>
<dict>
<key>aliases</key>
<array/>
<key>anchor</key>
<string>{0.5,0.5}</string>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{15,14}</string>
<key>spriteSourceSize</key>
<string>{15,14}</string>
<key>textureRect</key>
<string>{{226,122},{15,14}}</string>
<key>textureRotated</key>
<true/>
<key>triangles</key>
<string>2 3 4 0 2 4 0 1 2</string>
<key>vertices</key>
<string>15 14 2 14 0 7 0 0 15 0</string>
<key>verticesUV</key>
<string>226 137 226 124 233 122 240 122 240 137</string>
</dict>
<key>buttons/star-on-big</key>
<dict>
<key>aliases</key>
<array/>
<key>anchor</key>
<string>{0.5,0.5}</string>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{60,57}</string>
<key>spriteSourceSize</key>
<string>{60,57}</string>
<key>textureRect</key>
<string>{{185,435},{60,57}}</string>
<key>textureRotated</key>
<true/>
<key>triangles</key>
<string>0 11 12 10 8 9 10 11 8 0 5 8 6 7 8 5 6 8 3 4 5 0 2 5 0 1 2 5 2 3 0 8 11</string>
<key>vertices</key>
<string>40 19 60 21 60 23 49 57 47 57 34 49 14 57 11 57 11 34 0 23 0 21 28 0 31 0</string>
<key>verticesUV</key>
<string>223 475 221 495 219 495 185 484 185 482 193 469 185 449 185 446 208 446 219 435 221 435 242 463 242 466</string>
</dict>
<key>buttons/star-on-small</key>
<dict>
<key>aliases</key>
<array/>
<key>anchor</key>
<string>{0.5,0.5}</string>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{15,14}</string>
<key>spriteSourceSize</key>
<string>{15,14}</string>
<key>textureRect</key>
<string>{{214,147},{15,14}}</string>
<key>textureRotated</key>
<true/>
<key>triangles</key>
<string>2 3 4 0 2 4 0 1 2</string>
<key>vertices</key>
<string>15 14 2 14 0 7 0 0 15 0</string>
<key>verticesUV</key>
<string>214 162 214 149 221 147 228 147 228 162</string>
</dict>
<key>buttons/top-pause</key>
<dict>
<key>aliases</key>
<array/>
<key>anchor</key>
<string>{0.5,0.5}</string>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{32,32}</string>
<key>spriteSourceSize</key>
<string>{40,40}</string>
<key>textureRect</key>
<string>{{1,463},{32,32}}</string>
<key>textureRotated</key>
<false/>
<key>triangles</key>
<string>1 2 3 0 1 3</string>
<key>vertices</key>
<string>36 36 4 36 4 4 36 4</string>
<key>verticesUV</key>
<string>33 495 1 495 1 463 33 463</string>
</dict>
</dict>
<key>metadata</key>
<dict>
<key>format</key>
<integer>3</integer>
<key>pixelFormat</key>
<string>RGBA8888</string>
<key>premultiplyAlpha</key>
<false/>
<key>realTextureFileName</key>
<string>issue_17116.png</string>
<key>size</key>
<string>{243,496}</string>
<key>smartupdate</key>
<string>$TexturePacker:SmartUpdate:85cd28c08253ca791bc3bf6acce65315:ff114147eb1bd067b5ebf7fb51ac318b:416c7a4a89ac2daba4ec931906fb7ad0$</string>
<key>textureFileName</key>
<string>issue_17116.png</string>
</dict>
</dict>
</plist>

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

View File

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>frames</key>
<dict>
<key>firstPic.png</key>
<dict>
<key>aliases</key>
<array/>
<key>spriteOffset</key>
<string>{0,-58.5}</string>
<key>spriteSize</key>
<string>{512,395}</string>
<key>spriteSourceSize</key>
<string>{512,512}</string>
<key>textureRect</key>
<string>{{1,224},{512,395}}</string>
<key>textureRotated</key>
<false/>
<key>triangles</key>
<string>0 3 4 1 2 3 0 4 5 0 1 3 6 0 5</string>
<key>vertices</key>
<string>512 512 0 512 0 460 142 385 291 310 376 253 512 117</string>
<key>verticesUV</key>
<string>513 619 1 619 1 567 143 492 292 417 377 360 513 224</string>
</dict>
<key>secondPic.png</key>
<dict>
<key>aliases</key>
<array/>
<key>spriteOffset</key>
<string>{0,0}</string>
<key>spriteSize</key>
<string>{512,512}</string>
<key>spriteSourceSize</key>
<string>{512,512}</string>
<key>textureRect</key>
<string>{{1,1},{512,512}}</string>
<key>textureRotated</key>
<false/>
<key>triangles</key>
<string>2 3 4 2 4 5 1 2 5 1 5 6 0 1 6</string>
<key>vertices</key>
<string>512 54 321 171 172 320 99 512 0 512 0 0 512 0</string>
<key>verticesUV</key>
<string>513 55 322 172 173 321 100 513 1 513 1 1 513 1</string>
</dict>
</dict>
<key>metadata</key>
<dict>
<key>format</key>
<integer>3</integer>
<key>pixelFormat</key>
<string>RGBA8888</string>
<key>premultiplyAlpha</key>
<false/>
<key>realTextureFileName</key>
<string>issue_17119.png</string>
<key>size</key>
<string>{514,620}</string>
<key>smartupdate</key>
<string>$TexturePacker:SmartUpdate:4b00c1e9acb2f5b1804fe6d0b9da063c:8827ba6ff25dd56e8008db6ab418b2fa:96fb3d46aab20ec9eb9704de1ab972b6$</string>
<key>textureFileName</key>
<string>issue_17119.png</string>
</dict>
</dict>
</plist>

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB