Merge pull request #11946 from andyque/v3-final-android-9-patch-feature

add Android 9-patch image format support
This commit is contained in:
minggo 2015-05-22 09:52:12 +08:00
commit d5d329b74f
19 changed files with 1067 additions and 291 deletions

View File

@ -1190,6 +1190,10 @@
1AC0269D1914068200FA920D /* ConvertUTF.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AC026991914068200FA920D /* ConvertUTF.h */; }; 1AC0269D1914068200FA920D /* ConvertUTF.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AC026991914068200FA920D /* ConvertUTF.h */; };
29031E0719BFE8D400EFA1DF /* libchipmunk.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 29031E0619BFE8D400EFA1DF /* libchipmunk.a */; }; 29031E0719BFE8D400EFA1DF /* libchipmunk.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 29031E0619BFE8D400EFA1DF /* libchipmunk.a */; };
29031E0919BFE8DE00EFA1DF /* libchipmunk.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 29031E0819BFE8DE00EFA1DF /* 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 */; }; 292DB13D19B4574100A80320 /* UIEditBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 292DB12F19B4574100A80320 /* UIEditBox.cpp */; };
292DB13E19B4574100A80320 /* 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 */; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 292DB13119B4574100A80320 /* UIEditBoxImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIEditBoxImpl.h; sourceTree = "<group>"; };
@ -5620,6 +5626,8 @@
1A5700A2180BC5E60088DEC7 /* base */ = { 1A5700A2180BC5E60088DEC7 /* base */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
291901411B05895600F8B4BA /* CCNinePatchImageParser.h */,
291901421B05895600F8B4BA /* CCNinePatchImageParser.cpp */,
505385001B01887A00793096 /* CCProperties.h */, 505385001B01887A00793096 /* CCProperties.h */,
505385011B01887A00793096 /* CCProperties.cpp */, 505385011B01887A00793096 /* CCProperties.cpp */,
B63990CA1A490AFE00B07923 /* CCAsyncTaskPool.cpp */, B63990CA1A490AFE00B07923 /* CCAsyncTaskPool.cpp */,
@ -9408,6 +9416,7 @@
50ABBE211925AB6F00A911A9 /* atitc.h in Headers */, 50ABBE211925AB6F00A911A9 /* atitc.h in Headers */,
15AE19A519AAD39600C27E9E /* TextFieldReader.h in Headers */, 15AE19A519AAD39600C27E9E /* TextFieldReader.h in Headers */,
B665E3401AA80A6500DDB1C5 /* CCPUOnEventFlagObserverTranslator.h in Headers */, B665E3401AA80A6500DDB1C5 /* CCPUOnEventFlagObserverTranslator.h in Headers */,
291901431B05895600F8B4BA /* CCNinePatchImageParser.h in Headers */,
B24AA98B195A675C007B4522 /* CCFastTMXTiledMap.h in Headers */, B24AA98B195A675C007B4522 /* CCFastTMXTiledMap.h in Headers */,
B665E3A01AA80A6500DDB1C5 /* CCPUPositionEmitter.h in Headers */, B665E3A01AA80A6500DDB1C5 /* CCPUPositionEmitter.h in Headers */,
B29594B61926D5EC003EEF37 /* CCMeshCommand.h in Headers */, B29594B61926D5EC003EEF37 /* CCMeshCommand.h in Headers */,
@ -10210,6 +10219,7 @@
50ABBE481925AB6F00A911A9 /* CCEvent.h in Headers */, 50ABBE481925AB6F00A911A9 /* CCEvent.h in Headers */,
5027253B190BF1B900AAF4ED /* cocos2d.h in Headers */, 5027253B190BF1B900AAF4ED /* cocos2d.h in Headers */,
15AE1A9719AAD40300C27E9E /* b2Draw.h in Headers */, 15AE1A9719AAD40300C27E9E /* b2Draw.h in Headers */,
291901441B05895600F8B4BA /* CCNinePatchImageParser.h in Headers */,
3E6176691960F89B00DE83F5 /* CCController.h in Headers */, 3E6176691960F89B00DE83F5 /* CCController.h in Headers */,
B6CAB43E1AF9AA1A00B9B856 /* btGpuDefines.h in Headers */, B6CAB43E1AF9AA1A00B9B856 /* btGpuDefines.h in Headers */,
3823841D1A2590D2002C4610 /* ComAudioReader.h in Headers */, 3823841D1A2590D2002C4610 /* ComAudioReader.h in Headers */,
@ -10682,6 +10692,7 @@
50ED2BD919BE5D5D00A0AB90 /* CCEventListenerController.cpp in Sources */, 50ED2BD919BE5D5D00A0AB90 /* CCEventListenerController.cpp in Sources */,
B665E2321AA80A6500DDB1C5 /* CCPUBoxEmitter.cpp in Sources */, B665E2321AA80A6500DDB1C5 /* CCPUBoxEmitter.cpp in Sources */,
B257B460198A353E00D9A687 /* CCPrimitiveCommand.cpp in Sources */, B257B460198A353E00D9A687 /* CCPrimitiveCommand.cpp in Sources */,
291901451B05895600F8B4BA /* CCNinePatchImageParser.cpp in Sources */,
15AE19A419AAD39600C27E9E /* TextFieldReader.cpp in Sources */, 15AE19A419AAD39600C27E9E /* TextFieldReader.cpp in Sources */,
50ED2BDB19BE76D500A0AB90 /* UIVideoPlayer-ios.mm in Sources */, 50ED2BDB19BE76D500A0AB90 /* UIVideoPlayer-ios.mm in Sources */,
B665E32A1AA80A6500DDB1C5 /* CCPUOnCountObserver.cpp in Sources */, B665E32A1AA80A6500DDB1C5 /* CCPUOnCountObserver.cpp in Sources */,
@ -11642,6 +11653,7 @@
15AE19AA19AAD39700C27E9E /* ListViewReader.cpp in Sources */, 15AE19AA19AAD39700C27E9E /* ListViewReader.cpp in Sources */,
1A5701C8180BCB5A0088DEC7 /* CCLabelTextFormatter.cpp in Sources */, 1A5701C8180BCB5A0088DEC7 /* CCLabelTextFormatter.cpp in Sources */,
1A5701CC180BCB5A0088DEC7 /* CCLabelTTF.cpp in Sources */, 1A5701CC180BCB5A0088DEC7 /* CCLabelTTF.cpp in Sources */,
291901461B05895600F8B4BA /* CCNinePatchImageParser.cpp in Sources */,
B665E39B1AA80A6500DDB1C5 /* CCPUPointEmitterTranslator.cpp in Sources */, B665E39B1AA80A6500DDB1C5 /* CCPUPointEmitterTranslator.cpp in Sources */,
382384291A2590F9002C4610 /* NodeReader.cpp in Sources */, 382384291A2590F9002C4610 /* NodeReader.cpp in Sources */,
15AE193419AAD35100C27E9E /* CCActionObject.cpp in Sources */, 15AE193419AAD35100C27E9E /* CCActionObject.cpp in Sources */,

View File

@ -993,6 +993,10 @@ bool Sprite::isFrameDisplayed(SpriteFrame *frame) const
SpriteFrame* Sprite::getSpriteFrame() const SpriteFrame* Sprite::getSpriteFrame() const
{ {
if(nullptr != this->_spriteFrame)
{
return this->_spriteFrame;
}
return SpriteFrame::createWithTexture(_texture, return SpriteFrame::createWithTexture(_texture,
CC_RECT_POINTS_TO_PIXELS(_rect), CC_RECT_POINTS_TO_PIXELS(_rect),
_rectRotated, _rectRotated,

View File

@ -39,7 +39,7 @@ THE SOFTWARE.
#include "base/CCDirector.h" #include "base/CCDirector.h"
#include "renderer/CCTexture2D.h" #include "renderer/CCTexture2D.h"
#include "renderer/CCTextureCache.h" #include "renderer/CCTextureCache.h"
#include "base/CCNinePatchImageParser.h"
#include "deprecated/CCString.h" #include "deprecated/CCString.h"
@ -104,6 +104,10 @@ void SpriteFrameCache::addSpriteFramesWithDictionary(ValueMap& dictionary, Textu
// check the format // check the format
CCASSERT(format >=0 && format <= 3, "format is not supported for SpriteFrameCache addSpriteFramesWithDictionary:textureFilename:"); 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) for (auto iter = framesDict.begin(); iter != framesDict.end(); ++iter)
{ {
ValueMap& frameDict = iter->second.asValueMap(); ValueMap& frameDict = iter->second.asValueMap();
@ -192,9 +196,16 @@ void SpriteFrameCache::addSpriteFramesWithDictionary(ValueMap& dictionary, Textu
spriteSourceSize); spriteSourceSize);
} }
bool flag = NinePatchImageParser::isNinePatchImage(spriteFrameName);
if(flag)
{
parser.setSpriteFrameInfo(spriteFrame->getRectInPixels(), spriteFrame->isRotated());
texture->addSpriteFrameCapInset(spriteFrame, parser.parseCapInset());
}
// add sprite frame // add sprite frame
_spriteFrames.insert(spriteFrameName, spriteFrame); _spriteFrames.insert(spriteFrameName, spriteFrame);
} }
CC_SAFE_DELETE(image);
} }
void SpriteFrameCache::addSpriteFramesWithFile(const std::string& plist, Texture2D *texture) void SpriteFrameCache::addSpriteFramesWithFile(const std::string& plist, Texture2D *texture)
@ -327,6 +338,7 @@ void SpriteFrameCache::removeUnusedSpriteFrames()
if( spriteFrame->getReferenceCount() == 1 ) if( spriteFrame->getReferenceCount() == 1 )
{ {
toRemoveFrames.push_back(iter->first); toRemoveFrames.push_back(iter->first);
spriteFrame->getTexture()->removeSpriteFrameCapInset(spriteFrame);
CCLOG("cocos2d: SpriteFrameCache: removing unused frame: %s", iter->first.c_str()); CCLOG("cocos2d: SpriteFrameCache: removing unused frame: %s", iter->first.c_str());
removed = true; removed = true;
} }

View File

@ -432,6 +432,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\chipmunk\prebuilt\win32\release-lib\*.*
<ClCompile Include="..\base\CCEventTouch.cpp" /> <ClCompile Include="..\base\CCEventTouch.cpp" />
<ClCompile Include="..\base\ccFPSImages.c" /> <ClCompile Include="..\base\ccFPSImages.c" />
<ClCompile Include="..\base\CCIMEDispatcher.cpp" /> <ClCompile Include="..\base\CCIMEDispatcher.cpp" />
<ClCompile Include="..\base\CCNinePatchImageParser.cpp" />
<ClCompile Include="..\base\CCNS.cpp" /> <ClCompile Include="..\base\CCNS.cpp" />
<ClCompile Include="..\base\CCProfiling.cpp" /> <ClCompile Include="..\base\CCProfiling.cpp" />
<ClCompile Include="..\base\CCProperties.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\CCIMEDispatcher.h" />
<ClInclude Include="..\base\ccMacros.h" /> <ClInclude Include="..\base\ccMacros.h" />
<ClInclude Include="..\base\CCMap.h" /> <ClInclude Include="..\base\CCMap.h" />
<ClInclude Include="..\base\CCNinePatchImageParser.h" />
<ClInclude Include="..\base\CCNS.h" /> <ClInclude Include="..\base\CCNS.h" />
<ClInclude Include="..\base\CCProfiling.h" /> <ClInclude Include="..\base\CCProfiling.h" />
<ClInclude Include="..\base\CCProperties.h" /> <ClInclude Include="..\base\CCProperties.h" />

View File

@ -1872,6 +1872,9 @@
<ClCompile Include="..\renderer\CCVertexAttribBinding.cpp"> <ClCompile Include="..\renderer\CCVertexAttribBinding.cpp">
<Filter>renderer</Filter> <Filter>renderer</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\base\CCNinePatchImageParser.cpp">
<Filter>base</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\physics\CCPhysicsBody.h"> <ClInclude Include="..\physics\CCPhysicsBody.h">
@ -3662,6 +3665,9 @@
<ClInclude Include="..\renderer\CCVertexAttribBinding.h"> <ClInclude Include="..\renderer\CCVertexAttribBinding.h">
<Filter>renderer</Filter> <Filter>renderer</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\base\CCNinePatchImageParser.h">
<Filter>base</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\math\Mat4.inl"> <None Include="..\math\Mat4.inl">

View File

@ -285,6 +285,7 @@
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCIMEDispatcher.h" /> <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCIMEDispatcher.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\ccMacros.h" /> <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\ccMacros.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCMap.h" /> <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCMap.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCNinePatchImageParser.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCNS.h" /> <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCNS.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCProfiling.h" /> <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCProfiling.h" />
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCProperties.h" /> <ClInclude Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCProperties.h" />
@ -898,6 +899,7 @@
</ForcedIncludeFiles> </ForcedIncludeFiles>
</ClCompile> </ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCIMEDispatcher.cpp" /> <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCIMEDispatcher.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCNinePatchImageParser.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCNS.cpp" /> <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCNS.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCProfiling.cpp" /> <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCProfiling.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCProperties.cpp" /> <ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\base\CCProperties.cpp" />

View File

@ -103,6 +103,7 @@ math/TransformUtils.cpp \
math/Vec2.cpp \ math/Vec2.cpp \
math/Vec3.cpp \ math/Vec3.cpp \
math/Vec4.cpp \ math/Vec4.cpp \
base/CCNinePatchImageParser.cpp \
base/CCAsyncTaskPool.cpp \ base/CCAsyncTaskPool.cpp \
base/CCAutoreleasePool.cpp \ base/CCAutoreleasePool.cpp \
base/CCConfiguration.cpp \ base/CCConfiguration.cpp \

View File

@ -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

View File

@ -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

View File

@ -15,6 +15,7 @@ set(COCOS_BASE_SRC
base/CCController.cpp base/CCController.cpp
base/CCData.cpp base/CCData.cpp
base/CCDataVisitor.cpp base/CCDataVisitor.cpp
base/CCNinePatchImageParser.cpp
base/CCDirector.cpp base/CCDirector.cpp
base/CCEvent.cpp base/CCEvent.cpp
base/CCEventAcceleration.cpp base/CCEventAcceleration.cpp

View File

@ -45,7 +45,7 @@ THE SOFTWARE.
#include "renderer/CCGLProgram.h" #include "renderer/CCGLProgram.h"
#include "renderer/ccGLStateCache.h" #include "renderer/ccGLStateCache.h"
#include "renderer/CCGLProgramCache.h" #include "renderer/CCGLProgramCache.h"
#include "base/CCNinePatchImageParser.h"
#include "deprecated/CCString.h" #include "deprecated/CCString.h"
@ -435,6 +435,7 @@ Texture2D::Texture2D()
, _hasMipmaps(false) , _hasMipmaps(false)
, _shaderProgram(nullptr) , _shaderProgram(nullptr)
, _antialiasEnabled(true) , _antialiasEnabled(true)
, _ninePatchInfo(nullptr)
{ {
} }
@ -447,6 +448,8 @@ Texture2D::~Texture2D()
CCLOGINFO("deallocing Texture2D: %p - id=%u", this, _name); CCLOGINFO("deallocing Texture2D: %p - id=%u", this, _name);
CC_SAFE_RELEASE(_shaderProgram); CC_SAFE_RELEASE(_shaderProgram);
CC_SAFE_DELETE(_ninePatchInfo);
if(_name) if(_name)
{ {
GL::deleteTexture(_name); GL::deleteTexture(_name);
@ -1393,5 +1396,60 @@ const Texture2D::PixelFormatInfoMap& Texture2D::getPixelFormatInfoMap()
return _pixelFormatInfoTables; 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 NS_CC_END

View File

@ -29,6 +29,7 @@ THE SOFTWARE.
#include <string> #include <string>
#include <map> #include <map>
#include <unordered_map>
#include "base/CCRef.h" #include "base/CCRef.h"
#include "math/CCGeometry.h" #include "math/CCGeometry.h"
@ -40,8 +41,15 @@ THE SOFTWARE.
NS_CC_BEGIN NS_CC_BEGIN
class Image; class Image;
class NinePatchInfo;
class SpriteFrame;
typedef struct _MipmapInfo MipmapInfo; typedef struct _MipmapInfo MipmapInfo;
namespace ui
{
class Scale9Sprite;
}
/** /**
* @addtogroup _2d * @addtogroup _2d
* @{ * @{
@ -309,6 +317,7 @@ public:
* @endcode * @endcode
*/ */
void setTexParameters(const TexParams& texParams); void setTexParameters(const TexParams& texParams);
/** /**
* @js NA * @js NA
* @lua NA * @lua NA
@ -403,11 +412,54 @@ public:
/** Get a shader program from the texture.*/ /** Get a shader program from the texture.*/
GLProgram* getGLProgram() const; GLProgram* getGLProgram() const;
public: public:
/** Get pixel info map, the key-value pairs is PixelFormat and PixelFormatInfo.*/ /** Get pixel info map, the key-value pairs is PixelFormat and PixelFormatInfo.*/
static const PixelFormatInfoMap& getPixelFormatInfoMap(); static const PixelFormatInfoMap& getPixelFormatInfoMap();
private: 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*/ /**convert functions*/
@ -490,6 +542,10 @@ protected:
static const PixelFormatInfoMap _pixelFormatInfoTables; static const PixelFormatInfoMap _pixelFormatInfoTables;
bool _antialiasEnabled; bool _antialiasEnabled;
NinePatchInfo* _ninePatchInfo;
friend class SpriteFrameCache;
friend class TextureCache;
friend class ui::Scale9Sprite;
}; };

View File

@ -40,6 +40,7 @@ THE SOFTWARE.
#include "base/ccUtils.h" #include "base/ccUtils.h"
#include "deprecated/CCString.h" #include "deprecated/CCString.h"
#include "base/CCNinePatchImageParser.h"
#ifdef EMSCRIPTEN #ifdef EMSCRIPTEN
@ -275,7 +276,8 @@ void TextureCache::addImageAsyncCallBack(float dt)
texture = new (std::nothrow) Texture2D(); texture = new (std::nothrow) Texture2D();
texture->initWithImage(image); texture->initWithImage(image);
//parse 9-patch info
this->parseNinePatchImage(image, texture, filename);
#if CC_ENABLE_CACHE_TEXTURE_DATA #if CC_ENABLE_CACHE_TEXTURE_DATA
// cache the texture file name // cache the texture file name
VolatileTextureMgr::addImageTexture(texture, filename); VolatileTextureMgr::addImageTexture(texture, filename);
@ -351,6 +353,9 @@ Texture2D * TextureCache::addImage(const std::string &path)
#endif #endif
// texture already retained, no need to re-retain it // texture already retained, no need to re-retain it
_textures.insert( std::make_pair(fullpath, texture) ); _textures.insert( std::make_pair(fullpath, texture) );
//parse 9-patch info
this->parseNinePatchImage(image, texture, path);
} }
else else
{ {
@ -364,6 +369,17 @@ Texture2D * TextureCache::addImage(const std::string &path)
return texture; 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) Texture2D* TextureCache::addImage(Image *image, const std::string &key)
{ {
CCASSERT(image != nullptr, "TextureCache: image MUST not be nil"); CCASSERT(image != nullptr, "TextureCache: image MUST not be nil");
@ -524,6 +540,19 @@ void TextureCache::reloadAllTextures()
// #endif // #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() void TextureCache::waitForQuit()
{ {
// notify sub thread to quick // notify sub thread to quick

View File

@ -195,10 +195,19 @@ public:
/**Called by director, please do not called outside.*/ /**Called by director, please do not called outside.*/
void waitForQuit(); 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: private:
void addImageAsyncCallBack(float dt); void addImageAsyncCallBack(float dt);
void loadImage(); void loadImage();
void parseNinePatchImage(Image* image, Texture2D* texture, const std::string& path);
public: public:
struct AsyncStruct struct AsyncStruct
{ {

File diff suppressed because it is too large Load Diff

View File

@ -742,6 +742,7 @@ namespace ui {
bool _flippedX; bool _flippedX;
bool _flippedY; bool _flippedY;
bool _isPatch9;
}; };
}} //end of namespace }} //end of namespace

View File

@ -52,6 +52,7 @@ UIScale9SpriteTests::UIScale9SpriteTests()
ADD_TEST_CASE(UIS9ZOrder); ADD_TEST_CASE(UIS9ZOrder);
ADD_TEST_CASE(UIS9Flip); ADD_TEST_CASE(UIS9Flip);
ADD_TEST_CASE(UIS9ChangeAnchorPoint); ADD_TEST_CASE(UIS9ChangeAnchorPoint);
ADD_TEST_CASE(UIS9NinePatchTest);
} }
// UIScale9SpriteTest // UIScale9SpriteTest
@ -848,6 +849,53 @@ bool UIS9ChangeAnchorPoint::init()
this->addChild(button2); 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 true;
} }
return false; return false;

View File

@ -250,4 +250,12 @@ public:
virtual bool init() override; virtual bool init() override;
}; };
class UIS9NinePatchTest : public UIScene
{
public:
CREATE_FUNC(UIS9NinePatchTest);
virtual bool init() override;
};
#endif /* defined(__cocos2d_tests__UIScale9SpriteTest__) */ #endif /* defined(__cocos2d_tests__UIScale9SpriteTest__) */

@ -1 +1 @@
Subproject commit 0f5e0dff1a7545eef7bbe8f23d4b232d0d2d6ae3 Subproject commit 17afb919e9368b9a41e7e480bfd53d27ccce8feb