Merge branch 'gles20' of https://github.com/cocos2d/cocos2d-x into gles20

This commit is contained in:
walzer 2012-10-18 17:26:53 +08:00
commit 926ed0a2f7
78 changed files with 897 additions and 2986 deletions

View File

@ -12,6 +12,9 @@ Developers:
Rolando Abarca
Javascript Binding and testjs
wenbin wang
fix getDeviceModel bug in android CocosDenshion
Horcruxes
fix the bug that CCArray::createWithContentsOfFile() may not read file data on iOS

View File

@ -155,16 +155,17 @@ SimpleAudioEngine::SimpleAudioEngine()
methodInfo.env->DeleteLocalRef(methodInfo.classID);
const char* deviceModel = methodInfo.env->GetStringUTFChars(jstr, NULL);
methodInfo.env->ReleaseStringUTFChars(jstr, deviceModel);
methodInfo.env->DeleteLocalRef(jstr);
LOGD(deviceModel);
if (strcmp(I9100_MODEL, deviceModel) == 0)
{
LOGD("i9100 model\nSwitch to OpenSLES");
s_bI9100 = true;
}
methodInfo.env->ReleaseStringUTFChars(jstr, deviceModel);
methodInfo.env->DeleteLocalRef(jstr);
}
SimpleAudioEngine::~SimpleAudioEngine()

View File

@ -18,7 +18,7 @@ OpenSLEngine::~OpenSLEngine()
/**********************************************************************************
* jni
**********************************************************************************/
#define CLASS_NAME "org/cocos2dx/lib/Cocos2dxActivity"
#define CLASS_NAME "org/cocos2dx/lib/Cocos2dxHelper"
typedef struct JniMethodInfo_
{
@ -672,4 +672,4 @@ float OpenSLEngine::getEffectsVolume()
{
float volume = (m_effectVolume - MIN_VOLUME_MILLIBEL) / (1.0f * RANGE_VOLUME_MILLIBEL);
return volume;
}
}

View File

@ -136,7 +136,6 @@ bool CCDirector::init(void)
m_pobOpenGLView = NULL;
m_fContentScaleFactor = 1.0f;
m_bIsContentScaleSupported = false;
// scheduler
m_pScheduler = new CCScheduler();
@ -314,12 +313,7 @@ void CCDirector::setOpenGLView(CCEGLView *pobOpenGLView)
CHECK_GL_ERROR_DEBUG();
if (m_fContentScaleFactor != 1)
{
updateContentScaleFactor();
}
m_pobOpenGLView->setTouchDelegate(m_pTouchDispatcher);
m_pobOpenGLView->setTouchDelegate(m_pTouchDispatcher);
m_pTouchDispatcher->setDispatchEvents(true);
}
}
@ -331,12 +325,11 @@ void CCDirector::setNextDeltaTimeZero(bool bNextDeltaTimeZero)
void CCDirector::setProjection(ccDirectorProjection kProjection)
{
CCSize size = m_obWinSizeInPixels;
CCSize sizePoint = m_obWinSizeInPoints;
CCSize size = m_obWinSizeInPoints;
if (m_pobOpenGLView)
{
m_pobOpenGLView->setViewPortInPoints(0, 0, sizePoint.width, sizePoint.height);
m_pobOpenGLView->setViewPortInPoints(0, 0, size.width, size.height);
}
switch (kProjection)
@ -346,7 +339,7 @@ void CCDirector::setProjection(ccDirectorProjection kProjection)
kmGLMatrixMode(KM_GL_PROJECTION);
kmGLLoadIdentity();
kmMat4 orthoMatrix;
kmMat4OrthographicProjection(&orthoMatrix, 0, size.width / CC_CONTENT_SCALE_FACTOR(), 0, size.height / CC_CONTENT_SCALE_FACTOR(), -1024, 1024 );
kmMat4OrthographicProjection(&orthoMatrix, 0, size.width, 0, size.height, -1024, 1024 );
kmGLMultMatrix(&orthoMatrix);
kmGLMatrixMode(KM_GL_MODELVIEW);
kmGLLoadIdentity();
@ -371,8 +364,8 @@ void CCDirector::setProjection(ccDirectorProjection kProjection)
kmGLMatrixMode(KM_GL_MODELVIEW);
kmGLLoadIdentity();
kmVec3 eye, center, up;
kmVec3Fill( &eye, sizePoint.width/2, sizePoint.height/2, zeye );
kmVec3Fill( &center, sizePoint.width/2, sizePoint.height/2, 0.0f );
kmVec3Fill( &eye, size.width/2, size.height/2, zeye );
kmVec3Fill( &center, size.width/2, size.height/2, 0.0f );
kmVec3Fill( &up, 0.0f, 1.0f, 0.0f);
kmMat4LookAt(&matrixLookup, &eye, &center, &up);
kmGLMultMatrix(&matrixLookup);
@ -404,7 +397,7 @@ void CCDirector::purgeCachedData(void)
float CCDirector::getZEye(void)
{
return (m_obWinSizeInPixels.height / 1.1566f / CC_CONTENT_SCALE_FACTOR());
return (m_obWinSizeInPoints.height / 1.1566f);
}
void CCDirector::setAlphaBlending(bool bOn)
@ -782,20 +775,21 @@ void CCDirector::createStatsLabel()
m_pDrawsLabel = new CCLabelAtlas();
m_pDrawsLabel->initWithString("000", "fps_images.png", 12, 32, '.');
*/
m_pFPSLabel = CCLabelTTF::create("00.0", "Arial", 24);
int fontSize = (int)(m_obWinSizeInPoints.height / 320.0f * 24);
m_pFPSLabel = CCLabelTTF::create("00.0", "Arial", fontSize);
m_pFPSLabel->retain();
m_pSPFLabel = CCLabelTTF::create("0.000", "Arial", 24);
m_pSPFLabel = CCLabelTTF::create("0.000", "Arial", fontSize);
m_pSPFLabel->retain();
m_pDrawsLabel = CCLabelTTF::create("000", "Arial", 24);
m_pDrawsLabel = CCLabelTTF::create("000", "Arial", fontSize);
m_pDrawsLabel->retain();
//CCTexture2D::setDefaultAlphaPixelFormat(currentFormat);
CCSize contentSize = m_pDrawsLabel->getContentSize();
m_pDrawsLabel->setPosition(ccpAdd(ccp(contentSize.width/2, contentSize.height/2 + 40), CC_DIRECTOR_STATS_POSITION));
m_pDrawsLabel->setPosition(ccpAdd(ccp(contentSize.width/2, contentSize.height*5/2), CC_DIRECTOR_STATS_POSITION));
contentSize = m_pSPFLabel->getContentSize();
m_pSPFLabel->setPosition(ccpAdd(ccp(contentSize.width/2, contentSize.height/2 + 20), CC_DIRECTOR_STATS_POSITION));
m_pSPFLabel->setPosition(ccpAdd(ccp(contentSize.width/2, contentSize.height*3/2), CC_DIRECTOR_STATS_POSITION));
contentSize = m_pFPSLabel->getContentSize();
m_pFPSLabel->setPosition(ccpAdd(ccp(contentSize.width/2, contentSize.height/2), CC_DIRECTOR_STATS_POSITION));
}
@ -805,38 +799,6 @@ void CCDirector::createStatsLabel()
* mobile platforms specific functions
**************************************************/
void CCDirector::updateContentScaleFactor()
{
m_bIsContentScaleSupported = m_pobOpenGLView->setContentScaleFactor(m_fContentScaleFactor);
}
bool CCDirector::enableRetinaDisplay(bool enabled)
{
// Already enabled?
if (enabled && m_fContentScaleFactor == 2)
{
return true;
}
// Already disabled?
if (!enabled && m_fContentScaleFactor == 1)
{
return false;
}
if (! m_pobOpenGLView->enableRetina())
{
return false;
}
float newScale = (float)(enabled ? 2 : 1);
setContentScaleFactor(newScale);
createStatsLabel();
return true;
}
float CCDirector::getContentScaleFactor(void)
{
return m_fContentScaleFactor;
@ -847,15 +809,6 @@ void CCDirector::setContentScaleFactor(float scaleFactor)
if (scaleFactor != m_fContentScaleFactor)
{
m_fContentScaleFactor = scaleFactor;
m_obWinSizeInPixels = CCSizeMake(m_obWinSizeInPoints.width * scaleFactor, m_obWinSizeInPoints.height * scaleFactor);
if (m_pobOpenGLView)
{
updateContentScaleFactor();
}
// update projection
setProjection(m_eProjection);
}
}

View File

@ -159,8 +159,6 @@ public:
*/
CCNode* getNotificationNode();
void setNotificationNode(CCNode *node);
bool enableRetinaDisplay(bool bEnabelRetina);
// window size
@ -330,8 +328,6 @@ protected:
void purgeDirector();
bool m_bPurgeDirecotorInNextLoop; // this flag will be set to true in end()
void updateContentScaleFactor(void);
void setNextScene(void);
void showStats();
@ -408,9 +404,6 @@ protected:
/* Projection protocol delegate */
CCDirectorDelegate *m_pProjectionDelegate;
/* contentScaleFactor could be simulated */
bool m_bIsContentScaleSupported;
// CCEGLViewProtocol will recreate stats labels to fit visible rect
friend class CCEGLViewProtocol;

View File

@ -50,7 +50,7 @@ void CCAutoreleasePool::addObject(CCObject* pObject)
void CCAutoreleasePool::removeObject(CCObject* pObject)
{
for (int i = 0; i < pObject->m_uAutoReleaseCount; ++i)
for (unsigned int i = 0; i < pObject->m_uAutoReleaseCount; ++i)
{
m_pManagedObjectArray->removeObject(pObject, false);
}

View File

@ -174,8 +174,8 @@ bool CCRenderTexture::initWithWidthAndHeight(int w, int h, CCTexture2DPixelForma
void *data = NULL;
do
{
w *= (int)CC_CONTENT_SCALE_FACTOR();
h *= (int)CC_CONTENT_SCALE_FACTOR();
w = (int)(w * CC_CONTENT_SCALE_FACTOR());
h = (int)(h * CC_CONTENT_SCALE_FACTOR());
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &m_nOldFBO);

View File

@ -46,7 +46,6 @@ CCEGLViewProtocol::CCEGLViewProtocol()
: m_pDelegate(NULL)
, m_fScaleY(1.0f)
, m_fScaleX(1.0f)
, m_bIsRetinaEnabled(false)
, m_eResolutionPolicy(kResolutionUnKnown)
{
}
@ -58,7 +57,6 @@ CCEGLViewProtocol::~CCEGLViewProtocol()
void CCEGLViewProtocol::setDesignResolutionSize(float width, float height, ResolutionPolicy resolutionPolicy)
{
CCAssert(m_bIsRetinaEnabled == false, "can not enable retina while set design resolution size!");
CCAssert(resolutionPolicy != kResolutionUnKnown, "should set resolutionPolicy");
if (width == 0.0f || height == 0.0f)
@ -89,19 +87,13 @@ void CCEGLViewProtocol::setDesignResolutionSize(float width, float height, Resol
m_eResolutionPolicy = resolutionPolicy;
//setViewPortInPoints(0, 0,m_obScreenSize.width, m_obScreenSize.height);
// reset director's member variables to fit visible rect
// reset director's member variables to fit visible rect
CCDirector::sharedDirector()->m_obWinSizeInPoints = getSize();
CCDirector::sharedDirector()->m_obWinSizeInPixels = CCSizeMake(m_obDesignResolutionSize.width*CC_CONTENT_SCALE_FACTOR(), m_obDesignResolutionSize.height*CC_CONTENT_SCALE_FACTOR());
CCDirector::sharedDirector()->createStatsLabel();
CCDirector::sharedDirector()->m_obWinSizeInPoints = CCDirector::sharedDirector()->m_obWinSizeInPixels = getSize();
CCDirector::sharedDirector()->setGLDefaultValues();
}
bool CCEGLViewProtocol::enableRetina()
{
return false;
}
const CCSize& CCEGLViewProtocol::getSize() const
{
return m_obDesignResolutionSize;
@ -147,12 +139,6 @@ void CCEGLViewProtocol::setTouchDelegate(EGLTouchDelegate * pDelegate)
m_pDelegate = pDelegate;
}
bool CCEGLViewProtocol::setContentScaleFactor(float contentScaleFactor)
{
m_fScaleX = m_fScaleY = contentScaleFactor;
return false;
}
void CCEGLViewProtocol::setViewPortInPoints(float x , float y , float w , float h)
{
glViewport((GLint)(x * m_fScaleX + m_obViewPortRect.origin.x),
@ -169,6 +155,19 @@ void CCEGLViewProtocol::setScissorInPoints(float x , float y , float w , float h
(GLsizei)(h * m_fScaleY));
}
void CCEGLViewProtocol::setViewName(const char* pszViewName)
{
if (pszViewName != NULL && strlen(pszViewName) > 0)
{
strncpy(m_szViewName, pszViewName, sizeof(m_szViewName));
}
}
const char* CCEGLViewProtocol::getViewName()
{
return m_szViewName;
}
void CCEGLViewProtocol::handleTouchesBegin(int num, int ids[], float xs[], float ys[])
{
CCSet set;
@ -193,18 +192,8 @@ void CCEGLViewProtocol::handleTouchesBegin(int num, int ids[], float xs[], float
}
CCTouch* pTouch = s_pTouches[nUnusedIndex] = new CCTouch();
if (m_bIsRetinaEnabled)
{
// on iOS, though retina is enabled, the value got from os is also
// relative to its original size
pTouch->setTouchInfo(nUnusedIndex, (x - m_obViewPortRect.origin.x),
(y - m_obViewPortRect.origin.y));
}
else
{
pTouch->setTouchInfo(nUnusedIndex, (x - m_obViewPortRect.origin.x) / m_fScaleX,
pTouch->setTouchInfo(nUnusedIndex, (x - m_obViewPortRect.origin.x) / m_fScaleX,
(y - m_obViewPortRect.origin.y) / m_fScaleY);
}
//CCLOG("x = %f y = %f", pTouch->getLocationInView().x, pTouch->getLocationInView().y);
@ -243,16 +232,8 @@ void CCEGLViewProtocol::handleTouchesMove(int num, int ids[], float xs[], float
CCTouch* pTouch = s_pTouches[pIndex->getValue()];
if (pTouch)
{
if (m_bIsRetinaEnabled)
{
pTouch->setTouchInfo(pIndex->getValue(), (x - m_obViewPortRect.origin.x),
(y - m_obViewPortRect.origin.y));
}
else
{
pTouch->setTouchInfo(pIndex->getValue(), (x - m_obViewPortRect.origin.x) / m_fScaleX,
(y - m_obViewPortRect.origin.y) / m_fScaleY);
}
pTouch->setTouchInfo(pIndex->getValue(), (x - m_obViewPortRect.origin.x) / m_fScaleX,
(y - m_obViewPortRect.origin.y) / m_fScaleY);
set.addObject(pTouch);
}
@ -292,17 +273,8 @@ void CCEGLViewProtocol::getSetOfTouchesEndOrCancel(CCSet& set, int num, int ids[
if (pTouch)
{
CCLOGINFO("Ending touches with id: %d, x=%f, y=%f", id, x, y);
if (m_bIsRetinaEnabled)
{
pTouch->setTouchInfo(pIndex->getValue(), (x - m_obViewPortRect.origin.x),
(y - m_obViewPortRect.origin.y));
}
else
{
pTouch->setTouchInfo(pIndex->getValue(), (x - m_obViewPortRect.origin.x) / m_fScaleX,
(y - m_obViewPortRect.origin.y) / m_fScaleY);
}
pTouch->setTouchInfo(pIndex->getValue(), (x - m_obViewPortRect.origin.x) / m_fScaleX,
(y - m_obViewPortRect.origin.y) / m_fScaleY);
set.addObject(pTouch);
@ -358,9 +330,4 @@ float CCEGLViewProtocol::getScaleY() const
return m_fScaleY;
}
bool CCEGLViewProtocol::isRetinaEnabled() const
{
return m_bIsRetinaEnabled;
}
NS_CC_END

View File

@ -5,16 +5,16 @@
enum ResolutionPolicy
{
// The entire application is visible in the specified area without trying to preserve the original aspect ratio.
// The entire application is visible in the specified area without trying to preserve the original aspect ratio.
// Distortion can occur, and the application may appear stretched or compressed.
kResolutionExactFit,
// The entire application fills the specified area, without distortion but possibly with some cropping,
// The entire application fills the specified area, without distortion but possibly with some cropping,
// while maintaining the original aspect ratio of the application.
kResolutionNoBorder,
// The entire application is visible in the specified area without distortion while maintaining the original
// The entire application is visible in the specified area without distortion while maintaining the original
// aspect ratio of the application. Borders can appear on two sides of the application.
kResolutionShowAll,
kResolutionUnKnown,
};
@ -38,45 +38,45 @@ public:
/** Force destroying EGL view, subclass must implement this method. */
virtual void end() = 0;
/** Get whether opengl render system is ready, subclass must implement this method. */
virtual bool isOpenGLReady() = 0;
/** Exchanges the front and back buffers, subclass must implement this method. */
virtual void swapBuffers() = 0;
/** Open or close IME keyboard , subclass must implement this method. */
virtual void setIMEKeyboardState(bool bOpen) = 0;
/**
/**
* Get design resolution size.
* If setDesignResolutionSize wasn't invoked, the result of this function return is the same as 'getFrameSize'
*/
virtual const CCSize& getSize() const;
/**
* Get the frame size of EGL view.
* In general, it returns the screen size since the EGL view is a fullscreen view.
*/
virtual const CCSize& getFrameSize() const;
/**
* Set the frame size of EGL view.
*/
virtual void setFrameSize(float width, float height);
/**
* Get the visible area size of opengl viewport.
*/
virtual CCSize getVisibleSize() const;
/**
* Get the visible origin point of opengl viewport.
*/
virtual CCPoint getVisibleOrigin() const;
/**
/**
* Set the design resolution size.
* Behavior undefined when enableRetina == true.
* @param width Design resolution width.
@ -87,31 +87,23 @@ public:
* [3] kCCResolutionShowAll Full screen with black border: if the design resolution ratio of width to height is different from the screen resolution ratio, two black borders will be shown.
*/
virtual void setDesignResolutionSize(float width, float height, ResolutionPolicy resolutionPolicy);
/** Set touch delegate */
virtual void setTouchDelegate(EGLTouchDelegate * pDelegate);
/**
* Set content scale factor.
* @return If the return value is true, the platform supports retina display mode.
*/
virtual bool setContentScaleFactor(float contentScaleFactor);
/**
* Set opengl view port rectangle with points.
*/
virtual void setViewPortInPoints(float x , float y , float w , float h);
/**
* Set Scissor rectangle with points.
*/
virtual void setScissorInPoints(float x , float y , float w , float h);
/**
* Enable retina mode.
* You can't use it with setDesignResolutionSize
*/
virtual bool enableRetina();
virtual void setViewName(const char* pszViewName);
const char* getViewName();
/** Touch events are handled by default; if you want to customize your handlers, please override these functions: */
virtual void handleTouchesBegin(int num, int ids[], float xs[], float ys[]);
@ -123,24 +115,19 @@ public:
* Get the opengl view port rectangle.
*/
const CCRect& getViewPortRect() const;
/**
* Get scale factor of the horizontal direction.
*/
float getScaleX() const;
/**
* Get scale factor of the vertical direction.
*/
float getScaleY() const;
/**
* Get retina mode status (on if true).
*/
bool isRetinaEnabled() const;
private:
void getSetOfTouchesEndOrCancel(CCSet& set, int num, int ids[], float xs[], float ys[]);
protected:
EGLTouchDelegate* m_pDelegate;
@ -152,11 +139,10 @@ protected:
CCRect m_obViewPortRect;
// the view name
char m_szViewName[50];
float m_fScaleX;
float m_fScaleY;
ResolutionPolicy m_eResolutionPolicy;
bool m_bIsRetinaEnabled;
};
// end of platform group

View File

@ -38,7 +38,7 @@ void CCLog(const char * pszFormat, ...)
va_list args;
va_start(args, pszFormat);
vsprintf(buf, pszFormat, args);
vsnprintf(buf, MAX_LEN, pszFormat, args);
va_end(args);
__android_log_print(ANDROID_LOG_DEBUG, "cocos2d-x debug info", buf);

View File

@ -28,6 +28,7 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.Semaphore;
import android.content.Context;
import android.media.AudioManager;
@ -56,6 +57,11 @@ public class Cocos2dxSound {
private final HashMap<String, ArrayList<Integer>> mPathStreamIDsMap = new HashMap<String, ArrayList<Integer>>();
private final HashMap<String, Integer> mPathSoundIDMap = new HashMap<String, Integer>();
private final ArrayList<SoundInfoForLoadedCompleted> mEffecToPlayWhenLoadedArray = new ArrayList<SoundInfoForLoadedCompleted>();
private int mStreamIdSyn;
private Semaphore mSemaphore;
private static final int MAX_SIMULTANEOUS_STREAMS_DEFAULT = 5;
private static final float SOUND_RATE = 1.0f;
@ -77,9 +83,12 @@ public class Cocos2dxSound {
private void initData() {
this.mSoundPool = new SoundPool(Cocos2dxSound.MAX_SIMULTANEOUS_STREAMS_DEFAULT, AudioManager.STREAM_MUSIC, Cocos2dxSound.SOUND_QUALITY);
this.mSoundPool.setOnLoadCompleteListener(new OnLoadCompletedListener());
this.mLeftVolume = 0.5f;
this.mRightVolume = 0.5f;
this.mSemaphore = new Semaphore(0, true);
}
// ===========================================================
@ -127,15 +136,7 @@ public class Cocos2dxSound {
if (soundID != null) {
// play sound
streamID = this.mSoundPool.play(soundID.intValue(), this.mLeftVolume, this.mRightVolume, Cocos2dxSound.SOUND_PRIORITY, pLoop ? -1 : 0, Cocos2dxSound.SOUND_RATE);
// record stream id
ArrayList<Integer> streamIDs = this.mPathStreamIDsMap.get(pPath);
if (streamIDs == null) {
streamIDs = new ArrayList<Integer>();
this.mPathStreamIDsMap.put(pPath, streamIDs);
}
streamIDs.add(streamID);
streamID = this.doPlayEffect(pPath, soundID.intValue(), pLoop);
} else {
// the effect is not prepared
soundID = this.preloadEffect(pPath);
@ -143,16 +144,21 @@ public class Cocos2dxSound {
// can not preload effect
return Cocos2dxSound.INVALID_SOUND_ID;
}
/*
* Someone reports that, it can not play effect for the first time.
* If you are lucky to meet it. There are two ways to resolve it. 1.
* Add some delay here. I don't know how long it is, so I don't add
* it here. 2. If you use 2.2(API level 8), you can call
* SoundPool.setOnLoadCompleteListener() to play the effect. Because
* the method is supported from 2.2, so I can't use it here.
*/
this.playEffect(pPath, pLoop);
// only allow one playEffect at a time, or the semaphore will not work correctly
synchronized(this.mSoundPool) {
// add this effect into mEffecToPlayWhenLoadedArray, and it will be played when loaded completely
mEffecToPlayWhenLoadedArray.add(new SoundInfoForLoadedCompleted(pPath, soundID.intValue(), pLoop));
try {
// wait OnloadedCompleteListener to set streamID
this.mSemaphore.acquire();
streamID = this.mStreamIdSyn;
} catch(Exception e) {
return Cocos2dxSound.INVALID_SOUND_ID;
}
}
}
return streamID;
@ -183,8 +189,17 @@ public class Cocos2dxSound {
}
public void resumeAllEffects() {
// autoPause() is available since level 8
this.mSoundPool.autoResume();
// can not only invoke SoundPool.autoResume() here, because
// it only resumes all effects paused by pauseAllEffects()
if (!this.mPathStreamIDsMap.isEmpty()) {
final Iterator<Entry<String, ArrayList<Integer>>> iter = this.mPathStreamIDsMap.entrySet().iterator();
while (iter.hasNext()) {
final Entry<String, ArrayList<Integer>> entry = iter.next();
for (final int pStreamID : entry.getValue()) {
this.mSoundPool.resume(pStreamID);
}
}
}
}
@SuppressWarnings("unchecked")
@ -235,9 +250,12 @@ public class Cocos2dxSound {
this.mSoundPool.release();
this.mPathStreamIDsMap.clear();
this.mPathSoundIDMap.clear();
this.mEffecToPlayWhenLoadedArray.clear();
this.mLeftVolume = 0.5f;
this.mRightVolume = 0.5f;
this.initData();
}
public int createSoundIDFromAsset(final String pPath) {
@ -256,8 +274,62 @@ public class Cocos2dxSound {
return soundID;
}
private int doPlayEffect(final String pPath, final int soundId, final boolean pLoop) {
// play sound
int streamID = this.mSoundPool.play(soundId, this.mLeftVolume, this.mRightVolume, Cocos2dxSound.SOUND_PRIORITY, pLoop ? -1 : 0, Cocos2dxSound.SOUND_RATE);
// record stream id
ArrayList<Integer> streamIDs = this.mPathStreamIDsMap.get(pPath);
if (streamIDs == null) {
streamIDs = new ArrayList<Integer>();
this.mPathStreamIDsMap.put(pPath, streamIDs);
}
streamIDs.add(streamID);
return streamID;
}
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
public class SoundInfoForLoadedCompleted {
public int soundID;
public boolean isLoop;
public String path;
public SoundInfoForLoadedCompleted(String path, int soundId, boolean isLoop) {
this.path = path;
this.soundID = soundId;
this.isLoop = isLoop;
}
}
public class OnLoadCompletedListener implements SoundPool.OnLoadCompleteListener {
@Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
if (status == 0)
{
// only play effect that are in mEffecToPlayWhenLoadedArray
for ( SoundInfoForLoadedCompleted info : mEffecToPlayWhenLoadedArray) {
if (sampleId == info.soundID) {
// set the stream id which will be returned by playEffect()
mStreamIdSyn = doPlayEffect(info.path, info.soundID, info.isLoop);
// remove it from array, because we will break here
// so it is safe to do
mEffecToPlayWhenLoadedArray.remove(info);
break;
}
}
} else {
mStreamIdSyn = Cocos2dxSound.INVALID_SOUND_ID;
}
mSemaphore.release();
}
}
}

View File

@ -34,7 +34,7 @@ void CCLog(const char * pszFormat, ...)
va_list args;
va_start(args, pszFormat);
vsprintf(buf, pszFormat, args);
vsnprintf(buf, MAX_LEN, pszFormat, args);
va_end(args);
fprintf(stderr, "cocos2d-x debug info %s\n", buf);

View File

@ -38,7 +38,7 @@ void CCLog(const char * pszFormat, ...)
va_list ap;
va_start(ap, pszFormat);
vsprintf(szBuf, pszFormat, ap);
vsnprintf(szBuf, kMaxLogLen, pszFormat, ap);
va_end(ap);
printf("%s", szBuf);
printf("\n");

View File

@ -40,7 +40,6 @@ public:
virtual bool isOpenGLReady();
virtual bool setContentScaleFactor(float contentScaleFactor);
virtual bool enableRetina();
// keep compatible
virtual void end();

View File

@ -49,34 +49,11 @@ bool CCEGLView::isOpenGLReady()
bool CCEGLView::setContentScaleFactor(float contentScaleFactor)
{
assert(m_eResolutionPolicy == kResolutionUnKnown); // cannot enable retina mode
if ([[EAGLView sharedEGLView] respondsToSelector:@selector(setContentScaleFactor:)])
{
UIView * view = [EAGLView sharedEGLView];
view.contentScaleFactor = contentScaleFactor;
[view setNeedsLayout];
m_fScaleX = m_fScaleY = contentScaleFactor;
[[EAGLView sharedEGLView] setNeedsLayout];
m_fScaleX = m_fScaleY = contentScaleFactor;
m_bIsRetinaEnabled = true;
return true;
}
else
{
return false;
}
}
bool CCEGLView::enableRetina()
{
bool ret = true;
// can set content scale factor?
ret &= [[EAGLView sharedEGLView] respondsToSelector:@selector(setContentScaleFactor:)];
// SD device?
ret &= ([[UIScreen mainScreen] scale] != 1.0f);
return ret;
return true;
}
void CCEGLView::end()

View File

@ -28,10 +28,6 @@ THE SOFTWARE.
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
// FontLabel support
#import "FontLabel/FontManager.h"
#import "FontLabel/FontLabelStringDrawing.h"
typedef struct
{
unsigned int height;
@ -171,7 +167,7 @@ static bool _isValidFontName(const char *fontName)
return ret;
}
static CGSize _calculateStringSizeWithFontOrZFont(NSString *str, id font, CGSize *constrainSize, bool isZfont)
static CGSize _calculateStringSize(NSString *str, id font, CGSize *constrainSize)
{
NSArray *listItems = [str componentsSeparatedByString: @"\n"];
CGSize dim = CGSizeZero;
@ -184,15 +180,7 @@ static CGSize _calculateStringSizeWithFontOrZFont(NSString *str, id font, CGSize
for (NSString *s in listItems)
{
CGSize tmp;
if (isZfont)
{
tmp = [FontLabelStringDrawingHelper sizeWithZFont:s zfont:font constrainedToSize:textRect];
}
else
{
tmp = [s sizeWithFont:font constrainedToSize:textRect];
}
CGSize tmp = [s sizeWithFont:font constrainedToSize:textRect];
if (tmp.width > dim.width)
{
@ -228,19 +216,9 @@ static bool _initWithString(const char * pText, cocos2d::CCImage::ETextAlign eAl
font = [UIFont fontWithName:fntName size:nSize];
if (font)
{
dim = _calculateStringSizeWithFontOrZFont(str, font, &constrainSize, false);
dim = _calculateStringSize(str, font, &constrainSize);
}
if (! font)
{
font = [[FontManager sharedManager] zFontWithName:fntName pointSize:nSize];
if (font)
{
dim =_calculateStringSizeWithFontOrZFont(str, font, &constrainSize, true);
}
}
if (! font)
else
{
fntName = _isValidFontName(pFontName) ? fntName : @"MarkerFelt-Wide";
font = [UIFont fontWithName:fntName size:nSize];
@ -252,7 +230,7 @@ static bool _initWithString(const char * pText, cocos2d::CCImage::ETextAlign eAl
if (font)
{
dim = _calculateStringSizeWithFontOrZFont(str, font, &constrainSize, false);
dim = _calculateStringSize(str, font, &constrainSize);
}
}
@ -314,6 +292,7 @@ static bool _initWithString(const char * pText, cocos2d::CCImage::ETextAlign eAl
: UITextAlignmentLeft);
// normal fonts
/*
if( [font isKindOfClass:[UIFont class] ] )
{
[str drawInRect:CGRectMake(0, startH, dim.width, dim.height) withFont:font lineBreakMode:(UILineBreakMode)UILineBreakModeWordWrap alignment:align];
@ -322,6 +301,8 @@ static bool _initWithString(const char * pText, cocos2d::CCImage::ETextAlign eAl
{
[FontLabelStringDrawingHelper drawInRect:str rect:CGRectMake(0, startH, dim.width, dim.height) withZFont:font lineBreakMode:(UILineBreakMode)UILineBreakModeWordWrap alignment:align];
}
*/
[str drawInRect:CGRectMake(0, startH, dim.width, dim.height) withFont:font lineBreakMode:(UILineBreakMode)UILineBreakModeWordWrap alignment:align];
UIGraphicsPopContext();

View File

@ -151,6 +151,11 @@ static EAGLView *view = 0;
originalRect_ = self.frame;
self.keyboardShowNotification = nil;
if ([view respondsToSelector:@selector(setContentScaleFactor:)])
{
view.contentScaleFactor = [[UIScreen mainScreen] scale];
}
}
return self;
@ -200,13 +205,13 @@ static EAGLView *view = 0;
-(int) getWidth
{
CGSize bound = [self bounds].size;
return bound.width;
return bound.width * self.contentScaleFactor;
}
-(int) getHeight
{
CGSize bound = [self bounds].size;
return bound.height;
return bound.height * self.contentScaleFactor;
}
@ -401,8 +406,8 @@ static EAGLView *view = 0;
int i = 0;
for (UITouch *touch in touches) {
ids[i] = (int)touch;
xs[i] = [touch locationInView: [touch view]].x;
ys[i] = [touch locationInView: [touch view]].y;
xs[i] = [touch locationInView: [touch view]].x * view.contentScaleFactor;;
ys[i] = [touch locationInView: [touch view]].y * view.contentScaleFactor;;
++i;
}
cocos2d::CCEGLView::sharedOpenGLView()->handleTouchesBegin(i, ids, xs, ys);
@ -421,8 +426,8 @@ static EAGLView *view = 0;
int i = 0;
for (UITouch *touch in touches) {
ids[i] = (int)touch;
xs[i] = [touch locationInView: [touch view]].x;
ys[i] = [touch locationInView: [touch view]].y;
xs[i] = [touch locationInView: [touch view]].x * view.contentScaleFactor;;
ys[i] = [touch locationInView: [touch view]].y * view.contentScaleFactor;;
++i;
}
cocos2d::CCEGLView::sharedOpenGLView()->handleTouchesMove(i, ids, xs, ys);
@ -442,8 +447,8 @@ static EAGLView *view = 0;
int i = 0;
for (UITouch *touch in touches) {
ids[i] = (int)touch;
xs[i] = [touch locationInView: [touch view]].x;
ys[i] = [touch locationInView: [touch view]].y;
xs[i] = [touch locationInView: [touch view]].x * view.contentScaleFactor;;
ys[i] = [touch locationInView: [touch view]].y * view.contentScaleFactor;;
++i;
}
cocos2d::CCEGLView::sharedOpenGLView()->handleTouchesEnd(i, ids, xs, ys);
@ -463,8 +468,8 @@ static EAGLView *view = 0;
int i = 0;
for (UITouch *touch in touches) {
ids[i] = (int)touch;
xs[i] = [touch locationInView: [touch view]].x;
ys[i] = [touch locationInView: [touch view]].y;
xs[i] = [touch locationInView: [touch view]].x * view.contentScaleFactor;;
ys[i] = [touch locationInView: [touch view]].y * view.contentScaleFactor;;
++i;
}
cocos2d::CCEGLView::sharedOpenGLView()->handleTouchesCancel(i, ids, xs, ys);
@ -786,6 +791,32 @@ static EAGLView *view = 0;
break;
}
float scaleX = cocos2d::CCEGLView::sharedOpenGLView()->getScaleX();
float scaleY = cocos2d::CCEGLView::sharedOpenGLView()->getScaleY();
if (self.contentScaleFactor == 2.0f)
{
// Convert to pixel coordinate
begin = CGRectApplyAffineTransform(begin, CGAffineTransformScale(CGAffineTransformIdentity, 2.0f, 2.0f));
end = CGRectApplyAffineTransform(end, CGAffineTransformScale(CGAffineTransformIdentity, 2.0f, 2.0f));
}
float offestY = cocos2d::CCEGLView::sharedOpenGLView()->getViewPortRect().origin.y;
CCLOG("offestY = %f", offestY);
if (offestY < 0.0f)
{
begin.origin.y += offestY;
begin.size.height -= offestY;
end.size.height -= offestY;
}
// Convert to desigin coordinate
begin = CGRectApplyAffineTransform(begin, CGAffineTransformScale(CGAffineTransformIdentity, 1.0f/scaleX, 1.0f/scaleY));
end = CGRectApplyAffineTransform(end, CGAffineTransformScale(CGAffineTransformIdentity, 1.0f/scaleX, 1.0f/scaleY));
cocos2d::CCIMEKeyboardNotificationInfo notiInfo;
notiInfo.begin = cocos2d::CCRect(begin.origin.x,
begin.origin.y,
@ -797,31 +828,6 @@ static EAGLView *view = 0;
end.size.height);
notiInfo.duration = (float)aniDuration;
float offestY = cocos2d::CCEGLView::sharedOpenGLView()->getViewPortRect().origin.y;
if (offestY > 0.0f)
{
notiInfo.begin.origin.y += offestY;
notiInfo.begin.size.height -= offestY;
notiInfo.end.size.height -= offestY;
}
if (!cocos2d::CCEGLView::sharedOpenGLView()->isRetinaEnabled())
{
float scaleX = cocos2d::CCEGLView::sharedOpenGLView()->getScaleX();
float scaleY = cocos2d::CCEGLView::sharedOpenGLView()->getScaleY();
notiInfo.begin.origin.x /= scaleX;
notiInfo.begin.origin.y /= scaleY;
notiInfo.begin.size.width /= scaleX;
notiInfo.begin.size.height /= scaleY;
notiInfo.end.origin.x /= scaleX;
notiInfo.end.origin.y /= scaleY;
notiInfo.end.size.width /= scaleX;
notiInfo.end.size.height /= scaleY;
}
cocos2d::CCIMEDispatcher* dispatcher = cocos2d::CCIMEDispatcher::sharedDispatcher();
if (UIKeyboardWillShowNotification == type)
{
@ -856,13 +862,15 @@ static EAGLView *view = 0;
[UIView setAnimationDuration:duration];
[UIView setAnimationBeginsFromCurrentState:YES];
// NSLog(@"[animation] dis = %f\n", dis);
//NSLog(@"[animation] dis = %f, scale = %f \n", dis, cocos2d::CCEGLView::sharedOpenGLView()->getScaleY());
if (dis < 0.0f) dis = 0.0f;
if (!cocos2d::CCEGLView::sharedOpenGLView()->isRetinaEnabled())
dis *= cocos2d::CCEGLView::sharedOpenGLView()->getScaleY();
if (self.contentScaleFactor == 2.0f)
{
dis *= cocos2d::CCEGLView::sharedOpenGLView()->getScaleY();
dis /= 2.0f;
}
switch ([[UIApplication sharedApplication] statusBarOrientation])

View File

@ -1,44 +0,0 @@
//
// FontLabel.h
// FontLabel
//
// Created by Kevin Ballard on 5/8/09.
// Copyright © 2009 Zynga Game Networks
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@class ZFont;
@class ZAttributedString;
@interface FontLabel : UILabel {
void *reserved; // works around a bug in UILabel
ZFont *zFont;
ZAttributedString *zAttributedText;
}
@property (nonatomic, setter=setCGFont:) CGFontRef cgFont __AVAILABILITY_INTERNAL_DEPRECATED;
@property (nonatomic, assign) CGFloat pointSize __AVAILABILITY_INTERNAL_DEPRECATED;
@property (nonatomic, retain, setter=setZFont:) ZFont *zFont;
// if attributedText is nil, fall back on using the inherited UILabel properties
// if attributedText is non-nil, the font/text/textColor
// in addition, adjustsFontSizeToFitWidth does not work with attributed text
@property (nonatomic, copy) ZAttributedString *zAttributedText;
// -initWithFrame:fontName:pointSize: uses FontManager to look up the font name
- (id)initWithFrame:(CGRect)frame fontName:(NSString *)fontName pointSize:(CGFloat)pointSize;
- (id)initWithFrame:(CGRect)frame zFont:(ZFont *)font;
- (id)initWithFrame:(CGRect)frame font:(CGFontRef)font pointSize:(CGFloat)pointSize __AVAILABILITY_INTERNAL_DEPRECATED;
@end

View File

@ -1,197 +0,0 @@
//
// FontLabel.m
// FontLabel
//
// Created by Kevin Ballard on 5/8/09.
// Copyright © 2009 Zynga Game Networks
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import "FontLabel.h"
#import "FontManager.h"
#import "FontLabelStringDrawing.h"
#import "ZFont.h"
@interface ZFont (ZFontPrivate)
@property (nonatomic, readonly) CGFloat ratio;
@end
@implementation FontLabel
@synthesize zFont;
@synthesize zAttributedText;
- (id)initWithFrame:(CGRect)frame fontName:(NSString *)fontName pointSize:(CGFloat)pointSize {
return [self initWithFrame:frame zFont:[[FontManager sharedManager] zFontWithName:fontName pointSize:pointSize]];
}
- (id)initWithFrame:(CGRect)frame zFont:(ZFont *)font {
if ((self = [super initWithFrame:frame])) {
zFont = [font retain];
}
return self;
}
- (id)initWithFrame:(CGRect)frame font:(CGFontRef)font pointSize:(CGFloat)pointSize {
return [self initWithFrame:frame zFont:[ZFont fontWithCGFont:font size:pointSize]];
}
- (CGFontRef)cgFont {
return self.zFont.cgFont;
}
- (void)setCGFont:(CGFontRef)font {
if (self.zFont.cgFont != font) {
self.zFont = [ZFont fontWithCGFont:font size:self.zFont.pointSize];
}
}
- (CGFloat)pointSize {
return self.zFont.pointSize;
}
- (void)setPointSize:(CGFloat)pointSize {
if (self.zFont.pointSize != pointSize) {
self.zFont = [ZFont fontWithCGFont:self.zFont.cgFont size:pointSize];
}
}
- (void)setZAttributedText:(ZAttributedString *)attStr {
if (zAttributedText != attStr) {
[zAttributedText release];
zAttributedText = [attStr copy];
[self setNeedsDisplay];
}
}
- (void)drawTextInRect:(CGRect)rect {
if (self.zFont == NULL && self.zAttributedText == nil) {
[super drawTextInRect:rect];
return;
}
if (self.zAttributedText == nil) {
// this method is documented as setting the text color for us, but that doesn't appear to be the case
if (self.highlighted) {
[(self.highlightedTextColor ?: [UIColor whiteColor]) setFill];
} else {
[(self.textColor ?: [UIColor blackColor]) setFill];
}
ZFont *actualFont = self.zFont;
CGSize origSize = rect.size;
if (self.numberOfLines == 1) {
origSize.height = actualFont.leading;
CGPoint point = CGPointMake(rect.origin.x,
rect.origin.y + roundf(((rect.size.height - actualFont.leading) / 2.0f)));
CGSize size = [self.text sizeWithZFont:actualFont];
if (self.adjustsFontSizeToFitWidth && self.minimumFontSize < actualFont.pointSize) {
if (size.width > origSize.width) {
CGFloat desiredRatio = (origSize.width * actualFont.ratio) / size.width;
CGFloat desiredPointSize = desiredRatio * actualFont.pointSize / actualFont.ratio;
actualFont = [actualFont fontWithSize:MAX(MAX(desiredPointSize, self.minimumFontSize), 1.0f)];
size = [self.text sizeWithZFont:actualFont];
}
if (!CGSizeEqualToSize(origSize, size)) {
switch (self.baselineAdjustment) {
case UIBaselineAdjustmentAlignCenters:
point.y += roundf((origSize.height - size.height) / 2.0f);
break;
case UIBaselineAdjustmentAlignBaselines:
point.y += (self.zFont.ascender - actualFont.ascender);
break;
case UIBaselineAdjustmentNone:
break;
}
}
}
size.width = MIN(size.width, origSize.width);
// adjust the point for alignment
switch (self.textAlignment) {
case UITextAlignmentLeft:
break;
case UITextAlignmentCenter:
point.x += (origSize.width - size.width) / 2.0f;
break;
case UITextAlignmentRight:
point.x += origSize.width - size.width;
break;
default:
break;
}
[self.text drawAtPoint:point forWidth:size.width withZFont:actualFont lineBreakMode:self.lineBreakMode];
} else {
CGSize size = [self.text sizeWithZFont:actualFont constrainedToSize:origSize lineBreakMode:self.lineBreakMode numberOfLines:self.numberOfLines];
CGPoint point = rect.origin;
point.y += roundf((rect.size.height - size.height) / 2.0f);
rect = (CGRect){point, CGSizeMake(rect.size.width, size.height)};
[self.text drawInRect:rect withZFont:actualFont lineBreakMode:self.lineBreakMode alignment:self.textAlignment numberOfLines:self.numberOfLines];
}
} else {
ZAttributedString *attStr = self.zAttributedText;
if (self.highlighted) {
// modify the string to change the base color
ZMutableAttributedString *mutStr = [[attStr mutableCopy] autorelease];
NSRange activeRange = NSMakeRange(0, attStr.length);
while (activeRange.length > 0) {
NSRange effective;
UIColor *color = [attStr attribute:ZForegroundColorAttributeName atIndex:activeRange.location
longestEffectiveRange:&effective inRange:activeRange];
if (color == nil) {
[mutStr addAttribute:ZForegroundColorAttributeName value:[UIColor whiteColor] range:effective];
}
activeRange.location += effective.length, activeRange.length -= effective.length;
}
attStr = mutStr;
}
CGSize size = [attStr sizeConstrainedToSize:rect.size lineBreakMode:self.lineBreakMode numberOfLines:self.numberOfLines];
CGPoint point = rect.origin;
point.y += roundf((rect.size.height - size.height) / 2.0f);
rect = (CGRect){point, CGSizeMake(rect.size.width, size.height)};
[attStr drawInRect:rect withLineBreakMode:self.lineBreakMode alignment:self.textAlignment numberOfLines:self.numberOfLines];
}
}
- (CGRect)textRectForBounds:(CGRect)bounds limitedToNumberOfLines:(NSInteger)numberOfLines {
if (self.zFont == NULL && self.zAttributedText == nil) {
return [super textRectForBounds:bounds limitedToNumberOfLines:numberOfLines];
}
if (numberOfLines == 1) {
// if numberOfLines == 1 we need to use the version that converts spaces
CGSize size;
if (self.zAttributedText == nil) {
size = [self.text sizeWithZFont:self.zFont];
} else {
size = [self.zAttributedText size];
}
bounds.size.width = MIN(bounds.size.width, size.width);
bounds.size.height = MIN(bounds.size.height, size.height);
} else {
if (numberOfLines > 0) bounds.size.height = MIN(bounds.size.height, self.zFont.leading * numberOfLines);
if (self.zAttributedText == nil) {
bounds.size = [self.text sizeWithZFont:self.zFont constrainedToSize:bounds.size lineBreakMode:self.lineBreakMode];
} else {
bounds.size = [self.zAttributedText sizeConstrainedToSize:bounds.size lineBreakMode:self.lineBreakMode];
}
}
return bounds;
}
- (void)dealloc {
[zFont release];
[zAttributedText release];
[super dealloc];
}
@end

View File

@ -1,82 +0,0 @@
//
// FontLabelStringDrawing.h
// FontLabel
//
// Created by Kevin Ballard on 5/5/09.
// Copyright © 2009 Zynga Game Networks
// Copyright (c) 2011 cocos2d-x.org
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import <UIKit/UIKit.h>
#import "ZAttributedString.h"
@class ZFont;
@interface NSString (FontLabelStringDrawing)
// CGFontRef-based methods
- (CGSize)sizeWithCGFont:(CGFontRef)font pointSize:(CGFloat)pointSize __AVAILABILITY_INTERNAL_DEPRECATED;
- (CGSize)sizeWithCGFont:(CGFontRef)font pointSize:(CGFloat)pointSize constrainedToSize:(CGSize)size __AVAILABILITY_INTERNAL_DEPRECATED;
- (CGSize)sizeWithCGFont:(CGFontRef)font pointSize:(CGFloat)pointSize constrainedToSize:(CGSize)size
lineBreakMode:(UILineBreakMode)lineBreakMode __AVAILABILITY_INTERNAL_DEPRECATED;
- (CGSize)drawAtPoint:(CGPoint)point withCGFont:(CGFontRef)font pointSize:(CGFloat)pointSize __AVAILABILITY_INTERNAL_DEPRECATED;
- (CGSize)drawInRect:(CGRect)rect withCGFont:(CGFontRef)font pointSize:(CGFloat)pointSize __AVAILABILITY_INTERNAL_DEPRECATED;
- (CGSize)drawInRect:(CGRect)rect withCGFont:(CGFontRef)font pointSize:(CGFloat)pointSize
lineBreakMode:(UILineBreakMode)lineBreakMode __AVAILABILITY_INTERNAL_DEPRECATED;
- (CGSize)drawInRect:(CGRect)rect withCGFont:(CGFontRef)font pointSize:(CGFloat)pointSize
lineBreakMode:(UILineBreakMode)lineBreakMode alignment:(UITextAlignment)alignment __AVAILABILITY_INTERNAL_DEPRECATED;
// ZFont-based methods
- (CGSize)sizeWithZFont:(ZFont *)font;
- (CGSize)sizeWithZFont:(ZFont *)font constrainedToSize:(CGSize)size;
- (CGSize)sizeWithZFont:(ZFont *)font constrainedToSize:(CGSize)size lineBreakMode:(UILineBreakMode)lineBreakMode;
- (CGSize)sizeWithZFont:(ZFont *)font constrainedToSize:(CGSize)size lineBreakMode:(UILineBreakMode)lineBreakMode
numberOfLines:(NSUInteger)numberOfLines;
- (CGSize)drawAtPoint:(CGPoint)point withZFont:(ZFont *)font;
- (CGSize)drawAtPoint:(CGPoint)point forWidth:(CGFloat)width withZFont:(ZFont *)font lineBreakMode:(UILineBreakMode)lineBreakMode;
- (CGSize)drawInRect:(CGRect)rect withZFont:(ZFont *)font;
- (CGSize)drawInRect:(CGRect)rect withZFont:(ZFont *)font lineBreakMode:(UILineBreakMode)lineBreakMode;
- (CGSize)drawInRect:(CGRect)rect withZFont:(ZFont *)font lineBreakMode:(UILineBreakMode)lineBreakMode
alignment:(UITextAlignment)alignment;
- (CGSize)drawInRect:(CGRect)rect withZFont:(ZFont *)font lineBreakMode:(UILineBreakMode)lineBreakMode
alignment:(UITextAlignment)alignment numberOfLines:(NSUInteger)numberOfLines;
@end
@interface ZAttributedString (ZAttributedStringDrawing)
- (CGSize)size;
- (CGSize)sizeConstrainedToSize:(CGSize)size;
- (CGSize)sizeConstrainedToSize:(CGSize)size lineBreakMode:(UILineBreakMode)lineBreakMode;
- (CGSize)sizeConstrainedToSize:(CGSize)size lineBreakMode:(UILineBreakMode)lineBreakMode
numberOfLines:(NSUInteger)numberOfLines;
- (CGSize)drawAtPoint:(CGPoint)point;
- (CGSize)drawAtPoint:(CGPoint)point forWidth:(CGFloat)width lineBreakMode:(UILineBreakMode)lineBreakMode;
- (CGSize)drawInRect:(CGRect)rect;
- (CGSize)drawInRect:(CGRect)rect withLineBreakMode:(UILineBreakMode)lineBreakMode;
- (CGSize)drawInRect:(CGRect)rect withLineBreakMode:(UILineBreakMode)lineBreakMode alignment:(UITextAlignment)alignment;
- (CGSize)drawInRect:(CGRect)rect withLineBreakMode:(UILineBreakMode)lineBreakMode alignment:(UITextAlignment)alignment
numberOfLines:(NSUInteger)numberOfLines;
@end
// This class is used to invoke in .mm file.
// Can not invoke FontLabelStringDrawing directly in .mm.
// It seems that, in .mm it can not support category.
@interface FontLabelStringDrawingHelper : NSObject {
}
+ (CGSize)sizeWithZFont:(NSString*)string zfont:(ZFont *)font;
+ (CGSize)sizeWithZFont:(NSString *)string zfont:(ZFont *)font constrainedToSize:(CGSize)size;
+ (CGSize)drawInRect:(NSString*)string rect:(CGRect)rect withZFont:(ZFont *)font
lineBreakMode:(UILineBreakMode)lineBreakMode
alignment:(UITextAlignment)alignment;
@end

View File

@ -1,916 +0,0 @@
//
// FontLabelStringDrawing.m
// FontLabel
//
// Created by Kevin Ballard on 5/5/09.
// Copyright © 2009 Zynga Game Networks
// Copyright (c) 2011 cocos2d-x.org
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import "FontLabelStringDrawing.h"
#import "ZFont.h"
#import "ZAttributedStringPrivate.h"
@interface ZFont (ZFontPrivate)
@property (nonatomic, readonly) CGFloat ratio;
@end
#define kUnicodeHighSurrogateStart 0xD800
#define kUnicodeHighSurrogateEnd 0xDBFF
#define kUnicodeHighSurrogateMask kUnicodeHighSurrogateStart
#define kUnicodeLowSurrogateStart 0xDC00
#define kUnicodeLowSurrogateEnd 0xDFFF
#define kUnicodeLowSurrogateMask kUnicodeLowSurrogateStart
#define kUnicodeSurrogateTypeMask 0xFC00
#define UnicharIsHighSurrogate(c) ((c & kUnicodeSurrogateTypeMask) == kUnicodeHighSurrogateMask)
#define UnicharIsLowSurrogate(c) ((c & kUnicodeSurrogateTypeMask) == kUnicodeLowSurrogateMask)
#define ConvertSurrogatePairToUTF32(high, low) ((UInt32)((high - 0xD800) * 0x400 + (low - 0xDC00) + 0x10000))
typedef enum {
kFontTableFormat4 = 4,
kFontTableFormat12 = 12,
} FontTableFormat;
typedef struct fontTable {
NSUInteger retainCount;
CFDataRef cmapTable;
FontTableFormat format;
union {
struct {
UInt16 segCountX2;
UInt16 *endCodes;
UInt16 *startCodes;
UInt16 *idDeltas;
UInt16 *idRangeOffsets;
} format4;
struct {
UInt32 nGroups;
struct {
UInt32 startCharCode;
UInt32 endCharCode;
UInt32 startGlyphCode;
} *groups;
} format12;
} cmap;
} fontTable;
static FontTableFormat supportedFormats[] = { kFontTableFormat4, kFontTableFormat12 };
static size_t supportedFormatsCount = sizeof(supportedFormats) / sizeof(FontTableFormat);
static fontTable *newFontTable(CFDataRef cmapTable, FontTableFormat format) {
fontTable *table = (struct fontTable *)malloc(sizeof(struct fontTable));
table->retainCount = 1;
table->cmapTable = CFRetain(cmapTable);
table->format = format;
return table;
}
static fontTable *retainFontTable(fontTable *table) {
if (table != NULL) {
table->retainCount++;
}
return table;
}
static void releaseFontTable(fontTable *table) {
if (table != NULL) {
if (table->retainCount <= 1) {
CFRelease(table->cmapTable);
free(table);
} else {
table->retainCount--;
}
}
}
static const void *fontTableRetainCallback(CFAllocatorRef allocator, const void *value) {
return retainFontTable((fontTable *)value);
}
static void fontTableReleaseCallback(CFAllocatorRef allocator, const void *value) {
releaseFontTable((fontTable *)value);
}
static const CFDictionaryValueCallBacks kFontTableDictionaryValueCallBacks = {
.version = 0,
.retain = &fontTableRetainCallback,
.release = &fontTableReleaseCallback,
.copyDescription = NULL,
.equal = NULL
};
// read the cmap table from the font
// we only know how to understand some of the table formats at the moment
static fontTable *readFontTableFromCGFont(CGFontRef font) {
CFDataRef cmapTable = CGFontCopyTableForTag(font, 'cmap');
NSCAssert1(cmapTable != NULL, @"CGFontCopyTableForTag returned NULL for 'cmap' tag in font %@",
(font ? [(id)CFCopyDescription(font) autorelease] : @"(null)"));
const UInt8 * const bytes = CFDataGetBytePtr(cmapTable);
NSCAssert1(OSReadBigInt16(bytes, 0) == 0, @"cmap table for font %@ has bad version number",
(font ? [(id)CFCopyDescription(font) autorelease] : @"(null)"));
UInt16 numberOfSubtables = OSReadBigInt16(bytes, 2);
const UInt8 *unicodeSubtable = NULL;
//UInt16 unicodeSubtablePlatformID;
UInt16 unicodeSubtablePlatformSpecificID;
FontTableFormat unicodeSubtableFormat;
const UInt8 * const encodingSubtables = &bytes[4];
for (UInt16 i = 0; i < numberOfSubtables; i++) {
const UInt8 * const encodingSubtable = &encodingSubtables[8 * i];
UInt16 platformID = OSReadBigInt16(encodingSubtable, 0);
UInt16 platformSpecificID = OSReadBigInt16(encodingSubtable, 2);
// find the best subtable
// best is defined by a combination of encoding and format
// At the moment we only support format 4, so ignore all other format tables
// We prefer platformID == 0, but we will also accept Microsoft's unicode format
if (platformID == 0 || (platformID == 3 && platformSpecificID == 1)) {
BOOL preferred = NO;
if (unicodeSubtable == NULL) {
preferred = YES;
} else if (platformID == 0 && platformSpecificID > unicodeSubtablePlatformSpecificID) {
preferred = YES;
}
if (preferred) {
UInt32 offset = OSReadBigInt32(encodingSubtable, 4);
const UInt8 *subtable = &bytes[offset];
UInt16 format = OSReadBigInt16(subtable, 0);
for (size_t i = 0; i < supportedFormatsCount; i++) {
if (format == supportedFormats[i]) {
if (format >= 8) {
// the version is a fixed-point
UInt16 formatFrac = OSReadBigInt16(subtable, 2);
if (formatFrac != 0) {
// all the current formats with a Fixed version are always *.0
continue;
}
}
unicodeSubtable = subtable;
//unicodeSubtablePlatformID = platformID;
unicodeSubtablePlatformSpecificID = platformSpecificID;
unicodeSubtableFormat = format;
break;
}
}
}
}
}
fontTable *table = NULL;
if (unicodeSubtable != NULL) {
table = newFontTable(cmapTable, unicodeSubtableFormat);
switch (unicodeSubtableFormat) {
case kFontTableFormat4:
// subtable format 4
//UInt16 length = OSReadBigInt16(unicodeSubtable, 2);
//UInt16 language = OSReadBigInt16(unicodeSubtable, 4);
table->cmap.format4.segCountX2 = OSReadBigInt16(unicodeSubtable, 6);
//UInt16 searchRange = OSReadBigInt16(unicodeSubtable, 8);
//UInt16 entrySelector = OSReadBigInt16(unicodeSubtable, 10);
//UInt16 rangeShift = OSReadBigInt16(unicodeSubtable, 12);
table->cmap.format4.endCodes = (UInt16*)&unicodeSubtable[14];
table->cmap.format4.startCodes = (UInt16*)&((UInt8*)table->cmap.format4.endCodes)[table->cmap.format4.segCountX2+2];
table->cmap.format4.idDeltas = (UInt16*)&((UInt8*)table->cmap.format4.startCodes)[table->cmap.format4.segCountX2];
table->cmap.format4.idRangeOffsets = (UInt16*)&((UInt8*)table->cmap.format4.idDeltas)[table->cmap.format4.segCountX2];
//UInt16 *glyphIndexArray = &idRangeOffsets[segCountX2];
break;
case kFontTableFormat12:
table->cmap.format12.nGroups = OSReadBigInt32(unicodeSubtable, 12);
table->cmap.format12.groups = (void *)&unicodeSubtable[16];
break;
default:
releaseFontTable(table);
table = NULL;
}
}
CFRelease(cmapTable);
return table;
}
// outGlyphs must be at least size n
static void mapCharactersToGlyphsInFont(const fontTable *table, unichar characters[], size_t charLen, CGGlyph outGlyphs[], size_t *outGlyphLen) {
if (table != NULL) {
NSUInteger j = 0;
switch (table->format) {
case kFontTableFormat4: {
for (NSUInteger i = 0; i < charLen; i++, j++) {
unichar c = characters[i];
UInt16 segOffset;
BOOL foundSegment = NO;
for (segOffset = 0; segOffset < table->cmap.format4.segCountX2; segOffset += 2) {
UInt16 endCode = OSReadBigInt16(table->cmap.format4.endCodes, segOffset);
if (endCode >= c) {
foundSegment = YES;
break;
}
}
if (!foundSegment) {
// no segment
// this is an invalid font
outGlyphs[j] = 0;
} else {
UInt16 startCode = OSReadBigInt16(table->cmap.format4.startCodes, segOffset);
if (!(startCode <= c)) {
// the code falls in a hole between segments
outGlyphs[j] = 0;
} else {
UInt16 idRangeOffset = OSReadBigInt16(table->cmap.format4.idRangeOffsets, segOffset);
if (idRangeOffset == 0) {
UInt16 idDelta = OSReadBigInt16(table->cmap.format4.idDeltas, segOffset);
outGlyphs[j] = (c + idDelta) % 65536;
} else {
// use the glyphIndexArray
UInt16 glyphOffset = idRangeOffset + 2 * (c - startCode);
outGlyphs[j] = OSReadBigInt16(&((UInt8*)table->cmap.format4.idRangeOffsets)[segOffset], glyphOffset);
}
}
}
}
break;
}
case kFontTableFormat12: {
UInt32 lastSegment = UINT32_MAX;
for (NSUInteger i = 0; i < charLen; i++, j++) {
unichar c = characters[i];
UInt32 c32 = c;
if (UnicharIsHighSurrogate(c)) {
if (i+1 < charLen) { // do we have another character after this one?
unichar cc = characters[i+1];
if (UnicharIsLowSurrogate(cc)) {
c32 = ConvertSurrogatePairToUTF32(c, cc);
i++;
}
}
}
// Start the heuristic search
// If this is an ASCII char, just do a linear search
// Otherwise do a hinted, modified binary search
// Start the first pivot at the last range found
// And when moving the pivot, limit the movement by increasing
// powers of two. This should help with locality
__typeof__(table->cmap.format12.groups[0]) *foundGroup = NULL;
if (c32 <= 0x7F) {
// ASCII
for (UInt32 idx = 0; idx < table->cmap.format12.nGroups; idx++) {
__typeof__(table->cmap.format12.groups[idx]) *group = &table->cmap.format12.groups[idx];
if (c32 < OSSwapBigToHostInt32(group->startCharCode)) {
// we've fallen into a hole
break;
} else if (c32 <= OSSwapBigToHostInt32(group->endCharCode)) {
// this is the range
foundGroup = group;
break;
}
}
} else {
// heuristic search
UInt32 maxJump = (lastSegment == UINT32_MAX ? UINT32_MAX / 2 : 8);
UInt32 lowIdx = 0, highIdx = table->cmap.format12.nGroups; // highIdx is the first invalid idx
UInt32 pivot = (lastSegment == UINT32_MAX ? lowIdx + (highIdx - lowIdx) / 2 : lastSegment);
while (highIdx > lowIdx) {
__typeof__(table->cmap.format12.groups[pivot]) *group = &table->cmap.format12.groups[pivot];
if (c32 < OSSwapBigToHostInt32(group->startCharCode)) {
highIdx = pivot;
} else if (c32 > OSSwapBigToHostInt32(group->endCharCode)) {
lowIdx = pivot + 1;
} else {
// we've hit the range
foundGroup = group;
break;
}
if (highIdx - lowIdx > maxJump * 2) {
if (highIdx == pivot) {
pivot -= maxJump;
} else {
pivot += maxJump;
}
maxJump *= 2;
} else {
pivot = lowIdx + (highIdx - lowIdx) / 2;
}
}
if (foundGroup != NULL) lastSegment = pivot;
}
if (foundGroup == NULL) {
outGlyphs[j] = 0;
} else {
outGlyphs[j] = (CGGlyph)(OSSwapBigToHostInt32(foundGroup->startGlyphCode) +
(c32 - OSSwapBigToHostInt32(foundGroup->startCharCode)));
}
}
break;
}
}
if (outGlyphLen != NULL) *outGlyphLen = j;
} else {
// we have no table, so just null out the glyphs
bzero(outGlyphs, charLen*sizeof(CGGlyph));
if (outGlyphLen != NULL) *outGlyphLen = 0;
}
}
static BOOL mapGlyphsToAdvancesInFont(ZFont *font, size_t n, CGGlyph glyphs[], CGFloat outAdvances[]) {
int advances[n];
if (CGFontGetGlyphAdvances(font.cgFont, glyphs, n, advances)) {
CGFloat ratio = font.ratio;
for (size_t i = 0; i < n; i++) {
outAdvances[i] = advances[i]*ratio;
}
return YES;
} else {
bzero(outAdvances, n*sizeof(CGFloat));
}
return NO;
}
static id getValueOrDefaultForRun(ZAttributeRun *run, NSString *key) {
id value = [run.attributes objectForKey:key];
if (value == nil) {
static NSDictionary *defaultValues = nil;
if (defaultValues == nil) {
defaultValues = [[NSDictionary alloc] initWithObjectsAndKeys:
[ZFont fontWithUIFont:[UIFont systemFontOfSize:12]], ZFontAttributeName,
[UIColor blackColor], ZForegroundColorAttributeName,
[UIColor clearColor], ZBackgroundColorAttributeName,
[NSNumber numberWithInt:ZUnderlineStyleNone], ZUnderlineStyleAttributeName,
nil];
}
value = [defaultValues objectForKey:key];
}
return value;
}
static void readRunInformation(NSArray *attributes, NSUInteger len, CFMutableDictionaryRef fontTableMap,
NSUInteger index, ZAttributeRun **currentRun, NSUInteger *nextRunStart,
ZFont **currentFont, fontTable **currentTable) {
*currentRun = [attributes objectAtIndex:index];
*nextRunStart = ([attributes count] > index+1 ? [[attributes objectAtIndex:index+1] index] : len);
*currentFont = getValueOrDefaultForRun(*currentRun, ZFontAttributeName);
if (!CFDictionaryGetValueIfPresent(fontTableMap, (*currentFont).cgFont, (const void **)currentTable)) {
*currentTable = readFontTableFromCGFont((*currentFont).cgFont);
CFDictionarySetValue(fontTableMap, (*currentFont).cgFont, *currentTable);
releaseFontTable(*currentTable);
}
}
static CGSize drawOrSizeTextConstrainedToSize(BOOL performDraw, NSString *string, NSArray *attributes, CGSize constrainedSize, NSUInteger maxLines,
UILineBreakMode lineBreakMode, UITextAlignment alignment, BOOL ignoreColor) {
NSUInteger len = [string length];
NSUInteger idx = 0;
CGPoint drawPoint = CGPointZero;
CGSize retValue = CGSizeZero;
CGContextRef ctx = (performDraw ? UIGraphicsGetCurrentContext() : NULL);
BOOL convertNewlines = (maxLines == 1);
// Extract the characters from the string
// Convert newlines to spaces if necessary
unichar *characters = (unichar *)malloc(sizeof(unichar) * len);
if (convertNewlines) {
NSCharacterSet *charset = [NSCharacterSet newlineCharacterSet];
NSRange range = NSMakeRange(0, len);
size_t cIdx = 0;
while (range.length > 0) {
NSRange newlineRange = [string rangeOfCharacterFromSet:charset options:0 range:range];
if (newlineRange.location == NSNotFound) {
[string getCharacters:&characters[cIdx] range:range];
cIdx += range.length;
break;
} else {
NSUInteger delta = newlineRange.location - range.location;
if (newlineRange.location > range.location) {
[string getCharacters:&characters[cIdx] range:NSMakeRange(range.location, delta)];
}
cIdx += delta;
characters[cIdx] = (unichar)' ';
cIdx++;
delta += newlineRange.length;
range.location += delta, range.length -= delta;
if (newlineRange.length == 1 && range.length >= 1 &&
[string characterAtIndex:newlineRange.location] == (unichar)'\r' &&
[string characterAtIndex:range.location] == (unichar)'\n') {
// CRLF sequence, skip the LF
range.location += 1, range.length -= 1;
}
}
}
len = cIdx;
} else {
[string getCharacters:characters range:NSMakeRange(0, len)];
}
// Create storage for glyphs and advances
CGGlyph *glyphs;
CGFloat *advances;
{
NSUInteger maxRunLength = 0;
ZAttributeRun *a = [attributes objectAtIndex:0];
for (NSUInteger i = 1; i < [attributes count]; i++) {
ZAttributeRun *b = [attributes objectAtIndex:i];
maxRunLength = MAX(maxRunLength, b.index - a.index);
a = b;
}
maxRunLength = MAX(maxRunLength, len - a.index);
maxRunLength++; // for a potential ellipsis
glyphs = (CGGlyph *)malloc(sizeof(CGGlyph) * maxRunLength);
advances = (CGFloat *)malloc(sizeof(CGFloat) * maxRunLength);
}
// Use this table to cache all fontTable objects
CFMutableDictionaryRef fontTableMap = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks,
&kFontTableDictionaryValueCallBacks);
// Fetch initial style values
NSUInteger currentRunIdx = 0;
ZAttributeRun *currentRun;
NSUInteger nextRunStart;
ZFont *currentFont;
fontTable *currentTable;
#define READ_RUN() readRunInformation(attributes, len, fontTableMap, \
currentRunIdx, &currentRun, &nextRunStart, \
&currentFont, &currentTable)
READ_RUN();
// fetch the glyphs for the first run
size_t glyphCount;
NSUInteger glyphIdx;
#define READ_GLYPHS() do { \
mapCharactersToGlyphsInFont(currentTable, &characters[currentRun.index], (nextRunStart - currentRun.index), glyphs, &glyphCount); \
mapGlyphsToAdvancesInFont(currentFont, (nextRunStart - currentRun.index), glyphs, advances); \
glyphIdx = 0; \
} while (0)
READ_GLYPHS();
NSMutableCharacterSet *alphaCharset = [NSMutableCharacterSet alphanumericCharacterSet];
[alphaCharset addCharactersInString:@"([{'\"\u2019\u02BC"];
// scan left-to-right looking for newlines or until we hit the width constraint
// When we hit a wrapping point, calculate truncation as follows:
// If we have room to draw at least one more character on the next line, no truncation
// Otherwise apply the truncation algorithm to the current line.
// After calculating any truncation, draw.
// Each time we hit the end of an attribute run, calculate the new font and make sure
// it fits (vertically) within the size constraint. If not, truncate this line.
// When we draw, iterate over the attribute runs for this line and draw each run separately
BOOL lastLine = NO; // used to indicate truncation and to stop the iterating
NSUInteger lineCount = 1;
while (idx < len && !lastLine) {
if (maxLines > 0 && lineCount == maxLines) {
lastLine = YES;
}
// scan left-to-right
struct {
NSUInteger index;
NSUInteger glyphIndex;
NSUInteger currentRunIdx;
} indexCache = { idx, glyphIdx, currentRunIdx };
CGSize lineSize = CGSizeMake(0, currentFont.leading);
CGFloat lineAscender = currentFont.ascender;
struct {
NSUInteger index;
NSUInteger glyphIndex;
NSUInteger currentRunIdx;
CGSize lineSize;
} lastWrapCache = {0, 0, 0, CGSizeZero};
BOOL inAlpha = NO; // used for calculating wrap points
BOOL finishLine = NO;
for (;idx <= len && !finishLine;) {
NSUInteger skipCount = 0;
if (idx == len) {
finishLine = YES;
lastLine = YES;
} else {
if (idx >= nextRunStart) {
// cycle the font and table and grab the next set of glyphs
do {
currentRunIdx++;
READ_RUN();
} while (idx >= nextRunStart);
READ_GLYPHS();
// re-scan the characters to synchronize the glyph index
for (NSUInteger j = currentRun.index; j < idx; j++) {
if (UnicharIsHighSurrogate(characters[j]) && j+1<len && UnicharIsLowSurrogate(characters[j+1])) {
j++;
}
glyphIdx++;
}
if (currentFont.leading > lineSize.height) {
lineSize.height = currentFont.leading;
if (retValue.height + currentFont.ascender > constrainedSize.height) {
lastLine = YES;
finishLine = YES;
}
}
lineAscender = MAX(lineAscender, currentFont.ascender);
}
unichar c = characters[idx];
// Mark a wrap point before spaces and after any stretch of non-alpha characters
BOOL markWrap = NO;
if (c == (unichar)' ') {
markWrap = YES;
} else if ([alphaCharset characterIsMember:c]) {
if (!inAlpha) {
markWrap = YES;
inAlpha = YES;
}
} else {
inAlpha = NO;
}
if (markWrap) {
lastWrapCache = (__typeof__(lastWrapCache)){
.index = idx,
.glyphIndex = glyphIdx,
.currentRunIdx = currentRunIdx,
.lineSize = lineSize
};
}
// process the line
if (c == (unichar)'\n' || c == 0x0085) { // U+0085 is the NEXT_LINE unicode character
finishLine = YES;
skipCount = 1;
} else if (c == (unichar)'\r') {
finishLine = YES;
// check for CRLF
if (idx+1 < len && characters[idx+1] == (unichar)'\n') {
skipCount = 2;
} else {
skipCount = 1;
}
} else if (lineSize.width + advances[glyphIdx] > constrainedSize.width) {
finishLine = YES;
if (retValue.height + lineSize.height + currentFont.ascender > constrainedSize.height) {
lastLine = YES;
}
// walk backwards if wrapping is necessary
if (lastWrapCache.index > indexCache.index && lineBreakMode != UILineBreakModeCharacterWrap &&
(!lastLine || lineBreakMode != UILineBreakModeClip)) {
// we're doing some sort of word wrapping
idx = lastWrapCache.index;
lineSize = lastWrapCache.lineSize;
if (!lastLine) {
// re-check if this is the last line
if (lastWrapCache.currentRunIdx != currentRunIdx) {
currentRunIdx = lastWrapCache.currentRunIdx;
READ_RUN();
READ_GLYPHS();
}
if (retValue.height + lineSize.height + currentFont.ascender > constrainedSize.height) {
lastLine = YES;
}
}
glyphIdx = lastWrapCache.glyphIndex;
// skip any spaces
for (NSUInteger j = idx; j < len && characters[j] == (unichar)' '; j++) {
skipCount++;
}
}
}
}
if (finishLine) {
// TODO: support head/middle truncation
if (lastLine && idx < len && lineBreakMode == UILineBreakModeTailTruncation) {
// truncate
unichar ellipsis = 0x2026; // ellipsis ()
CGGlyph ellipsisGlyph;
mapCharactersToGlyphsInFont(currentTable, &ellipsis, 1, &ellipsisGlyph, NULL);
CGFloat ellipsisWidth;
mapGlyphsToAdvancesInFont(currentFont, 1, &ellipsisGlyph, &ellipsisWidth);
while ((idx - indexCache.index) > 1 && lineSize.width + ellipsisWidth > constrainedSize.width) {
// we have more than 1 character and we're too wide, so back up
idx--;
if (UnicharIsHighSurrogate(characters[idx]) && UnicharIsLowSurrogate(characters[idx+1])) {
idx--;
}
if (idx < currentRun.index) {
ZFont *oldFont = currentFont;
do {
currentRunIdx--;
READ_RUN();
} while (idx < currentRun.index);
READ_GLYPHS();
glyphIdx = glyphCount-1;
if (oldFont != currentFont) {
mapCharactersToGlyphsInFont(currentTable, &ellipsis, 1, &ellipsisGlyph, NULL);
mapGlyphsToAdvancesInFont(currentFont, 1, &ellipsisGlyph, &ellipsisWidth);
}
} else {
glyphIdx--;
}
lineSize.width -= advances[glyphIdx];
}
// skip any spaces before truncating
while ((idx - indexCache.index) > 1 && characters[idx-1] == (unichar)' ') {
idx--;
if (idx < currentRun.index) {
currentRunIdx--;
READ_RUN();
READ_GLYPHS();
glyphIdx = glyphCount-1;
} else {
glyphIdx--;
}
lineSize.width -= advances[glyphIdx];
}
lineSize.width += ellipsisWidth;
glyphs[glyphIdx] = ellipsisGlyph;
idx++;
glyphIdx++;
}
retValue.width = MAX(retValue.width, lineSize.width);
retValue.height += lineSize.height;
// draw
if (performDraw) {
switch (alignment) {
case UITextAlignmentLeft:
drawPoint.x = 0;
break;
case UITextAlignmentCenter:
drawPoint.x = (constrainedSize.width - lineSize.width) / 2.0f;
break;
case UITextAlignmentRight:
drawPoint.x = constrainedSize.width - lineSize.width;
break;
default:
break;
}
NSUInteger stopGlyphIdx = glyphIdx;
NSUInteger lastRunIdx = currentRunIdx;
NSUInteger stopCharIdx = idx;
idx = indexCache.index;
if (currentRunIdx != indexCache.currentRunIdx) {
currentRunIdx = indexCache.currentRunIdx;
READ_RUN();
READ_GLYPHS();
}
glyphIdx = indexCache.glyphIndex;
for (NSUInteger drawIdx = currentRunIdx; drawIdx <= lastRunIdx; drawIdx++) {
if (drawIdx != currentRunIdx) {
currentRunIdx = drawIdx;
READ_RUN();
READ_GLYPHS();
}
NSUInteger numGlyphs;
if (drawIdx == lastRunIdx) {
numGlyphs = stopGlyphIdx - glyphIdx;
idx = stopCharIdx;
} else {
numGlyphs = glyphCount - glyphIdx;
idx = nextRunStart;
}
CGContextSetFont(ctx, currentFont.cgFont);
CGContextSetFontSize(ctx, currentFont.pointSize);
// calculate the fragment size
CGFloat fragmentWidth = 0;
for (NSUInteger g = 0; g < numGlyphs; g++) {
fragmentWidth += advances[glyphIdx + g];
}
if (!ignoreColor) {
UIColor *foregroundColor = getValueOrDefaultForRun(currentRun, ZForegroundColorAttributeName);
UIColor *backgroundColor = getValueOrDefaultForRun(currentRun, ZBackgroundColorAttributeName);
if (backgroundColor != nil && ![backgroundColor isEqual:[UIColor clearColor]]) {
[backgroundColor setFill];
UIRectFillUsingBlendMode((CGRect){ drawPoint, { fragmentWidth, lineSize.height } }, kCGBlendModeNormal);
}
[foregroundColor setFill];
}
CGContextShowGlyphsAtPoint(ctx, drawPoint.x, drawPoint.y + lineAscender, &glyphs[glyphIdx], numGlyphs);
NSNumber *underlineStyle = getValueOrDefaultForRun(currentRun, ZUnderlineStyleAttributeName);
if ([underlineStyle integerValue] & ZUnderlineStyleMask) {
// we only support single for the time being
UIRectFill(CGRectMake(drawPoint.x, drawPoint.y + lineAscender, fragmentWidth, 1));
}
drawPoint.x += fragmentWidth;
glyphIdx += numGlyphs;
}
drawPoint.y += lineSize.height;
}
idx += skipCount;
glyphIdx += skipCount;
lineCount++;
} else {
lineSize.width += advances[glyphIdx];
glyphIdx++;
idx++;
if (idx < len && UnicharIsHighSurrogate(characters[idx-1]) && UnicharIsLowSurrogate(characters[idx])) {
// skip the second half of the surrogate pair
idx++;
}
}
}
}
CFRelease(fontTableMap);
free(glyphs);
free(advances);
free(characters);
#undef READ_GLYPHS
#undef READ_RUN
return retValue;
}
static NSArray *attributeRunForFont(ZFont *font) {
return [NSArray arrayWithObject:[ZAttributeRun attributeRunWithIndex:0
attributes:[NSDictionary dictionaryWithObject:font
forKey:ZFontAttributeName]]];
}
static CGSize drawTextInRect(CGRect rect, NSString *text, NSArray *attributes, UILineBreakMode lineBreakMode,
UITextAlignment alignment, NSUInteger numberOfLines, BOOL ignoreColor) {
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSaveGState(ctx);
// flip it upside-down because our 0,0 is upper-left, whereas ttfs are for screens where 0,0 is lower-left
CGAffineTransform textTransform = CGAffineTransformMake(1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f);
CGContextSetTextMatrix(ctx, textTransform);
CGContextTranslateCTM(ctx, rect.origin.x, rect.origin.y);
CGContextSetTextDrawingMode(ctx, kCGTextFill);
CGSize size = drawOrSizeTextConstrainedToSize(YES, text, attributes, rect.size, numberOfLines, lineBreakMode, alignment, ignoreColor);
CGContextRestoreGState(ctx);
return size;
}
@implementation NSString (FontLabelStringDrawing)
// CGFontRef-based methods
- (CGSize)sizeWithCGFont:(CGFontRef)font pointSize:(CGFloat)pointSize {
return [self sizeWithZFont:[ZFont fontWithCGFont:font size:pointSize]];
}
- (CGSize)sizeWithCGFont:(CGFontRef)font pointSize:(CGFloat)pointSize constrainedToSize:(CGSize)size {
return [self sizeWithZFont:[ZFont fontWithCGFont:font size:pointSize] constrainedToSize:size];
}
- (CGSize)sizeWithCGFont:(CGFontRef)font pointSize:(CGFloat)pointSize constrainedToSize:(CGSize)size
lineBreakMode:(UILineBreakMode)lineBreakMode {
return [self sizeWithZFont:[ZFont fontWithCGFont:font size:pointSize] constrainedToSize:size lineBreakMode:lineBreakMode];
}
- (CGSize)drawAtPoint:(CGPoint)point withCGFont:(CGFontRef)font pointSize:(CGFloat)pointSize {
return [self drawAtPoint:point withZFont:[ZFont fontWithCGFont:font size:pointSize]];
}
- (CGSize)drawInRect:(CGRect)rect withCGFont:(CGFontRef)font pointSize:(CGFloat)pointSize {
return [self drawInRect:rect withZFont:[ZFont fontWithCGFont:font size:pointSize]];
}
- (CGSize)drawInRect:(CGRect)rect withCGFont:(CGFontRef)font pointSize:(CGFloat)pointSize lineBreakMode:(UILineBreakMode)lineBreakMode {
return [self drawInRect:rect withZFont:[ZFont fontWithCGFont:font size:pointSize] lineBreakMode:lineBreakMode];
}
- (CGSize)drawInRect:(CGRect)rect withCGFont:(CGFontRef)font pointSize:(CGFloat)pointSize
lineBreakMode:(UILineBreakMode)lineBreakMode alignment:(UITextAlignment)alignment {
return [self drawInRect:rect withZFont:[ZFont fontWithCGFont:font size:pointSize] lineBreakMode:lineBreakMode alignment:alignment];
}
// ZFont-based methods
- (CGSize)sizeWithZFont:(ZFont *)font {
CGSize size = drawOrSizeTextConstrainedToSize(NO, self, attributeRunForFont(font), CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX), 1,
UILineBreakModeClip, UITextAlignmentLeft, YES);
return CGSizeMake(ceilf(size.width), ceilf(size.height));
}
- (CGSize)sizeWithZFont:(ZFont *)font constrainedToSize:(CGSize)size {
return [self sizeWithZFont:font constrainedToSize:size lineBreakMode:UILineBreakModeWordWrap];
}
/*
According to experimentation with UIStringDrawing, this can actually return a CGSize whose height is greater
than the one passed in. The two cases are as follows:
1. If the given size parameter's height is smaller than a single line, the returned value will
be the height of one line.
2. If the given size parameter's height falls between multiples of a line height, and the wrapped string
actually extends past the size.height, and the difference between size.height and the previous multiple
of a line height is >= the font's ascender, then the returned size's height is extended to the next line.
To put it simply, if the baseline point of a given line falls in the given size, the entire line will
be present in the output size.
*/
- (CGSize)sizeWithZFont:(ZFont *)font constrainedToSize:(CGSize)size lineBreakMode:(UILineBreakMode)lineBreakMode {
size = drawOrSizeTextConstrainedToSize(NO, self, attributeRunForFont(font), size, 0, lineBreakMode, UITextAlignmentLeft, YES);
return CGSizeMake(ceilf(size.width), ceilf(size.height));
}
- (CGSize)sizeWithZFont:(ZFont *)font constrainedToSize:(CGSize)size lineBreakMode:(UILineBreakMode)lineBreakMode
numberOfLines:(NSUInteger)numberOfLines {
size = drawOrSizeTextConstrainedToSize(NO, self, attributeRunForFont(font), size, numberOfLines, lineBreakMode, UITextAlignmentLeft, YES);
return CGSizeMake(ceilf(size.width), ceilf(size.height));
}
- (CGSize)drawAtPoint:(CGPoint)point withZFont:(ZFont *)font {
return [self drawAtPoint:point forWidth:CGFLOAT_MAX withZFont:font lineBreakMode:UILineBreakModeClip];
}
- (CGSize)drawAtPoint:(CGPoint)point forWidth:(CGFloat)width withZFont:(ZFont *)font lineBreakMode:(UILineBreakMode)lineBreakMode {
return drawTextInRect((CGRect){ point, { width, CGFLOAT_MAX } }, self, attributeRunForFont(font), lineBreakMode, UITextAlignmentLeft, 1, YES);
}
- (CGSize)drawInRect:(CGRect)rect withZFont:(ZFont *)font {
return [self drawInRect:rect withZFont:font lineBreakMode:UILineBreakModeWordWrap];
}
- (CGSize)drawInRect:(CGRect)rect withZFont:(ZFont *)font lineBreakMode:(UILineBreakMode)lineBreakMode {
return [self drawInRect:rect withZFont:font lineBreakMode:lineBreakMode alignment:UITextAlignmentLeft];
}
- (CGSize)drawInRect:(CGRect)rect withZFont:(ZFont *)font lineBreakMode:(UILineBreakMode)lineBreakMode
alignment:(UITextAlignment)alignment {
return drawTextInRect(rect, self, attributeRunForFont(font), lineBreakMode, alignment, 0, YES);
}
- (CGSize)drawInRect:(CGRect)rect withZFont:(ZFont *)font lineBreakMode:(UILineBreakMode)lineBreakMode
alignment:(UITextAlignment)alignment numberOfLines:(NSUInteger)numberOfLines {
return drawTextInRect(rect, self, attributeRunForFont(font), lineBreakMode, alignment, numberOfLines, YES);
}
@end
@implementation ZAttributedString (ZAttributedStringDrawing)
- (CGSize)size {
CGSize size = drawOrSizeTextConstrainedToSize(NO, self.string, self.attributes, CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX), 1,
UILineBreakModeClip, UITextAlignmentLeft, NO);
return CGSizeMake(ceilf(size.width), ceilf(size.height));
}
- (CGSize)sizeConstrainedToSize:(CGSize)size {
return [self sizeConstrainedToSize:size lineBreakMode:UILineBreakModeWordWrap];
}
- (CGSize)sizeConstrainedToSize:(CGSize)size lineBreakMode:(UILineBreakMode)lineBreakMode {
size = drawOrSizeTextConstrainedToSize(NO, self.string, self.attributes, size, 0, lineBreakMode, UITextAlignmentLeft, NO);
return CGSizeMake(ceilf(size.width), ceilf(size.height));
}
- (CGSize)sizeConstrainedToSize:(CGSize)size lineBreakMode:(UILineBreakMode)lineBreakMode
numberOfLines:(NSUInteger)numberOfLines {
size = drawOrSizeTextConstrainedToSize(NO, self.string, self.attributes, size, numberOfLines, lineBreakMode, UITextAlignmentLeft, NO);
return CGSizeMake(ceilf(size.width), ceilf(size.height));
}
- (CGSize)drawAtPoint:(CGPoint)point {
return [self drawAtPoint:point forWidth:CGFLOAT_MAX lineBreakMode:UILineBreakModeClip];
}
- (CGSize)drawAtPoint:(CGPoint)point forWidth:(CGFloat)width lineBreakMode:(UILineBreakMode)lineBreakMode {
return drawTextInRect((CGRect){ point, { width, CGFLOAT_MAX } }, self.string, self.attributes, lineBreakMode, UITextAlignmentLeft, 1, NO);
}
- (CGSize)drawInRect:(CGRect)rect {
return [self drawInRect:rect withLineBreakMode:UILineBreakModeWordWrap];
}
- (CGSize)drawInRect:(CGRect)rect withLineBreakMode:(UILineBreakMode)lineBreakMode {
return [self drawInRect:rect withLineBreakMode:lineBreakMode alignment:UITextAlignmentLeft];
}
- (CGSize)drawInRect:(CGRect)rect withLineBreakMode:(UILineBreakMode)lineBreakMode alignment:(UITextAlignment)alignment {
return drawTextInRect(rect, self.string, self.attributes, lineBreakMode, alignment, 0, NO);
}
- (CGSize)drawInRect:(CGRect)rect withLineBreakMode:(UILineBreakMode)lineBreakMode alignment:(UITextAlignment)alignment
numberOfLines:(NSUInteger)numberOfLines {
return drawTextInRect(rect, self.string, self.attributes, lineBreakMode, alignment, numberOfLines, NO);
}
@end
@implementation FontLabelStringDrawingHelper
+ (CGSize)sizeWithZFont:(NSString*)string zfont:(ZFont *)font {
CGSize size = drawOrSizeTextConstrainedToSize(NO, string, attributeRunForFont(font), CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX), 1,
UILineBreakModeClip, UITextAlignmentLeft, YES);
return CGSizeMake(ceilf(size.width), ceilf(size.height));
}
+ (CGSize)sizeWithZFont:(NSString *)string zfont:(ZFont *)font constrainedToSize:(CGSize)size {
CGSize s = drawOrSizeTextConstrainedToSize(NO, string, attributeRunForFont(font), size, 0, UILineBreakModeWordWrap, UITextAlignmentLeft, YES);
return CGSizeMake(ceilf(s.width), ceilf(s.height));
}
+ (CGSize)drawInRect:(NSString*)string rect:(CGRect)rect withZFont:(ZFont *)font lineBreakMode:(UILineBreakMode)lineBreakMode
alignment:(UITextAlignment)alignment {
return [string drawInRect:rect withZFont:font lineBreakMode:lineBreakMode alignment:alignment];
}
@end

View File

@ -1,85 +0,0 @@
//
// FontManager.h
// FontLabel
//
// Created by Kevin Ballard on 5/5/09.
// Copyright © 2009 Zynga Game Networks
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import <Foundation/Foundation.h>
#import <CoreGraphics/CoreGraphics.h>
@class ZFont;
@interface FontManager : NSObject {
CFMutableDictionaryRef fonts;
NSMutableDictionary *urls;
}
+ (FontManager *)sharedManager;
/*!
@method
@abstract Loads a TTF font from the main bundle
@param filename The name of the font file to load (with or without extension).
@return YES if the font was loaded, NO if an error occurred
@discussion If the font has already been loaded, this method does nothing and returns YES.
This method first attempts to load the font by appending .ttf to the filename.
If that file does not exist, it tries the filename exactly as given.
*/
- (BOOL)loadFont:(NSString *)filename;
/*!
@method
@abstract Loads a font from the given file URL
@param url A file URL that points to a font file
@return YES if the font was loaded, NO if an error occurred
@discussion If the font has already been loaded, this method does nothing and returns YES.
*/
- (BOOL)loadFontURL:(NSURL *)url;
/*!
@method
@abstract Returns the loaded font with the given filename
@param filename The name of the font file that was given to -loadFont:
@return A CGFontRef, or NULL if the specified font cannot be found
@discussion If the font has not been loaded yet, -loadFont: will be
called with the given name first.
*/
- (CGFontRef)fontWithName:(NSString *)filename __AVAILABILITY_INTERNAL_DEPRECATED;
/*!
@method
@abstract Returns a ZFont object corresponding to the loaded font with the given filename and point size
@param filename The name of the font file that was given to -loadFont:
@param pointSize The point size of the font
@return A ZFont, or NULL if the specified font cannot be found
@discussion If the font has not been loaded yet, -loadFont: will be
called with the given name first.
*/
- (ZFont *)zFontWithName:(NSString *)filename pointSize:(CGFloat)pointSize;
/*!
@method
@abstract Returns a ZFont object corresponding to the loaded font with the given file URL and point size
@param url A file URL that points to a font file
@param pointSize The point size of the font
@return A ZFont, or NULL if the specified font cannot be loaded
@discussion If the font has not been loaded yet, -loadFontURL: will be called with the given URL first.
*/
- (ZFont *)zFontWithURL:(NSURL *)url pointSize:(CGFloat)pointSize;
/*!
@method
@abstract Returns a CFArrayRef of all loaded CGFont objects
@return A CFArrayRef of all loaded CGFont objects
@description You are responsible for releasing the CFArrayRef
*/
- (CFArrayRef)copyAllFonts;
@end

View File

@ -1,123 +0,0 @@
//
// FontManager.m
// FontLabel
//
// Created by Kevin Ballard on 5/5/09.
// Copyright © 2009 Zynga Game Networks
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import "FontManager.h"
#import "ZFont.h"
static FontManager *sharedFontManager = nil;
@implementation FontManager
+ (FontManager *)sharedManager {
@synchronized(self) {
if (sharedFontManager == nil) {
sharedFontManager = [[self alloc] init];
}
}
return sharedFontManager;
}
- (id)init {
if ((self = [super init])) {
fonts = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
urls = [[NSMutableDictionary alloc] init];
}
return self;
}
- (BOOL)loadFont:(NSString *)filename {
NSString *fontPath = [[NSBundle mainBundle] pathForResource:filename ofType:@"ttf"];
if (fontPath == nil) {
fontPath = [[NSBundle mainBundle] pathForResource:filename ofType:nil];
}
if (fontPath == nil) return NO;
NSURL *url = [NSURL fileURLWithPath:fontPath];
if ([self loadFontURL:url]) {
[urls setObject:url forKey:filename];
return YES;
}
return NO;
}
- (BOOL)loadFontURL:(NSURL *)url {
CGDataProviderRef fontDataProvider = CGDataProviderCreateWithURL((CFURLRef)url);
if (fontDataProvider == NULL) return NO;
CGFontRef newFont = CGFontCreateWithDataProvider(fontDataProvider);
CGDataProviderRelease(fontDataProvider);
if (newFont == NULL) return NO;
CFDictionarySetValue(fonts, url, newFont);
CGFontRelease(newFont);
return YES;
}
- (CGFontRef)fontWithName:(NSString *)filename {
CGFontRef font = NULL;
NSURL *url = [urls objectForKey:filename];
if (url == nil && [self loadFont:filename]) {
url = [urls objectForKey:filename];
}
if (url != nil) {
font = (CGFontRef)CFDictionaryGetValue(fonts, url);
}
return font;
}
- (ZFont *)zFontWithName:(NSString *)filename pointSize:(CGFloat)pointSize {
NSURL *url = [urls objectForKey:filename];
if (url == nil && [self loadFont:filename]) {
url = [urls objectForKey:filename];
}
if (url != nil) {
CGFontRef cgFont = (CGFontRef)CFDictionaryGetValue(fonts, url);
if (cgFont != NULL) {
return [ZFont fontWithCGFont:cgFont size:pointSize];
}
}
return nil;
}
- (ZFont *)zFontWithURL:(NSURL *)url pointSize:(CGFloat)pointSize {
CGFontRef cgFont = (CGFontRef)CFDictionaryGetValue(fonts, url);
if (cgFont == NULL && [self loadFontURL:url]) {
cgFont = (CGFontRef)CFDictionaryGetValue(fonts, url);
}
if (cgFont != NULL) {
return [ZFont fontWithCGFont:cgFont size:pointSize];
}
return nil;
}
- (CFArrayRef)copyAllFonts {
CFIndex count = CFDictionaryGetCount(fonts);
CGFontRef *values = (CGFontRef *)malloc(sizeof(CGFontRef) * count);
CFDictionaryGetKeysAndValues(fonts, NULL, (const void **)values);
CFArrayRef array = CFArrayCreate(NULL, (const void **)values, count, &kCFTypeArrayCallBacks);
free(values);
return array;
}
- (void)dealloc {
CFRelease(fonts);
[urls release];
[super dealloc];
}
@end

View File

@ -1,77 +0,0 @@
//
// ZAttributedString.h
// FontLabel
//
// Created by Kevin Ballard on 9/22/09.
// Copyright 2009 Zynga Game Networks. All rights reserved.
//
#import <Foundation/Foundation.h>
#if NS_BLOCKS_AVAILABLE
#define Z_BLOCKS 1
#else
// set this to 1 if you are using PLBlocks
#define Z_BLOCKS 0
#endif
#if Z_BLOCKS
enum {
ZAttributedStringEnumerationReverse = (1UL << 1),
ZAttributedStringEnumerationLongestEffectiveRangeNotRequired = (1UL << 20)
};
typedef NSUInteger ZAttributedStringEnumerationOptions;
#endif
@interface ZAttributedString : NSObject <NSCoding, NSCopying, NSMutableCopying> {
NSMutableString *_buffer;
NSMutableArray *_attributes;
}
@property (nonatomic, readonly) NSUInteger length;
@property (nonatomic, readonly) NSString *string;
- (id)initWithAttributedString:(ZAttributedString *)attr;
- (id)initWithString:(NSString *)str;
- (id)initWithString:(NSString *)str attributes:(NSDictionary *)attributes;
- (id)attribute:(NSString *)attributeName atIndex:(NSUInteger)index effectiveRange:(NSRangePointer)aRange;
- (id)attribute:(NSString *)attributeName atIndex:(NSUInteger)index longestEffectiveRange:(NSRangePointer)aRange inRange:(NSRange)rangeLimit;
- (ZAttributedString *)attributedSubstringFromRange:(NSRange)aRange;
- (NSDictionary *)attributesAtIndex:(NSUInteger)index effectiveRange:(NSRangePointer)aRange;
- (NSDictionary *)attributesAtIndex:(NSUInteger)index longestEffectiveRange:(NSRangePointer)aRange inRange:(NSRange)rangeLimit;
#if Z_BLOCKS
- (void)enumerateAttribute:(NSString *)attrName inRange:(NSRange)enumerationRange options:(ZAttributedStringEnumerationOptions)opts
usingBlock:(void (^)(id value, NSRange range, BOOL *stop))block;
- (void)enumerateAttributesInRange:(NSRange)enumerationRange options:(ZAttributedStringEnumerationOptions)opts
usingBlock:(void (^)(NSDictionary *attrs, NSRange range, BOOL *stop))block;
#endif
- (BOOL)isEqualToAttributedString:(ZAttributedString *)otherString;
@end
@interface ZMutableAttributedString : ZAttributedString {
}
- (void)addAttribute:(NSString *)name value:(id)value range:(NSRange)range;
- (void)addAttributes:(NSDictionary *)attributes range:(NSRange)range;
- (void)appendAttributedString:(ZAttributedString *)str;
- (void)deleteCharactersInRange:(NSRange)range;
- (void)insertAttributedString:(ZAttributedString *)str atIndex:(NSUInteger)idx;
- (void)removeAttribute:(NSString *)name range:(NSRange)range;
- (void)replaceCharactersInRange:(NSRange)range withAttributedString:(ZAttributedString *)str;
- (void)replaceCharactersInRange:(NSRange)range withString:(NSString *)str;
- (void)setAttributedString:(ZAttributedString *)str;
- (void)setAttributes:(NSDictionary *)attributes range:(NSRange)range;
@end
extern NSString * const ZFontAttributeName;
extern NSString * const ZForegroundColorAttributeName;
extern NSString * const ZBackgroundColorAttributeName;
extern NSString * const ZUnderlineStyleAttributeName;
enum {
ZUnderlineStyleNone = 0x00,
ZUnderlineStyleSingle = 0x01
};
#define ZUnderlineStyleMask 0x00FF
enum {
ZUnderlinePatternSolid = 0x0000
};
#define ZUnderlinePatternMask 0xFF00

View File

@ -1,597 +0,0 @@
//
// ZAttributedString.m
// FontLabel
//
// Created by Kevin Ballard on 9/22/09.
// Copyright 2009 Zynga Game Networks. All rights reserved.
//
#import "ZAttributedString.h"
#import "ZAttributedStringPrivate.h"
@interface ZAttributedString ()
- (NSUInteger)indexOfEffectiveAttributeRunForIndex:(NSUInteger)index;
- (NSDictionary *)attributesAtIndex:(NSUInteger)index effectiveRange:(NSRangePointer)aRange uniquingOnName:(NSString *)attributeName;
- (NSDictionary *)attributesAtIndex:(NSUInteger)index longestEffectiveRange:(NSRangePointer)aRange
inRange:(NSRange)rangeLimit uniquingOnName:(NSString *)attributeName;
@end
@interface ZAttributedString ()
@property (nonatomic, readonly) NSArray *attributes;
@end
@implementation ZAttributedString
@synthesize string = _buffer;
@synthesize attributes = _attributes;
- (id)initWithAttributedString:(ZAttributedString *)attr {
NSParameterAssert(attr != nil);
if ((self = [super init])) {
_buffer = [attr->_buffer mutableCopy];
_attributes = [[NSMutableArray alloc] initWithArray:attr->_attributes copyItems:YES];
}
return self;
}
- (id)initWithString:(NSString *)str {
return [self initWithString:str attributes:nil];
}
- (id)initWithString:(NSString *)str attributes:(NSDictionary *)attributes {
if ((self = [super init])) {
_buffer = [str mutableCopy];
_attributes = [[NSMutableArray alloc] initWithObjects:[ZAttributeRun attributeRunWithIndex:0 attributes:attributes], nil];
}
return self;
}
- (id)init {
return [self initWithString:@"" attributes:nil];
}
- (id)initWithCoder:(NSCoder *)decoder {
if ((self = [super init])) {
_buffer = [[decoder decodeObjectForKey:@"buffer"] mutableCopy];
_attributes = [[decoder decodeObjectForKey:@"attributes"] mutableCopy];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_buffer forKey:@"buffer"];
[aCoder encodeObject:_attributes forKey:@"attributes"];
}
- (id)copyWithZone:(NSZone *)zone {
return [self retain];
}
- (id)mutableCopyWithZone:(NSZone *)zone {
return [(ZMutableAttributedString *)[ZMutableAttributedString allocWithZone:zone] initWithAttributedString:self];
}
- (NSUInteger)length {
return [_buffer length];
}
- (NSString *)description {
NSMutableArray *components = [NSMutableArray arrayWithCapacity:[_attributes count]*2];
NSRange range = NSMakeRange(0, 0);
for (NSUInteger i = 0; i <= [_attributes count]; i++) {
range.location = NSMaxRange(range);
ZAttributeRun *run;
if (i < [_attributes count]) {
run = [_attributes objectAtIndex:i];
range.length = run.index - range.location;
} else {
run = nil;
range.length = [_buffer length] - range.location;
}
if (range.length > 0) {
[components addObject:[NSString stringWithFormat:@"\"%@\"", [_buffer substringWithRange:range]]];
}
if (run != nil) {
NSMutableArray *attrDesc = [NSMutableArray arrayWithCapacity:[run.attributes count]];
for (id key in run.attributes) {
[attrDesc addObject:[NSString stringWithFormat:@"%@: %@", key, [run.attributes objectForKey:key]]];
}
[components addObject:[NSString stringWithFormat:@"{%@}", [attrDesc componentsJoinedByString:@", "]]];
}
}
return [NSString stringWithFormat:@"%@", [components componentsJoinedByString:@" "]];
}
- (id)attribute:(NSString *)attributeName atIndex:(NSUInteger)index effectiveRange:(NSRangePointer)aRange {
NSParameterAssert(attributeName != nil);
return [[self attributesAtIndex:index effectiveRange:aRange uniquingOnName:attributeName] objectForKey:attributeName];
}
- (id)attribute:(NSString *)attributeName atIndex:(NSUInteger)index longestEffectiveRange:(NSRangePointer)aRange inRange:(NSRange)rangeLimit {
NSParameterAssert(attributeName != nil);
return [[self attributesAtIndex:index longestEffectiveRange:aRange inRange:rangeLimit uniquingOnName:attributeName] objectForKey:attributeName];
}
- (ZAttributedString *)attributedSubstringFromRange:(NSRange)aRange {
if (NSMaxRange(aRange) > [_buffer length]) {
@throw [NSException exceptionWithName:NSRangeException reason:@"range was outside of the attributed string" userInfo:nil];
}
ZMutableAttributedString *newStr = [self mutableCopy];
if (aRange.location > 0) {
[newStr deleteCharactersInRange:NSMakeRange(0, aRange.location)];
}
if (NSMaxRange(aRange) < [_buffer length]) {
[newStr deleteCharactersInRange:NSMakeRange(aRange.length, [_buffer length] - NSMaxRange(aRange))];
}
return [newStr autorelease];
}
- (NSDictionary *)attributesAtIndex:(NSUInteger)index effectiveRange:(NSRangePointer)aRange {
return [NSDictionary dictionaryWithDictionary:[self attributesAtIndex:index effectiveRange:aRange uniquingOnName:nil]];
}
- (NSDictionary *)attributesAtIndex:(NSUInteger)index longestEffectiveRange:(NSRangePointer)aRange inRange:(NSRange)rangeLimit {
return [NSDictionary dictionaryWithDictionary:[self attributesAtIndex:index longestEffectiveRange:aRange inRange:rangeLimit uniquingOnName:nil]];
}
#if Z_BLOCKS
// Warning: this code has not been tested. The only guarantee is that it compiles.
- (void)enumerateAttribute:(NSString *)attrName inRange:(NSRange)enumerationRange options:(ZAttributedStringEnumerationOptions)opts
usingBlock:(void (^)(id, NSRange, BOOL*))block {
if (opts & ZAttributedStringEnumerationLongestEffectiveRangeNotRequired) {
[self enumerateAttributesInRange:enumerationRange options:opts usingBlock:^(NSDictionary *attrs, NSRange range, BOOL *stop) {
id value = [attrs objectForKey:attrName];
if (value != nil) {
block(value, range, stop);
}
}];
} else {
__block id oldValue = nil;
__block NSRange effectiveRange = NSMakeRange(0, 0);
[self enumerateAttributesInRange:enumerationRange options:opts usingBlock:^(NSDictionary *attrs, NSRange range, BOOL *stop) {
id value = [attrs objectForKey:attrName];
if (oldValue == nil) {
oldValue = value;
effectiveRange = range;
} else if (value != nil && [oldValue isEqual:value]) {
// combine the attributes
effectiveRange = NSUnionRange(effectiveRange, range);
} else {
BOOL innerStop = NO;
block(oldValue, effectiveRange, &innerStop);
if (innerStop) {
*stop = YES;
oldValue = nil;
} else {
oldValue = value;
}
}
}];
if (oldValue != nil) {
BOOL innerStop = NO; // necessary for the block, but unused
block(oldValue, effectiveRange, &innerStop);
}
}
}
- (void)enumerateAttributesInRange:(NSRange)enumerationRange options:(ZAttributedStringEnumerationOptions)opts
usingBlock:(void (^)(NSDictionary*, NSRange, BOOL*))block {
// copy the attributes so we can mutate the string if necessary during enumeration
// also clip the array during copy to only the subarray of attributes that cover the requested range
NSArray *attrs;
if (NSEqualRanges(enumerationRange, NSMakeRange(0, 0))) {
attrs = [NSArray arrayWithArray:_attributes];
} else {
// in this binary search, last is the first run after the range
NSUInteger first = 0, last = [_attributes count];
while (last > first+1) {
NSUInteger pivot = (last + first) / 2;
ZAttributeRun *run = [_attributes objectAtIndex:pivot];
if (run.index < enumerationRange.location) {
first = pivot;
} else if (run.index >= NSMaxRange(enumerationRange)) {
last = pivot;
}
}
attrs = [_attributes subarrayWithRange:NSMakeRange(first, last-first)];
}
if (opts & ZAttributedStringEnumerationReverse) {
NSUInteger end = [_buffer length];
for (ZAttributeRun *run in [attrs reverseObjectEnumerator]) {
BOOL stop = NO;
NSUInteger start = run.index;
// clip to enumerationRange
start = MAX(start, enumerationRange.location);
end = MIN(end, NSMaxRange(enumerationRange));
block(run.attributes, NSMakeRange(start, end - start), &stop);
if (stop) break;
end = run.index;
}
} else {
NSUInteger start = 0;
ZAttributeRun *run = [attrs objectAtIndex:0];
NSInteger offset = 0;
NSInteger oldLength = [_buffer length];
for (NSUInteger i = 1;;i++) {
NSUInteger end;
if (i >= [attrs count]) {
end = oldLength;
} else {
end = [[attrs objectAtIndex:i] index];
}
BOOL stop = NO;
NSUInteger clippedStart = MAX(start, enumerationRange.location);
NSUInteger clippedEnd = MIN(end, NSMaxRange(enumerationRange));
block(run.attributes, NSMakeRange(clippedStart + offset, clippedEnd - start), &stop);
if (stop || i >= [attrs count]) break;
start = end;
NSUInteger newLength = [_buffer length];
offset += (newLength - oldLength);
oldLength = newLength;
}
}
}
#endif
- (BOOL)isEqualToAttributedString:(ZAttributedString *)otherString {
return ([_buffer isEqualToString:otherString->_buffer] && [_attributes isEqualToArray:otherString->_attributes]);
}
- (BOOL)isEqual:(id)object {
return [object isKindOfClass:[ZAttributedString class]] && [self isEqualToAttributedString:(ZAttributedString *)object];
}
#pragma mark -
- (NSUInteger)indexOfEffectiveAttributeRunForIndex:(NSUInteger)index {
NSUInteger first = 0, last = [_attributes count];
while (last > first + 1) {
NSUInteger pivot = (last + first) / 2;
ZAttributeRun *run = [_attributes objectAtIndex:pivot];
if (run.index > index) {
last = pivot;
} else if (run.index < index) {
first = pivot;
} else {
first = pivot;
break;
}
}
return first;
}
- (NSDictionary *)attributesAtIndex:(NSUInteger)index effectiveRange:(NSRangePointer)aRange uniquingOnName:(NSString *)attributeName {
if (index >= [_buffer length]) {
@throw [NSException exceptionWithName:NSRangeException reason:@"index beyond range of attributed string" userInfo:nil];
}
NSUInteger runIndex = [self indexOfEffectiveAttributeRunForIndex:index];
ZAttributeRun *run = [_attributes objectAtIndex:runIndex];
if (aRange != NULL) {
aRange->location = run.index;
runIndex++;
if (runIndex < [_attributes count]) {
aRange->length = [[_attributes objectAtIndex:runIndex] index] - aRange->location;
} else {
aRange->length = [_buffer length] - aRange->location;
}
}
return run.attributes;
}
- (NSDictionary *)attributesAtIndex:(NSUInteger)index longestEffectiveRange:(NSRangePointer)aRange
inRange:(NSRange)rangeLimit uniquingOnName:(NSString *)attributeName {
if (index >= [_buffer length]) {
@throw [NSException exceptionWithName:NSRangeException reason:@"index beyond range of attributed string" userInfo:nil];
} else if (NSMaxRange(rangeLimit) > [_buffer length]) {
@throw [NSException exceptionWithName:NSRangeException reason:@"rangeLimit beyond range of attributed string" userInfo:nil];
}
NSUInteger runIndex = [self indexOfEffectiveAttributeRunForIndex:index];
ZAttributeRun *run = [_attributes objectAtIndex:runIndex];
if (aRange != NULL) {
if (attributeName != nil) {
id value = [run.attributes objectForKey:attributeName];
NSUInteger endRunIndex = runIndex+1;
runIndex--;
// search backwards
while (1) {
if (run.index <= rangeLimit.location) {
break;
}
ZAttributeRun *prevRun = [_attributes objectAtIndex:runIndex];
id prevValue = [prevRun.attributes objectForKey:attributeName];
if (prevValue == value || (value != nil && [prevValue isEqual:value])) {
runIndex--;
run = prevRun;
} else {
break;
}
}
// search forwards
ZAttributeRun *endRun = nil;
while (endRunIndex < [_attributes count]) {
ZAttributeRun *nextRun = [_attributes objectAtIndex:endRunIndex];
if (nextRun.index >= NSMaxRange(rangeLimit)) {
endRun = nextRun;
break;
}
id nextValue = [nextRun.attributes objectForKey:attributeName];
if (nextValue == value || (value != nil && [nextValue isEqual:value])) {
endRunIndex++;
} else {
endRun = nextRun;
break;
}
}
aRange->location = MAX(run.index, rangeLimit.location);
aRange->length = MIN((endRun ? endRun.index : [_buffer length]), NSMaxRange(rangeLimit)) - aRange->location;
} else {
// with no attribute name, we don't need to do any real searching,
// as we already guarantee each run has unique attributes.
// just make sure to clip the range to the rangeLimit
aRange->location = MAX(run.index, rangeLimit.location);
ZAttributeRun *endRun = (runIndex+1 < [_attributes count] ? [_attributes objectAtIndex:runIndex+1] : nil);
aRange->length = MIN((endRun ? endRun.index : [_buffer length]), NSMaxRange(rangeLimit)) - aRange->location;
}
}
return run.attributes;
}
- (void)dealloc {
[_buffer release];
[_attributes release];
[super dealloc];
}
@end
@interface ZMutableAttributedString ()
- (void)cleanupAttributesInRange:(NSRange)range;
- (NSRange)rangeOfAttributeRunsForRange:(NSRange)range;
- (void)offsetRunsInRange:(NSRange )range byOffset:(NSInteger)offset;
@end
@implementation ZMutableAttributedString
- (id)copyWithZone:(NSZone *)zone {
return [(ZAttributedString *)[ZAttributedString allocWithZone:zone] initWithAttributedString:self];
}
- (void)addAttribute:(NSString *)name value:(id)value range:(NSRange)range {
range = [self rangeOfAttributeRunsForRange:range];
for (ZAttributeRun *run in [_attributes subarrayWithRange:range]) {
[run.attributes setObject:value forKey:name];
}
[self cleanupAttributesInRange:range];
}
- (void)addAttributes:(NSDictionary *)attributes range:(NSRange)range {
range = [self rangeOfAttributeRunsForRange:range];
for (ZAttributeRun *run in [_attributes subarrayWithRange:range]) {
[run.attributes addEntriesFromDictionary:attributes];
}
[self cleanupAttributesInRange:range];
}
- (void)appendAttributedString:(ZAttributedString *)str {
[self insertAttributedString:str atIndex:[_buffer length]];
}
- (void)deleteCharactersInRange:(NSRange)range {
NSRange runRange = [self rangeOfAttributeRunsForRange:range];
[_buffer replaceCharactersInRange:range withString:@""];
[_attributes removeObjectsInRange:runRange];
for (NSUInteger i = runRange.location; i < [_attributes count]; i++) {
ZAttributeRun *run = [_attributes objectAtIndex:i];
ZAttributeRun *newRun = [[ZAttributeRun alloc] initWithIndex:(run.index - range.length) attributes:run.attributes];
[_attributes replaceObjectAtIndex:i withObject:newRun];
[newRun release];
}
[self cleanupAttributesInRange:NSMakeRange(runRange.location, 0)];
}
- (void)insertAttributedString:(ZAttributedString *)str atIndex:(NSUInteger)idx {
[self replaceCharactersInRange:NSMakeRange(idx, 0) withAttributedString:str];
}
- (void)removeAttribute:(NSString *)name range:(NSRange)range {
range = [self rangeOfAttributeRunsForRange:range];
for (ZAttributeRun *run in [_attributes subarrayWithRange:range]) {
[run.attributes removeObjectForKey:name];
}
[self cleanupAttributesInRange:range];
}
- (void)replaceCharactersInRange:(NSRange)range withAttributedString:(ZAttributedString *)str {
NSRange replaceRange = [self rangeOfAttributeRunsForRange:range];
NSInteger offset = [str->_buffer length] - range.length;
[_buffer replaceCharactersInRange:range withString:str->_buffer];
[_attributes replaceObjectsInRange:replaceRange withObjectsFromArray:str->_attributes];
NSRange newRange = NSMakeRange(replaceRange.location, [str->_attributes count]);
[self offsetRunsInRange:newRange byOffset:range.location];
[self offsetRunsInRange:NSMakeRange(NSMaxRange(newRange), [_attributes count] - NSMaxRange(newRange)) byOffset:offset];
[self cleanupAttributesInRange:NSMakeRange(newRange.location, 0)];
[self cleanupAttributesInRange:NSMakeRange(NSMaxRange(newRange), 0)];
}
- (void)replaceCharactersInRange:(NSRange)range withString:(NSString *)str {
[self replaceCharactersInRange:range withAttributedString:[[[ZAttributedString alloc] initWithString:str] autorelease]];
}
- (void)setAttributedString:(ZAttributedString *)str {
[_buffer release], _buffer = [str->_buffer mutableCopy];
[_attributes release], _attributes = [str->_attributes mutableCopy];
}
- (void)setAttributes:(NSDictionary *)attributes range:(NSRange)range {
range = [self rangeOfAttributeRunsForRange:range];
for (ZAttributeRun *run in [_attributes subarrayWithRange:range]) {
[run.attributes setDictionary:attributes];
}
[self cleanupAttributesInRange:range];
}
#pragma mark -
// splits the existing runs to provide one or more new runs for the given range
- (NSRange)rangeOfAttributeRunsForRange:(NSRange)range {
NSParameterAssert(NSMaxRange(range) <= [_buffer length]);
// find (or create) the first run
NSUInteger first = 0;
ZAttributeRun *lastRun = nil;
for (;;first++) {
if (first >= [_attributes count]) {
// we didn't find a run
first = [_attributes count];
ZAttributeRun *newRun = [[ZAttributeRun alloc] initWithIndex:range.location attributes:lastRun.attributes];
[_attributes addObject:newRun];
[newRun release];
break;
}
ZAttributeRun *run = [_attributes objectAtIndex:first];
if (run.index == range.location) {
break;
} else if (run.index > range.location) {
ZAttributeRun *newRun = [[ZAttributeRun alloc] initWithIndex:range.location attributes:lastRun.attributes];
[_attributes insertObject:newRun atIndex:first];
[newRun release];
break;
}
lastRun = run;
}
if (((ZAttributeRun *)[_attributes lastObject]).index < NSMaxRange(range)) {
NSRange subrange = NSMakeRange(first, [_attributes count] - first);
if (NSMaxRange(range) < [_buffer length]) {
ZAttributeRun *newRun = [[ZAttributeRun alloc] initWithIndex:NSMaxRange(range)
attributes:(NSDictionary*)[(ZAttributeRun *)[_attributes lastObject] attributes]];
[_attributes addObject:newRun];
[newRun release];
}
return subrange;
} else {
// find the last run within and the first run after the range
NSUInteger lastIn = first, firstAfter = [_attributes count]-1;
while (firstAfter > lastIn + 1) {
NSUInteger idx = (firstAfter + lastIn) / 2;
ZAttributeRun *run = [_attributes objectAtIndex:idx];
if (run.index < range.location) {
lastIn = idx;
} else if (run.index > range.location) {
firstAfter = idx;
} else {
// this is definitively the first run after the range
firstAfter = idx;
break;
}
}
if ([[_attributes objectAtIndex:firstAfter] index] > NSMaxRange(range)) {
// the first after is too far after, insert another run!
ZAttributeRun *newRun = [[ZAttributeRun alloc] initWithIndex:NSMaxRange(range)
attributes:[(ZAttributeRun *)[_attributes objectAtIndex:firstAfter-1] attributes]];
[_attributes insertObject:newRun atIndex:firstAfter];
[newRun release];
}
return NSMakeRange(lastIn, firstAfter - lastIn);
}
}
- (void)cleanupAttributesInRange:(NSRange)range {
// expand the range to include one surrounding attribute on each side
if (range.location > 0) {
range.location -= 1;
range.length += 1;
}
if (NSMaxRange(range) < [_attributes count]) {
range.length += 1;
} else {
// make sure the range is capped to the attributes count
range.length = [_attributes count] - range.location;
}
if (range.length == 0) return;
ZAttributeRun *lastRun = [_attributes objectAtIndex:range.location];
for (NSUInteger i = range.location+1; i < NSMaxRange(range);) {
ZAttributeRun *run = [_attributes objectAtIndex:i];
if ([lastRun.attributes isEqualToDictionary:run.attributes]) {
[_attributes removeObjectAtIndex:i];
range.length -= 1;
} else {
lastRun = run;
i++;
}
}
}
- (void)offsetRunsInRange:(NSRange)range byOffset:(NSInteger)offset {
for (NSUInteger i = range.location; i < NSMaxRange(range); i++) {
ZAttributeRun *run = [_attributes objectAtIndex:i];
ZAttributeRun *newRun = [[ZAttributeRun alloc] initWithIndex:run.index + offset attributes:run.attributes];
[_attributes replaceObjectAtIndex:i withObject:newRun];
[newRun release];
}
}
@end
@implementation ZAttributeRun
@synthesize index = _index;
@synthesize attributes = _attributes;
+ (id)attributeRunWithIndex:(NSUInteger)idx attributes:(NSDictionary *)attrs {
return [[[self alloc] initWithIndex:idx attributes:attrs] autorelease];
}
- (id)initWithIndex:(NSUInteger)idx attributes:(NSDictionary *)attrs {
NSParameterAssert(idx >= 0);
if ((self = [super init])) {
_index = idx;
if (attrs == nil) {
_attributes = [[NSMutableDictionary alloc] init];
} else {
_attributes = [attrs mutableCopy];
}
}
return self;
}
- (id)initWithCoder:(NSCoder *)decoder {
if ((self = [super init])) {
_index = [[decoder decodeObjectForKey:@"index"] unsignedIntegerValue];
_attributes = [[decoder decodeObjectForKey:@"attributes"] mutableCopy];
}
return self;
}
- (id)init {
return [self initWithIndex:0 attributes:[NSDictionary dictionary]];
}
- (id)copyWithZone:(NSZone *)zone {
return [[ZAttributeRun allocWithZone:zone] initWithIndex:_index attributes:_attributes];
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:[NSNumber numberWithUnsignedInteger:_index] forKey:@"index"];
[aCoder encodeObject:_attributes forKey:@"attributes"];
}
- (NSString *)description {
NSMutableArray *components = [NSMutableArray arrayWithCapacity:[_attributes count]];
for (id key in _attributes) {
[components addObject:[NSString stringWithFormat:@"%@=%@", key, [_attributes objectForKey:key]]];
}
return [NSString stringWithFormat:@"<%@: %p index=%lu attributes={%@}>",
NSStringFromClass([self class]), self, (unsigned long)_index, [components componentsJoinedByString:@" "]];
}
- (BOOL)isEqual:(id)object {
if (![object isKindOfClass:[ZAttributeRun class]]) return NO;
ZAttributeRun *other = (ZAttributeRun *)object;
return _index == other->_index && [_attributes isEqualToDictionary:other->_attributes];
}
- (void)dealloc {
[_attributes release];
[super dealloc];
}
@end
NSString * const ZFontAttributeName = @"ZFontAttributeName";
NSString * const ZForegroundColorAttributeName = @"ZForegroundColorAttributeName";
NSString * const ZBackgroundColorAttributeName = @"ZBackgroundColorAttributeName";
NSString * const ZUnderlineStyleAttributeName = @"ZUnderlineStyleAttributeName";

View File

@ -1,24 +0,0 @@
//
// ZAttributedStringPrivate.h
// FontLabel
//
// Created by Kevin Ballard on 9/23/09.
// Copyright 2009 Zynga Game Networks. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "ZAttributedString.h"
@interface ZAttributeRun : NSObject <NSCopying, NSCoding> {
NSUInteger _index;
NSMutableDictionary *_attributes;
}
@property (nonatomic, readonly) NSUInteger index;
@property (nonatomic, readonly) NSMutableDictionary *attributes;
+ (id)attributeRunWithIndex:(NSUInteger)idx attributes:(NSDictionary *)attrs;
- (id)initWithIndex:(NSUInteger)idx attributes:(NSDictionary *)attrs;
@end
@interface ZAttributedString (ZAttributedStringPrivate)
@property (nonatomic, readonly) NSArray *attributes;
@end

View File

@ -1,47 +0,0 @@
//
// ZFont.h
// FontLabel
//
// Created by Kevin Ballard on 7/2/09.
// Copyright © 2009 Zynga Game Networks
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface ZFont : NSObject {
CGFontRef _cgFont;
CGFloat _pointSize;
CGFloat _ratio;
NSString *_familyName;
NSString *_fontName;
NSString *_postScriptName;
}
@property (nonatomic, readonly) CGFontRef cgFont;
@property (nonatomic, readonly) CGFloat pointSize;
@property (nonatomic, readonly) CGFloat ascender;
@property (nonatomic, readonly) CGFloat descender;
@property (nonatomic, readonly) CGFloat leading;
@property (nonatomic, readonly) CGFloat xHeight;
@property (nonatomic, readonly) CGFloat capHeight;
@property (nonatomic, readonly) NSString *familyName;
@property (nonatomic, readonly) NSString *fontName;
@property (nonatomic, readonly) NSString *postScriptName;
+ (ZFont *)fontWithCGFont:(CGFontRef)cgFont size:(CGFloat)fontSize;
+ (ZFont *)fontWithUIFont:(UIFont *)uiFont;
- (id)initWithCGFont:(CGFontRef)cgFont size:(CGFloat)fontSize;
- (ZFont *)fontWithSize:(CGFloat)fontSize;
@end

View File

@ -1,170 +0,0 @@
//
// ZFont.m
// FontLabel
//
// Created by Kevin Ballard on 7/2/09.
// Copyright © 2009 Zynga Game Networks
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import "ZFont.h"
@interface ZFont ()
@property (nonatomic, readonly) CGFloat ratio;
- (NSString *)copyNameTableEntryForID:(UInt16)nameID;
@end
@implementation ZFont
@synthesize cgFont=_cgFont, pointSize=_pointSize, ratio=_ratio;
+ (ZFont *)fontWithCGFont:(CGFontRef)cgFont size:(CGFloat)fontSize {
return [[[self alloc] initWithCGFont:cgFont size:fontSize] autorelease];
}
+ (ZFont *)fontWithUIFont:(UIFont *)uiFont {
NSParameterAssert(uiFont != nil);
CGFontRef cgFont = CGFontCreateWithFontName((CFStringRef)uiFont.fontName);
ZFont *zFont = [[self alloc] initWithCGFont:cgFont size:uiFont.pointSize];
CGFontRelease(cgFont);
return [zFont autorelease];
}
- (id)initWithCGFont:(CGFontRef)cgFont size:(CGFloat)fontSize {
if ((self = [super init])) {
_cgFont = CGFontRetain(cgFont);
_pointSize = fontSize;
_ratio = fontSize/CGFontGetUnitsPerEm(cgFont);
}
return self;
}
- (id)init {
NSAssert(NO, @"-init is not valid for ZFont");
return nil;
}
- (CGFloat)ascender {
return ceilf(self.ratio * CGFontGetAscent(self.cgFont));
}
- (CGFloat)descender {
return floorf(self.ratio * CGFontGetDescent(self.cgFont));
}
- (CGFloat)leading {
return (self.ascender - self.descender);
}
- (CGFloat)capHeight {
return ceilf(self.ratio * CGFontGetCapHeight(self.cgFont));
}
- (CGFloat)xHeight {
return ceilf(self.ratio * CGFontGetXHeight(self.cgFont));
}
- (NSString *)familyName {
if (_familyName == nil) {
_familyName = [self copyNameTableEntryForID:1];
}
return _familyName;
}
- (NSString *)fontName {
if (_fontName == nil) {
_fontName = [self copyNameTableEntryForID:4];
}
return _fontName;
}
- (NSString *)postScriptName {
if (_postScriptName == nil) {
_postScriptName = [self copyNameTableEntryForID:6];
}
return _postScriptName;
}
- (ZFont *)fontWithSize:(CGFloat)fontSize {
if (fontSize == self.pointSize) return self;
NSParameterAssert(fontSize > 0.0);
return [[[ZFont alloc] initWithCGFont:self.cgFont size:fontSize] autorelease];
}
- (BOOL)isEqual:(id)object {
if (![object isKindOfClass:[ZFont class]]) return NO;
ZFont *font = (ZFont *)object;
return (font.cgFont == self.cgFont && font.pointSize == self.pointSize);
}
- (NSString *)copyNameTableEntryForID:(UInt16)aNameID {
CFDataRef nameTable = CGFontCopyTableForTag(self.cgFont, 'name');
NSAssert1(nameTable != NULL, @"CGFontCopyTableForTag returned NULL for 'name' tag in font %@",
[(id)CFCopyDescription(self.cgFont) autorelease]);
const UInt8 * const bytes = CFDataGetBytePtr(nameTable);
NSAssert1(OSReadBigInt16(bytes, 0) == 0, @"name table for font %@ has bad version number",
[(id)CFCopyDescription(self.cgFont) autorelease]);
const UInt16 count = OSReadBigInt16(bytes, 2);
const UInt16 stringOffset = OSReadBigInt16(bytes, 4);
const UInt8 * const nameRecords = &bytes[6];
UInt16 nameLength = 0;
UInt16 nameOffset = 0;
NSStringEncoding encoding = 0;
for (UInt16 idx = 0; idx < count; idx++) {
const uintptr_t recordOffset = 12 * idx;
const UInt16 nameID = OSReadBigInt16(nameRecords, recordOffset + 6);
if (nameID != aNameID) continue;
const UInt16 platformID = OSReadBigInt16(nameRecords, recordOffset + 0);
const UInt16 platformSpecificID = OSReadBigInt16(nameRecords, recordOffset + 2);
encoding = 0;
// for now, we only support a subset of encodings
switch (platformID) {
case 0: // Unicode
encoding = NSUTF16StringEncoding;
break;
case 1: // Macintosh
switch (platformSpecificID) {
case 0:
encoding = NSMacOSRomanStringEncoding;
break;
}
case 3: // Microsoft
switch (platformSpecificID) {
case 1:
encoding = NSUTF16StringEncoding;
break;
}
}
if (encoding == 0) continue;
nameLength = OSReadBigInt16(nameRecords, recordOffset + 8);
nameOffset = OSReadBigInt16(nameRecords, recordOffset + 10);
break;
}
NSString *result = nil;
if (nameOffset > 0) {
const UInt8 *nameBytes = &bytes[stringOffset + nameOffset];
result = [[NSString alloc] initWithBytes:nameBytes length:nameLength encoding:encoding];
}
CFRelease(nameTable);
return result;
}
- (void)dealloc {
CGFontRelease(_cgFont);
[_familyName release];
[_fontName release];
[_postScriptName release];
[super dealloc];
}
@end

View File

@ -39,7 +39,7 @@ void CCLog(const char * pszFormat, ...)
va_list ap;
va_start(ap, pszFormat);
vsprintf(szBuf, pszFormat, ap);
vsnprintf(szBuf, kMaxLogLen, pszFormat, ap);
va_end(ap);
printf("%s", szBuf);
printf("\n");

View File

@ -35,12 +35,43 @@ THE SOFTWARE.
NS_CC_BEGIN
#if(_MSC_VER >= 1600) // Visual Studio 2010 or higher version.
// Windows Touch define
#define MOUSEEVENTF_FROMTOUCH 0xFF515700
// Windows Touch functions
// Workaround to be able tu run app on Windows XP
typedef WINUSERAPI BOOL (WINAPI *RegisterTouchWindowFn)(_In_ HWND hwnd, _In_ ULONG ulFlags);
typedef WINUSERAPI BOOL (WINAPI *UnregisterTouchWindowFn)(_In_ HWND hwnd);
typedef WINUSERAPI LPARAM (WINAPI *GetMessageExtraInfoFn)(VOID);
typedef WINUSERAPI BOOL (WINAPI *GetTouchInputInfoFn)(_In_ HTOUCHINPUT hTouchInput, _In_ UINT cInputs, __out_ecount(cInputs) PTOUCHINPUT pInputs, _In_ int cbSize);
typedef WINUSERAPI BOOL (WINAPI *CloseTouchInputHandleFn)(_In_ HTOUCHINPUT hTouchInput);
static RegisterTouchWindowFn s_pfRegisterTouchWindowFunction = NULL;
static UnregisterTouchWindowFn s_pfUnregisterTouchWindowFunction = NULL;
static GetMessageExtraInfoFn s_pfGetMessageExtraInfoFunction = NULL;
static GetTouchInputInfoFn s_pfGetTouchInputInfoFunction = NULL;
static CloseTouchInputHandleFn s_pfCloseTouchInputHandleFunction = NULL;
bool CheckTouchSupport()
{
s_pfRegisterTouchWindowFunction = (RegisterTouchWindowFn)GetProcAddress(GetModuleHandle(TEXT("user32.dll")), "RegisterTouchWindow");
s_pfUnregisterTouchWindowFunction = (UnregisterTouchWindowFn)GetProcAddress(GetModuleHandle(TEXT("user32.dll")), "UnregisterTouchWindow");
s_pfGetMessageExtraInfoFunction = (GetMessageExtraInfoFn)GetProcAddress(GetModuleHandle(TEXT("user32.dll")), "GetMessageExtraInfo");
s_pfGetTouchInputInfoFunction = (GetTouchInputInfoFn)GetProcAddress(GetModuleHandle(TEXT("user32.dll")), "GetTouchInputInfo");
s_pfCloseTouchInputHandleFunction = (CloseTouchInputHandleFn)GetProcAddress(GetModuleHandle(TEXT("user32.dll")), "CloseTouchInputHandle");
return (s_pfRegisterTouchWindowFunction && s_pfUnregisterTouchWindowFunction && s_pfGetMessageExtraInfoFunction && s_pfGetTouchInputInfoFunction && s_pfCloseTouchInputHandleFunction);
}
#endif /* #if(_MSC_VER >= 1600) */
static void SetupPixelFormat(HDC hDC)
{
int pixelFormat;
PIXELFORMATDESCRIPTOR pfd =
{
{
sizeof(PIXELFORMATDESCRIPTOR), // size
1, // version
PFD_SUPPORT_OPENGL | // OpenGL window
@ -65,6 +96,68 @@ static void SetupPixelFormat(HDC hDC)
SetPixelFormat(hDC, pixelFormat, &pfd);
}
bool glew_dynamic_binding()
{
const char *gl_extensions = (const char*)glGetString(GL_EXTENSIONS);
// If the current opengl driver doesn't have framebuffers methods, check if an extension exists
if (glGenFramebuffers == NULL)
{
CCLog("OpenGL: glGenFramebuffers is NULL, try to detect an extension\n");
if (strstr(gl_extensions, "ARB_framebuffer_object"))
{
CCLog("OpenGL: ARB_framebuffer_object is supported\n");
glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC) wglGetProcAddress("glIsRenderbuffer");
glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC) wglGetProcAddress("glBindRenderbuffer");
glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC) wglGetProcAddress("glDeleteRenderbuffers");
glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC) wglGetProcAddress("glGenRenderbuffers");
glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) wglGetProcAddress("glRenderbufferStorage");
glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC) wglGetProcAddress("glGetRenderbufferParameteriv");
glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC) wglGetProcAddress("glIsFramebuffer");
glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) wglGetProcAddress("glBindFramebuffer");
glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) wglGetProcAddress("glDeleteFramebuffers");
glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) wglGetProcAddress("glGenFramebuffers");
glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) wglGetProcAddress("glCheckFramebufferStatus");
glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC) wglGetProcAddress("glFramebufferTexture1D");
glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) wglGetProcAddress("glFramebufferTexture2D");
glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC) wglGetProcAddress("glFramebufferTexture3D");
glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) wglGetProcAddress("glFramebufferRenderbuffer");
glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) wglGetProcAddress("glGetFramebufferAttachmentParameteriv");
glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC) wglGetProcAddress("glGenerateMipmap");
}
else
if (strstr(gl_extensions, "EXT_framebuffer_object"))
{
CCLog("OpenGL: EXT_framebuffer_object is supported\n");
glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC) wglGetProcAddress("glIsRenderbufferEXT");
glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC) wglGetProcAddress("glBindRenderbufferEXT");
glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC) wglGetProcAddress("glDeleteRenderbuffersEXT");
glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC) wglGetProcAddress("glGenRenderbuffersEXT");
glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) wglGetProcAddress("glRenderbufferStorageEXT");
glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC) wglGetProcAddress("glGetRenderbufferParameterivEXT");
glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC) wglGetProcAddress("glIsFramebufferEXT");
glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) wglGetProcAddress("glBindFramebufferEXT");
glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) wglGetProcAddress("glDeleteFramebuffersEXT");
glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) wglGetProcAddress("glGenFramebuffersEXT");
glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) wglGetProcAddress("glCheckFramebufferStatusEXT");
glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC) wglGetProcAddress("glFramebufferTexture1DEXT");
glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) wglGetProcAddress("glFramebufferTexture2DEXT");
glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC) wglGetProcAddress("glFramebufferTexture3DEXT");
glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) wglGetProcAddress("glFramebufferRenderbufferEXT");
glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) wglGetProcAddress("glGetFramebufferAttachmentParameterivEXT");
glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC) wglGetProcAddress("glGenerateMipmapEXT");
}
else
{
CCLog("OpenGL: No framebuffers extension is supported\n");
CCLog("OpenGL: Any call to Fbo will crash!\n");
return false;
}
}
return true;
}
//////////////////////////////////////////////////////////////////////////
// impliment CCEGLView
//////////////////////////////////////////////////////////////////////////
@ -95,6 +188,7 @@ CCEGLView::CCEGLView()
, m_windowHeight(0)
, m_windowTouchScaleX(1.0f)
, m_windowTouchScaleY(1.0f)
, m_bSupportTouch(false)
{
strcpy(m_szViewName, "Cocos2dxWin32");
}
@ -119,16 +213,17 @@ bool CCEGLView::initGL()
if ( atof((const char*)glVersion) < 1.5 )
{
char strComplain[256] = {0};
sprintf(strComplain,
"Your OpenGL version is %s, but Cocos2d-x requires OpenGL 1.5 or higher on Windows. Please upgrade the driver of your video card",
sprintf(strComplain,
"OpenGL 1.5 or higher is required (your version is %s). Please upgrade the driver of your video card.",
glVersion);
CCMessageBox(strComplain, "OpenGL version tooooooooooold");
CCMessageBox(strComplain, "OpenGL version too old");
return false;
}
GLenum GlewInitResult = glewInit();
if (GLEW_OK != GlewInitResult)
if (GLEW_OK != GlewInitResult)
{
fprintf(stderr,"ERROR: %s\n",glewGetErrorString(GlewInitResult));
CCMessageBox((char *)glewGetErrorString(GlewInitResult), "OpenGL error");
return false;
}
@ -136,7 +231,7 @@ bool CCEGLView::initGL()
{
CCLog("Ready for GLSL");
}
else
else
{
CCLog("Not totally ready :(");
}
@ -149,6 +244,13 @@ bool CCEGLView::initGL()
{
CCLog("OpenGL 2.0 not supported");
}
if(glew_dynamic_binding() == false)
{
CCMessageBox("No OpenGL framebuffer support. Please upgrade the driver of your video card.", "OpenGL error");
return false;
}
return true;
}
@ -162,10 +264,10 @@ void CCEGLView::destroyGL()
}
}
bool CCEGLView::Create(LPCTSTR pTitle, int w, int h)
bool CCEGLView::Create()
{
bool bRet = false;
do
do
{
CC_BREAK_IF(m_hWnd);
@ -173,7 +275,7 @@ bool CCEGLView::Create(LPCTSTR pTitle, int w, int h)
WNDCLASS wc; // Windows Class Structure
// Redraw On Size, And Own DC For Window.
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = _WindowProc; // WndProc Handles Messages
wc.cbClsExtra = 0; // No Extra Window Data
wc.cbWndExtra = 0; // No Extra Window Data
@ -181,10 +283,10 @@ bool CCEGLView::Create(LPCTSTR pTitle, int w, int h)
wc.hIcon = LoadIcon( NULL, IDI_WINLOGO ); // Load The Default Icon
wc.hCursor = LoadCursor( NULL, IDC_ARROW ); // Load The Arrow Pointer
wc.hbrBackground = NULL; // No Background Required For GL
wc.lpszMenuName = m_menu; //
wc.lpszMenuName = m_menu; //
wc.lpszClassName = kWindowClassName; // Set The Class Name
CC_BREAK_IF(! RegisterClass(&wc) && 1410 != GetLastError());
CC_BREAK_IF(! RegisterClass(&wc) && 1410 != GetLastError());
// center window position
RECT rcDesktop;
@ -200,8 +302,9 @@ bool CCEGLView::Create(LPCTSTR pTitle, int w, int h)
wszBuf, // Window Title
WS_CAPTION | WS_POPUPWINDOW | WS_MINIMIZEBOX, // Defined Window Style
0, 0, // Window Position
0, // Window Width
0, // Window Height
//TODO: Initializing width with a large value to avoid getting a wrong client area by 'GetClientRect' function.
1000, // Window Width
1000, // Window Height
NULL, // No Parent Window
NULL, // No Menu
hInstance, // Instance
@ -209,15 +312,22 @@ bool CCEGLView::Create(LPCTSTR pTitle, int w, int h)
CC_BREAK_IF(! m_hWnd);
resize(w, h);
bRet = initGL();
if(!bRet) destroyGL();
CC_BREAK_IF(!bRet);
s_pMainWindow = this;
bRet = true;
} while (0);
#if(_MSC_VER >= 1600)
m_bSupportTouch = CheckTouchSupport();
if(m_bSupportTouch)
{
m_bSupportTouch = (s_pfRegisterTouchWindowFunction(m_hWnd, 0) != 0);
}
#endif /* #if(_MSC_VER >= 1600) */
return bRet;
}
@ -228,10 +338,15 @@ LRESULT CCEGLView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
switch (message)
{
case WM_LBUTTONDOWN:
#if(_MSC_VER >= 1600)
// Don't process message generated by Windows Touch
if (m_bSupportTouch && (s_pfGetMessageExtraInfoFunction() & MOUSEEVENTF_FROMTOUCH) == MOUSEEVENTF_FROMTOUCH) break;
#endif /* #if(_MSC_VER >= 1600) */
if (m_pDelegate && MK_LBUTTON == wParam)
{
POINT point = {(short)LOWORD(lParam), (short)HIWORD(lParam)};
CCPoint pt(point.x/CC_CONTENT_SCALE_FACTOR(), point.y/CC_CONTENT_SCALE_FACTOR());
CCPoint pt(point.x, point.y);
CCPoint tmp = ccp(pt.x, m_obScreenSize.height - pt.y);
if (m_obViewPortRect.equals(CCRectZero) || m_obViewPortRect.containsPoint(tmp))
{
@ -246,10 +361,14 @@ LRESULT CCEGLView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
break;
case WM_MOUSEMOVE:
#if(_MSC_VER >= 1600)
// Don't process message generated by Windows Touch
if (m_bSupportTouch && (s_pfGetMessageExtraInfoFunction() & MOUSEEVENTF_FROMTOUCH) == MOUSEEVENTF_FROMTOUCH) break;
#endif /* #if(_MSC_VER >= 1600) */
if (MK_LBUTTON == wParam && m_bCaptured)
{
POINT point = {(short)LOWORD(lParam), (short)HIWORD(lParam)};
CCPoint pt(point.x/CC_CONTENT_SCALE_FACTOR(), point.y/CC_CONTENT_SCALE_FACTOR());
CCPoint pt(point.x, point.y);
int id = 0;
pt.x *= m_windowTouchScaleX;
pt.y *= m_windowTouchScaleY;
@ -258,10 +377,14 @@ LRESULT CCEGLView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
break;
case WM_LBUTTONUP:
#if(_MSC_VER >= 1600)
// Don't process message generated by Windows Touch
if (m_bSupportTouch && (s_pfGetMessageExtraInfoFunction() & MOUSEEVENTF_FROMTOUCH) == MOUSEEVENTF_FROMTOUCH) break;
#endif /* #if(_MSC_VER >= 1600) */
if (m_bCaptured)
{
POINT point = {(short)LOWORD(lParam), (short)HIWORD(lParam)};
CCPoint pt(point.x/CC_CONTENT_SCALE_FACTOR(), point.y/CC_CONTENT_SCALE_FACTOR());
CCPoint pt(point.x, point.y);
int id = 0;
pt.x *= m_windowTouchScaleX;
pt.y *= m_windowTouchScaleY;
@ -271,6 +394,49 @@ LRESULT CCEGLView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
m_bCaptured = false;
}
break;
#if(_MSC_VER >= 1600)
case WM_TOUCH:
{
BOOL bHandled = FALSE;
UINT cInputs = LOWORD(wParam);
PTOUCHINPUT pInputs = new TOUCHINPUT[cInputs];
if (pInputs)
{
if (s_pfGetTouchInputInfoFunction((HTOUCHINPUT)lParam, cInputs, pInputs, sizeof(TOUCHINPUT)))
{
for (UINT i=0; i < cInputs; i++)
{
TOUCHINPUT ti = pInputs[i];
POINT input;
input.x = TOUCH_COORD_TO_PIXEL(ti.x);
input.y = TOUCH_COORD_TO_PIXEL(ti.y);
ScreenToClient(m_hWnd, &input);
CCPoint pt(input.x, input.y);
CCPoint tmp = ccp(pt.x, m_obScreenSize.height - pt.y);
if (m_obViewPortRect.equals(CCRectZero) || m_obViewPortRect.containsPoint(tmp))
{
pt.x *= m_windowTouchScaleX;
pt.y *= m_windowTouchScaleY;
if (ti.dwFlags & TOUCHEVENTF_DOWN)
handleTouchesBegin(1, reinterpret_cast<int*>(&ti.dwID), &pt.x, &pt.y);
else if (ti.dwFlags & TOUCHEVENTF_MOVE)
handleTouchesMove(1, reinterpret_cast<int*>(&ti.dwID), &pt.x, &pt.y);
else if (ti.dwFlags & TOUCHEVENTF_UP)
handleTouchesEnd(1, reinterpret_cast<int*>(&ti.dwID), &pt.x, &pt.y);
}
}
bHandled = TRUE;
}
delete [] pInputs;
}
if (bHandled)
{
s_pfCloseTouchInputHandleFunction((HTOUCHINPUT)lParam);
}
}
break;
#endif /* #if(_MSC_VER >= 1600) */
case WM_SIZE:
switch (wParam)
{
@ -386,6 +552,12 @@ void CCEGLView::end()
{
if (m_hWnd)
{
#if(_MSC_VER >= 1600)
if(m_bSupportTouch)
{
s_pfUnregisterTouchWindowFunction(m_hWnd);
}
#endif /* #if(_MSC_VER >= 1600) */
DestroyWindow(m_hWnd);
m_hWnd = NULL;
}
@ -408,15 +580,14 @@ void CCEGLView::setIMEKeyboardState(bool /*bOpen*/)
}
bool CCEGLView::enableRetina()
{
m_bIsRetinaEnabled = true;
return true;
}
void CCEGLView::setMenuResource(LPCWSTR menu)
{
m_menu = menu;
if (m_hWnd != NULL)
{
HMENU hMenu = LoadMenu(GetModuleHandle(NULL), menu);
SetMenu(m_hWnd, hMenu);
}
}
void CCEGLView::setWndProc(CUSTOM_WND_PROC proc)
@ -457,14 +628,16 @@ void CCEGLView::resize(int width, int height)
m_windowTouchScaleX = frameSize.width / width;
m_windowTouchScaleY = frameSize.height / height;
#ifdef _DEBUG
TCHAR buff[MAX_PATH + 1];
memset(buff, 0, sizeof(buff));
swprintf_s(buff, MAX_PATH, L"%s - %0.0fx%0.0f - %0.2f",
kWindowClassName, frameSize.width, frameSize.height, 1.0f / m_windowTouchScaleX);
SetWindowText(m_hWnd, buff);
#endif
}
AdjustWindowRectEx(&rcClient, GetWindowLong(m_hWnd, GWL_STYLE), false, GetWindowLong(m_hWnd, GWL_EXSTYLE));
AdjustWindowRectEx(&rcClient, GetWindowLong(m_hWnd, GWL_STYLE), FALSE, GetWindowLong(m_hWnd, GWL_EXSTYLE));
// change width and height
SetWindowPos(m_hWnd, 0, 0, 0, width + ptDiff.x, height + ptDiff.y,
@ -473,7 +646,6 @@ void CCEGLView::resize(int width, int height)
void CCEGLView::setFrameSize(float width, float height)
{
Create((LPCTSTR)m_szViewName, (int)width, (int)height);
CCEGLViewProtocol::setFrameSize(width, height);
resize(width, height); // adjust window size for menubar
@ -512,22 +684,19 @@ void CCEGLView::centerWindow()
SetWindowPos(m_hWnd, 0, offsetX, offsetY, 0, 0, SWP_NOCOPYBITS | SWP_NOSIZE | SWP_NOOWNERZORDER | SWP_NOZORDER);
}
bool CCEGLView::setContentScaleFactor(float contentScaleFactor)
{
CCEGLViewProtocol::setContentScaleFactor(contentScaleFactor);
resize((int)(m_obScreenSize.width * contentScaleFactor), (int)(m_obScreenSize.height * contentScaleFactor));
centerWindow();
return true;
}
CCEGLView* CCEGLView::sharedOpenGLView()
{
static CCEGLView* s_pEglView = NULL;
if (s_pEglView == NULL)
{
s_pEglView = new CCEGLView();
if(!s_pEglView->Create())
{
delete s_pEglView;
s_pEglView = NULL;
}
}
return s_pEglView;
}

View File

@ -46,16 +46,14 @@ public:
virtual bool isOpenGLReady();
virtual void end();
virtual void swapBuffers();
virtual bool setContentScaleFactor(float contentScaleFactor);
virtual void setFrameSize(float width, float height);
virtual void setIMEKeyboardState(bool bOpen);
virtual bool enableRetina();
void setMenuResource(LPCWSTR menu);
void setWndProc(CUSTOM_WND_PROC proc);
private:
virtual bool Create(LPCTSTR pTitle, int w, int h);
virtual bool Create();
bool initGL();
void destroyGL();
public:
@ -83,6 +81,7 @@ private:
HDC m_hDC;
HGLRC m_hRC;
LPFN_ACCELEROMETER_KEYHOOK m_lpfnAccelerometerKeyHook;
bool m_bSupportTouch;
LPCWSTR m_menu;
CUSTOM_WND_PROC m_wndproc;

View File

@ -24,6 +24,7 @@ THE SOFTWARE.
#define __CC_PLATFORM_FILEUTILS_CPP__
#include "platform/CCFileUtilsCommon_cpp.h"
#include <windows.h>
#include <Shlobj.h>
#include "CCDirector.h"
#include "CCApplication.h"
@ -39,10 +40,10 @@ static void _CheckPath()
if (! s_pszResourcePath[0])
{
WCHAR wszPath[MAX_PATH] = {0};
int nNum = WideCharToMultiByte(CP_ACP, 0, wszPath,
GetCurrentDirectoryW(sizeof(wszPath), wszPath),
int nNum = WideCharToMultiByte(CP_ACP, 0, wszPath,
GetCurrentDirectoryW(sizeof(wszPath), wszPath),
s_pszResourcePath, MAX_PATH, NULL, NULL);
s_pszResourcePath[nNum] = '\\';
s_pszResourcePath[nNum] = '\\';
}
}
@ -64,7 +65,7 @@ void CCFileUtils::purgeFileUtils()
{
s_pFileUtils->purgeCachedEntries();
}
CC_SAFE_DELETE(s_pFileUtils);
}
@ -85,7 +86,7 @@ const char* CCFileUtils::fullPathFromRelativePath(const char *pszRelativePath)
// path start with "x:", is absolute path
pRet->m_sString = pszRelativePath;
}
else if (strlen(pszRelativePath) > 0
else if (strlen(pszRelativePath) > 0
&& ('/' == pszRelativePath[0] || '\\' == pszRelativePath[0]))
{
// path start with '/' or '\', is absolute path without driver name
@ -122,7 +123,7 @@ const char* CCFileUtils::fullPathFromRelativePath(const char *pszRelativePath)
{ // Can't find the file, return the relative path.
pRet->m_sString = pszRelativePath;
}
return pRet->m_sString.c_str();
}
@ -141,7 +142,7 @@ unsigned char* CCFileUtils::getFileData(const char* pszFileName, const char* psz
unsigned char* pBuffer = NULL;
CCAssert(pszFileName != NULL && pSize != NULL && pszMode != NULL, "Invaild parameters.");
*pSize = 0;
do
do
{
// read the file from hardware
FILE *fp = fopen(pszFileName, pszMode);
@ -168,17 +169,48 @@ unsigned char* CCFileUtils::getFileData(const char* pszFileName, const char* psz
string CCFileUtils::getWriteablePath()
{
// return the path that the exe file saved in
// Get full path of executable, e.g. c:\Program Files (x86)\My Game Folder\MyGame.exe
char full_path[_MAX_PATH + 1];
::GetModuleFileNameA(NULL, full_path, _MAX_PATH + 1);
char full_path[_MAX_PATH + 1];
::GetModuleFileNameA(NULL, full_path, _MAX_PATH + 1);
// Debug app uses executable directory; Non-debug app uses local app data directory
#ifndef _DEBUG
// Get filename of executable only, e.g. MyGame.exe
char *base_name = strrchr(full_path, '\\');
string ret((char*)full_path);
if(base_name)
{
char app_data_path[_MAX_PATH + 1];
// remove xxx.exe
ret = ret.substr(0, ret.rfind("\\") + 1);
// Get local app data directory, e.g. C:\Documents and Settings\username\Local Settings\Application Data
if (SUCCEEDED(SHGetFolderPathA(NULL, CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, app_data_path)))
{
string ret((char*)app_data_path);
return ret;
// Adding executable filename, e.g. C:\Documents and Settings\username\Local Settings\Application Data\MyGame.exe
ret += base_name;
// Remove ".exe" extension, e.g. C:\Documents and Settings\username\Local Settings\Application Data\MyGame
ret = ret.substr(0, ret.rfind("."));
ret += "\\";
// Create directory
if (SUCCEEDED(SHCreateDirectoryExA(NULL, ret.c_str(), NULL)))
{
return ret;
}
}
}
#endif // not defined _DEBUG
// If fetching of local app data directory fails, use the executable one
string ret((char*)full_path);
// remove xxx.exe
ret = ret.substr(0, ret.rfind("\\") + 1);
return ret;
}
NS_CC_END

View File

@ -1 +1 @@
c6b576d638eb4ac03aebd8111bba28397aa96625
d9f2b205ba4de8125ca7740a1740767028020681

View File

@ -57,7 +57,7 @@
</PreBuildEvent>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..;..\platform\win32;..\platform\third_party\win32\iconv;..\platform\third_party\win32\zlib;..\platform\third_party\win32\libpng;..\platform\third_party\win32\libjpeg;..\platform\third_party\win32\libtiff;..\platform\third_party\win32\libxml2;..\platform\third_party\win32\pthread;..\platform\third_party\win32\OGLES;..\include;..\kazmath\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(ProjectDir)..;$(ProjectDir)..\platform\win32;$(ProjectDir)..\platform\third_party\win32\iconv;$(ProjectDir)..\platform\third_party\win32\zlib;$(ProjectDir)..\platform\third_party\win32\libpng;$(ProjectDir)..\platform\third_party\win32\libjpeg;$(ProjectDir)..\platform\third_party\win32\libtiff;$(ProjectDir)..\platform\third_party\win32\libxml2;$(ProjectDir)..\platform\third_party\win32\pthread;$(ProjectDir)..\platform\third_party\win32\OGLES;..\include;$(ProjectDir)..\kazmath\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;COCOS2DXWIN32_EXPORTS;GL_GLEXT_PROTOTYPES;COCOS2D_DEBUG=1;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@ -70,7 +70,7 @@
</ClCompile>
<PreLinkEvent>
<Command>if not exist "$(OutDir)" mkdir "$(OutDir)"
xcopy /Y /Q "$(ProjectDir)..\..\cocos2dx\platform\third_party\win32\libraries\*.*" "$(OutDir)"
xcopy /Y /Q "$(ProjectDir)..\platform\third_party\win32\libraries\*.*" "$(OutDir)"
</Command>
</PreLinkEvent>
<Link>
@ -95,7 +95,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\cocos2dx\platform\third_party\win32\libraries\*.
</Command>
</PreBuildEvent>
<ClCompile>
<AdditionalIncludeDirectories>..;..\platform\win32;..\platform\third_party\win32\iconv;..\platform\third_party\win32\zlib;..\platform\third_party\win32\libpng;..\platform\third_party\win32\libjpeg;..\platform\third_party\win32\libtiff;..\platform\third_party\win32\libxml2;..\platform\third_party\win32\pthread;..\platform\third_party\win32\OGLES;..\include;..\kazmath\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(ProjectDir)..;$(ProjectDir)..\platform\win32;$(ProjectDir)..\platform\third_party\win32\iconv;$(ProjectDir)..\platform\third_party\win32\zlib;$(ProjectDir)..\platform\third_party\win32\libpng;$(ProjectDir)..\platform\third_party\win32\libjpeg;$(ProjectDir)..\platform\third_party\win32\libtiff;$(ProjectDir)..\platform\third_party\win32\libxml2;$(ProjectDir)..\platform\third_party\win32\pthread;$(ProjectDir)..\platform\third_party\win32\OGLES;..\include;$(ProjectDir)..\kazmath\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;COCOS2DXWIN32_EXPORTS;GL_GLEXT_PROTOTYPES;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<PrecompiledHeader>
@ -106,7 +106,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\cocos2dx\platform\third_party\win32\libraries\*.
</ClCompile>
<PreLinkEvent>
<Command>if not exist "$(OutDir)" mkdir "$(OutDir)"
xcopy /Y /Q "$(SolutionDir)cocos2dx\platform\third_party\win32\libraries\*.*" "$(OutDir)"
xcopy /Y /Q "$(ProjectDir)..\platform\third_party\win32\libraries\*.*" "$(OutDir)"
</Command>
</PreLinkEvent>
<Link>

View File

@ -131,8 +131,10 @@ void CCNotificationCenter::unregisterScriptObserver(void)
void CCNotificationCenter::postNotification(const char *name, CCObject *object)
{
CCArray* ObserversCopy = CCArray::createWithCapacity(m_observers->count());
ObserversCopy->addObjectsFromArray(m_observers);
CCObject* obj = NULL;
CCARRAY_FOREACH(m_observers, obj)
CCARRAY_FOREACH(ObserversCopy, obj)
{
CCNotificationObserver* observer = (CCNotificationObserver*) obj;
if (!observer)

View File

@ -46,7 +46,7 @@ public:
CCPoint getLocation() const;
/** returns the previous touch location in OpenGL coordinates */
CCPoint getPreviousLocation() const;
/** returns the current touch location in screen coordinates */
/** returns the delta of 2 current touches locations in screen coordinates */
CCPoint getDelta() const;
/** returns the current touch location in screen coordinates */
CCPoint getLocationInView() const;

View File

@ -80,7 +80,10 @@ bool CCControlColourPicker::init()
// MIPMAP
// ccTexParams params = {GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT};
spriteSheet->getTexture()->setAliasTexParameters();
/* Comment next line to avoid something like mosaic in 'CCControlExtensionTest',
especially the display of 'huePickerBackground.png' when in 800*480 window size with 480*320 design resolution and hd(960*640) resources.
*/
// spriteSheet->getTexture()->setAliasTexParameters();
// spriteSheet->getTexture()->setTexParameters(&params);
// spriteSheet->getTexture()->generateMipmap();

View File

@ -64,6 +64,7 @@ private:
CCSize m_tContentSize;
void* m_pSysEdit;
int m_nMaxTextLength;
bool m_bInRetinaMode;
};

View File

@ -42,7 +42,7 @@ CCEditBoxImplIOS::CCEditBoxImplIOS(CCEditBox* pEditText)
, m_pSysEdit(NULL)
, m_nMaxTextLength(-1)
{
m_bInRetinaMode = [[EAGLView sharedEGLView] contentScaleFactor] == 2.0f ? true : false;
}
CCEditBoxImplIOS::~CCEditBoxImplIOS()
@ -64,15 +64,14 @@ bool CCEditBoxImplIOS::initWithSize(const CCSize& size)
{
CCEGLViewProtocol* eglView = CCEGLView::sharedOpenGLView();
CGRect rect;
if (eglView->isRetinaEnabled())
CGRect rect = CGRectMake(0, 0, size.width * eglView->getScaleX(),size.height * eglView->getScaleY());
if (m_bInRetinaMode)
{
rect = CGRectMake(0, 0, size.width,size.height);
}
else
{
rect = CGRectMake(0, 0, size.width * eglView->getScaleX(),size.height * eglView->getScaleY());
rect.size.width /= 2.0f;
rect.size.height /= 2.0f;
}
m_pSysEdit = [[EditBoxImplIOS alloc] initWithFrame:rect editBox:this];
if (!m_pSysEdit) break;
@ -195,29 +194,29 @@ void CCEditBoxImplIOS::setPlaceHolder(const char* pText)
GET_IMPL.textField.placeholder = [NSString stringWithUTF8String:pText];
}
static CGPoint convertDesignCoordToScreenCoord(const CCPoint& designCoord)
static CGPoint convertDesignCoordToScreenCoord(const CCPoint& designCoord, bool bInRetinaMode)
{
float viewH = (float)[[EAGLView sharedEGLView] getHeight];
CCEGLViewProtocol* eglView = CCEGLView::sharedOpenGLView();
CCPoint visiblePos;
if (eglView->isRetinaEnabled())
{
visiblePos = ccp(designCoord.x, designCoord.y);
}
else
{
visiblePos = ccp(designCoord.x * eglView->getScaleX(), designCoord.y * eglView->getScaleY());
}
float viewH = (float)[[EAGLView sharedEGLView] getHeight];
CCPoint visiblePos = ccp(designCoord.x * eglView->getScaleX(), designCoord.y * eglView->getScaleY());
CCPoint screenGLPos = ccpAdd(visiblePos, eglView->getViewPortRect().origin);
CGPoint screenPos = CGPointMake(screenGLPos.x, viewH - screenGLPos.y);
if (bInRetinaMode)
{
screenPos.x = screenPos.x / 2.0f;
screenPos.y = screenPos.y / 2.0f;
}
CCLOG("[EditBox] pos x = %f, y = %f", screenGLPos.x, screenGLPos.y);
return screenPos;
}
void CCEditBoxImplIOS::setPosition(const CCPoint& pos)
{
//TODO should consider anchor point, the default value is (0.5, 0,5)
[GET_IMPL setPosition:convertDesignCoordToScreenCoord(ccp(pos.x-m_tContentSize.width/2, pos.y+m_tContentSize.height/2))];
[GET_IMPL setPosition:convertDesignCoordToScreenCoord(ccp(pos.x-m_tContentSize.width/2, pos.y+m_tContentSize.height/2), m_bInRetinaMode)];
}
void CCEditBoxImplIOS::setContentSize(const CCSize& size)

View File

@ -131,15 +131,19 @@ CCTableViewCell *CCTableView::cellAtIndex(unsigned int idx)
void CCTableView::updateCellAtIndex(unsigned int idx)
{
if (idx == CC_INVALID_INDEX || idx > m_pDataSource->numberOfCellsInTableView(this)-1)
if (idx == CC_INVALID_INDEX)
{
return;
}
CCTableViewCell *cell;
cell = this->_cellWithIndex(idx);
if (cell) {
unsigned int uCountOfItems = m_pDataSource->numberOfCellsInTableView(this);
if (0 == uCountOfItems || idx > uCountOfItems-1)
{
return;
}
CCTableViewCell* cell = this->_cellWithIndex(idx);
if (cell)
{
this->_moveCellOutOfSight(cell);
}
cell = m_pDataSource->tableCellAtIndex(this, idx);
@ -149,11 +153,19 @@ void CCTableView::updateCellAtIndex(unsigned int idx)
void CCTableView::insertCellAtIndex(unsigned int idx)
{
if (idx == CC_INVALID_INDEX || idx > m_pDataSource->numberOfCellsInTableView(this)-1) {
if (idx == CC_INVALID_INDEX)
{
return;
}
CCTableViewCell *cell;
int newIdx;
unsigned int uCountOfItems = m_pDataSource->numberOfCellsInTableView(this);
if (0 == uCountOfItems || idx > uCountOfItems-1)
{
return;
}
CCTableViewCell* cell = NULL;
int newIdx = 0;
cell = (CCTableViewCell*)m_pCellsUsed->objectWithObjectID(idx);
if (cell)
@ -178,12 +190,19 @@ void CCTableView::insertCellAtIndex(unsigned int idx)
void CCTableView::removeCellAtIndex(unsigned int idx)
{
if (idx == CC_INVALID_INDEX || idx > m_pDataSource->numberOfCellsInTableView(this)-1) {
if (idx == CC_INVALID_INDEX)
{
return;
}
CCTableViewCell *cell;
unsigned int newIdx;
unsigned int uCountOfItems = m_pDataSource->numberOfCellsInTableView(this);
if (0 == uCountOfItems || idx > uCountOfItems-1)
{
return;
}
CCTableViewCell* cell = NULL;
unsigned int newIdx = 0;
cell = this->_cellWithIndex(idx);
if (!cell) {
@ -362,15 +381,19 @@ void CCTableView::_setIndexForCell(unsigned int index, CCTableViewCell *cell)
void CCTableView::scrollViewDidScroll(CCScrollView* view)
{
unsigned int startIdx = 0, endIdx = 0, idx = 0, maxIdx = 0;
CCPoint offset;
unsigned int uCountOfItems = m_pDataSource->numberOfCellsInTableView(this);
if (0 == uCountOfItems)
{
return;
}
offset = ccpMult(this->getContentOffset(), -1);
maxIdx = MAX(m_pDataSource->numberOfCellsInTableView(this)-1, 0);
unsigned int startIdx = 0, endIdx = 0, idx = 0, maxIdx = 0;
CCPoint offset = ccpMult(this->getContentOffset(), -1);
maxIdx = MAX(uCountOfItems-1, 0);
const CCSize cellSize = m_pDataSource->cellSizeForTable(this);
if (m_eVordering == kCCTableViewFillTopDown) {
if (m_eVordering == kCCTableViewFillTopDown)
{
offset.y = offset.y + m_tViewSize.height/this->getContainer()->getScaleY() - cellSize.height;
}
startIdx = this->_indexFromOffset(offset);

View File

@ -67,7 +67,7 @@
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(SolutionDir)cocos2dx;$(SolutionDir)cocos2dx\include;$(SolutionDir)cocos2dx\kazmath\include;$(SolutionDir)cocos2dx\platform\win32;$(SolutionDir)cocos2dx\platform\third_party\win32;$(SolutionDir)cocos2dx\platform\third_party\win32\pthread;$(SolutionDir)cocos2dx\platform\third_party\win32\OGLES;..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\cocos2dx;$(ProjectDir)..\..\cocos2dx\include;$(ProjectDir)..\..\cocos2dx\kazmath\include;$(ProjectDir)..\..\cocos2dx\platform\win32;$(ProjectDir)..\..\cocos2dx\platform\third_party\win32;$(ProjectDir)..\..\cocos2dx\platform\third_party\win32\pthread;$(ProjectDir)..\..\cocos2dx\platform\third_party\win32\OGLES;..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>

View File

@ -1,5 +1,6 @@
#include "AppDelegate.h"
#include "HelloWorldScene.h"
#include "AppMacros.h"
USING_NS_CC;
@ -16,41 +17,27 @@ bool AppDelegate::applicationDidFinishLaunching() {
CCDirector *pDirector = CCDirector::sharedDirector();
pDirector->setOpenGLView(CCEGLView::sharedOpenGLView());
//pDirector->setProjection(kCCDirectorProjection2D);
CCSize screenSize = CCEGLView::sharedOpenGLView()->getFrameSize();
TargetPlatform target = getTargetPlatform();
if (screenSize.height > 768)
{
CCFileUtils::sharedFileUtils()->setResourceDirectory("ipadhd");
pDirector->setContentScaleFactor(1536.0f/kDesignResolutionSize_height);
}
else if (screenSize.height > 320)
{
CCFileUtils::sharedFileUtils()->setResourceDirectory("ipad");
pDirector->setContentScaleFactor(768.0f/kDesignResolutionSize_height);
}
else
{
CCFileUtils::sharedFileUtils()->setResourceDirectory("iphone");
pDirector->setContentScaleFactor(320.0f/kDesignResolutionSize_height);
}
CCEGLView::sharedOpenGLView()->setDesignResolutionSize(kDesignResolutionSize_width, kDesignResolutionSize_height, kResolutionNoBorder);
if (target == kTargetIpad)
{
// ipad
CCFileUtils::sharedFileUtils()->setResourceDirectory("iphonehd");
// don't enable retina because we don't have ipad hd resource
CCEGLView::sharedOpenGLView()->setDesignResolutionSize(960, 640, kResolutionNoBorder);
}
else if (target == kTargetIphone)
{
// iphone
// try to enable retina on device
if (true == CCDirector::sharedDirector()->enableRetinaDisplay(true))
{
// iphone hd
CCFileUtils::sharedFileUtils()->setResourceDirectory("iphonehd");
}
else
{
CCFileUtils::sharedFileUtils()->setResourceDirectory("iphone");
}
}
else
{
// android, windows, blackberry, linux or mac
// use 960*640 resources as design resolution size
CCFileUtils::sharedFileUtils()->setResourceDirectory("iphonehd");
CCEGLView::sharedOpenGLView()->setDesignResolutionSize(960, 640, kResolutionNoBorder);
}
// turn on display FPS
pDirector->setDisplayStats(true);

View File

@ -0,0 +1,30 @@
#ifndef __APPMACROS_H__
#define __APPMACROS_H__
#define kDesignResolution_480x320 0
#define kDesignResolution_1024x768 1
#define kDesignResolution_2048x1536 2
#define kTargetDesignResolutionSize kDesignResolution_2048x1536
#if (kTargetDesignResolutionSize == kDesignResolution_480x320)
#define kDesignResolutionSize_width 480.0f
#define kDesignResolutionSize_height 320.0f
#elif (kTargetDesignResolutionSize == kDesignResolution_1024x768)
#define kDesignResolutionSize_width 1024.0f
#define kDesignResolutionSize_height 768.0f
#elif (kTargetDesignResolutionSize == kDesignResolution_2048x1536)
#define kDesignResolutionSize_width 2048.0f
#define kDesignResolutionSize_height 1536.0f
#else
#error unknown target design resolution!
#endif
#define kTitleFontSize (kDesignResolutionSize_width / 480.0f * 24)
#endif /* __APPMACROS_H__ */

View File

@ -1,7 +1,8 @@
#include "HelloWorldScene.h"
#include "AppMacros.h"
USING_NS_CC;
CCScene* HelloWorld::scene()
{
// 'scene' is an autorelease object
@ -40,8 +41,8 @@ bool HelloWorld::init()
"CloseSelected.png",
this,
menu_selector(HelloWorld::menuCloseCallback));
pCloseItem->setPosition(ccp(origin.x + visibleSize.width - pCloseItem->getContentSize().width/2 ,
pCloseItem->setPosition(ccp(origin.x + visibleSize.width - pCloseItem->getContentSize().width/2 ,
origin.y + pCloseItem->getContentSize().height/2));
// create menu, it's an autorelease object
@ -54,8 +55,9 @@ bool HelloWorld::init()
// add a label shows "Hello World"
// create and initialize a label
CCLabelTTF* pLabel = CCLabelTTF::create("Hello World", "Arial", 24);
CCLabelTTF* pLabel = CCLabelTTF::create("Hello World", "Arial", kTitleFontSize);
// position the label on the center of the screen
pLabel->setPosition(ccp(origin.x + visibleSize.width/2,
origin.y + visibleSize.height - pLabel->getContentSize().height));
@ -72,12 +74,10 @@ bool HelloWorld::init()
// add the sprite as a child to this layer
this->addChild(pSprite, 0);
// enable standard touch
this->setTouchEnabled(true);
return true;
}
void HelloWorld::menuCloseCallback(CCObject* pSender)
{
CCDirector::sharedDirector()->end();
@ -86,11 +86,3 @@ void HelloWorld::menuCloseCallback(CCObject* pSender)
exit(0);
#endif
}
void HelloWorld::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent)
{
CCTouch* touch = (CCTouch*)(* pTouches->begin());
CCPoint pos = touch->getLocation();
CCLog("touch, x = %f, y = %f", pos.x, pos.y);
}

View File

@ -14,9 +14,6 @@ public:
// a selector callback
void menuCloseCallback(CCObject* pSender);
// touch callback
void ccTouchesBegan(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent);
// implement the "static node()" method manually
CREATE_FUNC(HelloWorld);

View File

@ -0,0 +1 @@
709d78b7f3eab27056a98d63e9153b35d57b84bc

View File

@ -0,0 +1 @@
7aa1e9dc799acf384a1c4603054242cc09c1b63e

View File

@ -1 +1 @@
5fe89fb5bd58cedf13b0363f97b20e3ea7ff255d
9d6facb31897d010352e7b57f4a82715c260408a

View File

@ -1 +0,0 @@
6b7a2544be32ce26e75737865743649598d83bdf

View File

@ -8,8 +8,9 @@
/* Begin PBXBuildFile section */
15003FA315D2601D00B6775A /* iphone in Resources */ = {isa = PBXBuildFile; fileRef = 15003FA215D2601D00B6775A /* iphone */; };
15003FA515D2602400B6775A /* iphonehd in Resources */ = {isa = PBXBuildFile; fileRef = 15003FA415D2602400B6775A /* iphonehd */; };
154269EB15B5669E00712A7F /* libcocos2dx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 154269D015B5644500712A7F /* libcocos2dx.a */; };
1A1CF3691626CEFF00AFC938 /* ipad in Resources */ = {isa = PBXBuildFile; fileRef = 1A1CF3671626CEFF00AFC938 /* ipad */; };
1A1CF36A1626CEFF00AFC938 /* ipadhd in Resources */ = {isa = PBXBuildFile; fileRef = 1A1CF3681626CEFF00AFC938 /* ipadhd */; };
1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; };
288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765A40DF7441C002DB57D /* CoreGraphics.framework */; };
@ -50,8 +51,10 @@
/* Begin PBXFileReference section */
15003FA215D2601D00B6775A /* iphone */ = {isa = PBXFileReference; lastKnownFileType = folder; path = iphone; sourceTree = "<group>"; };
15003FA415D2602400B6775A /* iphonehd */ = {isa = PBXFileReference; lastKnownFileType = folder; path = iphonehd; sourceTree = "<group>"; };
154269C815B5644500712A7F /* cocos2dx.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = cocos2dx.xcodeproj; path = ../../../cocos2dx/proj.ios/cocos2dx.xcodeproj; sourceTree = "<group>"; };
1A1CF3661626CB6000AFC938 /* AppMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppMacros.h; sourceTree = "<group>"; };
1A1CF3671626CEFF00AFC938 /* ipad */ = {isa = PBXFileReference; lastKnownFileType = folder; path = ipad; sourceTree = "<group>"; };
1A1CF3681626CEFF00AFC938 /* ipadhd */ = {isa = PBXFileReference; lastKnownFileType = folder; path = ipadhd; sourceTree = "<group>"; };
1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
1D6058910D05DD3D006BFB54 /* HelloCpp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HelloCpp.app; sourceTree = BUILT_PRODUCTS_DIR; };
1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
@ -149,7 +152,8 @@
784521C214EBA449009D533B /* Resources */ = {
isa = PBXGroup;
children = (
15003FA415D2602400B6775A /* iphonehd */,
1A1CF3671626CEFF00AFC938 /* ipad */,
1A1CF3681626CEFF00AFC938 /* ipadhd */,
15003FA215D2601D00B6775A /* iphone */,
D4EF94ED15BD319D00D803EB /* Icon-144.png */,
D4EF94EB15BD319B00D803EB /* Icon-72.png */,
@ -166,6 +170,7 @@
BF23D4E2143315EB00657E08 /* Classes */ = {
isa = PBXGroup;
children = (
1A1CF3661626CB6000AFC938 /* AppMacros.h */,
BF23D4E3143315EB00657E08 /* AppDelegate.cpp */,
BF23D4E4143315EB00657E08 /* AppDelegate.h */,
BF23D4E5143315EB00657E08 /* HelloWorldScene.cpp */,
@ -261,10 +266,11 @@
D4EF94EC15BD319B00D803EB /* Icon-72.png in Resources */,
D4EF94EE15BD319D00D803EB /* Icon-144.png in Resources */,
15003FA315D2601D00B6775A /* iphone in Resources */,
15003FA515D2602400B6775A /* iphonehd in Resources */,
D446FD79161028E9000ADA7B /* Default.png in Resources */,
D446FD7B161028ED000ADA7B /* Default@2x.png in Resources */,
D446FD7D161028F4000ADA7B /* Default-568h@2x.png in Resources */,
1A1CF3691626CEFF00AFC938 /* ipad in Resources */,
1A1CF36A1626CEFF00AFC938 /* ipadhd in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -53,7 +53,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(SolutionDir)cocos2dx;$(SolutionDir)cocos2dx\include;$(SolutionDir)cocos2dx\kazmath\include;$(SolutionDir)cocos2dx\platform\win32;$(SolutionDir)cocos2dx\platform\third_party\win32\OGLES;..\Classes;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\cocos2dx;$(ProjectDir)..\..\..\cocos2dx\include;$(ProjectDir)..\..\..\cocos2dx\kazmath\include;$(ProjectDir)..\..\..\cocos2dx\platform\win32;$(ProjectDir)..\..\..\cocos2dx\platform\third_party\win32\OGLES;..\Classes;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;COCOS2D_DEBUG=1;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@ -81,7 +81,7 @@
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(SolutionDir)cocos2dx;$(SolutionDir)cocos2dx\include;$(SolutionDir)cocos2dx\kazmath\include;$(SolutionDir)cocos2dx\platform\win32;$(SolutionDir)cocos2dx\platform\third_party\win32\OGLES;..\Classes;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\cocos2dx;$(ProjectDir)..\..\..\cocos2dx\include;$(ProjectDir)..\..\..\cocos2dx\kazmath\include;$(ProjectDir)..\..\..\cocos2dx\platform\win32;$(ProjectDir)..\..\..\cocos2dx\platform\third_party\win32\OGLES;..\Classes;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>

View File

@ -15,6 +15,6 @@ int APIENTRY _tWinMain(HINSTANCE hInstance,
// create the application instance
AppDelegate app;
CCEGLView* eglView = CCEGLView::sharedOpenGLView();
eglView->setFrameSize(960, 640 );
eglView->setFrameSize(1136, 640 );
return CCApplication::sharedApplication()->run();
}

View File

@ -26,7 +26,7 @@ bool AppDelegate::applicationDidFinishLaunching()
CCDirector *pDirector = CCDirector::sharedDirector();
pDirector->setOpenGLView(CCEGLView::sharedOpenGLView());
CCEGLView::sharedOpenGLView()->setDesignResolutionSize(480, 320, kResolutionShowAll);
CCEGLView::sharedOpenGLView()->setDesignResolutionSize(480, 320, kResolutionNoBorder);
// enable High Resource Mode(2x, such as iphone4) and maintains low resource on other devices.
// pDirector->enableRetinaDisplay(true);

View File

@ -21,7 +21,8 @@ local function main()
---------------
local winSize = CCDirector:sharedDirector():getWinSize()
local visibleSize = CCDirector:sharedDirector():getVisibleSize()
local origin = CCDirector:sharedDirector():getVisibleOrigin()
-- add the moving dog
local function creatDog()
@ -37,7 +38,7 @@ local function main()
local spriteDog = CCSprite:createWithSpriteFrame(frame0)
spriteDog.isPaused = false
spriteDog:setPosition(0, winSize.height / 4 * 3)
spriteDog:setPosition(origin.x, origin.y + visibleSize.height / 4 * 3)
local animFrames = CCArray:create()
@ -52,8 +53,8 @@ local function main()
local function tick()
if spriteDog.isPaused then return end
local x, y = spriteDog:getPosition()
if x > winSize.width then
x = 0
if x > origin.x + visibleSize.width then
x = origin.x
else
x = x + 1
end
@ -72,7 +73,7 @@ local function main()
-- add in farm background
local bg = CCSprite:create("farm.jpg")
bg:setPosition(winSize.width / 2 + 80, winSize.height / 2)
bg:setPosition(origin.x + visibleSize.width / 2 + 80, origin.y + visibleSize.height / 2)
layerFarm:addChild(bg)
-- add land sprite
@ -166,7 +167,7 @@ local function main()
menuPopupItem:setPosition(0, 0)
menuPopupItem:registerScriptTapHandler(menuCallbackClosePopup)
menuPopup = CCMenu:createWithItem(menuPopupItem)
menuPopup:setPosition(winSize.width / 2, winSize.height / 2)
menuPopup:setPosition(origin.x + visibleSize.width / 2, origin.y + visibleSize.height / 2)
menuPopup:setVisible(false)
layerMenu:addChild(menuPopup)
@ -175,7 +176,9 @@ local function main()
menuToolsItem:setPosition(0, 0)
menuToolsItem:registerScriptTapHandler(menuCallbackOpenPopup)
menuTools = CCMenu:createWithItem(menuToolsItem)
menuTools:setPosition(30, 40)
local itemWidth = menuToolsItem:getContentSize().width
local itemHeight = menuToolsItem:getContentSize().height
menuTools:setPosition(origin.x + itemWidth/2, origin.y + itemHeight/2)
layerMenu:addChild(menuTools)
return layerMenu

View File

@ -63,7 +63,7 @@
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.;..\Classes;$(SolutionDir)scripting\lua\cocos2dx_support;$(SolutionDir)scripting\lua\lua;$(SolutionDir)scripting\lua\tolua;$(SolutionDir)scripting\lua\src;$(SolutionDir)cocos2dx;$(SolutionDir)cocos2dx\include;$(SolutionDir)cocos2dx\kazmath\include;$(SolutionDir)cocos2dx\platform\win32;$(SolutionDir)cocos2dx\platform\third_party\win32\OGLES;$(SolutionDir)CocosDenshion\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(ProjectDir)..\Classes;$(ProjectDir)..\..\..\scripting\lua\cocos2dx_support;$(ProjectDir)..\..\..\scripting\lua\lua;$(ProjectDir)..\..\..\scripting\lua\tolua;$(ProjectDir)..\..\..\scripting\lua\src;$(ProjectDir)..\..\..\cocos2dx;$(ProjectDir)..\..\..\cocos2dx\include;$(ProjectDir)..\..\..\cocos2dx\kazmath\include;$(ProjectDir)..\..\..\cocos2dx\platform\win32;$(ProjectDir)..\..\..\cocos2dx\platform\third_party\win32\OGLES;$(ProjectDir)..\..\..\CocosDenshion\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_WINDOWS;STRICT;_DEBUG;COCOS2D_DEBUG=1;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@ -101,7 +101,7 @@
<ProxyFileName>HelloLua_p.c</ProxyFileName>
</Midl>
<ClCompile>
<AdditionalIncludeDirectories>.;..\Classes;$(SolutionDir)scripting\lua\cocos2dx_support;$(SolutionDir)scripting\lua\lua;$(SolutionDir)scripting\lua\tolua;$(SolutionDir)scripting\lua\src;$(SolutionDir)cocos2dx;$(SolutionDir)cocos2dx\include;$(SolutionDir)cocos2dx\kazmath\include;$(SolutionDir)cocos2dx\platform\win32;$(SolutionDir)cocos2dx\platform\third_party\win32\OGLES;$(SolutionDir)CocosDenshion\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(ProjectDir)..\Classes;$(ProjectDir)..\..\..\scripting\lua\cocos2dx_support;$(ProjectDir)..\..\..\scripting\lua\lua;$(ProjectDir)..\..\..\scripting\lua\tolua;$(ProjectDir)..\..\..\scripting\lua\src;$(ProjectDir)..\..\..\cocos2dx;$(ProjectDir)..\..\..\cocos2dx\include;$(ProjectDir)..\..\..\cocos2dx\kazmath\include;$(ProjectDir)..\..\..\cocos2dx\platform\win32;$(ProjectDir)..\..\..\cocos2dx\platform\third_party\win32\OGLES;$(ProjectDir)..\..\..\CocosDenshion\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_WINDOWS;STRICT;NDEBUG;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>
</ExceptionHandling>

View File

@ -18,37 +18,20 @@ bool AppDelegate::applicationDidFinishLaunching() {
pDirector->setOpenGLView(CCEGLView::sharedOpenGLView());
TargetPlatform target = getTargetPlatform();
CCSize screenSize = CCEGLView::sharedOpenGLView()->getFrameSize();
CCSize designSize = CCSizeMake(480, 320);
if (target == kTargetIpad)
if (screenSize.height > 320)
{
// ipad
CCFileUtils::sharedFileUtils()->setResourceDirectory("hd");
// don't enable retina because we don't have ipad hd resource
CCEGLView::sharedOpenGLView()->setDesignResolutionSize(960, 640, kResolutionNoBorder);
pDirector->setContentScaleFactor(640.0f/designSize.height);
}
else if (target == kTargetIphone)
{
if (CCDirector::sharedDirector()->enableRetinaDisplay(true))
{
// well, it's a iPhone 4, iPhone 4S or iPhone 5
CCFileUtils::sharedFileUtils()->setResourceDirectory("hd");
}
else
{
// iPhone 3GS and before, with 480x320 resolution
CCFileUtils::sharedFileUtils()->setResourceDirectory("sd");
}
}
else
else
{
// android, windows, blackberry, linux or mac
// use 960*640 resources as design resolution size
CCFileUtils::sharedFileUtils()->setResourceDirectory("sd");
CCEGLView::sharedOpenGLView()->setDesignResolutionSize(480, 320, kResolutionNoBorder);
pDirector->setContentScaleFactor(320.0f/designSize.height);
}
CCEGLView::sharedOpenGLView()->setDesignResolutionSize(designSize.width, designSize.height, kResolutionNoBorder);
// turn on display FPS
pDirector->setDisplayStats(true);

View File

@ -199,8 +199,9 @@ void HelloWorld::ccTouchesEnded(CCSet* touches, CCEvent* event)
// Set up initial location of projectile
CCSize winSize = CCDirector::sharedDirector()->getVisibleSize();
CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
CCSprite *projectile = CCSprite::create("Projectile.png", CCRectMake(0, 0, 20, 20));
projectile->setPosition( ccp(20, winSize.height/2) );
projectile->setPosition( ccp(origin.x+20, origin.y+winSize.height/2) );
// Determinie offset of location to projectile
float offX = location.x - projectile->getPosition().x;
@ -213,7 +214,7 @@ void HelloWorld::ccTouchesEnded(CCSet* touches, CCEvent* event)
this->addChild(projectile);
// Determine where we wish to shoot the projectile to
float realX = winSize.width + (projectile->getContentSize().width/2);
float realX = origin.x+winSize.width + (projectile->getContentSize().width/2);
float ratio = offY / offX;
float realY = (realX * ratio) + projectile->getPosition().y;
CCPoint realDest = ccp(realX, realY);

View File

@ -164,25 +164,27 @@ void ActionsDemo::onEnter()
addChild(m_tamara, 2);
addChild(m_kathia, 3);
CCSize s = CCDirector::sharedDirector()->getWinSize();
CCDirector* pDirector = CCDirector::sharedDirector();
CCPoint visibleOrigin = pDirector->getVisibleOrigin();
CCSize visibleSize = pDirector->getVisibleSize();
m_grossini->setPosition(CCPointMake(s.width/2, s.height/3));
m_tamara->setPosition(CCPointMake(s.width/2, 2*s.height/3));
m_kathia->setPosition(CCPointMake(s.width/2, s.height/2));
m_grossini->setPosition(ccp(visibleOrigin.x+visibleSize.width/2, visibleOrigin.y+visibleSize.height/3));
m_tamara->setPosition(ccp(visibleOrigin.x+visibleSize.width/2, visibleOrigin.y+2*visibleSize.height/3));
m_kathia->setPosition(ccp(visibleOrigin.x+visibleSize.width/2, visibleOrigin.y+visibleSize.height/2));
// add title and subtitle
std::string str = title();
const char * pTitle = str.c_str();
CCLabelTTF* label = CCLabelTTF::create(pTitle, "Arial", 18);
addChild(label, 1);
label->setPosition( CCPointMake(s.width/2, s.height - 30) );
label->setPosition( ccp(visibleOrigin.x+visibleSize.width/2, visibleOrigin.y+visibleSize.height - 30) );
std::string strSubtitle = subtitle();
if( ! strSubtitle.empty() )
{
CCLabelTTF* l = CCLabelTTF::create(strSubtitle.c_str(), "Thonburi", 22);
addChild(l, 1);
l->setPosition( CCPointMake(s.width/2, s.height - 60) );
l->setPosition( ccp(visibleOrigin.x+visibleSize.width/2, visibleOrigin.y+visibleSize.height - 60) );
}
// add menu
@ -193,9 +195,9 @@ void ActionsDemo::onEnter()
CCMenu *menu = CCMenu::create(item1, item2, item3, NULL);
menu->setPosition(CCPointZero);
item1->setPosition(CCPointMake(s.width/2 - item2->getContentSize().width*2, item2->getContentSize().height/2));
item2->setPosition(CCPointMake(s.width/2, item2->getContentSize().height/2));
item3->setPosition(CCPointMake(s.width/2 + item2->getContentSize().width*2, item2->getContentSize().height/2));
item1->setPosition(ccp(visibleOrigin.x+visibleSize.width/2 - item2->getContentSize().width*2, visibleOrigin.y+item2->getContentSize().height/2));
item2->setPosition(ccp(visibleOrigin.x+visibleSize.width/2, visibleOrigin.y+item2->getContentSize().height/2));
item3->setPosition(ccp(visibleOrigin.x+visibleSize.width/2 + item2->getContentSize().width*2, visibleOrigin.y+item2->getContentSize().height/2));
addChild(menu, 1);
}

View File

@ -22,32 +22,26 @@ bool AppDelegate::applicationDidFinishLaunching()
CCDirector *pDirector = CCDirector::sharedDirector();
pDirector->setOpenGLView(CCEGLView::sharedOpenGLView());
TargetPlatform target = getTargetPlatform();
if (target == kTargetIpad)
{
// ipad
CCSize screenSize = CCEGLView::sharedOpenGLView()->getFrameSize();
CCSize designSize = CCSizeMake(480, 320);
if (pDirector->enableRetinaDisplay(true))
{
// ipad hd
CCFileUtils::sharedFileUtils()->setResourceDirectory("ipadhd");
}
else
{
CCFileUtils::sharedFileUtils()->setResourceDirectory("ipad");
}
}
else if (target == kTargetIphone)
if (screenSize.height > 768)
{
// iphone
if (pDirector->enableRetinaDisplay(true))
{
// iphone hd
CCFileUtils::sharedFileUtils()->setResourceDirectory("hd");
}
CCFileUtils::sharedFileUtils()->setResourceDirectory("ipadhd");
pDirector->setContentScaleFactor(1536.0f/designSize.height);
}
else if (screenSize.height > 640)
{
CCFileUtils::sharedFileUtils()->setResourceDirectory("ipad");
pDirector->setContentScaleFactor(768.0f/designSize.height);
}
else if (screenSize.height > 320)
{
CCFileUtils::sharedFileUtils()->setResourceDirectory("hd");
pDirector->setContentScaleFactor(640.0f/designSize.height);
}
CCEGLView::sharedOpenGLView()->setDesignResolutionSize(designSize.width, designSize.height, kResolutionNoBorder);
// turn on display FPS
pDirector->setDisplayStats(true);

View File

@ -46,8 +46,10 @@ MenuLayer* MenuLayer::menuWithEntryID(int entryId)
bool MenuLayer::initWithEntryID(int entryId)
{
CCSize s = CCDirector::sharedDirector()->getWinSize();
CCDirector* pDirector = CCDirector::sharedDirector();
CCPoint visibleOrigin = pDirector->getVisibleOrigin();
CCSize visibleSize = pDirector->getVisibleSize();
m_entryID = entryId;
setTouchEnabled( true );
@ -56,14 +58,14 @@ bool MenuLayer::initWithEntryID(int entryId)
addChild(view, 0, kTagBox2DNode);
view->setScale(15);
view->setAnchorPoint( ccp(0,0) );
view->setPosition( ccp(s.width/2, s.height/3) );
view->setPosition( ccp(visibleOrigin.x+visibleSize.width/2, visibleOrigin.y+visibleSize.height/3) );
//#if (CC_TARGET_PLATFORM == CC_PLATFORM_MARMALADE)
// CCLabelBMFont* label = CCLabelBMFont::create(view->title().c_str(), "fonts/arial16.fnt");
//#else
CCLabelTTF* label = CCLabelTTF::create(view->title().c_str(), "Arial", 28);
//#endif
addChild(label, 1);
label->setPosition( ccp(s.width/2, s.height-50) );
label->setPosition( ccp(visibleOrigin.x+visibleSize.width/2, visibleOrigin.y+visibleSize.height-50) );
CCMenuItemImage *item1 = CCMenuItemImage::create("Images/b1.png", "Images/b2.png", this, menu_selector(MenuLayer::backCallback) );
CCMenuItemImage *item2 = CCMenuItemImage::create("Images/r1.png","Images/r2.png", this, menu_selector(MenuLayer::restartCallback) );
@ -72,9 +74,9 @@ bool MenuLayer::initWithEntryID(int entryId)
CCMenu *menu = CCMenu::create(item1, item2, item3, NULL);
menu->setPosition( CCPointZero );
item1->setPosition( ccp( s.width/2 - 100,30) );
item2->setPosition( ccp( s.width/2, 30) );
item3->setPosition( ccp( s.width/2 + 100,30) );
item1->setPosition( ccp( visibleOrigin.x+visibleSize.width/2 - 100,visibleOrigin.y+30) );
item2->setPosition( ccp( visibleOrigin.x+visibleSize.width/2, visibleOrigin.y+30) );
item3->setPosition( ccp( visibleOrigin.x+visibleSize.width/2 + 100,visibleOrigin.y+30) );
addChild(menu, 1);

View File

@ -9,7 +9,7 @@
bool Bug899Layer::init()
{
CCDirector::sharedDirector()->enableRetinaDisplay(true);
// CCDirector::sharedDirector()->enableRetinaDisplay(true);
if (BugsTestBaseLayer::init())
{
CCSprite *bg = CCSprite::create("Images/bugs/RetinaDisplay.jpg");

View File

@ -165,7 +165,7 @@ void BugsTestBaseLayer::onEnter()
void BugsTestBaseLayer::backCallback(CCObject* pSender)
{
CCDirector::sharedDirector()->enableRetinaDisplay(false);
// CCDirector::sharedDirector()->enableRetinaDisplay(false);
BugsTestScene* pScene = new BugsTestScene();
pScene->runThisTest();
pScene->autorelease();

View File

@ -13,15 +13,23 @@ static int fontIdx = 0;
static std::string fontList[] =
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
// custom ttf files are defined in Test-info.plist
"American Typewriter",
"Marker Felt",
#endif
"A Damn Mess",
"Abberancy",
"Abduction",
"Paint Boy",
"Schwarzwald Regular",
"Scissor Cuts",
#else
"fonts/A Damn Mess.ttf",
"fonts/Abberancy.ttf",
"fonts/Abduction.ttf",
"fonts/Paint Boy.ttf",
"fonts/Schwarzwald Regular.ttf",
"fonts/Scissor Cuts.ttf",
#endif
};
static int fontCount = sizeof(fontList) / sizeof(*fontList);

View File

@ -150,6 +150,11 @@ ShaderNode::ShaderNode()
{
}
ShaderNode::~ShaderNode()
{
CCNotificationCenter::sharedNotificationCenter()->removeObserver(this, EVNET_COME_TO_FOREGROUND);
}
ShaderNode* ShaderNode::shaderNodeWithVertex(const char *vert, const char *frag)
{
ShaderNode *node = new ShaderNode();
@ -161,6 +166,10 @@ ShaderNode* ShaderNode::shaderNodeWithVertex(const char *vert, const char *frag)
bool ShaderNode::initWithVertex(const char *vert, const char *frag)
{
CCNotificationCenter::sharedNotificationCenter()->addObserver(this,
callfuncO_selector(ShaderNode::listenBackToForeground),
EVNET_COME_TO_FOREGROUND,
NULL);
loadShaderVertex(vert, frag);
@ -171,10 +180,19 @@ bool ShaderNode::initWithVertex(const char *vert, const char *frag)
setContentSize(CCSizeMake(SIZE_X, SIZE_Y));
setAnchorPoint(ccp(0.5f, 0.5f));
m_vertFileName = vert;
m_fragFileName = frag;
return true;
}
void ShaderNode::listenBackToForeground(CCObject *obj)
{
this->setShaderProgram(NULL);
loadShaderVertex(m_vertFileName.c_str(), m_fragFileName.c_str());
}
void ShaderNode::loadShaderVertex(const char *vert, const char *frag)
{
CCGLProgram *shader = new CCGLProgram();
@ -438,9 +456,12 @@ std::string ShaderPlasma::subtitle()
class SpriteBlur : public CCSprite
{
public:
~SpriteBlur();
void setBlurSize(float f);
bool initWithTexture(CCTexture2D* texture, const CCRect& rect);
void draw();
void initProgram();
void listenBackToForeground(CCObject *obj);
static SpriteBlur* create(const char *pszFileName);
@ -451,6 +472,11 @@ public:
GLuint subLocation;
};
SpriteBlur::~SpriteBlur()
{
CCNotificationCenter::sharedNotificationCenter()->removeObserver(this, EVNET_COME_TO_FOREGROUND);
}
SpriteBlur* SpriteBlur::create(const char *pszFileName)
{
SpriteBlur* pRet = new SpriteBlur();
@ -466,48 +492,65 @@ SpriteBlur* SpriteBlur::create(const char *pszFileName)
return pRet;
}
void SpriteBlur::listenBackToForeground(CCObject *obj)
{
setShaderProgram(NULL);
initProgram();
}
bool SpriteBlur::initWithTexture(CCTexture2D* texture, const CCRect& rect)
{
if( CCSprite::initWithTexture(texture, rect) )
{
CCNotificationCenter::sharedNotificationCenter()->addObserver(this,
callfuncO_selector(SpriteBlur::listenBackToForeground),
EVNET_COME_TO_FOREGROUND,
NULL);
CCSize s = getTexture()->getContentSizeInPixels();
blur_ = ccp(1/s.width, 1/s.height);
sub_[0] = sub_[1] = sub_[2] = sub_[3] = 0;
GLchar * fragSource = (GLchar*) CCString::createWithContentsOfFile(
CCFileUtils::sharedFileUtils()->fullPathFromRelativePath("Shaders/example_Blur.fsh"))->getCString();
CCGLProgram* pProgram = new CCGLProgram();
pProgram->initWithVertexShaderByteArray(ccPositionTextureColor_vert, fragSource);
setShaderProgram(pProgram);
pProgram->release();
CHECK_GL_ERROR_DEBUG();
getShaderProgram()->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position);
getShaderProgram()->addAttribute(kCCAttributeNameColor, kCCVertexAttrib_Color);
getShaderProgram()->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords);
CHECK_GL_ERROR_DEBUG();
getShaderProgram()->link();
CHECK_GL_ERROR_DEBUG();
getShaderProgram()->updateUniforms();
CHECK_GL_ERROR_DEBUG();
subLocation = glGetUniformLocation( getShaderProgram()->getProgram(), "substract");
blurLocation = glGetUniformLocation( getShaderProgram()->getProgram(), "blurSize");
CHECK_GL_ERROR_DEBUG();
this->initProgram();
return true;
}
return false;
}
void SpriteBlur::initProgram()
{
GLchar * fragSource = (GLchar*) CCString::createWithContentsOfFile(
CCFileUtils::sharedFileUtils()->fullPathFromRelativePath("Shaders/example_Blur.fsh"))->getCString();
CCGLProgram* pProgram = new CCGLProgram();
pProgram->initWithVertexShaderByteArray(ccPositionTextureColor_vert, fragSource);
setShaderProgram(pProgram);
pProgram->release();
CHECK_GL_ERROR_DEBUG();
getShaderProgram()->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position);
getShaderProgram()->addAttribute(kCCAttributeNameColor, kCCVertexAttrib_Color);
getShaderProgram()->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords);
CHECK_GL_ERROR_DEBUG();
getShaderProgram()->link();
CHECK_GL_ERROR_DEBUG();
getShaderProgram()->updateUniforms();
CHECK_GL_ERROR_DEBUG();
subLocation = glGetUniformLocation( getShaderProgram()->getProgram(), "substract");
blurLocation = glGetUniformLocation( getShaderProgram()->getProgram(), "blurSize");
CHECK_GL_ERROR_DEBUG();
}
void SpriteBlur::draw()
{
ccGLEnableVertexAttribs(kCCVertexAttribFlag_PosColorTex );

View File

@ -114,9 +114,11 @@ class ShaderNode : public CCNode
{
public:
ShaderNode();
~ShaderNode();
bool initWithVertex(const char *vert, const char *frag);
void loadShaderVertex(const char *vert, const char *frag);
void listenBackToForeground(CCObject *obj);
virtual void update(float dt);
virtual void setPosition(const CCPoint &newPosition);
@ -130,6 +132,8 @@ private:
ccVertex2F m_resolution;
float m_time;
GLuint m_uniformCenter, m_uniformResolution, m_uniformTime;
std::string m_vertFileName;
std::string m_fragFileName;
};
class ShaderTestScene : public TestScene

View File

@ -53,7 +53,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(SolutionDir)cocos2dx;$(SolutionDir)cocos2dx\include;$(SolutionDir)cocos2dx\kazmath\include;$(SolutionDir)cocos2dx\platform\win32;$(SolutionDir)cocos2dx\platform\third_party\win32;$(SolutionDir)cocos2dx\platform\third_party\win32\OGLES;$(SolutionDir)external;$(SolutionDir)external\chipmunk\include\chipmunk;$(SolutionDir)CocosDenshion\include;$(SolutionDir)extensions;..\Classes;..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\cocos2dx;$(ProjectDir)..\..\..\cocos2dx\include;$(ProjectDir)..\..\..\cocos2dx\kazmath\include;$(ProjectDir)..\..\..\cocos2dx\platform\win32;$(ProjectDir)..\..\..\cocos2dx\platform\third_party\win32;$(ProjectDir)..\..\..\cocos2dx\platform\third_party\win32\OGLES;$(ProjectDir)..\..\..\external;$(ProjectDir)..\..\..\external\chipmunk\include\chipmunk;$(ProjectDir)..\..\..\CocosDenshion\include;$(ProjectDir)..\..\..\extensions;..\Classes;..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USE_MATH_DEFINES;GL_GLEXT_PROTOTYPES;COCOS2D_DEBUG=1;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@ -81,7 +81,7 @@
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(SolutionDir)cocos2dx;$(SolutionDir)cocos2dx\include;$(SolutionDir)cocos2dx\kazmath\include;$(SolutionDir)cocos2dx\platform\win32;$(SolutionDir)cocos2dx\platform\third_party\win32;$(SolutionDir)cocos2dx\platform\third_party\win32\OGLES;$(SolutionDir)external;$(SolutionDir)external\chipmunk\include\chipmunk;$(SolutionDir)CocosDenshion\include;$(SolutionDir)extensions;..\Classes;..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\cocos2dx;$(ProjectDir)..\..\..\cocos2dx\include;$(ProjectDir)..\..\..\cocos2dx\kazmath\include;$(ProjectDir)..\..\..\cocos2dx\platform\win32;$(ProjectDir)..\..\..\cocos2dx\platform\third_party\win32;$(ProjectDir)..\..\..\cocos2dx\platform\third_party\win32\OGLES;$(ProjectDir)..\..\..\external;$(ProjectDir)..\..\..\external\chipmunk\include\chipmunk;$(ProjectDir)..\..\..\CocosDenshion\include;$(ProjectDir)..\..\..\extensions;..\Classes;..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USE_MATH_DEFINES;GL_GLEXT_PROTOTYPES;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>

View File

@ -63,7 +63,7 @@
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.;..\Classes;$(SolutionDir)scripting\javascript\spidermonkey-win32\include;$(SolutionDir)external\chipmunk\include\chipmunk;$(SolutionDir)scripting\javascript\bindings;$(SolutionDir)extensions;$(SolutionDir)cocos2dx;$(SolutionDir)cocos2dx\include;$(SolutionDir)cocos2dx\kazmath\include;$(SolutionDir)cocos2dx\platform\win32;$(SolutionDir)cocos2dx\platform\third_party\win32;$(SolutionDir)cocos2dx\platform\third_party\win32\OGLES;$(SolutionDir)CocosDenshion\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(ProjectDir)..\Classes;$(ProjectDir)..\..\..\scripting\javascript\spidermonkey-win32\include;$(ProjectDir)..\..\..\external\chipmunk\include\chipmunk;$(ProjectDir)..\..\..\extensions;$(ProjectDir)..\..\..\scripting\javascript\bindings;$(ProjectDir)..\..\..\cocos2dx;$(ProjectDir)..\..\..\cocos2dx\include;$(ProjectDir)..\..\..\cocos2dx\kazmath\include;$(ProjectDir)..\..\..\cocos2dx\platform\win32;$(ProjectDir)..\..\..\cocos2dx\platform\third_party\win32;$(ProjectDir)..\..\..\cocos2dx\platform\third_party\win32\OGLES;$(ProjectDir)..\..\..\CocosDenshion\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_WINDOWS;STRICT;_DEBUG;XP_WIN;JS_HAVE___INTN;JS_INTPTR_TYPE=int;COCOS2D_DEBUG=1;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@ -81,7 +81,7 @@
</ResourceCompile>
<PreLinkEvent>
<Command>if not exist "$(OutDir)" mkdir "$(OutDir)"
xcopy /Y /Q "$(SolutionDir)scripting\javascript\spidermonkey-win32\lib\*.*" "$(OutDir)"
xcopy /Y /Q "$(ProjectDir)..\..\..\scripting\javascript\spidermonkey-win32\lib\*.*" "$(OutDir)"
</Command>
</PreLinkEvent>
<Link>
@ -120,7 +120,7 @@ if exist filelist.txt del /f /q filelist.txt
<ProxyFileName>testjs_p.c</ProxyFileName>
</Midl>
<ClCompile>
<AdditionalIncludeDirectories>.;..\Classes;$(SolutionDir)scripting\javascript\spidermonkey-win32\include;$(SolutionDir)external\chipmunk\include\chipmunk;$(SolutionDir)scripting\javascript\bindings;$(SolutionDir)extensions;$(SolutionDir)cocos2dx;$(SolutionDir)cocos2dx\include;$(SolutionDir)cocos2dx\kazmath\include;$(SolutionDir)cocos2dx\platform\win32;$(SolutionDir)cocos2dx\platform\third_party\win32;$(SolutionDir)cocos2dx\platform\third_party\win32\OGLES;$(SolutionDir)CocosDenshion\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(ProjectDir)..\Classes;$(ProjectDir)..\..\..\scripting\javascript\spidermonkey-win32\include;$(ProjectDir)..\..\..\external\chipmunk\include\chipmunk;$(ProjectDir)..\..\..\extensions;$(ProjectDir)..\..\..\scripting\javascript\bindings;$(ProjectDir)..\..\..\cocos2dx;$(ProjectDir)..\..\..\cocos2dx\include;$(ProjectDir)..\..\..\cocos2dx\kazmath\include;$(ProjectDir)..\..\..\cocos2dx\platform\win32;$(ProjectDir)..\..\..\cocos2dx\platform\third_party\win32;$(ProjectDir)..\..\..\cocos2dx\platform\third_party\win32\OGLES;$(ProjectDir)..\..\..\CocosDenshion\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_WINDOWS;STRICT;NDEBUG;XP_WIN;JS_HAVE___INTN;JS_INTPTR_TYPE=int;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>
</ExceptionHandling>
@ -139,7 +139,7 @@ if exist filelist.txt del /f /q filelist.txt
</ResourceCompile>
<PreLinkEvent>
<Command>if not exist "$(OutDir)" mkdir "$(OutDir)"
xcopy /Y /Q "$(SolutionDir)scripting\javascript\spidermonkey-win32\lib\*.*" "$(OutDir)"
xcopy /Y /Q "$(ProjectDir)..\..\..\scripting\javascript\spidermonkey-win32\lib\*.*" "$(OutDir)"
</Command>
</PreLinkEvent>
<Link>

View File

@ -50,7 +50,7 @@
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>.;..\Classes;$(SolutionDir)scripting\lua\cocos2dx_support;$(SolutionDir)scripting\lua\lua;$(SolutionDir)scripting\lua\tolua;$(SolutionDir)scripting\lua\src;$(SolutionDir)cocos2dx;$(SolutionDir)cocos2dx\include;$(SolutionDir)cocos2dx\kazmath\include;$(SolutionDir)cocos2dx\platform\win32;$(SolutionDir)cocos2dx\platform\third_party\win32;$(SolutionDir)cocos2dx\platform\third_party\win32\OGLES;$(SolutionDir)external;$(SolutionDir)external\chipmunk\include\chipmunk;$(SolutionDir)CocosDenshion\include;$(SolutionDir)scripting\lua\cocos2dx_support;$(SolutionDir)scripting\lua\tolua;$(SolutionDir)scripting\lua\lua;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(ProjectDir)..\Classes;$(ProjectDir)..\..\..\scripting\lua\cocos2dx_support;$(ProjectDir)..\..\..\scripting\lua\lua;$(ProjectDir)..\..\..\scripting\lua\tolua;$(ProjectDir)..\..\..\scripting\lua\src;$(ProjectDir)..\..\..\cocos2dx;$(ProjectDir)..\..\..\cocos2dx\include;$(ProjectDir)..\..\..\cocos2dx\kazmath\include;$(ProjectDir)..\..\..\cocos2dx\platform\win32;$(ProjectDir)..\..\..\cocos2dx\platform\third_party\win32;$(ProjectDir)..\..\..\cocos2dx\platform\third_party\win32\OGLES;$(ProjectDir)..\..\..\external;$(ProjectDir)..\..\..\external\chipmunk\include\chipmunk;$(ProjectDir)..\..\..\CocosDenshion\include;$(ProjectDir)..\..\..\scripting\lua\cocos2dx_support;$(ProjectDir)..\..\..\scripting\lua\tolua;$(ProjectDir)..\..\..\scripting\lua\lua;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
@ -87,13 +87,13 @@
</DllDataFileName>
</Midl>
<PreBuildEvent>
<Command>xcopy $(SolutionDir)samples\TestCpp\Resources $(SolutionDir)samples\TestLua\Resources /e /Y</Command>
<Command>xcopy $(ProjectDir)..\..\TestCpp\Resources $(ProjectDir)..\..\TestLua\Resources /e /Y</Command>
<Message>copy files from TestCpp to TestLua</Message>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>.;..\Classes;$(SolutionDir)cocos2dx;$(SolutionDir)cocos2dx\include;$(SolutionDir)cocos2dx\kazmath\include;$(SolutionDir)cocos2dx\platform\win32;$(SolutionDir)cocos2dx\platform\third_party\win32;$(SolutionDir)cocos2dx\platform\third_party\win32\OGLES;$(SolutionDir)external;$(SolutionDir)external\chipmunk\include\chipmunk;$(SolutionDir)CocosDenshion\include;$(SolutionDir)scripting\lua\cocos2dx_support;$(SolutionDir)scripting\lua\tolua;$(SolutionDir)scripting\lua\lua;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(ProjectDir)..\Classes;$(ProjectDir)..\..\..\scripting\lua\cocos2dx_support;$(ProjectDir)..\..\..\scripting\lua\lua;$(ProjectDir)..\..\..\scripting\lua\tolua;$(ProjectDir)..\..\..\scripting\lua\src;$(ProjectDir)..\..\..\cocos2dx;$(ProjectDir)..\..\..\cocos2dx\include;$(ProjectDir)..\..\..\cocos2dx\kazmath\include;$(ProjectDir)..\..\..\cocos2dx\platform\win32;$(ProjectDir)..\..\..\cocos2dx\platform\third_party\win32;$(ProjectDir)..\..\..\cocos2dx\platform\third_party\win32\OGLES;$(ProjectDir)..\..\..\external;$(ProjectDir)..\..\..\external\chipmunk\include\chipmunk;$(ProjectDir)..\..\..\CocosDenshion\include;$(ProjectDir)..\..\..\scripting\lua\cocos2dx_support;$(ProjectDir)..\..\..\scripting\lua\tolua;$(ProjectDir)..\..\..\scripting\lua\lua;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
@ -129,7 +129,7 @@
</DllDataFileName>
</Midl>
<PreBuildEvent>
<Command>xcopy $(SolutionDir)samples\TestCpp\Resources $(SolutionDir)samples\TestLua\Resources /e /Y</Command>
<Command>xcopy $(ProjectDir)..\..\TestCpp\Resources $(ProjectDir)..\..\TestLua\Resources /e /Y</Command>
<Message>copy files from TestCpp to TestLua</Message>
</PreBuildEvent>
</ItemDefinitionGroup>

@ -1 +1 @@
Subproject commit 7bee281e6c33d25ed2874261da6658b66a43e073
Subproject commit 79337ba58c9b43e603a0ec41db6cdb968d7284f2

View File

@ -1 +1 @@
a63c014d165a6c8390f07040db1cb55d588edd53
29c015353614a093d22d1bee3429e9188d368789

View File

@ -1 +1 @@
7fd7d46ae368602d9da448188c2ccdde3d43b984
8754a55b4cfc1c5e9d997ae3ed037cdfd5943c6c

View File

@ -1 +1 @@
57601a5ee61c442f04b4d1bbfd2697330dfc63cb
e4c5f54d0a54b4473017366d09c364ede1078c90

View File

@ -51,7 +51,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(SolutionDir)scripting\lua\tolua;$(SolutionDir)scripting\lua\lua;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(ProjectDir)..\tolua;$(ProjectDir)..\lua;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
@ -74,7 +74,7 @@
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(SolutionDir)scripting\lua\tolua;$(SolutionDir)scripting\lua\lua;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(ProjectDir)..\tolua;$(ProjectDir)..\lua;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBLUA_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>

View File

@ -21,7 +21,8 @@ local function main()
---------------
local winSize = CCDirector:sharedDirector():getWinSize()
local visibleSize = CCDirector:sharedDirector():getVisibleSize()
local origin = CCDirector:sharedDirector():getVisibleOrigin()
-- add the moving dog
local function creatDog()
@ -37,7 +38,7 @@ local function main()
local spriteDog = CCSprite:createWithSpriteFrame(frame0)
spriteDog.isPaused = false
spriteDog:setPosition(0, winSize.height / 4 * 3)
spriteDog:setPosition(origin.x, origin.y + visibleSize.height / 4 * 3)
local animFrames = CCArray:create()
@ -52,8 +53,8 @@ local function main()
local function tick()
if spriteDog.isPaused then return end
local x, y = spriteDog:getPosition()
if x > winSize.width then
x = 0
if x > origin.x + visibleSize.width then
x = origin.x
else
x = x + 1
end
@ -72,7 +73,7 @@ local function main()
-- add in farm background
local bg = CCSprite:create("farm.jpg")
bg:setPosition(winSize.width / 2 + 80, winSize.height / 2)
bg:setPosition(origin.x + visibleSize.width / 2 + 80, origin.y + visibleSize.height / 2)
layerFarm:addChild(bg)
-- add land sprite
@ -166,7 +167,7 @@ local function main()
menuPopupItem:setPosition(0, 0)
menuPopupItem:registerScriptTapHandler(menuCallbackClosePopup)
menuPopup = CCMenu:createWithItem(menuPopupItem)
menuPopup:setPosition(winSize.width / 2, winSize.height / 2)
menuPopup:setPosition(origin.x + visibleSize.width / 2, origin.y + visibleSize.height / 2)
menuPopup:setVisible(false)
layerMenu:addChild(menuPopup)
@ -175,7 +176,9 @@ local function main()
menuToolsItem:setPosition(0, 0)
menuToolsItem:registerScriptTapHandler(menuCallbackOpenPopup)
menuTools = CCMenu:createWithItem(menuToolsItem)
menuTools:setPosition(30, 40)
local itemWidth = menuToolsItem:getContentSize().width
local itemHeight = menuToolsItem:getContentSize().height
menuTools:setPosition(origin.x + itemWidth/2, origin.y + itemHeight/2)
layerMenu:addChild(menuTools)
return layerMenu

View File

@ -21,7 +21,8 @@ local function main()
---------------
local winSize = CCDirector:sharedDirector():getWinSize()
local visibleSize = CCDirector:sharedDirector():getVisibleSize()
local origin = CCDirector:sharedDirector():getVisibleOrigin()
-- add the moving dog
local function creatDog()
@ -37,7 +38,7 @@ local function main()
local spriteDog = CCSprite:createWithSpriteFrame(frame0)
spriteDog.isPaused = false
spriteDog:setPosition(0, winSize.height / 4 * 3)
spriteDog:setPosition(origin.x, origin.y + visibleSize.height / 4 * 3)
local animFrames = CCArray:create()
@ -52,8 +53,8 @@ local function main()
local function tick()
if spriteDog.isPaused then return end
local x, y = spriteDog:getPosition()
if x > winSize.width then
x = 0
if x > origin.x + visibleSize.width then
x = origin.x
else
x = x + 1
end
@ -72,7 +73,7 @@ local function main()
-- add in farm background
local bg = CCSprite:create("farm.jpg")
bg:setPosition(winSize.width / 2 + 80, winSize.height / 2)
bg:setPosition(origin.x + visibleSize.width / 2 + 80, origin.y + visibleSize.height / 2)
layerFarm:addChild(bg)
-- add land sprite
@ -166,7 +167,7 @@ local function main()
menuPopupItem:setPosition(0, 0)
menuPopupItem:registerScriptTapHandler(menuCallbackClosePopup)
menuPopup = CCMenu:createWithItem(menuPopupItem)
menuPopup:setPosition(winSize.width / 2, winSize.height / 2)
menuPopup:setPosition(origin.x + visibleSize.width / 2, origin.y + visibleSize.height / 2)
menuPopup:setVisible(false)
layerMenu:addChild(menuPopup)
@ -175,7 +176,9 @@ local function main()
menuToolsItem:setPosition(0, 0)
menuToolsItem:registerScriptTapHandler(menuCallbackOpenPopup)
menuTools = CCMenu:createWithItem(menuToolsItem)
menuTools:setPosition(30, 40)
local itemWidth = menuToolsItem:getContentSize().width
local itemHeight = menuToolsItem:getContentSize().height
menuTools:setPosition(origin.x + itemWidth/2, origin.y + itemHeight/2)
layerMenu:addChild(menuTools)
return layerMenu

View File

@ -17,16 +17,26 @@
#
# For automatically pushing changes:
#
# * REMOTE_COCOS2DX_REPOSITORY
# * REMOTE_AUTOGEN_BINDINGS_REPOSITORY
# * Ensure you have ssh access to above repositories
# Exit on error
set -e
# * REMOTE_COCOS2DX_REPOSITORY
# * Note : Ensure you have commit access to above repositories
# * COCOS2DX_PULL_BASE
# * hub
# * see http://defunkt.io/hub/
# * Ensure that hub has an OAuth token to REMOTE_COCOS2DX_REPOSITORY
# * see http://defunkt.io/hub/hub.1.html#CONFIGURATION
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
COCOS2DX_ROOT="$DIR"/../../../..
if [ -z "${HUB+aaa}" ]; then
# ... if HUB is not set, use "$HOME/bin/hub"
HUB="$HOME/bin/hub"
fi
# Exit on error
set -e
# 1. Generate JS bindings
COCOS2DX_ROOT="$COCOS2DX_ROOT" /bin/bash ../../../tojs/genbindings.sh
@ -39,12 +49,12 @@ if [ -z "${REMOTE_AUTOGEN_BINDINGS_REPOSITORY+aaa}" ]; then
echo Environment variable must be set REMOTE_AUTOGEN_BINDINGS_REPOSITORY
echo This script expects to automatically push changes
echo to this repo
echo example
echo REMOTE_AUTOGEN_BINDINGS_REPOSITORY=\"git@github.com:folecr/cocos2dx-autogen-bindings.git\"
echo REMOTE_AUTOGEN_BINDINGS_REPOSITORY=\"\$HOME/test/cocos2dx-autogen-bindings\"
echo
echo Exiting with failure.
echo
# example
# REMOTE_AUTOGEN_BINDINGS_REPOSITORY="git@github.com:folecr/cocos2dx-autogen-bindings.git"
# REMOTE_AUTOGEN_BINDINGS_REPOSITORY="$HOME/test/cocos2dx-autogen-bindings"
exit 1
fi
@ -52,40 +62,71 @@ if [ -z "${COMMITTAG+aaa}" ]; then
# ... if COMMITTAG is not set, use this machine's hostname
COMMITTAG=`hostname -s`
fi
echo
echo Using "'$COMMITTAG'" in the commit messages
echo
ELAPSEDSECS=`date +%s`
echo Using "$ELAPSEDSECS" in the branch names for pseudo-uniqueness
GENERATED_BRANCH=autogeneratedbindings_"$ELAPSEDSECS"
GENERATED_GITDIR="$COCOS2DX_ROOT"/scripting/javascript/bindings/generated/.git
GENERATED_WORKTREE="$COCOS2DX_ROOT"/scripting/javascript/bindings/generated
# git command shortcut
gitcmd_GEN="git --git-dir=$GENERATED_GITDIR --work-tree=$GENERATED_WORKTREE"
# 2. In JSBindings repo, Check if there are any files that are different from the index
# testing...
${gitcmd_GEN} status
pushd "$GENERATED_WORKTREE"
# 2. In JSBindings repo, Check out a branch named "autogeneratedbindings" and commit the auto generated bindings to it
${gitcmd_GEN} add README cocos2dx.cpp cocos2dx.hpp cocos2dxapi.js
${gitcmd_GEN} checkout origin/master -b "$GENERATED_BRANCH"
${gitcmd_GEN} commit -m "$COMMITTAG : autogenerated bindings"
# Run status to record the output in the log
git status
# 3. In JSBindings repo, Push the commit with generated bindings to "master" of the auto generated bindings repository
${gitcmd_GEN} push "$REMOTE_AUTOGEN_BINDINGS_REPOSITORY" "$GENERATED_BRANCH":master
echo
echo Comparing with origin/master ...
echo
# Don't exit on non-zero return value
set +e
git diff --stat --exit-code origin/master
DIFF_RETVAL=$?
if [ $DIFF_RETVAL -eq 0 ]
then
echo
echo "No differences in generated files"
echo "Exiting with success."
echo
exit 0
else
echo
echo "Generated files differ from origin/master. Continuing."
echo
fi
# Exit on error
set -e
# 3. In JSBindings repo, Check out a branch named "autogeneratedbindings" and commit the auto generated bindings to it
git checkout origin/master -b "$GENERATED_BRANCH"
git add --verbose README cocos2dx.cpp cocos2dx.hpp cocos2dxapi.js
git commit --verbose -m "$COMMITTAG : autogenerated bindings"
# 4. In JSBindings repo, Push the commit with generated bindings to "master" of the auto generated bindings repository
git push --verbose "$REMOTE_AUTOGEN_BINDINGS_REPOSITORY" "$GENERATED_BRANCH":master
popd
if [ -z "${REMOTE_COCOS2DX_REPOSITORY+aaa}" ]; then
echo
echo Environment variable is not set REMOTE_COCOS2DX_REPOSITORY
echo This script will NOT automatically push changes
echo unless this variable is set.
echo example
echo REMOTE_COCOS2DX_REPOSITORY=\"git@github.com:cocos2d/cocos2d-x.git\"
echo REMOTE_COCOS2DX_REPOSITORY=\"\$HOME/test/cocos2d-x\"
echo
echo Exiting with success.
echo
# example
# REMOTE_COCOS2DX_REPOSITORY="git@github.com:cocos2d/cocos2d-x.git"
# REMOTE_COCOS2DX_REPOSITORY="$HOME/test/cocos2d-x"
exit 0
fi
@ -93,13 +134,30 @@ COCOS_BRANCH=updategeneratedsubmodule_"$ELAPSEDSECS"
pushd "${DIR}"
# 4. In Cocos2D-X repo, Checkout a branch named "updategeneratedsubmodule" Update the submodule reference to point to the commit with generated bindings
# 5. In Cocos2D-X repo, Checkout a branch named "updategeneratedsubmodule" Update the submodule reference to point to the commit with generated bindings
cd "${COCOS2DX_ROOT}"
git add scripting/javascript/bindings/generated
git checkout origin/gles20 -b "$COCOS_BRANCH"
git commit -m "$COMMITTAG : updating submodule reference to latest autogenerated bindings"
# 5. In Cocos2D-X repo, Push the commit with updated submodule to "gles20" of the cocos2d-x repository
git push "$REMOTE_COCOS2DX_REPOSITORY" "$COCOS_BRANCH":gles20
# 6. In Cocos2D-X repo, Push the commit with updated submodule to "gles20" of the cocos2d-x repository
git push "$REMOTE_COCOS2DX_REPOSITORY" "$COCOS_BRANCH"
if [ -z "${COCOS2DX_PULL_BASE+aaa}" ]; then
echo
echo Environment variable is not set COCOS2DX_PULL_BASE
echo This script will NOT automatically generate pull requests
echo unless this variable is set.
echo example
echo COCOS2DX_PULL_BASE=\"cocos2d/cocos2d-x:gles20\"
echo COCOS2DX_PULL_BASE=\"username/repository:branch\"
echo
echo Exiting with success.
echo
exit 0
fi
# 7.
${HUB} pull-request "$COMMITTAG : updating submodule reference to latest autogenerated bindings" -b "$COCOS2DX_PULL_BASE" -h "$COCOS_BRANCH"
popd

View File

@ -19,7 +19,6 @@ class CCDirector : public CCObject
unsigned int getTotalFrames(void);
CCEGLViewProtocol* getOpenGLView(void);
bool enableRetinaDisplay(bool bEnableRetina);
CCSize getWinSize(void);
CCSize getWinSizeInPixels(void);

View File

@ -58,12 +58,6 @@ class CCEGLViewProtocol
/** Set touch delegate */
void setTouchDelegate(EGLTouchDelegate * pDelegate);
/**
* Set content scale factor.
* @return If return true, it means the plaform supports retina display.
*/
bool setContentScaleFactor(float contentScaleFactor);
/**
* Set opengl view port rectangle with points.
*/
@ -89,9 +83,4 @@ class CCEGLViewProtocol
* Get the scale factor of vertical direction.
*/
float getScaleY() const;
/**
* Get whether the retina mode is enabled.
*/
bool isRetinaEnabled() const;
};