diff --git a/cocos/ui/UIScale9Sprite.cpp b/cocos/ui/UIScale9Sprite.cpp index aef00adf7a..914265a84f 100644 --- a/cocos/ui/UIScale9Sprite.cpp +++ b/cocos/ui/UIScale9Sprite.cpp @@ -454,6 +454,7 @@ namespace ui { _spriteFrameRotated = rotated; _originalSize = size; _preferredSize = size; + _offset = offset; _capInsetsInternal = capInsets; @@ -503,23 +504,31 @@ namespace ui { auto capInsets = CC_RECT_POINTS_TO_PIXELS(_capInsetsInternal); auto textureRect = CC_RECT_POINTS_TO_PIXELS(_spriteRect); - auto spriteRectSize = CC_SIZE_POINTS_TO_PIXELS(_originalSize); + auto spriteRectSize = _spriteRect.size; + auto originalSize = CC_SIZE_POINTS_TO_PIXELS(_originalSize); + auto offset = CC_POINT_POINTS_TO_PIXELS(_offset); + + Vec4 offsets; + offsets.x = offset.x + (originalSize.width - textureRect.size.width) / 2; + offsets.w = offset.y + (originalSize.height - textureRect.size.height) / 2; + offsets.z = originalSize.width - textureRect.size.width - offsets.x; + offsets.y = originalSize.height - textureRect.size.height - offsets.w; //handle .9.png if (_isPatch9) { - spriteRectSize = Size(spriteRectSize.width - 2, spriteRectSize.height-2); + originalSize = Size(originalSize.width - 2, originalSize.height-2); } if(capInsets.equals(Rect::ZERO)) { - capInsets = Rect(spriteRectSize.width/3, spriteRectSize.height/3, - spriteRectSize.width/3, spriteRectSize.height/3); + capInsets = Rect(originalSize.width/3, originalSize.height/3, + originalSize.width/3, originalSize.height/3); } - auto uv = this->calculateUV(tex, capInsets, spriteRectSize); - auto vertices = this->calculateVertices(capInsets, spriteRectSize); + auto uv = this->calculateUV(tex, capInsets, originalSize, offsets); + auto vertices = this->calculateVertices(capInsets, originalSize, offsets); auto triangles = this->calculateTriangles(uv, vertices); _scale9Image->getPolygonInfo().setTriangles(triangles); @@ -633,7 +642,7 @@ namespace ui { this->updateWithSprite(this->_scale9Image, _spriteRect, _spriteFrameRotated, - Vec2::ZERO, + _offset, _originalSize, capInsets); this->_insetLeft = capInsets.origin.x; @@ -1062,7 +1071,8 @@ namespace ui { // u0 u1 u2 u3 std::vector Scale9Sprite::calculateUV(Texture2D *tex, const Rect& capInsets, - const Size& spriteRectSize) + const Size& originalSize, + const Vec4& offsets) { auto atlasWidth = tex->getPixelsWide(); auto atlasHeight = tex->getPixelsHigh(); @@ -1073,23 +1083,46 @@ namespace ui { if (_spriteFrameRotated) { - rightWidth = capInsets.origin.y; + rightWidth = capInsets.origin.y - offsets.y; centerWidth = capInsets.size.height; - leftWidth = spriteRectSize.height - centerWidth - rightWidth; + leftWidth = originalSize.height - centerWidth - capInsets.origin.y - offsets.w; - topHeight = capInsets.origin.x; + topHeight = capInsets.origin.x - offsets.x; centerHeight = capInsets.size.width; - bottomHeight = spriteRectSize.width - (topHeight + centerHeight); + bottomHeight = originalSize.width - (capInsets.origin.x + centerHeight) - offsets.z; } else { - leftWidth = capInsets.origin.x; + leftWidth = capInsets.origin.x - offsets.x; centerWidth = capInsets.size.width; - rightWidth = spriteRectSize.width - (leftWidth + centerWidth); + rightWidth = originalSize.width - (capInsets.origin.x + centerWidth) - offsets.z; - topHeight = capInsets.origin.y; + topHeight = capInsets.origin.y - offsets.y; centerHeight = capInsets.size.height; - bottomHeight =spriteRectSize.height - (topHeight + centerHeight); + bottomHeight = originalSize.height - (capInsets.origin.y + centerHeight) - offsets.w; + } + + + if(leftWidth<0) + { + centerWidth += leftWidth; + leftWidth = 0; + } + if(rightWidth<0) + { + centerWidth += rightWidth; + rightWidth = 0; + } + + if(topHeight<0) + { + centerHeight += topHeight; + topHeight = 0; + } + if(bottomHeight<0) + { + centerHeight += bottomHeight; + bottomHeight = 0; } auto textureRect = CC_RECT_POINTS_TO_PIXELS(_spriteRect); @@ -1159,67 +1192,111 @@ namespace ui { //x0,y0-------------------- // x1 x2 x3 std::vector Scale9Sprite::calculateVertices(const Rect& capInsets, - const Size& spriteRectSize) + const Size& originalSize, + const Vec4& offsets) { - float leftWidth = 0, centerWidth = 0, rightWidth = 0; - float topHeight = 0, centerHeight = 0, bottomHeight = 0; - - leftWidth = capInsets.origin.x; - centerWidth = capInsets.size.width; - rightWidth = spriteRectSize.width - (leftWidth + centerWidth); - - topHeight = capInsets.origin.y; - centerHeight = capInsets.size.height; - bottomHeight = spriteRectSize.height - (topHeight + centerHeight); - - - leftWidth = leftWidth / CC_CONTENT_SCALE_FACTOR(); - rightWidth = rightWidth / CC_CONTENT_SCALE_FACTOR(); - topHeight = topHeight / CC_CONTENT_SCALE_FACTOR(); - bottomHeight = bottomHeight / CC_CONTENT_SCALE_FACTOR(); - float sizableWidth = _preferredSize.width - leftWidth - rightWidth; - float sizableHeight = _preferredSize.height - topHeight - bottomHeight; - float x0,x1,x2,x3; - float y0,y1,y2,y3; - if(sizableWidth >= 0) - { - x0 = 0; - x1 = leftWidth; - x2 = leftWidth + sizableWidth; - x3 = _preferredSize.width; - } - else - { - float xScale = _preferredSize.width / (leftWidth + rightWidth); - x0 = 0; - x1 = x2 = leftWidth * xScale; - x3 = (leftWidth + rightWidth) * xScale; - } - - if(sizableHeight >= 0) - { - y0 = 0; - y1 = bottomHeight; - y2 = bottomHeight + sizableHeight; - y3 = _preferredSize.height; - } - else - { - float yScale = _preferredSize.height / (topHeight + bottomHeight); - y0 = 0; - y1 = y2= bottomHeight * yScale; - y3 = (bottomHeight + topHeight) * yScale; - } - - std::vector vertices; + float offsetLeft = offsets.x / CC_CONTENT_SCALE_FACTOR(); + float offsetTop = offsets.y / CC_CONTENT_SCALE_FACTOR(); + float offsetRight = offsets.z / CC_CONTENT_SCALE_FACTOR(); + float offsetBottom = offsets.w / CC_CONTENT_SCALE_FACTOR(); + + std::vector vertices; if (_renderingType == RenderingType::SIMPLE) { - vertices = {Vec2(x0,y0), Vec2(x3,y3)}; + float hScale = _preferredSize.width / (originalSize.width / CC_CONTENT_SCALE_FACTOR()); + float vScale = _preferredSize.height / (originalSize.height / CC_CONTENT_SCALE_FACTOR()); + + vertices = {Vec2(offsetLeft * hScale, offsetBottom * vScale), + Vec2(_preferredSize.width - offsetRight * hScale, _preferredSize.height - offsetTop * vScale)}; } else { - vertices = {Vec2(x0,y0), Vec2(x1,y1), Vec2(x2,y2), Vec2(x3,y3)}; + float leftWidth = 0, centerWidth = 0, rightWidth = 0; + float topHeight = 0, centerHeight = 0, bottomHeight = 0; + + leftWidth = capInsets.origin.x; + centerWidth = capInsets.size.width; + rightWidth = originalSize.width - (leftWidth + centerWidth); + + topHeight = capInsets.origin.y; + centerHeight = capInsets.size.height; + bottomHeight = originalSize.height - (topHeight + centerHeight); + + leftWidth = leftWidth / CC_CONTENT_SCALE_FACTOR(); + rightWidth = rightWidth / CC_CONTENT_SCALE_FACTOR(); + centerWidth = centerWidth / CC_CONTENT_SCALE_FACTOR(); + topHeight = topHeight / CC_CONTENT_SCALE_FACTOR(); + bottomHeight = bottomHeight / CC_CONTENT_SCALE_FACTOR(); + centerHeight = centerHeight / CC_CONTENT_SCALE_FACTOR(); + + float sizableWidth = _preferredSize.width - leftWidth - rightWidth; + float sizableHeight = _preferredSize.height - topHeight - bottomHeight; + + leftWidth -= offsetLeft; + rightWidth -= offsetRight; + topHeight -= offsetTop; + bottomHeight -= offsetBottom; + + float hScale = sizableWidth / centerWidth; + float vScale = sizableHeight / centerHeight; + + if(leftWidth<0) + { + offsetLeft -= leftWidth * (hScale - 1.0f); + sizableWidth += leftWidth * hScale; + leftWidth = 0; + } + if(rightWidth<0) + { + sizableWidth += rightWidth * hScale; + rightWidth = 0; + } + if(topHeight<0) + { + sizableHeight += topHeight * vScale; + topHeight = 0; + } + if(bottomHeight<0) + { + offsetBottom -= bottomHeight * (vScale - 1.0f); + sizableHeight += bottomHeight * vScale; + bottomHeight = 0; + } + + float x0,x1,x2,x3; + float y0,y1,y2,y3; + if(sizableWidth >= 0) + { + x0 = offsetLeft; + x1 = x0 + leftWidth; + x2 = x1 + sizableWidth; + x3 = x2 + rightWidth; + } + else + { + float xScale = _preferredSize.width / (leftWidth + rightWidth); + x0 = offsetLeft; + x1 = x2 = offsetLeft + leftWidth * xScale; + x3 = x2 + rightWidth * xScale; + } + + if(sizableHeight >= 0) + { + y0 = offsetBottom; + y1 = y0 + bottomHeight; + y2 = y1 + sizableHeight; + y3 = y2 + topHeight; + } + else + { + float yScale = _preferredSize.height / (topHeight + bottomHeight); + y0 = offsetBottom; + y1 = y2 = y0 + bottomHeight * yScale; + y3 = y2 + topHeight * yScale; + } + + vertices = {Vec2(x0,y0), Vec2(x1,y1), Vec2(x2,y2), Vec2(x3,y3)}; } return vertices; } diff --git a/cocos/ui/UIScale9Sprite.h b/cocos/ui/UIScale9Sprite.h index 4404ac9a64..1dc5d851e9 100644 --- a/cocos/ui/UIScale9Sprite.h +++ b/cocos/ui/UIScale9Sprite.h @@ -685,8 +685,8 @@ namespace ui { void applyBlendFunc(); void updateBlendFunc(Texture2D *texture); std::vector calculateUV(Texture2D *tex, const Rect& capInsets, - const Size& spriteRectSize); - std::vector calculateVertices(const Rect& capInsets, const Size& spriteRectSize); + const Size& originalSize, const Vec4& offsets); + std::vector calculateVertices(const Rect& capInsets, const Size& originalSize, const Vec4& offsets); TrianglesCommand::Triangles calculateTriangles(const std::vector& uv, const std::vector& vertices); @@ -701,6 +701,7 @@ namespace ui { /** Original sprite's size. */ Size _originalSize; + Vec2 _offset; /** Preferred sprite's size. By default the preferred size is the original size. */ //if the preferredSize component is given as -1, it is ignored diff --git a/tests/cpp-tests/Classes/UITest/CocoStudioGUITest/UIScale9SpriteTest.cpp b/tests/cpp-tests/Classes/UITest/CocoStudioGUITest/UIScale9SpriteTest.cpp index 4357efc8ef..dd5628d656 100644 --- a/tests/cpp-tests/Classes/UITest/CocoStudioGUITest/UIScale9SpriteTest.cpp +++ b/tests/cpp-tests/Classes/UITest/CocoStudioGUITest/UIScale9SpriteTest.cpp @@ -38,6 +38,8 @@ UIScale9SpriteTests::UIScale9SpriteTests() ADD_TEST_CASE(UIS9FrameNameSpriteSheetRotated); ADD_TEST_CASE(UIS9FrameNameSpriteSheetCropped); ADD_TEST_CASE(UIS9FrameNameSpriteSheetCroppedRotated); + ADD_TEST_CASE(UIS9FrameNameSpriteSheetCroppedSimple); + ADD_TEST_CASE(UIS9FrameNameSpriteSheetCroppedRotatedSimple); ADD_TEST_CASE(UIS9BatchNodeScaledNoInsets); ADD_TEST_CASE(UIS9FrameNameSpriteSheetScaledNoInsets); ADD_TEST_CASE(UIS9FrameNameSpriteSheetRotatedScaledNoInsets); @@ -330,6 +332,8 @@ bool UIS9FrameNameSpriteSheetRotated::init() auto blocks = ui::Scale9Sprite::createWithSpriteFrameName("blocks9r.png"); + blocks->setPreferredSize(Size(400,80)); + blocks->setPosition(Vec2(x, y)); this->addChild(blocks); @@ -350,11 +354,15 @@ bool UIS9FrameNameSpriteSheetCropped::init() SpriteFrameCache::getInstance()->addSpriteFramesWithFile(s_s9s_blocks9_plist); auto blocks = ui::Scale9Sprite::createWithSpriteFrameName("blocks9c.png"); - blocks->setRenderingType(Scale9Sprite::RenderingType::SIMPLE); - blocks->setPosition(Vec2(x, y)); - blocks->setCapInsets(Rect(5,5,5,5)); + blocks->setPreferredSize(Size(400,80)); + blocks->setPosition(Vec2(x, y + 45)); this->addChild(blocks); + auto blocks2 = ui::Scale9Sprite::create("Images/blocks9c.png"); + blocks2->setPreferredSize(Size(400,80)); + blocks2->setPosition(Vec2(x, y - 45)); + this->addChild(blocks2); + return true; } @@ -371,11 +379,67 @@ bool UIS9FrameNameSpriteSheetCroppedRotated::init() SpriteFrameCache::getInstance()->addSpriteFramesWithFile(s_s9s_blocks9_plist); auto blocks = ui::Scale9Sprite::createWithSpriteFrameName("blocks9cr.png"); - blocks->setRenderingType(Scale9Sprite::RenderingType::SIMPLE); - blocks->setPosition(Vec2(x, y)); - blocks->setInsetBottom(10); + blocks->setPreferredSize(Size(400,80)); + blocks->setPosition(Vec2(x, y + 45)); this->addChild(blocks); + auto blocks2 = ui::Scale9Sprite::create("Images/blocks9cr.png"); + blocks2->setPreferredSize(Size(400,80)); + blocks2->setPosition(Vec2(x, y - 45)); + this->addChild(blocks2); + + return true; + } + + return false; +} + +bool UIS9FrameNameSpriteSheetCroppedSimple::init() +{ + if (UIScene::init()) { + auto winSize = Director::getInstance()->getWinSize(); + float x = winSize.width / 2; + float y = 0 + (winSize.height / 2); + + SpriteFrameCache::getInstance()->addSpriteFramesWithFile(s_s9s_blocks9_plist); + + auto blocks = ui::Scale9Sprite::createWithSpriteFrameName("blocks9c.png"); + blocks->setRenderingType(Scale9Sprite::RenderingType::SIMPLE); + blocks->setPreferredSize(Size(400,80)); + blocks->setPosition(Vec2(x, y + 45)); + this->addChild(blocks); + + auto blocksSprite = Sprite::createWithSpriteFrameName("blocks9c.png"); + blocksSprite->setScale(400/blocksSprite->getContentSize().width, 80/blocksSprite->getContentSize().height); + blocksSprite->setPosition(Vec2(x, y - 45)); + this->addChild(blocksSprite); + + return true; + } + + return false; +} + +bool UIS9FrameNameSpriteSheetCroppedRotatedSimple::init() +{ + if (UIScene::init()) { + auto winSize = Director::getInstance()->getWinSize(); + float x = winSize.width / 2; + float y = 0 + (winSize.height / 2); + + SpriteFrameCache::getInstance()->addSpriteFramesWithFile(s_s9s_blocks9_plist); + + auto blocks = ui::Scale9Sprite::createWithSpriteFrameName("blocks9cr.png"); + blocks->setRenderingType(Scale9Sprite::RenderingType::SIMPLE); + blocks->setPreferredSize(Size(400,80)); + blocks->setPosition(Vec2(x, y + 45)); + this->addChild(blocks); + + auto blocksSprite = Sprite::createWithSpriteFrameName("blocks9cr.png"); + blocksSprite->setScale(400/blocksSprite->getContentSize().width, 80/blocksSprite->getContentSize().height); + blocksSprite->setPosition(Vec2(x, y - 45)); + this->addChild(blocksSprite); + return true; } diff --git a/tests/cpp-tests/Classes/UITest/CocoStudioGUITest/UIScale9SpriteTest.h b/tests/cpp-tests/Classes/UITest/CocoStudioGUITest/UIScale9SpriteTest.h index 66e6d238df..11042a7990 100644 --- a/tests/cpp-tests/Classes/UITest/CocoStudioGUITest/UIScale9SpriteTest.h +++ b/tests/cpp-tests/Classes/UITest/CocoStudioGUITest/UIScale9SpriteTest.h @@ -91,6 +91,27 @@ public: virtual bool init() override; }; +// S9FrameNameSpriteSheetCroppedSimple + +class UIS9FrameNameSpriteSheetCroppedSimple : public UIScene +{ +public: + CREATE_FUNC(UIS9FrameNameSpriteSheetCroppedSimple); + + virtual bool init() override; +}; + +// S9FrameNameSpriteSheetCroppedRotatedSimple + +class UIS9FrameNameSpriteSheetCroppedRotatedSimple : public UIScene +{ +public: + CREATE_FUNC(UIS9FrameNameSpriteSheetCroppedRotatedSimple); + + virtual bool init() override; +}; + + // S9FrameNameSpriteSheetCropped class UIS9FrameNameSpriteSheetCropped : public UIScene diff --git a/tests/cpp-tests/Resources/Images/blocks9c.png b/tests/cpp-tests/Resources/Images/blocks9c.png new file mode 100644 index 0000000000..39674a445c Binary files /dev/null and b/tests/cpp-tests/Resources/Images/blocks9c.png differ diff --git a/tests/cpp-tests/Resources/Images/blocks9cr.png b/tests/cpp-tests/Resources/Images/blocks9cr.png new file mode 100644 index 0000000000..beea86d7f8 Binary files /dev/null and b/tests/cpp-tests/Resources/Images/blocks9cr.png differ diff --git a/tests/cpp-tests/Resources/Images/blocks9ss.plist b/tests/cpp-tests/Resources/Images/blocks9ss.plist index 2cc9ac518e..07f3083a4a 100755 --- a/tests/cpp-tests/Resources/Images/blocks9ss.plist +++ b/tests/cpp-tests/Resources/Images/blocks9ss.plist @@ -33,28 +33,28 @@ blocks9c.png frame - {{103,189},{50,60}} + {{101,197},{58, 48}} offset - {13,18} + {15, -20} rotated sourceColorRect - {{0,0},{192,192}} + {{34, 44}, {58, 48}} sourceSize - {96,96} + {96, 96} blocks9cr.png frame - {{103,91},{50,60}} + {{71,89},{58, 48}} offset - {13,18} + {15, -20} rotated sourceColorRect - {{0,0},{96,96}} + {{34, 44}, {58, 48}} sourceSize - {96,96} + {96, 96} grossini_dance_01.png diff --git a/tests/cpp-tests/Resources/hd/Images/blocks9c.png b/tests/cpp-tests/Resources/hd/Images/blocks9c.png new file mode 100644 index 0000000000..2dca858356 Binary files /dev/null and b/tests/cpp-tests/Resources/hd/Images/blocks9c.png differ diff --git a/tests/cpp-tests/Resources/hd/Images/blocks9cr.png b/tests/cpp-tests/Resources/hd/Images/blocks9cr.png new file mode 100644 index 0000000000..74fc6c8b01 Binary files /dev/null and b/tests/cpp-tests/Resources/hd/Images/blocks9cr.png differ diff --git a/tests/cpp-tests/Resources/hd/Images/blocks9r.png b/tests/cpp-tests/Resources/hd/Images/blocks9r.png new file mode 100644 index 0000000000..79c0c94604 Binary files /dev/null and b/tests/cpp-tests/Resources/hd/Images/blocks9r.png differ diff --git a/tests/cpp-tests/Resources/hd/Images/blocks9ss.plist b/tests/cpp-tests/Resources/hd/Images/blocks9ss.plist index 9f77a49011..4548217df5 100755 --- a/tests/cpp-tests/Resources/hd/Images/blocks9ss.plist +++ b/tests/cpp-tests/Resources/hd/Images/blocks9ss.plist @@ -33,28 +33,28 @@ blocks9c.png frame - {{204,374},{100,120}} + {{197,388}, {122, 102}} offset - {26,36} + {30, -41} rotated sourceColorRect - {{0,0},{192,192}} + {{65, 86}, {122, 102}} sourceSize - {192,192} + {192, 192} blocks9cr.png frame - {{204,180},{100,120}} + {{136,173}, {122, 102}} offset - {26,36} + {30, -41} rotated sourceColorRect - {{0,0},{192,192}} + {{65, 86}, {122, 102}} sourceSize - {192,192} + {192, 192} grossini_dance_01.png