mirror of https://github.com/axmolengine/axmol.git
Merge pull request #11946 from andyque/v3-final-android-9-patch-feature
add Android 9-patch image format support
This commit is contained in:
commit
d5d329b74f
|
@ -1190,6 +1190,10 @@
|
|||
1AC0269D1914068200FA920D /* ConvertUTF.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AC026991914068200FA920D /* ConvertUTF.h */; };
|
||||
29031E0719BFE8D400EFA1DF /* libchipmunk.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 29031E0619BFE8D400EFA1DF /* libchipmunk.a */; };
|
||||
29031E0919BFE8DE00EFA1DF /* libchipmunk.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 29031E0819BFE8DE00EFA1DF /* libchipmunk.a */; };
|
||||
291901431B05895600F8B4BA /* CCNinePatchImageParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 291901411B05895600F8B4BA /* CCNinePatchImageParser.h */; };
|
||||
291901441B05895600F8B4BA /* CCNinePatchImageParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 291901411B05895600F8B4BA /* CCNinePatchImageParser.h */; };
|
||||
291901451B05895600F8B4BA /* CCNinePatchImageParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 291901421B05895600F8B4BA /* CCNinePatchImageParser.cpp */; };
|
||||
291901461B05895600F8B4BA /* CCNinePatchImageParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 291901421B05895600F8B4BA /* CCNinePatchImageParser.cpp */; };
|
||||
292DB13D19B4574100A80320 /* UIEditBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 292DB12F19B4574100A80320 /* UIEditBox.cpp */; };
|
||||
292DB13E19B4574100A80320 /* UIEditBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 292DB12F19B4574100A80320 /* UIEditBox.cpp */; };
|
||||
292DB13F19B4574100A80320 /* UIEditBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 292DB13019B4574100A80320 /* UIEditBox.h */; };
|
||||
|
@ -3921,6 +3925,8 @@
|
|||
2905FA1318CF08D100240AA3 /* UIWidget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UIWidget.cpp; sourceTree = "<group>"; };
|
||||
2905FA1418CF08D100240AA3 /* UIWidget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIWidget.h; sourceTree = "<group>"; };
|
||||
29080DEB191B82CE0066F8DF /* UIDeprecated.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UIDeprecated.h; sourceTree = "<group>"; };
|
||||
291901411B05895600F8B4BA /* CCNinePatchImageParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CCNinePatchImageParser.h; path = ../base/CCNinePatchImageParser.h; sourceTree = "<group>"; };
|
||||
291901421B05895600F8B4BA /* CCNinePatchImageParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CCNinePatchImageParser.cpp; path = ../base/CCNinePatchImageParser.cpp; sourceTree = "<group>"; };
|
||||
292DB12F19B4574100A80320 /* UIEditBox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UIEditBox.cpp; sourceTree = "<group>"; };
|
||||
292DB13019B4574100A80320 /* UIEditBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIEditBox.h; sourceTree = "<group>"; };
|
||||
292DB13119B4574100A80320 /* UIEditBoxImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIEditBoxImpl.h; sourceTree = "<group>"; };
|
||||
|
@ -5620,6 +5626,8 @@
|
|||
1A5700A2180BC5E60088DEC7 /* base */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
291901411B05895600F8B4BA /* CCNinePatchImageParser.h */,
|
||||
291901421B05895600F8B4BA /* CCNinePatchImageParser.cpp */,
|
||||
505385001B01887A00793096 /* CCProperties.h */,
|
||||
505385011B01887A00793096 /* CCProperties.cpp */,
|
||||
B63990CA1A490AFE00B07923 /* CCAsyncTaskPool.cpp */,
|
||||
|
@ -9408,6 +9416,7 @@
|
|||
50ABBE211925AB6F00A911A9 /* atitc.h in Headers */,
|
||||
15AE19A519AAD39600C27E9E /* TextFieldReader.h in Headers */,
|
||||
B665E3401AA80A6500DDB1C5 /* CCPUOnEventFlagObserverTranslator.h in Headers */,
|
||||
291901431B05895600F8B4BA /* CCNinePatchImageParser.h in Headers */,
|
||||
B24AA98B195A675C007B4522 /* CCFastTMXTiledMap.h in Headers */,
|
||||
B665E3A01AA80A6500DDB1C5 /* CCPUPositionEmitter.h in Headers */,
|
||||
B29594B61926D5EC003EEF37 /* CCMeshCommand.h in Headers */,
|
||||
|
@ -10210,6 +10219,7 @@
|
|||
50ABBE481925AB6F00A911A9 /* CCEvent.h in Headers */,
|
||||
5027253B190BF1B900AAF4ED /* cocos2d.h in Headers */,
|
||||
15AE1A9719AAD40300C27E9E /* b2Draw.h in Headers */,
|
||||
291901441B05895600F8B4BA /* CCNinePatchImageParser.h in Headers */,
|
||||
3E6176691960F89B00DE83F5 /* CCController.h in Headers */,
|
||||
B6CAB43E1AF9AA1A00B9B856 /* btGpuDefines.h in Headers */,
|
||||
3823841D1A2590D2002C4610 /* ComAudioReader.h in Headers */,
|
||||
|
@ -10682,6 +10692,7 @@
|
|||
50ED2BD919BE5D5D00A0AB90 /* CCEventListenerController.cpp in Sources */,
|
||||
B665E2321AA80A6500DDB1C5 /* CCPUBoxEmitter.cpp in Sources */,
|
||||
B257B460198A353E00D9A687 /* CCPrimitiveCommand.cpp in Sources */,
|
||||
291901451B05895600F8B4BA /* CCNinePatchImageParser.cpp in Sources */,
|
||||
15AE19A419AAD39600C27E9E /* TextFieldReader.cpp in Sources */,
|
||||
50ED2BDB19BE76D500A0AB90 /* UIVideoPlayer-ios.mm in Sources */,
|
||||
B665E32A1AA80A6500DDB1C5 /* CCPUOnCountObserver.cpp in Sources */,
|
||||
|
@ -11642,6 +11653,7 @@
|
|||
15AE19AA19AAD39700C27E9E /* ListViewReader.cpp in Sources */,
|
||||
1A5701C8180BCB5A0088DEC7 /* CCLabelTextFormatter.cpp in Sources */,
|
||||
1A5701CC180BCB5A0088DEC7 /* CCLabelTTF.cpp in Sources */,
|
||||
291901461B05895600F8B4BA /* CCNinePatchImageParser.cpp in Sources */,
|
||||
B665E39B1AA80A6500DDB1C5 /* CCPUPointEmitterTranslator.cpp in Sources */,
|
||||
382384291A2590F9002C4610 /* NodeReader.cpp in Sources */,
|
||||
15AE193419AAD35100C27E9E /* CCActionObject.cpp in Sources */,
|
||||
|
|
|
@ -993,6 +993,10 @@ bool Sprite::isFrameDisplayed(SpriteFrame *frame) const
|
|||
|
||||
SpriteFrame* Sprite::getSpriteFrame() const
|
||||
{
|
||||
if(nullptr != this->_spriteFrame)
|
||||
{
|
||||
return this->_spriteFrame;
|
||||
}
|
||||
return SpriteFrame::createWithTexture(_texture,
|
||||
CC_RECT_POINTS_TO_PIXELS(_rect),
|
||||
_rectRotated,
|
||||
|
|
|
@ -39,7 +39,7 @@ THE SOFTWARE.
|
|||
#include "base/CCDirector.h"
|
||||
#include "renderer/CCTexture2D.h"
|
||||
#include "renderer/CCTextureCache.h"
|
||||
|
||||
#include "base/CCNinePatchImageParser.h"
|
||||
|
||||
#include "deprecated/CCString.h"
|
||||
|
||||
|
@ -104,6 +104,10 @@ void SpriteFrameCache::addSpriteFramesWithDictionary(ValueMap& dictionary, Textu
|
|||
// check the format
|
||||
CCASSERT(format >=0 && format <= 3, "format is not supported for SpriteFrameCache addSpriteFramesWithDictionary:textureFilename:");
|
||||
|
||||
auto textureFileName = Director::getInstance()->getTextureCache()->getTextureFilePath(texture);
|
||||
auto image = new Image();
|
||||
image->initWithImageFile(textureFileName);
|
||||
NinePatchImageParser parser(image);
|
||||
for (auto iter = framesDict.begin(); iter != framesDict.end(); ++iter)
|
||||
{
|
||||
ValueMap& frameDict = iter->second.asValueMap();
|
||||
|
@ -183,7 +187,7 @@ void SpriteFrameCache::addSpriteFramesWithDictionary(ValueMap& dictionary, Textu
|
|||
|
||||
_spriteFramesAliases[oneAlias] = Value(spriteFrameName);
|
||||
}
|
||||
|
||||
|
||||
// create frame
|
||||
spriteFrame = SpriteFrame::createWithTexture(texture,
|
||||
Rect(textureRect.origin.x, textureRect.origin.y, spriteSize.width, spriteSize.height),
|
||||
|
@ -192,9 +196,16 @@ void SpriteFrameCache::addSpriteFramesWithDictionary(ValueMap& dictionary, Textu
|
|||
spriteSourceSize);
|
||||
}
|
||||
|
||||
bool flag = NinePatchImageParser::isNinePatchImage(spriteFrameName);
|
||||
if(flag)
|
||||
{
|
||||
parser.setSpriteFrameInfo(spriteFrame->getRectInPixels(), spriteFrame->isRotated());
|
||||
texture->addSpriteFrameCapInset(spriteFrame, parser.parseCapInset());
|
||||
}
|
||||
// add sprite frame
|
||||
_spriteFrames.insert(spriteFrameName, spriteFrame);
|
||||
}
|
||||
CC_SAFE_DELETE(image);
|
||||
}
|
||||
|
||||
void SpriteFrameCache::addSpriteFramesWithFile(const std::string& plist, Texture2D *texture)
|
||||
|
@ -327,13 +338,14 @@ void SpriteFrameCache::removeUnusedSpriteFrames()
|
|||
if( spriteFrame->getReferenceCount() == 1 )
|
||||
{
|
||||
toRemoveFrames.push_back(iter->first);
|
||||
spriteFrame->getTexture()->removeSpriteFrameCapInset(spriteFrame);
|
||||
CCLOG("cocos2d: SpriteFrameCache: removing unused frame: %s", iter->first.c_str());
|
||||
removed = true;
|
||||
}
|
||||
}
|
||||
|
||||
_spriteFrames.erase(toRemoveFrames);
|
||||
|
||||
|
||||
// FIXME:. Since we don't know the .plist file that originated the frame, we must remove all .plist from the cache
|
||||
if( removed )
|
||||
{
|
||||
|
|
|
@ -432,6 +432,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\chipmunk\prebuilt\win32\release-lib\*.*
|
|||
<ClCompile Include="..\base\CCEventTouch.cpp" />
|
||||
<ClCompile Include="..\base\ccFPSImages.c" />
|
||||
<ClCompile Include="..\base\CCIMEDispatcher.cpp" />
|
||||
<ClCompile Include="..\base\CCNinePatchImageParser.cpp" />
|
||||
<ClCompile Include="..\base\CCNS.cpp" />
|
||||
<ClCompile Include="..\base\CCProfiling.cpp" />
|
||||
<ClCompile Include="..\base\CCProperties.cpp" />
|
||||
|
@ -995,6 +996,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\chipmunk\prebuilt\win32\release-lib\*.*
|
|||
<ClInclude Include="..\base\CCIMEDispatcher.h" />
|
||||
<ClInclude Include="..\base\ccMacros.h" />
|
||||
<ClInclude Include="..\base\CCMap.h" />
|
||||
<ClInclude Include="..\base\CCNinePatchImageParser.h" />
|
||||
<ClInclude Include="..\base\CCNS.h" />
|
||||
<ClInclude Include="..\base\CCProfiling.h" />
|
||||
<ClInclude Include="..\base\CCProperties.h" />
|
||||
|
|
|
@ -1872,6 +1872,9 @@
|
|||
<ClCompile Include="..\renderer\CCVertexAttribBinding.cpp">
|
||||
<Filter>renderer</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\base\CCNinePatchImageParser.cpp">
|
||||
<Filter>base</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\physics\CCPhysicsBody.h">
|
||||
|
@ -3662,6 +3665,9 @@
|
|||
<ClInclude Include="..\renderer\CCVertexAttribBinding.h">
|
||||
<Filter>renderer</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\base\CCNinePatchImageParser.h">
|
||||
<Filter>base</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\math\Mat4.inl">
|
||||
|
|
|
@ -285,6 +285,7 @@
|
|||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCIMEDispatcher.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\ccMacros.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCMap.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCNinePatchImageParser.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCNS.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCProfiling.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCProperties.h" />
|
||||
|
@ -898,6 +899,7 @@
|
|||
</ForcedIncludeFiles>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCIMEDispatcher.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCNinePatchImageParser.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCNS.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCProfiling.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCProperties.cpp" />
|
||||
|
|
|
@ -103,6 +103,7 @@ math/TransformUtils.cpp \
|
|||
math/Vec2.cpp \
|
||||
math/Vec3.cpp \
|
||||
math/Vec4.cpp \
|
||||
base/CCNinePatchImageParser.cpp \
|
||||
base/CCAsyncTaskPool.cpp \
|
||||
base/CCAutoreleasePool.cpp \
|
||||
base/CCConfiguration.cpp \
|
||||
|
|
|
@ -0,0 +1,208 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2013-2015 Chukong Technologies Inc.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
#include "CCNinePatchImageParser.h"
|
||||
#include "platform/CCImage.h"
|
||||
#include "base/CCDirector.h"
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
NinePatchImageParser::~NinePatchImageParser()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
NinePatchImageParser::NinePatchImageParser(Image* image)
|
||||
{
|
||||
this->_image = image;
|
||||
this->_imageFrame = Rect(0,0,image->getWidth(), image->getHeight());
|
||||
CCASSERT(image->getRenderFormat()==Texture2D::PixelFormat::RGBA8888,
|
||||
"unsupported format, currently only supports rgba8888");
|
||||
this->_isRotated = false;
|
||||
}
|
||||
|
||||
NinePatchImageParser::NinePatchImageParser(Image* image, const Rect& frame, bool rotated)
|
||||
{
|
||||
this->_image = image;
|
||||
CCASSERT(image->getRenderFormat()==Texture2D::PixelFormat::RGBA8888,
|
||||
"unsupported format, currently only supports rgba8888");
|
||||
this->_imageFrame = frame;
|
||||
this->_isRotated = rotated;
|
||||
}
|
||||
|
||||
int NinePatchImageParser::getFrameHeight()const
|
||||
{
|
||||
if (_isRotated)
|
||||
{
|
||||
return _imageFrame.size.width;
|
||||
}
|
||||
return _imageFrame.size.height;
|
||||
}
|
||||
|
||||
int NinePatchImageParser::getFrameWidth()const
|
||||
{
|
||||
if (_isRotated)
|
||||
{
|
||||
return _imageFrame.size.height;
|
||||
}
|
||||
return _imageFrame.size.width;
|
||||
}
|
||||
|
||||
int NinePatchImageParser::getPixelOriginOffset(Direction direction)const
|
||||
{
|
||||
int imageWidth = _image->getWidth();
|
||||
int frameWidth = this->getFrameWidth();
|
||||
|
||||
int topLineLeftOffset = (int)_imageFrame.origin.y * imageWidth * 4 + (int)_imageFrame.origin.x * 4;
|
||||
if(direction == Direction::HORIZONTAL)
|
||||
{
|
||||
return topLineLeftOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(_isRotated)
|
||||
{
|
||||
return topLineLeftOffset + (frameWidth - 1) * 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
return topLineLeftOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vec2 NinePatchImageParser::parseHorizontalMargin()const
|
||||
{
|
||||
unsigned char* data = _image->getData();
|
||||
|
||||
data = data + this->getPixelOriginOffset(Direction::HORIZONTAL);
|
||||
unsigned char lastPixel = *(data + 3);
|
||||
int x1 = 0;
|
||||
int x2 = 0;
|
||||
|
||||
int length = _imageFrame.origin.x + this->getFrameWidth();
|
||||
for(int i = (int)_imageFrame.origin.x; i <= length ; i++)
|
||||
{
|
||||
unsigned char pixel = *(data + (i - (int)_imageFrame.origin.x) * 4 +3);
|
||||
if(pixel != lastPixel)
|
||||
{
|
||||
if (pixel > 0)
|
||||
{
|
||||
x1 = (i - (int)_imageFrame.origin.x);
|
||||
}
|
||||
else
|
||||
{
|
||||
x2 = (i - (int)_imageFrame.origin.x);
|
||||
break;
|
||||
}
|
||||
}
|
||||
lastPixel = pixel;
|
||||
}
|
||||
return Vec2(x1,x2);
|
||||
}
|
||||
|
||||
Vec2 NinePatchImageParser::parseVerticalMargin()const
|
||||
{
|
||||
unsigned char* data = _image->getData();
|
||||
int imageWidth = _image->getWidth();
|
||||
|
||||
int y1 = 0;
|
||||
int y2 = 0;
|
||||
|
||||
data = data + this->getPixelOriginOffset(Direction::VERTICAL);
|
||||
unsigned char lastPixel = *(data + 3);
|
||||
|
||||
int length = (int)(_imageFrame.origin.y + this->getFrameHeight());
|
||||
for(int i = _imageFrame.origin.y; i <= length; i++)
|
||||
{
|
||||
unsigned char pixel = *(data + (i - (int)_imageFrame.origin.y) * imageWidth * 4 + 3);
|
||||
if(pixel != lastPixel)
|
||||
{
|
||||
if(pixel > 0)
|
||||
{
|
||||
y1 = (i - (int)_imageFrame.origin.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
y2 = (i - (int)_imageFrame.origin.y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
lastPixel = pixel;
|
||||
}
|
||||
return Vec2(y1,y2);
|
||||
}
|
||||
|
||||
Rect NinePatchImageParser::parseCapInset() const
|
||||
{
|
||||
Rect capInsets;
|
||||
Vec2 horizontalLine = this->parseHorizontalMargin();
|
||||
Vec2 verticalLine = this->parseVerticalMargin();
|
||||
|
||||
if(_isRotated)
|
||||
{
|
||||
capInsets = Rect(verticalLine.y,
|
||||
_imageFrame.size.height - horizontalLine.y,
|
||||
verticalLine.y - verticalLine.x,
|
||||
horizontalLine.y - horizontalLine.x);
|
||||
}
|
||||
else
|
||||
{
|
||||
capInsets = Rect(horizontalLine.x,
|
||||
verticalLine.x,
|
||||
horizontalLine.y - horizontalLine.x,
|
||||
verticalLine.y - verticalLine.x);
|
||||
}
|
||||
|
||||
capInsets = Rect(capInsets.origin.x / CC_CONTENT_SCALE_FACTOR(),
|
||||
capInsets.origin.y / CC_CONTENT_SCALE_FACTOR(),
|
||||
capInsets.size.width / CC_CONTENT_SCALE_FACTOR(),
|
||||
capInsets.size.height / CC_CONTENT_SCALE_FACTOR());
|
||||
return capInsets;
|
||||
}
|
||||
|
||||
void NinePatchImageParser::setSpriteFrameInfo( const cocos2d::Rect& frameRect, bool rotated )
|
||||
{
|
||||
this->_imageFrame = frameRect;
|
||||
this->_isRotated = rotated;
|
||||
}
|
||||
|
||||
bool NinePatchImageParser::isNinePatchImage(const std::string& filepath)
|
||||
{
|
||||
size_t length = filepath.length();
|
||||
if(length <7 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(filepath.compare(length-6, 6, ".9.png") == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
NS_CC_END
|
|
@ -0,0 +1,114 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2013-2015 Chukong Technologies Inc.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
#include "platform/CCPlatformMacros.h"
|
||||
#include "math/CCGeometry.h"
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
class Image;
|
||||
class SpriteFrame;
|
||||
|
||||
|
||||
/**
|
||||
* A class for paring Android .9 patch image.
|
||||
* For more about Android .9 patch image format, please refer to
|
||||
* http://developer.android.com/tools/help/draw9patch.html
|
||||
*
|
||||
* The class could parse a single .9 patch image and produce the capInsets
|
||||
* as well as a sprite atlas and store all the capInsets infos in a Texture2D.
|
||||
* Note:
|
||||
* - Currently only PixelFormat::RGBA8888 is supported.
|
||||
* - TexturePacker Trim mode is not supported at the moment.
|
||||
*/
|
||||
|
||||
class CC_DLL NinePatchImageParser
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Determines whether a filename contains ".9.png" suffix.
|
||||
* @param filename A 9-patch image name.
|
||||
*
|
||||
* @return If the filename contains ".9.png", then return true, otherwise false.
|
||||
*/
|
||||
static bool isNinePatchImage(const std::string& filename);
|
||||
|
||||
/**
|
||||
* Instantiate a NinePatchImageParser with a Image object.
|
||||
*
|
||||
* @param image A Image object pointer.
|
||||
*
|
||||
* @return A NinePatchImageParser instance.
|
||||
*/
|
||||
NinePatchImageParser(Image* image);
|
||||
|
||||
/**
|
||||
* Instantiate a NinePatchImageParser with a Image object and the spriteFrame info.
|
||||
* The spriteFrame contains the frame rect in the image atlas and whether it
|
||||
* is rotated or not.
|
||||
*
|
||||
* @param image A Image object pointer.
|
||||
* @param frameRect The sprite frame rect in the image atlas.
|
||||
* @param ratated Whether is sprite frame is rotated in the image atlas.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
NinePatchImageParser(Image* image, const Rect& frameRect, bool ratated);
|
||||
|
||||
/**
|
||||
* Change the sprite frame info.
|
||||
* It is useful when parsing multiple sprite frame with only on NinePatchImageParser.
|
||||
*
|
||||
* @param frameRect The sprite frame rect in the image atlas.
|
||||
* @param rotated Whether is sprite frame is rotated in the image atlas.
|
||||
*/
|
||||
void setSpriteFrameInfo(const Rect& frameRect, bool rotated);
|
||||
|
||||
/**
|
||||
* Default destructor.
|
||||
*/
|
||||
virtual ~NinePatchImageParser();
|
||||
|
||||
/**
|
||||
* Parsing the image data and extract the capInsets info.
|
||||
* @return The capInsets Rect.
|
||||
*/
|
||||
Rect parseCapInset()const;
|
||||
private:
|
||||
enum class Direction
|
||||
{
|
||||
HORIZONTAL,
|
||||
VERTICAL
|
||||
};
|
||||
int getPixelOriginOffset(Direction direction)const;
|
||||
Vec2 parseHorizontalMargin()const;
|
||||
Vec2 parseVerticalMargin()const;
|
||||
int getFrameWidth()const;
|
||||
int getFrameHeight()const;
|
||||
|
||||
Image* _image;
|
||||
Rect _imageFrame;
|
||||
bool _isRotated;
|
||||
};
|
||||
|
||||
NS_CC_END
|
|
@ -15,6 +15,7 @@ set(COCOS_BASE_SRC
|
|||
base/CCController.cpp
|
||||
base/CCData.cpp
|
||||
base/CCDataVisitor.cpp
|
||||
base/CCNinePatchImageParser.cpp
|
||||
base/CCDirector.cpp
|
||||
base/CCEvent.cpp
|
||||
base/CCEventAcceleration.cpp
|
||||
|
|
|
@ -45,7 +45,7 @@ THE SOFTWARE.
|
|||
#include "renderer/CCGLProgram.h"
|
||||
#include "renderer/ccGLStateCache.h"
|
||||
#include "renderer/CCGLProgramCache.h"
|
||||
|
||||
#include "base/CCNinePatchImageParser.h"
|
||||
#include "deprecated/CCString.h"
|
||||
|
||||
|
||||
|
@ -435,6 +435,7 @@ Texture2D::Texture2D()
|
|||
, _hasMipmaps(false)
|
||||
, _shaderProgram(nullptr)
|
||||
, _antialiasEnabled(true)
|
||||
, _ninePatchInfo(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -447,6 +448,8 @@ Texture2D::~Texture2D()
|
|||
CCLOGINFO("deallocing Texture2D: %p - id=%u", this, _name);
|
||||
CC_SAFE_RELEASE(_shaderProgram);
|
||||
|
||||
CC_SAFE_DELETE(_ninePatchInfo);
|
||||
|
||||
if(_name)
|
||||
{
|
||||
GL::deleteTexture(_name);
|
||||
|
@ -1393,5 +1396,60 @@ const Texture2D::PixelFormatInfoMap& Texture2D::getPixelFormatInfoMap()
|
|||
return _pixelFormatInfoTables;
|
||||
}
|
||||
|
||||
void Texture2D::addSpriteFrameCapInset(SpriteFrame* spritframe, const Rect& capInsets)
|
||||
{
|
||||
if(nullptr == _ninePatchInfo)
|
||||
{
|
||||
_ninePatchInfo = new NinePatchInfo;
|
||||
}
|
||||
if(nullptr == spritframe)
|
||||
{
|
||||
_ninePatchInfo->capInsetSize = capInsets;
|
||||
}
|
||||
else
|
||||
{
|
||||
_ninePatchInfo->capInsetMap[spritframe] = capInsets;
|
||||
}
|
||||
}
|
||||
|
||||
bool Texture2D::isContain9PatchInfo()const
|
||||
{
|
||||
return nullptr != _ninePatchInfo;
|
||||
}
|
||||
|
||||
const Rect& Texture2D::getSpriteFrameCapInset( cocos2d::SpriteFrame *spriteFrame )const
|
||||
{
|
||||
CCASSERT(_ninePatchInfo != nullptr,
|
||||
"Can't get the sprite frame capInset when the texture contains no 9-patch info.");
|
||||
if(nullptr == spriteFrame)
|
||||
{
|
||||
return this->_ninePatchInfo->capInsetSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto capInsetMap = this->_ninePatchInfo->capInsetMap;
|
||||
if(capInsetMap.find(spriteFrame) != capInsetMap.end())
|
||||
{
|
||||
return capInsetMap.at(spriteFrame);
|
||||
}
|
||||
else
|
||||
{
|
||||
return this->_ninePatchInfo->capInsetSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Texture2D::removeSpriteFrameCapInset(SpriteFrame* spriteFrame)
|
||||
{
|
||||
if(nullptr != this->_ninePatchInfo)
|
||||
{
|
||||
auto capInsetMap = this->_ninePatchInfo->capInsetMap;
|
||||
if(capInsetMap.find(spriteFrame) != capInsetMap.end())
|
||||
{
|
||||
capInsetMap.erase(spriteFrame);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_CC_END
|
||||
|
|
|
@ -29,6 +29,7 @@ THE SOFTWARE.
|
|||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "base/CCRef.h"
|
||||
#include "math/CCGeometry.h"
|
||||
|
@ -40,8 +41,15 @@ THE SOFTWARE.
|
|||
NS_CC_BEGIN
|
||||
|
||||
class Image;
|
||||
class NinePatchInfo;
|
||||
class SpriteFrame;
|
||||
typedef struct _MipmapInfo MipmapInfo;
|
||||
|
||||
namespace ui
|
||||
{
|
||||
class Scale9Sprite;
|
||||
}
|
||||
|
||||
/**
|
||||
* @addtogroup _2d
|
||||
* @{
|
||||
|
@ -309,6 +317,7 @@ public:
|
|||
* @endcode
|
||||
*/
|
||||
void setTexParameters(const TexParams& texParams);
|
||||
|
||||
/**
|
||||
* @js NA
|
||||
* @lua NA
|
||||
|
@ -402,12 +411,55 @@ public:
|
|||
|
||||
/** Get a shader program from the texture.*/
|
||||
GLProgram* getGLProgram() const;
|
||||
|
||||
|
||||
|
||||
public:
|
||||
/** Get pixel info map, the key-value pairs is PixelFormat and PixelFormatInfo.*/
|
||||
static const PixelFormatInfoMap& getPixelFormatInfoMap();
|
||||
|
||||
private:
|
||||
/**
|
||||
* A struct for storing 9-patch image capInsets.
|
||||
*/
|
||||
|
||||
class NinePatchInfo
|
||||
{
|
||||
public:
|
||||
Rect capInsetSize;
|
||||
std::unordered_map<SpriteFrame*, Rect> capInsetMap;
|
||||
};
|
||||
|
||||
/**
|
||||
* Whether the texture contains a 9-patch capInset info or not.
|
||||
*
|
||||
* @return True is Texture contains a 9-patch info, false otherwise.
|
||||
*/
|
||||
bool isContain9PatchInfo()const;
|
||||
|
||||
/**
|
||||
* Get spriteFrame capInset, If spriteFrame can't be found in 9-patch info map,
|
||||
* then single 9-patch texture capInset will be returned.
|
||||
* If the arg is nullptr, the capInset of single 9-patch texture will be returned.
|
||||
*
|
||||
* @param spriteFrame A SpriteFrame object pointer.
|
||||
*
|
||||
* @return The capInset of the SpriteFrame object.
|
||||
*/
|
||||
const Rect& getSpriteFrameCapInset(SpriteFrame* spriteFrame)const;
|
||||
/**
|
||||
* Remove the spriteFrame capInset info when the spriteFrame is removed.
|
||||
*
|
||||
* @param spriteFrame A SpriteFrame object pointer.
|
||||
*/
|
||||
void removeSpriteFrameCapInset(SpriteFrame* spriteFrame);
|
||||
/**
|
||||
* Add capInset for sprite atlas.
|
||||
* When handling single texture, pass nullptr in the first arg.
|
||||
*
|
||||
* @param spritframe The sprite frame object.
|
||||
* @param capInsets The parsed capInset from a .9 patch image.
|
||||
*/
|
||||
void addSpriteFrameCapInset(SpriteFrame* spritframe, const Rect& capInsets);
|
||||
|
||||
/**convert functions*/
|
||||
|
||||
|
@ -490,6 +542,10 @@ protected:
|
|||
static const PixelFormatInfoMap _pixelFormatInfoTables;
|
||||
|
||||
bool _antialiasEnabled;
|
||||
NinePatchInfo* _ninePatchInfo;
|
||||
friend class SpriteFrameCache;
|
||||
friend class TextureCache;
|
||||
friend class ui::Scale9Sprite;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ THE SOFTWARE.
|
|||
#include "base/ccUtils.h"
|
||||
|
||||
#include "deprecated/CCString.h"
|
||||
#include "base/CCNinePatchImageParser.h"
|
||||
|
||||
|
||||
#ifdef EMSCRIPTEN
|
||||
|
@ -275,7 +276,8 @@ void TextureCache::addImageAsyncCallBack(float dt)
|
|||
texture = new (std::nothrow) Texture2D();
|
||||
|
||||
texture->initWithImage(image);
|
||||
|
||||
//parse 9-patch info
|
||||
this->parseNinePatchImage(image, texture, filename);
|
||||
#if CC_ENABLE_CACHE_TEXTURE_DATA
|
||||
// cache the texture file name
|
||||
VolatileTextureMgr::addImageTexture(texture, filename);
|
||||
|
@ -351,6 +353,9 @@ Texture2D * TextureCache::addImage(const std::string &path)
|
|||
#endif
|
||||
// texture already retained, no need to re-retain it
|
||||
_textures.insert( std::make_pair(fullpath, texture) );
|
||||
|
||||
//parse 9-patch info
|
||||
this->parseNinePatchImage(image, texture, path);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -364,6 +369,17 @@ Texture2D * TextureCache::addImage(const std::string &path)
|
|||
return texture;
|
||||
}
|
||||
|
||||
void TextureCache::parseNinePatchImage(cocos2d::Image *image, cocos2d::Texture2D *texture,const std::string& path)
|
||||
{
|
||||
if(NinePatchImageParser::isNinePatchImage(path))
|
||||
{
|
||||
Rect frameRect = Rect(0,0,image->getWidth(), image->getHeight());
|
||||
NinePatchImageParser parser(image, frameRect, false);
|
||||
texture->addSpriteFrameCapInset(nullptr, parser.parseCapInset());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Texture2D* TextureCache::addImage(Image *image, const std::string &key)
|
||||
{
|
||||
CCASSERT(image != nullptr, "TextureCache: image MUST not be nil");
|
||||
|
@ -524,6 +540,19 @@ void TextureCache::reloadAllTextures()
|
|||
// #endif
|
||||
}
|
||||
|
||||
const std::string TextureCache::getTextureFilePath( cocos2d::Texture2D *texture )const
|
||||
{
|
||||
for(auto& item : _textures)
|
||||
{
|
||||
if(item.second == texture)
|
||||
{
|
||||
return item.first;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
void TextureCache::waitForQuit()
|
||||
{
|
||||
// notify sub thread to quick
|
||||
|
|
|
@ -195,10 +195,19 @@ public:
|
|||
/**Called by director, please do not called outside.*/
|
||||
void waitForQuit();
|
||||
|
||||
/**
|
||||
* Get the file path of the texture
|
||||
*
|
||||
* @param texture A Texture2D object pointer.
|
||||
*
|
||||
* @return The full path of the file.
|
||||
*/
|
||||
const std::string getTextureFilePath(Texture2D* texture)const;
|
||||
|
||||
private:
|
||||
void addImageAsyncCallBack(float dt);
|
||||
void loadImage();
|
||||
|
||||
void parseNinePatchImage(Image* image, Texture2D* texture, const std::string& path);
|
||||
public:
|
||||
struct AsyncStruct
|
||||
{
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -742,6 +742,7 @@ namespace ui {
|
|||
|
||||
bool _flippedX;
|
||||
bool _flippedY;
|
||||
bool _isPatch9;
|
||||
};
|
||||
|
||||
}} //end of namespace
|
||||
|
|
|
@ -52,6 +52,7 @@ UIScale9SpriteTests::UIScale9SpriteTests()
|
|||
ADD_TEST_CASE(UIS9ZOrder);
|
||||
ADD_TEST_CASE(UIS9Flip);
|
||||
ADD_TEST_CASE(UIS9ChangeAnchorPoint);
|
||||
ADD_TEST_CASE(UIS9NinePatchTest);
|
||||
}
|
||||
|
||||
// UIScale9SpriteTest
|
||||
|
@ -847,7 +848,54 @@ bool UIS9ChangeAnchorPoint::init()
|
|||
});
|
||||
this->addChild(button2);
|
||||
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool UIS9NinePatchTest::init()
|
||||
{
|
||||
if (UIScene::init()) {
|
||||
SpriteFrameCache::getInstance()->addSpriteFramesWithFile("cocosui/android9patch.plist");
|
||||
|
||||
auto winSize = Director::getInstance()->getWinSize();
|
||||
float x = winSize.width / 2;
|
||||
float y = 0 + (winSize.height / 2 + 50);
|
||||
|
||||
auto preferedSize = Size(99,99);
|
||||
|
||||
//9-patch sprite with filename
|
||||
auto playerSprite = ui::Scale9Sprite::create("cocosui/player.9.png");
|
||||
playerSprite->setPosition(x, y);
|
||||
playerSprite->setContentSize(preferedSize);
|
||||
auto capInsets = playerSprite->getCapInsets();
|
||||
CCLOG("player sprite capInset = %f, %f %f, %f", capInsets.origin.x,
|
||||
capInsets.origin.y, capInsets.size.width, capInsets.size.height);
|
||||
this->addChild(playerSprite);
|
||||
|
||||
auto animationBtnSprite = ui::Scale9Sprite::createWithSpriteFrameName("animationbuttonpressed.png");
|
||||
animationBtnSprite->setPosition(x-100, y-100);
|
||||
capInsets = animationBtnSprite->getCapInsets();
|
||||
CCLOG("animationBtnSprite capInset = %f, %f %f, %f", capInsets.origin.x,
|
||||
capInsets.origin.y, capInsets.size.width, capInsets.size.height);
|
||||
this->addChild(animationBtnSprite);
|
||||
|
||||
|
||||
auto monsterSprite = ui::Scale9Sprite::createWithSpriteFrameName("monster.9.png");
|
||||
monsterSprite->setPosition(x+100, y-100);
|
||||
capInsets = monsterSprite->getCapInsets();
|
||||
monsterSprite->setContentSize(preferedSize);
|
||||
CCLOG("monsterSprite capInset = %f, %f %f, %f", capInsets.origin.x,
|
||||
capInsets.origin.y, capInsets.size.width, capInsets.size.height);
|
||||
this->addChild(monsterSprite);
|
||||
|
||||
auto spriteFrame = SpriteFrameCache::getInstance()->getSpriteFrameByName("buttonnormal.9.png");
|
||||
auto buttonScale9Sprite = Scale9Sprite::createWithSpriteFrame(spriteFrame);
|
||||
buttonScale9Sprite->setContentSize(Size(150,80));
|
||||
buttonScale9Sprite->setPosition(Vec2(100,200));
|
||||
this->addChild(buttonScale9Sprite);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -250,4 +250,12 @@ public:
|
|||
virtual bool init() override;
|
||||
};
|
||||
|
||||
class UIS9NinePatchTest : public UIScene
|
||||
{
|
||||
public:
|
||||
CREATE_FUNC(UIS9NinePatchTest);
|
||||
|
||||
virtual bool init() override;
|
||||
};
|
||||
|
||||
#endif /* defined(__cocos2d_tests__UIScale9SpriteTest__) */
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 0f5e0dff1a7545eef7bbe8f23d4b232d0d2d6ae3
|
||||
Subproject commit 17afb919e9368b9a41e7e480bfd53d27ccce8feb
|
Loading…
Reference in New Issue