text:
#include "cocoa/CCString.h"
#include "CCNode.h"
#include "support/CCPointExtension.h"
#include "support/TransformUtils.h"
#include "CCCamera.h"
#include "effects/CCGrid.h"
#include "CCDirector.h"
#include "CCScheduler.h"
#include "touch_dispatcher/CCTouch.h"
#include "actions/CCActionManager.h"
#include "script_support/CCScriptSupport.h"
#include "shaders/CCGLProgram.h"
// externals
#include "kazmath/GL/matrix.h"

#if CC_NODE_RENDER_SUBPIXEL
#define RENDER_IN_SUBPIXEL
#else
#define RENDER_IN_SUBPIXEL (__ARGS__) (ceil(__ARGS__))
#endif

NS_CC_BEGIN

// XXX: Yes, nodes might have a sort problem once every 15 days if the game runs at 60 FPS and each frame sprites are reordered.
static int s_globalOrderOfArrival = 1;

CCNode::CCNode(void)
: m_fRotationX(0.0f)
, m_fRotationY(0.0f)
, m_fScaleX(1.0f)
, m_fScaleY(1.0f)
, m_fVertexZ(0.0f)
, m_obPosition(CCPointZero)
, m_fSkewX(0.0f)
, m_fSkewY(0.0f)
, m_obAnchorPointInPoints(CCPointZero)
, m_obAnchorPoint(CCPointZero)
, m_obContentSize(CCSizeZero)
, m_sAdditionalTransform(CCAffineTransformMakeIdentity())
, m_pCamera(NULL)
// children (lazy allocs)
// lazy alloc
, m_pGrid(NULL)
, m_nZOrder(0)
, m_pChildren(NULL)
, m_pParent(NULL)
// "whole screen" objects. like Scenes and Layers, should set m_bIgnoreAnchorPointForPosition to false
, m_nTag(kCCNodeTagInvalid)
// userData is always inited as nil
, m_pUserData(NULL)
, m_pUserObject(NULL)
, m_pShaderProgram(NULL)
, m_eGLServerState(ccGLServerState(0))
, m_uOrderOfArrival(0)
, m_bRunning(false)
, m_bTransformDirty(true)
, m_bInverseDirty(true)
, m_bAdditionalTransformDirty(false)
, m_bVisible(true)
, m_bIgnoreAnchorPointForPosition(false)
, m_bReorderChildDirty(false)
, m_nScriptHandler(0)
, m_nUpdateScriptHandler(0)
{
    // set default scheduler and actionManager
    CCDirector *director = CCDirector::sharedDirector();
    m_pActionManager = director->getActionManager();
    m_pActionManager->retain();
    m_pScheduler = director->getScheduler();
    m_pScheduler->retain();

    CCScriptEngineProtocol* pEngine = CCScriptEngineManager::sharedManager()->getScriptEngine();
    m_eScriptType = pEngine != NULL ? pEngine->getScriptType() : kScriptTypeNone;
}

CCNode::~CCNode(void)
{
    CCLOGINFO( "cocos2d: deallocing" );

    unregisterScriptHandler();
    if (m_nUpdateScriptHandler)
    {
        CCScriptEngineManager::sharedManager()->getScriptEngine()->removeScriptHandler(m_nUpdateScriptHandler);
    }

    CC_SAFE_RELEASE(m_pActionManager);
    CC_SAFE_RELEASE(m_pScheduler);
    // attributes
    CC_SAFE_RELEASE(m_pCamera);

    CC_SAFE_RELEASE(m_pGrid);
    CC_SAFE_RELEASE(m_pShaderProgram);
    CC_SAFE_RELEASE(m_pUserObject);

    if(m_pChildren && m_pChildren->count() > 0)
    {
        CCObject* child;
        CCARRAY_FOREACH(m_pChildren, child)
        {
            CCNode* pChild = (CCNode*) child;
            if (pChild)
            {
                pChild->m_pParent = NULL;
            }
        }
    }

    // children
    CC_SAFE_RELEASE(m_pChildren);
}

bool CCNode::init()
{
    return true;
}

float CCNode::getSkewX()
{
    return m_fSkewX;
}

void CCNode::setSkewX(float newSkewX)
{
    m_fSkewX = newSkewX;
    m_bTransformDirty = m_bInverseDirty = true;
}

float CCNode::getSkewY()
{
    return m_fSkewY;
}

void CCNode::setSkewY(float newSkewY)
{
    m_fSkewY = newSkewY;

    m_bTransformDirty = m_bInverseDirty = true;
}

/// zOrder getter
int CCNode::getZOrder()
{
    return m_nZOrder;
}

/// zOrder setter : private method
/// used internally to alter the zOrder variable. DON'T call this method manually
void CCNode::_setZOrder(int z)
{
    m_nZOrder = z;
}

void CCNode::setZOrder(int z)
{
    _setZOrder(z);
    if (m_pParent)
    {
        m_pParent->reorderChild(this, z);
    }
}

/// vertexZ getter
float CCNode::getVertexZ()
{
    return m_fVertexZ;
}

/// vertexZ setter
void CCNode::setVertexZ(float var)
{
    m_fVertexZ = var;
}

/// rotation getter
float CCNode::getRotation()
{
    CCAssert(m_fRotationX == m_fRotationY, "CCNode#rotation. RotationX != RotationY. Don't know which one to return");
    return m_fRotationX;
}

/// rotation setter
void CCNode::setRotation(float newRotation)
{
    m_fRotationX = m_fRotationY = newRotation;
    m_bTransformDirty = m_bInverseDirty = true;
}

float CCNode::getRotationX()
{
    return m_fRotationX;
}

void CCNode::setRotationX(float fRotationX)
{
    m_fRotationX = fRotationX;
    m_bTransformDirty = m_bInverseDirty = true;
}

float CCNode::getRotationY()
{
    return m_fRotationY;
}

void CCNode::setRotationY(float fRotationY)
{
    m_fRotationY = fRotationY;
    m_bTransformDirty = m_bInverseDirty = true;
}

/// scale getter
float CCNode::getScale(void)
{
    CCAssert( m_fScaleX == m_fScaleY, "CCNode#scale. ScaleX != ScaleY. Don't know which one to return");
    return m_fScaleX;
}

/// scale setter
void CCNode::setScale(float scale)
{
    m_fScaleX = m_fScaleY = scale;
    m_bTransformDirty = m_bInverseDirty = true;
}

/// scaleX getter
float CCNode::getScaleX()
{
    return m_fScaleX;
}

/// scaleX setter
void CCNode::setScaleX(float newScaleX)
{
    m_fScaleX = newScaleX;
    m_bTransformDirty = m_bInverseDirty = true;
}

/// scaleY getter
float CCNode::getScaleY()
{
    return m_fScaleY;
}

/// scaleY setter
void CCNode::setScaleY(float newScaleY)
{
    m_fScaleY = newScaleY;
    m_bTransformDirty = m_bInverseDirty = true;
}

/// position getter
const CCPoint& CCNode::getPosition()
{
    return m_obPosition;
}

/// position setter
void CCNode::setPosition(const CCPoint& newPosition)
{
    m_obPosition = newPosition;
    m_bTransformDirty = m_bInverseDirty = true;
}

void CCNode::getPosition(float* x, float* y)
{
    *x = m_obPosition.x;
    *y = m_obPosition.y;
}

void CCNode::setPosition(float x, float y)
{
    setPosition(ccp(x, y));
}

float CCNode::getPositionX(void)
{
    return m_obPosition.x;
}

float CCNode::getPositionY(void)
{
    return  m_obPosition.y;
}

void CCNode::setPositionX(float x)
{
    setPosition(ccp(x, m_obPosition.y));
}

void CCNode::setPositionY(float y)
{
    setPosition(ccp(m_obPosition.x, y));
}

/// children getter
CCArray* CCNode::getChildren()
{
    return m_pChildren;
}

unsigned int CCNode::getChildrenCount(void)
{
    return m_pChildren ? m_pChildren->count() : 0;
}

/// camera getter: lazy alloc
CCCamera* CCNode::getCamera()
{
    if (!m_pCamera)
    {
        m_pCamera = new CCCamera();
    }

    return m_pCamera;
}

/// grid getter
CCGridBase* CCNode::getGrid()
{
    return m_pGrid;
}

/// grid setter
void CCNode::setGrid(CCGridBase* pGrid)
{
    CC_SAFE_RETAIN(pGrid);
    CC_SAFE_RELEASE(m_pGrid);
    m_pGrid = pGrid;
}

/// isVisible getter
bool CCNode::isVisible()
{
    return m_bVisible;
}

/// isVisible setter
void CCNode::setVisible(bool var)
{
    m_bVisible = var;
}

const CCPoint& CCNode::getAnchorPointInPoints()
{
    return m_obAnchorPointInPoints;
}

/// anchorPoint getter
const CCPoint& CCNode::getAnchorPoint()
{
    return m_obAnchorPoint;
}

void CCNode::setAnchorPoint(const CCPoint& point)
{
    if( ! point.equals(m_obAnchorPoint))
    {
        m_obAnchorPoint = point;
        m_obAnchorPointInPoints = ccp(m_obContentSize.width * m_obAnchorPoint.x, m_obContentSize.height * m_obAnchorPoint.y );
        m_bTransformDirty = m_bInverseDirty = true;
    }
}

/// contentSize getter
const CCSize& CCNode::getContentSize()
{
    return m_obContentSize;
}

void CCNode::setContentSize(const CCSize & size)
{
    if ( ! size.equals(m_obContentSize))
    {
        m_obContentSize = size;

        m_obAnchorPointInPoints = ccp(m_obContentSize.width * m_obAnchorPoint.x, m_obContentSize.height * m_obAnchorPoint.y );
        m_bTransformDirty = m_bInverseDirty = true;
    }
}

// isRunning getter
bool CCNode::isRunning()
{
    return m_bRunning;
}

/// parent getter
CCNode * CCNode::getParent()
{
    return m_pParent;
}
/// parent setter
void CCNode::setParent(CCNode * var)
{
    m_pParent = var;
}

/// isRelativeAnchorPoint getter
bool CCNode::isIgnoreAnchorPointForPosition()
{
    return m_bIgnoreAnchorPointForPosition;
}
/// isRelativeAnchorPoint setter
void CCNode::ignoreAnchorPointForPosition(bool newValue)
{
    if (newValue != m_bIgnoreAnchorPointForPosition)
    {
		m_bIgnoreAnchorPointForPosition = newValue;
		m_bTransformDirty = m_bInverseDirty = true;
	}
}

/// tag getter
int CCNode::getTag()
{
    return m_nTag;
}

/// tag setter
void CCNode::setTag(int var)
{
    m_nTag = var;
}

/// userData getter
void * CCNode::getUserData()
{
    return m_pUserData;
}

/// userData setter
void CCNode::setUserData(void *var)
{
    m_pUserData = var;
}

unsigned int CCNode::getOrderOfArrival()
{
    return m_uOrderOfArrival;
}

void CCNode::setOrderOfArrival(unsigned int uOrderOfArrival)
{
    m_uOrderOfArrival = uOrderOfArrival;
}

CCGLProgram* CCNode::getShaderProgram()
{
    return m_pShaderProgram;
}

CCObject* CCNode::getUserObject()
{
    return m_pUserObject;
}

ccGLServerState CCNode::getGLServerState()
{
    return m_eGLServerState;
}

void CCNode::setGLServerState(ccGLServerState glServerState)
{
    m_eGLServerState = glServerState;
}

void CCNode::setUserObject(CCObject *pUserObject)
{
    CC_SAFE_RELEASE(m_pUserObject);
    CC_SAFE_RETAIN(pUserObject);
    m_pUserObject = pUserObject;
}

void CCNode::setShaderProgram(CCGLProgram *pShaderProgram)
{
    CC_SAFE_RELEASE(m_pShaderProgram);
    m_pShaderProgram = pShaderProgram;
    CC_SAFE_RETAIN(m_pShaderProgram);
}

CCRect CCNode::boundingBox()
{
    CCRect rect = CCRectMake(0, 0, m_obContentSize.width, m_obContentSize.height);
    return CCRectApplyAffineTransform(rect, nodeToParentTransform());
}

CCNode * CCNode::create(void)
{
	CCNode * pRet = new CCNode();
    if (pRet && pRet->init())
    {
        pRet->autorelease();
    }
    else
    {
        CC_SAFE_DELETE(pRet);
    }
	return pRet;
}

void CCNode::cleanup()
{
    // actions
    this->stopAllActions();
    this->unscheduleAllSelectors();

    if ( m_eScriptType != kScriptTypeNone)
    {
        CCScriptEngineManager::sharedManager()->getScriptEngine()->executeNodeEvent(this, kCCNodeOnCleanup);
    }

    // timers
    arrayMakeObjectsPerformSelector(m_pChildren, cleanup, CCNode*);
}

const char* CCNode::description()
{
    return CCString::createWithFormat("<CCNode | Tag = %d>", m_nTag)->getCString();
}

// lazy allocs
void CCNode::childrenAlloc(void)
{
    m_pChildren = CCArray::createWithCapacity(4);
    m_pChildren->retain();
}

CCNode* CCNode::getChildByTag(int aTag)
{
    CCAssert( aTag != kCCNodeTagInvalid, "Invalid tag");

    if(m_pChildren && m_pChildren->count() > 0)
    {
        CCObject* child;
        CCARRAY_FOREACH(m_pChildren, child)
        {
            CCNode* pNode = (CCNode*) child;
            if(pNode && pNode->m_nTag == aTag)
                return pNode;
        }
    }
    return NULL;
}

/* "add" logic MUST only be on this method
* If a class want's to extend the 'addChild' behavior it only needs
* to override this method
*/
void CCNode::addChild(CCNode *child, int zOrder, int tag)
{
    CCAssert( child != NULL, "Argument must be non-nil");
    CCAssert( child->m_pParent == NULL, "child already added. It can't be added again");

    if( ! m_pChildren )
    {
        this->childrenAlloc();
    }

    this->insertChild(child, zOrder);

    child->m_nTag = tag;

    child->setParent(this);
    child->setOrderOfArrival(s_globalOrderOfArrival++);

    if( m_bRunning )
    {
        child->onEnter();
        child->onEnterTransitionDidFinish();
    }
}

void CCNode::addChild(CCNode *child, int zOrder)
{
    CCAssert( child != NULL, "Argument must be non-nil");
    this->addChild(child, zOrder, child->m_nTag);
}

void CCNode::addChild(CCNode *child)
{
    CCAssert( child != NULL, "Argument must be non-nil");
    this->addChild(child, child->m_nZOrder, child->m_nTag);
}

void CCNode::removeFromParent()
{
    this->removeFromParentAndCleanup(true);
}

void CCNode::removeFromParentAndCleanup(bool cleanup)
{
    if (m_pParent != NULL)
    {
        m_pParent->removeChild(this,cleanup);
    }
}

void CCNode::removeChild(CCNode* child)
{
    this->removeChild(child, true);
}

/* "remove" logic MUST only be on this method
* If a class want's to extend the 'removeChild' behavior it only needs
* to override this method
*/
void CCNode::removeChild(CCNode* child, bool cleanup)
{
    // explicit nil handling
    if (m_pChildren == NULL)
    {
        return;
    }

    if ( m_pChildren->containsObject(child) )
    {
        this->detachChild(child,cleanup);
    }
}

void CCNode::removeChildByTag(int tag)
{
    this->removeChildByTag(tag, true);
}

void CCNode::removeChildByTag(int tag, bool cleanup)
{
    CCAssert( tag != kCCNodeTagInvalid, "Invalid tag");

    CCNode *child = this->getChildByTag(tag);

    if (child == NULL)
    {
        CCLOG("cocos2d: removeChildByTag: child not found!");
    }
    else
    {
        this->removeChild(child, cleanup);
    }
}

void CCNode::removeAllChildren()
{
    this->removeAllChildrenWithCleanup(true);
}

void CCNode::removeAllChildrenWithCleanup(bool cleanup)
{
    // not using detachChild improves speed here
    if ( m_pChildren && m_pChildren->count() > 0 )
    {
        CCObject* child;
        CCARRAY_FOREACH(m_pChildren, child)
        {
            CCNode* pNode = (CCNode*) child;
            if (pNode)
            {
                // IMPORTANT:
                //  -1st do onExit
                //  -2nd cleanup
                if(m_bRunning)
                {
                    pNode->onExitTransitionDidStart();
                    pNode->onExit();
                }

                if (cleanup)
                {
                    pNode->cleanup();
                }
                // set parent nil at the end
                pNode->setParent(NULL);
            }
        }

        m_pChildren->removeAllObjects();
    }

}

void CCNode::detachChild(CCNode *child, bool doCleanup)
{
    // IMPORTANT:
    //  -1st do onExit
    //  -2nd cleanup
    if (m_bRunning)
    {
        child->onExitTransitionDidStart();
        child->onExit();
    }

    // If you don't do cleanup, the child's actions will not get removed and the
    // its scheduledSelectors_ dict will not get released!
    if (doCleanup)
    {
        child->cleanup();
    }

    // set parent nil at the end
    child->setParent(NULL);

    m_pChildren->removeObject(child);
}

// helper used by reorderChild & add
void CCNode::insertChild(CCNode* child, int z)
{
    m_bReorderChildDirty = true;
    ccArrayAppendObjectWithResize(m_pChildren->data, child);
    child->_setZOrder(z);
}

void CCNode::reorderChild(CCNode *child, int zOrder)
{
    CCAssert( child != NULL, "Child must be non-nil");
    m_bReorderChildDirty = true;
    child->setOrderOfArrival(s_globalOrderOfArrival++);
    child->_setZOrder(zOrder);
}

void CCNode::sortAllChildren()
{
    if (m_bReorderChildDirty)
    {
        int i,j,length = m_pChildren->data->num;
        CCNode ** x = (CCNode**)m_pChildren->data->arr;
        CCNode *tempItem;

        // insertion sort
        for(i=1; i<length; i++)
        {
            tempItem = x[i];
            j = i-1;

            //continue moving element downwards while zOrder is smaller or when zOrder is the same but mutatedIndex is smaller
            while(j>=0 && ( tempItem->m_nZOrder < x[j]->m_nZOrder || ( tempItem->m_nZOrder== x[j]->m_nZOrder && tempItem->m_uOrderOfArrival < x[j]->m_uOrderOfArrival ) ) )
            {
                x[j+1] = x[j];
                j = j-1;
            }
            x[j+1] = tempItem;
        }

        //don't need to check children recursively, that's done in visit of each child

        m_bReorderChildDirty = false;
    }
}

 void CCNode::draw()
 {
     //CCAssert(0);
     // override me
     // Only use- this function to draw your stuff.
     // DON'T draw your stuff outside this method
 }

void CCNode::visit()
{
    // quick return if not visible. children won't be drawn.
    if (!m_bVisible)
    {
        return;
    }
    kmGLPushMatrix();

     if (m_pGrid && m_pGrid->isActive())
     {
         m_pGrid->beforeDraw();
     }

    this->transform();

    CCNode* pNode = NULL;
    unsigned int i = 0;

    if(m_pChildren && m_pChildren->count() > 0)
    {
        sortAllChildren();
        // draw children zOrder < 0
        ccArray *arrayData = m_pChildren->data;
        for( ; i < arrayData->num; i++ )
        {
            pNode = (CCNode*) arrayData->arr[i];

            if ( pNode && pNode->m_nZOrder < 0 )
            {
                pNode->visit();
            }
            else
            {
                break;
            }
        }
        // self draw
        this->draw();

        for( ; i < arrayData->num; i++ )
        {
            pNode = (CCNode*) arrayData->arr[i];
            if (pNode)
            {
                pNode->visit();
            }
        }
    }
    else
    {
        this->draw();
    }

    // reset for next frame
    m_uOrderOfArrival = 0;

     if (m_pGrid && m_pGrid->isActive())
     {
         m_pGrid->afterDraw(this);
    }

    kmGLPopMatrix();
}

void CCNode::transformAncestors()
{
    if( m_pParent != NULL  )
    {
        m_pParent->transformAncestors();
        m_pParent->transform();
    }
}

void CCNode::transform()
{
    kmMat4 transfrom4x4;

    // Convert 3x3 into 4x4 matrix
    CCAffineTransform tmpAffine = this->nodeToParentTransform();
    CGAffineToGL(&tmpAffine, transfrom4x4.mat);

    // Update Z vertex manually
    transfrom4x4.mat[14] = m_fVertexZ;

    kmGLMultMatrix( &transfrom4x4 );

    // XXX: Expensive calls. Camera should be integrated into the cached affine matrix
    if ( m_pCamera != NULL && !(m_pGrid != NULL && m_pGrid->isActive()) )
    {
        bool translate = (m_obAnchorPointInPoints.x != 0.0f || m_obAnchorPointInPoints.y != 0.0f);

        if( translate )
            kmGLTranslatef(RENDER_IN_SUBPIXEL(m_obAnchorPointInPoints.x), RENDER_IN_SUBPIXEL(m_obAnchorPointInPoints.y), 0 );

        m_pCamera->locate();

        if( translate )
            kmGLTranslatef(RENDER_IN_SUBPIXEL(-m_obAnchorPointInPoints.x), RENDER_IN_SUBPIXEL(-m_obAnchorPointInPoints.y), 0 );
    }

}

void CCNode::onEnter()
{
    arrayMakeObjectsPerformSelector(m_pChildren, onEnter, CCNode*);

    this->resumeSchedulerAndActions();

    m_bRunning = true;

    if (m_eScriptType != kScriptTypeNone)
    {
        CCScriptEngineManager::sharedManager()->getScriptEngine()->executeNodeEvent(this, kCCNodeOnEnter);
    }
}

void CCNode::onEnterTransitionDidFinish()
{
    arrayMakeObjectsPerformSelector(m_pChildren, onEnterTransitionDidFinish, CCNode*);

    if (m_eScriptType == kScriptTypeJavascript)
    {
        CCScriptEngineManager::sharedManager()->getScriptEngine()->executeNodeEvent(this, kCCNodeOnEnterTransitionDidFinish);
    }
}

void CCNode::onExitTransitionDidStart()
{
    arrayMakeObjectsPerformSelector(m_pChildren, onExitTransitionDidStart, CCNode*);

    if (m_eScriptType == kScriptTypeJavascript)
    {
        CCScriptEngineManager::sharedManager()->getScriptEngine()->executeNodeEvent(this, kCCNodeOnExitTransitionDidStart);
    }
}

void CCNode::onExit()
{
    this->pauseSchedulerAndActions();

    m_bRunning = false;

    if ( m_eScriptType != kScriptTypeNone)
    {
        CCScriptEngineManager::sharedManager()->getScriptEngine()->executeNodeEvent(this, kCCNodeOnExit);
    }

    arrayMakeObjectsPerformSelector(m_pChildren, onExit, CCNode*);
}

void CCNode::registerScriptHandler(int nHandler)
{
    unregisterScriptHandler();
    m_nScriptHandler = nHandler;
    LUALOG("[LUA] Add CCNode event handler: %d", m_nScriptHandler);
}

void CCNode::unregisterScriptHandler(void)
{
    if (m_nScriptHandler)
    {
        CCScriptEngineManager::sharedManager()->getScriptEngine()->removeScriptHandler(m_nScriptHandler);
        LUALOG("[LUA] Remove CCNode event handler: %d", m_nScriptHandler);
        m_nScriptHandler = 0;
    }
}

void CCNode::setActionManager(CCActionManager* actionManager)
{
    if( actionManager != m_pActionManager ) {
        this->stopAllActions();
        CC_SAFE_RETAIN(actionManager);
        CC_SAFE_RELEASE(m_pActionManager);
        m_pActionManager = actionManager;
    }
}

CCActionManager* CCNode::getActionManager()
{
    return m_pActionManager;
}

CCAction * CCNode::runAction(CCAction* action)
{
    CCAssert( action != NULL, "Argument must be non-nil");
    m_pActionManager->addAction(action, this, !m_bRunning);
    return action;
}

void CCNode::stopAllActions()
{
    m_pActionManager->removeAllActionsFromTarget(this);
}

void CCNode::stopAction(CCAction* action)
{
    m_pActionManager->removeAction(action);
}

void CCNode::stopActionByTag(int tag)
{
    CCAssert( tag != kCCActionTagInvalid, "Invalid tag");
    m_pActionManager->removeActionByTag(tag, this);
}

CCAction * CCNode::getActionByTag(int tag)
{
    CCAssert( tag != kCCActionTagInvalid, "Invalid tag");
    return m_pActionManager->getActionByTag(tag, this);
}

unsigned int CCNode::numberOfRunningActions()
{
    return m_pActionManager->numberOfRunningActionsInTarget(this);
}

// CCNode - Callbacks

void CCNode::setScheduler(CCScheduler* scheduler)
{
    if( scheduler != m_pScheduler ) {
        this->unscheduleAllSelectors();
        CC_SAFE_RETAIN(scheduler);
        CC_SAFE_RELEASE(m_pScheduler);
        m_pScheduler = scheduler;
    }
}

CCScheduler* CCNode::getScheduler()
{
    return m_pScheduler;
}

void CCNode::scheduleUpdate()
{
    scheduleUpdateWithPriority(0);
}

void CCNode::scheduleUpdateWithPriority(int priority)
{
    m_pScheduler->scheduleUpdateForTarget(this, priority, !m_bRunning);
}

void CCNode::scheduleUpdateWithPriorityLua(int nHandler, int priority)
{
    unscheduleUpdate();
    m_nUpdateScriptHandler = nHandler;
    m_pScheduler->scheduleUpdateForTarget(this, priority, !m_bRunning);
}

void CCNode::unscheduleUpdate()
{
    m_pScheduler->unscheduleUpdateForTarget(this);
    if (m_nUpdateScriptHandler)
    {
        CCScriptEngineManager::sharedManager()->getScriptEngine()->removeScriptHandler(m_nUpdateScriptHandler);
        m_nUpdateScriptHandler = 0;
    }
}

void CCNode::schedule(SEL_SCHEDULE selector)
{
    this->schedule(selector, 0.0f, kCCRepeatForever, 0.0f);
}

void CCNode::schedule(SEL_SCHEDULE selector, float interval)
{
    this->schedule(selector, interval, kCCRepeatForever, 0.0f);
}

void CCNode::schedule(SEL_SCHEDULE selector, float interval, unsigned int repeat, float delay)
{
    CCAssert( selector, "Argument must be non-nil");
    CCAssert( interval >=0, "Argument must be positive");

    m_pScheduler->scheduleSelector(selector, this, interval , repeat, delay, !m_bRunning);
}

void CCNode::scheduleOnce(SEL_SCHEDULE selector, float delay)
{
    this->schedule(selector, 0.0f, 0, delay);
}

void CCNode::unschedule(SEL_SCHEDULE selector)
{
    // explicit nil handling
    if (selector == 0)
        return;

    m_pScheduler->unscheduleSelector(selector, this);
}

void CCNode::unscheduleAllSelectors()
{
    m_pScheduler->unscheduleAllForTarget(this);
}

void CCNode::resumeSchedulerAndActions()
{
    m_pScheduler->resumeTarget(this);
    m_pActionManager->resumeTarget(this);
}

void CCNode::pauseSchedulerAndActions()
{
    m_pScheduler->pauseTarget(this);
    m_pActionManager->pauseTarget(this);
}

// override me
void CCNode::update(float fDelta)
{
    if (m_nUpdateScriptHandler)
    {
        CCScriptEngineManager::sharedManager()->getScriptEngine()->executeSchedule(m_nUpdateScriptHandler, fDelta, this);
    }
}

CCAffineTransform CCNode::nodeToParentTransform(void)
{
    if (m_bTransformDirty)
    {

        // Translate values
        float x = m_obPosition.x;
        float y = m_obPosition.y;

        if (m_bIgnoreAnchorPointForPosition)
        {
            x += m_obAnchorPointInPoints.x;
            y += m_obAnchorPointInPoints.y;
        }

        // Rotation values
		// Change rotation code to handle X and Y
		// If we skew with the exact same value for both x and y then we're simply just rotating
        float cx = 1, sx = 0, cy = 1, sy = 0;
        if (m_fRotationX || m_fRotationY)
        {
            float radiansX = -CC_DEGREES_TO_RADIANS(m_fRotationX);
            float radiansY = -CC_DEGREES_TO_RADIANS(m_fRotationY);
            cx = cosf(radiansX);
            sx = sinf(radiansX);
            cy = cosf(radiansY);
            sy = sinf(radiansY);
        }

        bool needsSkewMatrix = ( m_fSkewX || m_fSkewY );

        // optimization:
        // inline anchor point calculation if skew is not needed
        // Adjusted transform calculation for rotational skew
        if (! needsSkewMatrix && !m_obAnchorPointInPoints.equals(CCPointZero))
        {
            x += cy * -m_obAnchorPointInPoints.x * m_fScaleX + -sx * -m_obAnchorPointInPoints.y * m_fScaleY;
            y += sy * -m_obAnchorPointInPoints.x * m_fScaleX +  cx * -m_obAnchorPointInPoints.y * m_fScaleY;
        }

        // Build Transform Matrix
        // Adjusted transform calculation for rotational skew
        m_sTransform = CCAffineTransformMake( cy * m_fScaleX,  sy * m_fScaleX,
            -sx * m_fScaleY, cx * m_fScaleY,
            x, y );

        // XXX: Try to inline skew
        // If skew is needed, apply skew and then anchor point
        if (needsSkewMatrix)
        {
            CCAffineTransform skewMatrix = CCAffineTransformMake(1.0f, tanf(CC_DEGREES_TO_RADIANS(m_fSkewY)),
                tanf(CC_DEGREES_TO_RADIANS(m_fSkewX)), 1.0f,
                0.0f, 0.0f );
            m_sTransform = CCAffineTransformConcat(skewMatrix, m_sTransform);

            // adjust anchor point
            if (!m_obAnchorPointInPoints.equals(CCPointZero))
            {
                m_sTransform = CCAffineTransformTranslate(m_sTransform, -m_obAnchorPointInPoints.x, -m_obAnchorPointInPoints.y);
            }
        }

        if (m_bAdditionalTransformDirty)
        {
            m_sTransform = CCAffineTransformConcat(m_sTransform, m_sAdditionalTransform);
            m_bAdditionalTransformDirty = false;
        }

        m_bTransformDirty = false;
    }

    return m_sTransform;
}

void CCNode::setAdditionalTransform(const CCAffineTransform& additionalTransform)
{
    m_sAdditionalTransform = additionalTransform;
    m_bTransformDirty = true;
    m_bAdditionalTransformDirty = true;
}

CCAffineTransform CCNode::parentToNodeTransform(void)
{
    if ( m_bInverseDirty ) {
        m_sInverse = CCAffineTransformInvert(this->nodeToParentTransform());
        m_bInverseDirty = false;
    }

    return m_sInverse;
}

CCAffineTransform CCNode::nodeToWorldTransform()
{
    CCAffineTransform t = this->nodeToParentTransform();

    for (CCNode *p = m_pParent; p != NULL; p = p->getParent())
        t = CCAffineTransformConcat(t, p->nodeToParentTransform());

    return t;
}

CCAffineTransform CCNode::worldToNodeTransform(void)
{
    return CCAffineTransformInvert(this->nodeToWorldTransform());
}

CCPoint CCNode::convertToNodeSpace(const CCPoint& worldPoint)
{
    CCPoint ret = CCPointApplyAffineTransform(worldPoint, worldToNodeTransform());
    return ret;
}

CCPoint CCNode::convertToWorldSpace(const CCPoint& nodePoint)
{
    CCPoint ret = CCPointApplyAffineTransform(nodePoint, nodeToWorldTransform());
    return ret;
}

CCPoint CCNode::convertToNodeSpaceAR(const CCPoint& worldPoint)
{
    CCPoint nodePoint = convertToNodeSpace(worldPoint);
    return ccpSub(nodePoint, m_obAnchorPointInPoints);
}

CCPoint CCNode::convertToWorldSpaceAR(const CCPoint& nodePoint)
{
    CCPoint pt = ccpAdd(nodePoint, m_obAnchorPointInPoints);
    return convertToWorldSpace(pt);
}

CCPoint CCNode::convertToWindowSpace(const CCPoint& nodePoint)
{
    CCPoint worldPoint = this->convertToWorldSpace(nodePoint);
    return CCDirector::sharedDirector()->convertToUI(worldPoint);
}

// convenience methods which take a CCTouch instead of CCPoint
CCPoint CCNode::convertTouchToNodeSpace(CCTouch *touch)
{
    CCPoint point = touch->getLocation();
    return this->convertToNodeSpace(point);
}
CCPoint CCNode::convertTouchToNodeSpaceAR(CCTouch *touch)
{
    CCPoint point = touch->getLocation();
    return this->convertToNodeSpaceAR(point);
}

void CCNode::updateTransform()
{
    // Recursively iterate over children
    arrayMakeObjectsPerformSelector(m_pChildren, updateTransform, CCNode*);
}

// CCNodeRGBA
CCNodeRGBA::CCNodeRGBA()
: _displayedOpacity(255)
, _realOpacity(255)
, _displayedColor(ccWHITE)
, _realColor(ccWHITE)
, _cascadeColorEnabled(false)
, _cascadeOpacityEnabled(false)
{}

CCNodeRGBA::~CCNodeRGBA() {}

bool CCNodeRGBA::init()
{
    if (CCNode::init())
    {
        _displayedOpacity = _realOpacity = 255;
        _displayedColor = _realColor = ccWHITE;
        _cascadeOpacityEnabled = _cascadeColorEnabled = false;
        return true;
    }
    return false;
}

GLubyte CCNodeRGBA::getOpacity(void)
{
	return _realOpacity;
}

GLubyte CCNodeRGBA::getDisplayedOpacity(void)
{
	return _displayedOpacity;
}

void CCNodeRGBA::setOpacity(GLubyte opacity)
{
    _displayedOpacity = _realOpacity = opacity;

	if (_cascadeOpacityEnabled)
    {
		GLubyte parentOpacity = 255;
        CCRGBAProtocol* pParent = dynamic_cast<CCRGBAProtocol*>(m_pParent);
        if (pParent && pParent->isCascadeOpacityEnabled())
        {
            parentOpacity = pParent->getDisplayedOpacity();
        }
        this->updateDisplayedOpacity(parentOpacity);
	}
}

void CCNodeRGBA::updateDisplayedOpacity(GLubyte parentOpacity)
{
	_displayedOpacity = _realOpacity * parentOpacity/255.0;

    if (_cascadeOpacityEnabled)
    {
        CCObject* pObj;
        CCARRAY_FOREACH(m_pChildren, pObj)
        {
            CCRGBAProtocol* item = dynamic_cast<CCRGBAProtocol*>(pObj);
            if (item)
            {
                item->updateDisplayedOpacity(_displayedOpacity);
            }
        }
    }
}

bool CCNodeRGBA::isCascadeOpacityEnabled(void)
{
    return _cascadeOpacityEnabled;
}

void CCNodeRGBA::setCascadeOpacityEnabled(bool cascadeOpacityEnabled)
{
    _cascadeOpacityEnabled = cascadeOpacityEnabled;
}

const ccColor3B& CCNodeRGBA::getColor(void)
{
	return _realColor;
}

const ccColor3B& CCNodeRGBA::getDisplayedColor()
{
	return _displayedColor;
}

void CCNodeRGBA::setColor(const ccColor3B& color)
{
	_displayedColor = _realColor = color;

	if (_cascadeColorEnabled)
    {
		ccColor3B parentColor = ccWHITE;
        CCRGBAProtocol *parent = dynamic_cast<CCRGBAProtocol*>(m_pParent);
		if (parent && parent->isCascadeColorEnabled())
        {
            parentColor = parent->getDisplayedColor();
        }

        updateDisplayedColor(parentColor);
	}
}

void CCNodeRGBA::updateDisplayedColor(const ccColor3B& parentColor)
{
	_displayedColor.r = _realColor.r * parentColor.r/255.0;
	_displayedColor.g = _realColor.g * parentColor.g/255.0;
	_displayedColor.b = _realColor.b * parentColor.b/255.0;

    if (_cascadeColorEnabled)
    {
        CCObject *obj = NULL;
        CCARRAY_FOREACH(m_pChildren, obj)
        {
            CCRGBAProtocol *item = dynamic_cast<CCRGBAProtocol*>(obj);
            if (item)
            {
                item->updateDisplayedColor(_displayedColor);
            }
        }
    }
}

bool CCNodeRGBA::isCascadeColorEnabled(void)
{
    return _cascadeColorEnabled;
}

void CCNodeRGBA::setCascadeColorEnabled(bool cascadeColorEnabled)
{
    _cascadeColorEnabled = cascadeColorEnabled;
}

NS_CC_END


In an electronic endoscope system, a flexible scope has a solid image sensor provided at a distal end thereof, to generate image-pixel signals. A proximal end of the scope is detachably connected to a video-signal processing unit, which produces a video signal based on the image-pixel signals. A monitor reproduces an image in accordance with the video signal. A displaying-size changer changes a size of a displaying-area of the image on a screen of the monitor to another size and vice versa. A pointer-image generator generates a pointer image on the monitor screen. A pointer-image controller controls a shifting of the pointer image on the monitor screen, and includes a pointer-image-position converter that converts a position of the pointer image on the monitor screen in accordance with the size-change of the displaying-area of the image on the monitor screen, such that two positions, indicated by the pointer image on the two-sized displaying-areas, correspond to each other.
This invention relates to an electronic endoscope system comprising a flexible conduit or elongated scope having a solid state image sensor provided at a distal end thereof, to generate image-pixel signals; a video-signal processing unit, to which the flexible scope is detachably connected at a proximal end thereof, to produce a video signal on the basis of the image-pixel signals; and a TV monitor for reproducing an image in accordance with the video signal.
In such an electronic endoscope system, a CCD (charge-coupled-device) image sensor is usually utilized as the solid state image sensor, and is associated with an objective lens system provided at the distal end of the flexible scope. Also, a flexible optical guide, formed as a bundle of optical fibers, is extended through the flexible scope, and is associated with a lighting lens system provided at the distal end of the flexible scope.
On the other hand, the video-signal processing unit includes a white-light source, such as a halogen lamp, a xenon lamp or the like. When the flexible scope is connected to the video-signal processing unit, the proximal end of the optical light guide is optically connected to the light source. Thus, an object image to be photographed is illuminated by light radiating from the distal end of the optical light guide, and is focused as an optical image on a light-receiving surface of the CCD image sensor by the objective lens system.
The focused optical image is converted into a frame of analog image-pixel signals by the CCD image sensor, and the frame of analog image-pixel signals is read from the CCD image sensor. The reading of the frame of image-pixel signals from the CCD image sensor is successively performed at a given regular time-interval, and the successively-read frames of image-pixel signals are fed to the video-signal processing unit, in which the frames of image-pixel signals are suitably processed, thereby producing a video signal including image-pixel signals and various synchronizing signals. Then, the video signal is fed from the video-signal processing unit to the monitor to reproduce the photographed object on a screen of the monitor in accordance with the video signal.
As is well known, the CCD image sensor, used in the electronic endoscope system, has a smaller size than that of a CCD image sensor used in a usual TV camera. Namely, a number of image pixels, included in one frame, obtained from the former CCD image sensor, is less than a number of image pixels, included in one frame, obtained from the latter CCD image sensor. Nevertheless, in the electronic endoscope system, the monitor having a usual standard size is used, and thus an object photographed by the CCD image sensor is only reproduced and displayed on a partial area of the screen of the monitor.
Note, in reality, although a video signal is produced and prepared with respect to an overall area of the screen of the monitor, the video signal exhibits a pedestal level over the remaining area of the screen except for the partial area on which the photographed image is only reproduced and displayed.
A size of the reproduced image is sufficient for a scope operator who observes the image at close range. However, when the reproduced image is observed at far range by some persons, for example, medical trainees, the size of the image is too small. Thus, conventionally, an electronic endoscope system has already been proposed, in which an image to be reproduced and displayed on a screen of a TV monitor can be selectively and optionally enlarged to a predetermined size.
On the other hand, in the conventional electronic endoscope system, a CRT controller is frequently incorporated in the video-signal processing unit to produce and display a pointer image on the screen of the monitor. The pointer image is superposed on an image reproduced and displayed on the screen of the monitor, and can be freely moved under control of the CRT controller. Namely, the pointer image is used to indicate a location on the reproduced and displayed image, at which, for example, a lesion occurs. Note, the CRT controller per se is well known in this field.
Conventionally, in a case where the CRT controller is utilized in the electronic endoscope system in which a size of a reproduced and displayed image is changeable on the screen of the monitor, a position of the displayed pointer image cannot be converted in accordance with the size-change of the reproduced and displayed image or displaying-area. Thus, for example, when an originally-sized image, on which a significant location is indicated by the pointer image, is enlarged to a large-sized image, it is necessary to shift and adjust the position of the pointer image on the screen of the monitor before a corresponding significant location can be indicated by the pointer image on the large-sized image. Of course, this is also true for a case where the large-sized image is returned to the originally-sized image.
Therefore, an object of the present invention is to provide an electronic endoscope system as mentioned above, in which a position of a displayed pointer image on a screen of a monitor can be automatically converted in accordance with a size-change of a reproduced and displayed image on the screen of the monitor such that two locations, indicated by the pointer image on two-sized displaying-areas, can correspond to each other.
In accordance with a first aspect of the present invention, there is provided an electronic endoscope system, which comprises: an elongated scope having a solid state image sensor, such as a CCD image sensor, provided at a distal end thereof, to generate image-pixel signals; a video-signal processing unit, to which the elongated scope is detachably connected at a proximal end thereof, to provide a video signal on the basis of the image-pixel signals; a monitor that reproduces an image in accordance with the video signal; a displaying-size changer that changes a size of a displaying-area of the reproduced image on a screen of the monitor to another size and vice versa; a pointer-image generator that generates a pointer image on the screen of the monitor; and a pointer-image controller that controls a shifting of the pointer image on the screen of the monitor. The pointer image controller includes a pointer-image-position converter that converts a position of the pointer image on the screen of the monitor in accordance with the size-change of the displaying-area of the reproduced image on the screen of the monitor, such that two positions, indicated by the pointer image on the two-sized displaying-areas, correspond to each other.
Preferably, the pointer-image-position converter comprises a two-dimensional coordinate system defined with respect to the screen of the monitor, a two-dimensional coordinate generator that generates two-dimensional coordinates representing the position of the pointer image, and a proportional position-convertor that proportionally converts a set of two-dimensional coordinates, representing a position of the pointer image on one of the two-sized displaying-areas, into another set of two-dimensional coordinates, representing a corresponding position of the pointer image on the other-sized displaying-area.
The electronic endoscope system may further comprises a shift limiter that limits a shifting of the pointer image within each of the two-sized displaying-areas. Preferably, the shift limiter comprises a boundary converter that converts a two-dimensional limit range, corresponding to one of the two-sized displaying-areas, within which the shifting of the pointer image is limited, into another two-dimensional limit range, corresponding to the other-sized displaying-areas, within which the shifting of the pointer image is limited, in accordance with the size-change of the displaying-area of the reproduced image on the screen of the monitor.
In accordance with a second aspect of the present invention, there is provided an electronic endoscope system, which comprises: an elongated scope having a solid state image sensor provided at a distal end thereof, to generate image-pixel signals; a video-signal processing unit, to which the elongated scope is detachably connected at a proximal end thereof, to produce a video signal on the basis of the image-pixel signals; a monitor that reproduces an image in accordance with the video signal; a displaying-area changer that changes a displaying-area of the reproduced image on a screen of the monitor between a first-sized displaying-area and a second-sized displaying-area; a pointer-image generator that generates a pointer image on the screen of the monitor; and a pointer-image controller that controls a shifting of the pointer image on the screen of the monitor. The pointer image controller includes a pointer-image-position converter that converts a position of the pointer image on the screen of the monitor in accordance with the displaying-area change of the reproduced image on the screen of the monitor between the first-sized displaying-area and the second-sized displaying-area, such that a position, indicated by the pointer image on the first-sized displaying-area, corresponds to a position, indicated by the pointer image on the second-sized displaying-area.
According to the second aspect of the present invention, preferably, the pointer-image-position converter comprises a two-dimensional coordinate system defined with respect to the screen of the monitor, a two-dimensional coordinate generator that generates two-dimensional coordinates representing the position of the pointer image, and a proportional position-convertor that proportionally converts a set of two-dimensional coordinates, representing a position of the pointer image on the first-sized displaying-area, into another set of two-dimensional coordinates, representing a corresponding position of the pointer image on the second-sized displaying-area.
According to the second aspect of the present invention, the electronic endoscope system may comprises a shift limiter that limits a shifting of the pointer image within each of the first-sized and second-sized displaying-areas. Preferably, the shift limiter comprises a boundary converter that converts a two-dimensional limit range, corresponding to the first-sized displaying-area, within which the shifting of the pointer image is limited, into another two-dimensional limit range, corresponding to the second-sized displaying-areas, within which the shifting of the pointer image is limited, in accordance with the displaying-area change of the reproduced image on the screen of the monitor between the first-sized displaying-area and the second-sized displaying-area.
FIG. 11 is a flowchart of a fourth pointer-shifting routine forming a part of the key-manipulation-monitoring routine of the FIG. 6.
With reference to FIG. 1, an electronic endoscope system according to the present invention is illustrated as a block diagram. The electronic endoscope system comprises a flexible conduit or elongated scope 10, and a video-signal processing unit 12 to which the flexible elongated scope 10 is detachably connected at a proximal end thereof.
The flexible elongated scope 10 includes an objective lens system (not shown) provided at a distal end thereof, and a solid state image sensor 14, such as a CCD (charge-coupled-device) image sensor, associated therewith. An optical object to be photographed is focused, as an optical image, on a light-receiving surface of the CCD image sensor 14 by the objective lens system.
The flexible elongated scope 10 also includes an optical light guide 16 extended therethrough and formed as a bundle of optical fibers. The optical light guide 16 terminates at a light-radiating end face at the distal end of the flexible scope 10, and is associated with a lighting lens system (not shown) provided thereat. When the flexible scope 10 is connected to the video-signal processing unit 12, the proximal end of the optical light guide 16 is optically connected to a white-light source 18, such as a halogen lamp, a xenon lamp or the like, provided in the video-signal processing unit 12. The light, emitted from the white-light source or lamp 18, is directed to the proximal end of the optical light guide 16, and then radiates as an illuminating-light from the distal end of the optical light guide 16.
As shown in FIG. 1, an aperture-stop 20 and a condenser lens 22 are provided between the white-light lamp 18 and the proximal end of the optical light guide 16. The aperture-stop 20 is used to adjust an amount of the light directed from the lamp 18 to the proximal end of the optical light guide 16, i.e. an amount of the illuminating-light radiating from the distal end of the optical light guide 16. The condenser lens 22 is used to converge the light, emitted from the lamp 18, on the proximal end of the optical light guide 16.
In this embodiment, for reproduction of a photographed image as a color image, an RGB field sequential-type color imaging system is incorporated in the electronic endoscope system. Thus, a rotary RGB color filter disk 24 is interposed between the white-light lamp 18 and the proximal end of the optical light guide 16.
The rotary RGB color filter disk 24 has three sector-shaped color filters, i.e. a red filter, a green filter and a blue filter, and these color filters are circumferentially and uniformly arranged such that three centers of the color filters are spaced from each other at regular angular-intervals of 120 degrees, with a sector area between two adjacent color filters serving as a light-shielding area.
As shown in FIG. 1, the rotary RGB color filter disk 24 is rotated by a suitable electric motor 26, such as a servo-motor, a stepping motor or the like, at a given rotational frequency in accordance with a used image-reproduction method, such as the NTSC system, the PAL system or the like, whereby an optical object to be photographed is sequentially illuminated by red light, green light and blue light. Namely, a red optical image, a green optical image and a blue optical image are sequentially and cyclically focused on the light-receiving surface of the CCD image sensor 14.
Note, in the NTSC system, the rotational frequency of the color filter disk 24 is 30 Hz, and, in the PAL system, the rotational frequency of the color filter disk 24 is 25 Hz.
Each of the red, green and blue optical images is sequentially converted into a frame of monochromatic (red, green, blue) analog image-pixel signals by the CCD image sensor 14, and the monochromatic (red, green, blue) analog image-pixel signals are successively read from the CCD image sensor 14 over consecutive light-shielding time periods corresponding to the light-shielding areas between two adjacent color filters. The reading of the monochromatic (red, green, blue) analog image-pixel signals from the CCD image sensor 14 is performed in accordance with a series of clock pulses, having a given frequency, output from a CCD driver circuit 28 provided in the flexible scope 10.
As shown in FIG. 1, the video-signal processing unit 12 is provided with a system control circuit 30, which may be constituted as a microcomputer, used to control the electronic endoscope system as a whole, comprising, for example, a central processing unit (CPU), a read-only memory (ROM) for storing programs and constants, a random-access memory (RAM) for storing temporary data, and an input/output interface circuit (I/O).
The video-signal processing unit 12 is provided with a CCD-process circuit 32, which is connected to the CCD driver circuit 28 when the flexible scope 10 is connected to the video-signal processing unit 12. The monochromatic analog image-pixel signals, read from the CCD image sensor 14 by the CCD driver circuit 28, are fed to the CCD-process circuit 32, in which the monochromatic image-pixel signals are subjected to various image-processings, such as a white-balance correction processing, a gamma-correction processing, a profile-enhancing processing and so on.
The monochromatic analog image-pixel signals, suitably processed in the CCD-process circuit 32, are fed to an analog-to-digital (A/D) converter 34, and are converted by the A/D converter 34 into monochromatic digital image-pixel signals which are temporarily stored in a frame memory 36. In this frame memory 36, three frame memory sections are defined for the storage of red digital image-pixel signals, green digital image-pixel signals and blue digital image-pixel signals, respectively. In short, the monochromatic digital image-pixel signals are stored in a corresponding frame memory section defined in the frame memory 36.
Then, the respective red, green and blue digital image-pixel signals are simultaneously read from the three frame memory sections of the frame memory 36, and are output to a video-process circuit 38, as a red digital video signal R, a green digital video signal G and a blue digital video signal B, respectively. Namely, each of the red, green and blue digital video signals R, G and B is produced by suitably adding various synchronizing signals to the monochromatic (red, green, blue) digital image-pixel signals read from the frame memory 36.
In the video-process circuit 38, the red digital video signal R, the green digital video signal G and the blue digital video signal B are converted into a red analog video signal, a green analog video signal and a blue analog video signal, respectively, and each of the red, green and blue analog video signals is processed such that a high frequency noise component is eliminated therefrom. Then, the red, green and blue analog video signals are output from the video process circuit 38 to a TV monitor 40 to thereby reproduce and display the photographed color image on a screen thereof.
Also, the video-process circuit 38 includes a color encoder for producing various types of color digital video signals on the basis of the red, green and blue digital video signals, and the various types of video color digital signals are output from the video-process circuit 38 to various pieces of peripheral equipment (not shown), such as a remote monitor, a video tape recorder, a printer, an image-processing computer and so on.
As shown in FIG. 1, the aperture-stop 20 is operated by a suitable electric motor 42, such as a servo-motor, a stepping motor or the like, driven by a series of driver clock pulses output from a driver circuit 44, which is operated under control of the system control circuit 30. The operation of the aperture-stop 20 is controlled in a well-known manner such that an amount of the light passing through the aperture-stop 20, and therefore, a radiation of light from the distal end of the optical light guide 16 is regulated so that a constant luminance of a reproduced image on the monitor 40 can be maintained. Also, as shown in FIG. 1, the lamp 18 is electrically powered by a power source circuit 46, which is operated under control of the system control circuit 30, whereby the lamp 18 is lit.
Further, the video-signal processing unit 12 features a CRT controller 48 which is operated through a keyboard 50 under control of the system control circuit 30. The CRT controller 48 produces a pointer image on the screen of the monitor 40 such that the pointer image is superposed on a photographed image reproduced and displayed on the monitor screen, and controls a shifting or movement of the pointer image within a partial area of the screen of the monitor 40, on which the photographed image is reproduced and displayed.
As shown in FIG. 2, the CRT controller 48 includes a pointer-image-signal-generating (PISG) circuit 48A which generates pointer-image signals, representing the pointer image, under control of the system control circuit 30. The pointer-image signals are output at a given timing from the PISG circuit 48A to the video-process circuit 38, in which the pointer-image signals are superposed on a video signal representing a photographed image, whereby the pointer image is displayed at a given position on the screen of the monitor 40, as shown by way of example in FIG. 3.
Note, in FIG. 3, reference "P" indicates the pointer image; reference "S" indicates the screen of the monitor 40; and reference "R" indicates the partial area of the screen "S" of the monitor 40, on which the photographed image is reproduced and displayed. Also, note, as shown in FIG. 3, an X-Y coordinate system is defined with respect to the screen of the monitor 40, and an origin of the X-Y coordinate system is positioned at a corner of the screen of the monitor screen 40.
As shown in FIG. 2, the CRT controller 48 also features an X-coordinate register 48B and a Y-coordinate register 48C, and both the registers 48B and 48C control the timing of the output of the pointer-image signals from the PISG circuit 48A to the video-process circuit 38. Namely, the registers 48B and 48C respectively hold X-coordinate data and Y-coordinate data, and the timing of the output of the pointer-image signals from the PISG circuit 48A to the video-process circuit 38 is controlled in accordance with a combination of the X-coordinate data and the Y-coordinate data, such that the pointer image "P" is displayed at an X-Y coordinate position represented by the combination of the X-coordinate data and the Y-coordinate data. Thus, by varying one or both of the X-coordinate data and the Y-coordinate data, it is possible to shift and move the displayed pointer image "P" on the screen of the monitor 40.
The X-coordinate data and the Y-coordinate data can be changed by manipulating the keyboard 50. In particular, the change of the x-coordinate data and the Y-coordinate data can be performed by manipulating four shift keys 50A, 50B, 50C and 50D. Whenever the left-shift key 50A is depressed, the X-coordinate data is reduced by a unit of value, so that the pointer image "P" is shifted left by a unit of distance, and, whenever the right-shift key 50B is depressed, the X-coordinate data is increased by the unit of value, so that the pointer image "P" is shifted right by the unit of distance. Similarly, whenever the up-shift key 50C is depressed, the Y-coordinate data is decreased by a unit of value, so that the pointer image "P" is shifted upward, and, whenever the down-shift key 50D is depressed, the Y-coordinate data is increased by the unit of value, so that the pointer image "P" is shifted downward by the unit of distance. Note, in this embodiment, the shifting or movement of the pointer image "P" is limited within the partial area "R" of the screen "S" of the monitor 40.
Thus, when the function key 52A is depressed, three-primary color image-pixel signals included in one frame are increased by a suitable interpolation processing, executed in the video-process circuit 38, such that the partial area "R", on which a photographed image is reproduced and displayed, is expanded to a predetermined large area on the screen "S" of the monitor 40. Namely, by the depression of the function key 52A, an image to be reproduced and displayed on the screen "S" of the monitor 40 is enlarged to a large-sized image at a predetermined magnification. After the enlargement of the reproduced and displayed image to the large-sized image, when the function key 52A is again depressed, the execution of the interpolation processing in the video-process circuit 38 is stopped, whereby the large-sized image is returned to the originally-sized image. In short, in this embodiment, the function key 52A serves as the enlargement/return key for enlarging the reproduced and displayed image to the large-sized image and for returning the large-sized image to the originally-sized image.
With reference to FIG. 4, which is similar to FIG. 3, the expanded area on the screen "S" of the monitor 40, on which the large-sized image is reproduced and displayed, is indicated by reference "L". As is apparent from this drawing, the expanded area or large-sized-image-displaying area "L" on the screen "S" of the monitor 40 is defined by a left boundary represented by an X-coordinate K0x, a right boundary represented by an X-coordinate (K0x+K1x), an upper boundary represented by a Y-coordinate K0y, and a lower boundary represented by a Y-coordinate (K0y+K1y). Also, the partial area or originally-sized-image-displaying area "R" on the screen "S" of the monitor 40 is defined by a left boundary represented by an X-coordinate A0x, a right boundary represented by an X-coordinate (A0x+A1x), an upper boundary represented by a Y-coordinate A0y, and a lower boundary represented by a Y-coordinate (A0y+A1y).
If the X-coordinate register 48B and Y-coordinate register 48C respectively hold an X-coordinate data ax and a Y-coordinate data ay, the pointer image "P" (FIG. 3) is displayed at a position represented by the X-Y coordinates Q(ax, ay) on the originally-sized-image-displaying area "R", as shown in FIG. 4. Note, strictly speaking, the X-Y coordinates Q(ax, ay) represent a tip of an arrow head of the pointer image "P" (FIG. 3).
Conventionally, although when the originally-sized-image-displaying area "R" is expanded to the large-sized-imaged-displaying area "L" due to the depression of the function key 52A, the pointer image "P" (FIG. 3) remains at the position represented by the X-Y coordinates Q(ax, ay), because the coordinate data ax and ay, held by the registers 48B and 48C, are not changed.
According to the present invention, as soon as the originally-sized-image-displaying area "R" is expanded to the large-sized-image-displaying area "L", the X-coordinate data ax, held by the X-coordinate register 48B, is changed to a X-coordinate data kx, and the Y-coordinate data ay, held by the Y-coordinate register 48C, is changed to a Y-coordinate data ky. Of course, the position on the originally-sized-image-displaying area "R", represented by the X-Y coordinates Q(ax, ay), correspond to the position on the large-sized-image-displaying area "L", represented by the X-Y coordinates Q′ (kx, ky). Thus, for example, when a lesion location is indicated by the pointer image "P" on an image reproduced and displayed on the originally-sized-image-displaying area "R", and when the image concerned is enlarged by the depression of the function key 52A, an indication of a corresponding lesion location by the pointer image "P" can be ensured on an enlarged image reproduced and displayed on the large-sized-image-displaying area "L".
K1y: a vertical height of the large-sized-image-displaying area "L".
K0y: a vertical distance between the X-axis and the upper boundary of the large-sized-image-displaying area "L".
FIG. 5 shows a flowchart of an operation routine for the aforementioned electronic endoscope system, executed by the system control circuit 30, and the execution of the operation routine is started by turning ON a power ON/OFF switch (not shown) of the video-signal processing unit 12.
Herein, qx is a variable to be written in the X-coordinate register 48B, and qy is a variable to be written in the Y-coordinate register 48C.
Namely, at step 501, X-Y coordinates of the center of the originally-sized-image-displaying area "R" are calculated, and the calculated results qx and qy are written in the registers 48B and 48C, respectively, whereby the pointer image "P" (FIG. 3) is displayed at the center of the originally-sized-image-displaying area "R". Note, at an initial stage just after the power ON/OFF switch is turned ON, the video-signal processing unit 12 is set that a photographed image is reproduced and displayed on the originally-sized-image-displaying area "R".
As is apparent from FIG. 4, the calculated results XMIN, XMAX, YMIN and YMAX represent the left, right, upper and lower boundaries of the originally-sized-image-displaying area "R", respectively, and a shifting or movement of the pointer image "P" (FIG. 3) is limited within an area which is defined by the four boundaries XMIN, XMAX, YMIN and YMAX of the originally-sized-image-displaying area "R", as described hereinafter in an explanation of first, second, third and fourth pointer-shifting routines respectively shown in FIGS. 8, 9, 10 and 11.
At step 503, a flag F is initialized to be "0". The flag F indicates whether either the originally-sized-image-displaying area "R" or the large-sized-image-displaying area "L" is set on the screen "S" of the monitor 40. Namely, if F=0, it indicates that the originally-sized-image-displaying area "R" is set on the screen "S" of the monitor 40, and if F=1, it indicates that the large-sized-image-displaying area "L" is set on the screen "S" of the monitor 40. As mentioned hereinafter, when the function key or enlargement/return key 52A is initially depressed after the turning-ON of the power ON/OFF switch, the flag F is changed from "0" to "1", and, when the enlargement/return key 52A is again depressed, the flag F is returned from "1" to "0".
At step 504, a key-manipulation-monitoring routine, as shown in FIG. 6, is executed, whereby depressions of various keys, especially the shift keys 50A, 50B, 50C and 50D and the enlargement/return key 52A, on the keyboard 50 are monitored, as stated in detail hereinafter. Then, at step 505, various routines, which are necessary for the operation of the system, are executed. For example, at step 505, a control routine for the aperture-stop 20 is executed, whereby a constant luminance of a reproduced image on the monitor 40 can be maintained.
Note, the routine comprising steps 504 and 505 is repeatedly executed at a suitable regular time-interval of, for example, 2 ms.
FIG. 6 shows a flowchart of the key-manipulation-monitoring routine executed in step 504 of FIG. 5.
At step 601, it is determined whether the function key or enlargement/return key 52A is depressed. If the depression of the enlargement/return key 52A is confirmed, the control proceeds to step 602, in which an enlargement/return routine, as shown in FIG. 7, is executed. If the depression of the enlargement/return key 52A is not confirmed, the control proceeds from step 601 to step 603.
At step 603, it is determined whether the left-shift key 50A is depressed. If the depression of the left-shift key 50A is confirmed, the control proceeds to step 604, in which a first pointer-shifting routine, as shown in FIG. 8, is executed. If the depression of the left-shift key 50A is not confirmed, the control proceeds from step 603 to step 605.
At step 605, it is determined whether the right-shift key 50B is depressed. If the depression of the right-shift key 50B is confirmed, the control proceeds to step 606, in which a second pointer-shifting routine, as shown in FIG. 9, is executed. If the depression of the right-shift key SOB is not confirmed, the control proceeds from step 605 to step 607.
At step 607, it is determined whether the up-shift key 50C is depressed. If the depression of the up-shift key 50C is confirmed, the control proceeds to step 608, in which a third pointer-shifting routine, as shown in FIG. 10, is executed. If the depression of the up-shift key 50C is not confirmed, the control proceeds from step 607 to step 609.
At step 609 it is determined whether the down-shift key 50D is depressed. If the depression of the down-shift key 50D is confirmed, the control proceeds to step 610, in which a fourth pointer-shifting routine, as shown in FIG. 11, is executed. If the depression of the down-shift key 50D is not confirmed, the control proceeds from step 609 to step 611.
At step 611, it is determined whether another key on the keyboard 50 is depressed. If the depression of the other key concerned is confirmed, the control proceeds to step 612, in which a necessary routine is executed. Of course, step 611 is shown as a representative step for various keys on the keyboard 50 except for the pointer shift keys 50A, 50B, 50C and 50D and the enlargement/return key 52A, which especially relate to the present invention.
In any event, the execution of the key-manipulation-monitoring routine is repeated at the regular time-interval of 2 ms, and, whenever any one of the keys on the keyboard 50 is depressed, a corresponding routine is executed.
FIG. 7 shows a flowchart of the enlargement/return routine executed at step 602 of FIG. 6.
At step 701, it is determined whether the flag F is "0" or "1". If F=0, i.e. if the originally-sized-image-displaying area "R" is set on the screen "S" of the monitor 40, the control proceeds to step 702, in which the flag F is made to be "1". The value of the flag F must be changed from "0" to "1", because the expansion of the originally-sized-image-displaying area "R" to the large-sized-image-displaying area "L" is performed by the depression of the enlargement/return key 52A whenever the originally-sized-image-displaying area "R" is set on the screen "S" of the monitor 40 (F=0).
At step 703, an enlargement-demanding signal is output from the system control circuit 30 to the video-process circuit 38. By outputting the enlargement-demanding signal, in the video-process circuit 38, a suitable interpolation processing is executed such that three-primary color image-pixel signals included in one frame are increased, whereby an originally-sized image, reproduced and displayed on the originally-sized-image-displaying area "R" of the screen "S" of the monitor 40, is enlarged to a large-sized image, resulting in the expansion of the originally-sized-image-displaying area "R" to the large-sized-image-displaying area "L".
At step 705, the calculated results kx and ky are made to be the variables qx and qy, respectively. In other words, the calculated results kx and ky and are written in the registers 48B and 48C, respectively, whereby the pointer image "P" is displayed at a position, represented by the X-Y coordinates (kx, ky), on the large-sized-image-displaying area "L". Namely, the pointer image "P" displayed at the position represented by the X-Y coordinates (ax, ay) on the originally-sized-image-displaying area "R", is shifted to the corresponding position, represented by the X-Y coordinates (kx, ky), on the large-sized-image-displaying area "L".
As is apparent from FIG. 4, the calculated results XMIN, XMAX, YMIN and YMAX represent the left, right, upper and lower boundaries of the large-sized-image-displaying area "L", respectively, and a shifting or movement of the pointer image "P" is limited within an area which is defined by the four boundaries XMIN, XMAX, YMIN and YMAX of the large-sized-image-displaying area "L", as described hereinafter in an explanation of the first, second, third and fourth pointer-shifting routines shown in FIGS. 8, 9, 10 and 11.
At step 708, a return-demanding signal is output from the system control circuit 30 to the video-process circuit 38. By outputting the return-demanding signal, the execution of the interpolation processing is stopped in the video-process circuit 38, whereby a large-sized image, reproduced and displayed on the large-sized-image-displaying area "L" of the screen "S" of the monitor 40, is returned to an originally-sized image, resulting in the return of the large-sized-image-displaying area "L" to the originally-sized-image-displaying area "R".
At step 710, the calculated results ax and a are made to be the variables qx and qy, respectively. In other words, the calculated results ax and ay and are written in the registers 48B and 48C, respectively, whereby the pointer image "P" is displayed at a position, represented by the X-Y coordinates (ax, ay), on the originally-sized-image-displaying area "L". Namely, the pointer image "P", displayed at the position represented by the X-Y coordinates (kx, ky) on the large-sized-image-displaying area "L", is shifted to the corresponding position, represented by the X-Y coordinates (ax, ay), on the originally-sized-image-displaying area "R".
Namely, as described in the explanation of step S02 of FIG. 5, the calculated results XMIN, XMAX, YMIN and MAX. represent the left, right, upper and lower boundaries of the originally-sized-image-displaying area "R", respectively, and the shifting or movement of the point image "P" (FIG. 3) is limited within the area which is defined by the four boundaries XMIN, XMAX, YMIN and MAX. of the originally-sized-image-displaying area "R".
FIG. 8 shows a flowchart of the first pointer-shifting routine executed in step 604 of FIG. 6.
At step 801, if (qx−x0)≧XMIN, the control proceeds to step 802, in which the result of the calculation (qx−x0) is made to be qx. Namely, the variable qx, held in the X-coordinate register 48B, is replaced by the result of the calculation (qx−x0), whereby the pointer image "P" is shifted left with the minimum unit of distance x0 on one of the originally-sized-image-displaying area "R" and the large-sized image displaying area "L", set on the screen "S" of the monitor 40.
At step 801, if the result of the calculation (qx−x0) is smaller than the left boundary XMIN (A0x or K0x), the control returns to the operation routine of FIG. 5, without shifting the pointer image "P". Namely, when the pointer image "P" reaches the left boundary XMIN, it cannot cross beyond the left boundary XMIN by further depressing the left-shift key 50A.
FIG. 9 shows a flowchart of the second pointer-shifting routine executed in step 606 of FIG. 6.
At step 901, it is determined whether a result of a calculation (qx+x0) is smaller than or equal to the right boundary XMAX. Note, as stated above, x0 represents the minimum unit of distance with which the pointer image "P" is shifted or moved along the X-axis by once depressing either the left-shift key 50A or the right-shift key 50B. Of course, when the originally-sized-image-displaying area "R" is set on the screen "S" of the monitor 40, XMAX=(A0x+A1x), and, when the large-sized-image displaying area "L" is set on the screen "S" of the monitor 40, XMAX=(K0x+K1x).
At step 901, if (qx+x0)≦XMAX, the control proceeds to step 902, in which the result of the calculation (qx+x0) is made to be qx. Namely, the variable qx, held in the X-coordinate register 48B, is replaced by the result of the calculation (qx+x0), whereby the pointer image "P" is shifted right with the minimum unit of distance x0 on one of the originally-sized-image-displaying area "R" and the large-sized-image displaying area "L", set on the screen "S" of the monitor 40.
At step 901, if the result of the calculation (qx+x0) is larger than the right boundary XMAX ((A0x+A1x) or (K0x+K1x)), the control returns to the operation routine of FIG. 5, without shifting the pointer image "P". Namely, when the pointer image "P" reaches the right boundary XMAX, it cannot cross beyond the right boundary XMAX by further depressing the right-shift key 50B.
FIG. 10 shows a flowchart of the third pointer-shifting routine executed in step 608 of FIG. 6.
At step 1001, it is determined whether a result of a calculation (qy−y0) is larger than or equal to the upper boundary YMIN. Note, y0 represents a minimum unit of distance with which the pointer image "P" is shifted or moved along the Y-axis by once depressing either the up-shift key 50C or the down-shift key 50D. Of course, when the originally-sized-image-displaying area "R" is set on the screen "S" of the monitor 40, YMIN=A0y, and, when the large-sized-image displaying area "L" is set on the screen "S" of the monitor 40, YMIN=K0y.
At step 1001, if (qy−y0)≧YMIN, the control proceeds to step 1002, in which the result of the calculation (qy−y0) is made to be qy. Namely, the variable qy, held in the Y-coordinate register 48C, is replaced by the result of the calculation (qy−y0), whereby the pointer image "P" is shifted upward with the minimum unit of distance y0 on one of the originally-sized-image-displaying area "R" and the large-sized-image displaying area "L", set on the screen "S" of the monitor 40.
At step 1001, if the result of the calculation (qy−y0) is smaller than the upper boundary YMIN (A0y or K0y), the control returns to the operation routine of FIG. 5, without shifting the pointer image "P". Namely, when the pointer image "P" reaches the upper boundary YMIN, it cannot cross beyond the upper boundary YMIN by further depressing the up-shift key 50C.
FIG. 11 shows a flowchart of the fourth pointer-shifting routine executed in step 610 of FIG. 6.
At step 1101, it is determined whether a result of a calculation (qy+y0) is smaller than or equal to the lower boundary YMAX. Note, as stated above, y0 represents the minimum unit of distance with which the pointer image "P" is shifted or moved along the Y-axis by once depressing either the up-shift key 50C or the down-shift key 50D. Of course, when the originally-sized-image-displaying area "R" is set on the screen "S" of the monitor 40, YMAX=(A0y+A1y), and, when the large-sized-image displaying area "L" is set on the screen "S" of the monitor 40, YMAX=(K0y+K1y).
At step 1101, if (qy+y0)≦YMAX, the control proceeds to step 1102, in which the result of the calculation (qy+y0) is made to be qy. Namely, the variable qy, held in the Y-coordinate register 48C, is replaced by the result of the calculation (qy+y0), whereby the pointer image "P" is shifted downward with the minimum unit of distance y0 on one of the originally-sized-image-displaying area "R" and the large-sized-image displaying area "L", set on the screen "S" of the monitor 40.
At step 1101, if the result of the calculation (qy+y0) is larger than the right boundary YMAX ((A0y+A1y) or (K0y+K1y)), the control returns to the operation routine of FIG. 5, without shifting the pointer image "U". Namely, when the pointer image "P" reaches the right boundary YMAX, it cannot cross beyond the lower boundary YMAX by further depressing the right-shift key 50D.
Finally, it will be understood by those skilled in the art that the foregoing description is of preferred embodiments of the system, and that various changes and modifications may be made to the present invention without departing from the spirit and scope thereof.
The present disclosure relates to subject matters contained in Japanese Patent Application No. 10-261991 (filed on Sep. 16, 1998) which is expressly incorporated herein, by reference, in its entirety.
wherein said pointer image controller includes a pointer-image-position converter that converts a position of said pointer image on the screen of said monitor in accordance with the size change of the displaying-area of the reproduced image on the screen of said monitor, such that two positions, indicated by said pointer image on two-sized display-areas, correspond to each other.
2. An electronic endoscope system as set forth in claim 1, further comprising a shift limiter that limits a shifting of said pointer image within each of the two-sized display-areas.
3. An electronic endoscope system as set forth in claim 2, wherein said shift limiter comprises a boundary converter that converts a two-dimensional limit range, corresponding to one of the two-sized display-areas, within which the shifting of said pointer image is limited, into another two-dimensional limit range, corresponding to another-sized display-area, within which the shifting of said pointer image is limited, in accordance with the size change of the displaying-area of the reproduced image on the screen of said monitor.
a proportional position-converter that proportionally converts a set of two-dimensional coordinates, representing a position of said pointer image on one of the two-sized display-areas, into another set of two-dimensional coordinates, representing a corresponding position of said pointer image on another-sized display-area.
5. An electronic endoscope system as set forth in claim 4, further comprising a shift limiter that limits a shifting of said pointer image within each of the two-sized display-areas.
6. An electronic endoscope system as set forth in claim 5, wherein said shift limiter comprises a boundary converter that converts a two-dimensional limit range, corresponding to one of the two-sized display-areas, within which the shifting of said pointer image is limited, into another two-dimensional limit range, corresponding to another-sized display-area, within which the shifting of said pointer image is limited, in accordance with the size-change of the displaying-area of the reproduced image on the screen of said monitor.
wherein said pointer image controller includes a pointer-image-position converter that converts a position of said pointer image on the screen of said monitor in accordance with the displaying-area change of the reproduced image on the screen of said monitor between said first-sized displaying-area and said second-sized displaying-area, such that a position, indicated by said pointer image on said first-sized displaying-area, corresponds to a position, indicated by said pointer image on said second-sized displaying area.
8. An electronic endoscope system as set forth in claim 7, further comprising a shift limiter that limits a shifting of said pointer image within each of said first-sized and second-sized displaying-areas.
9. An electronic endoscope system as set forth in claim 8, wherein said shift limiter comprises a boundary converter that converts a two-dimensional limit range, corresponding to said first-sized display area, within which the shifting of said pointer image is limited, into another two-dimensional limit range, corresponding to said second-sized displaying-area, within which the shifting of said pointer image is limited, and in accordance with the displaying-area change of the reproduced image on the screen of said monitor between said first-sized displaying-area and said second-sized displaying-area.
a proportional position-convertor that proportionally converts a set of two-dimensional coordinates, representing a position of said pointer image on said first-sized displaying-area, into another set of two-dimensional coordinates, representing a corresponding position of said pointer image on said second-sized displaying-area.
11. An electronic endoscope system as set forth in claim 10, further comprising a shift limiter that limits a shifting of said pointer image within each of said first-sized and second-sized displaying-areas.
12. An electronic endoscope system as set forth in claim 11, wherein said shift limiter comprises a boundary converter that converts a two-dimensional limit range, corresponding to said first-sized displaying-area, within which the shifting of said pointer image is limited, into another two-dimensional limit range, corresponding to said second-sized displaying-areas, within which the shifting of said pointer image is limited, in accordance with the displaying-area change of the reproduced image on the screen of said monitor between said first-sized displaying-area and said second-sized displaying-area.


Lima, Peru, May 03, 2018 --(PR.com)-- Amazing Peru is spreading its wings in Latin America, with more planes and more pilots and a new office in Brazil. They are the first Latin American company offering private jets.
The Latin America-based charter jet company announced today it has increased its fleet for its private flights throughout Latin America and worldwide.
Asked what prompted the expansion, Nicole Wagner, Latin America Branch Manager of Amazing Peru Private Jets, said: "Primarily there was a market available, and being the first and only Latin American Company offering this service, an opportunity became available, so we jumped on it."
The expansion will allow the company to offer "new and more varied options" to its customers worldwide, she said.
The response to the service in Latin America has been great, Wagner said.
With the expansion, Amazing Peru Private Jets has planes based in Lima, Sao Paulo, Rio de Janeiro, Quito, Buenos Aires and Santiago.
Private Jets has a variety of aircraft.
"We have over 30 planes in our fleet," Wagner said. "We have the capacity to move any of those planes to anywhere in the world if required."
Amazing Peru Private Jets primarily serves destinations in the United States, Canada, Mexico, the Caribbean, Central America, South America and Europe.
Charter flights are available 24 hours a day, seven days a week, year-round, weather and safety permitting.
Amazing Peru pioneered the luxury adventure and private aviation in South America more than 47 years ago. Today we are the world's undisputed Latin America luxury-travel leader and the only Latin American private jet Company, offering award-winning "tours of a lifetime" by National Geographic offering travel solutions to our discerning worldwide clientele.


Each dispenser carton contains 18 pods.
Pods are sold in quantities of 4 dispenser cartons per case.
You may choose up to 4 different blends per case.
Minimum order is 1 case (4 dispenser cartons).
Contact Us for special pricing available on orders greater than 18 cases.
The 1-Cup Pod and the new, low-pressure brewers are changing the way coffee is brewed at home.
Enjoy a variety of premium coffee house coffees and teas, fresh brewed one cup at a time.
You can brew a fresh cup, when you want it, in about 30 seconds. Since you are brewing one cup instead of a whole pot, there is less waste and no loose grinds or even messy coffee pots to clean.


text:
Ultimate Inspirational SMS page 1
1 universe, • 8 planets, • 195 countries, .., 137 character
1 universe,
• 8 planets,
• 195 countries,
• 5 oceans,
• 7 billion people.. ...
and I choose to fall in love with those who ignore me
You can't change how people feel about you, s.., 92 character
You can't change how people feel about you, so don't try. Just live your life and be happy..
Relationships are not about "I want this" or .., 113 character
Relationships are not about "I want this" or "I want that." It's about two people caring for each other's desires
If you really love someone, do not tell them..., 55 character
If you really love someone, do not tell them. Show them
2 SWEET words DIFFICULT 2 say in life: 1. "H.., 136 character
2 SWEET words DIFFICULT 2 say in life:
1. "Hi" for the FIRST time to unknown Person...!
2. "Bye" for the LAST time to loved ones....!!
Best lines: "Always look for what's Wrong bef.., 128 character
Best lines:
"Always look for what's Wrong
before looking who's wrong..!!
Read it once again to keep YouR relations safe n Strong
Some people say never forget me. Some people .., 138 character
Some people say never forget me.
Some people say always remember me.
But i love my attitude, so.. I will say . . .
Forget ME if u can..!!
''Don't fall for anyone in life...! Until the.., 97 character
''Don't fall for anyone in life...! Until they are really ready to catch you in any situation..."
The Value of a Relationship is not How Happy .., 108 character
The Value of a Relationship is not How Happy you Feel with them but How Much Someone Feels alone Without you
No matter how "busy" a person's day may be. I.., 99 character
No matter how "busy" a person's day may be. If they "really care", they'll always find time for you

redpajama_set_name: RedPajamaCommonCrawl


During the month of April, you'll automatically receive Free Shipping in your cart when you add $20 CAD or more worth of products tagged CD, CD-EP, CD-R, Digi Pak CD or Flags.
$20 CAD is only $15 USD or 13,33€ !!!
Your cart must only contain qualified items.
Next Next post: Get May's MASSIVE Coupon Code ONE WEEK EARLY!


text:
Q: How to easily consume an API response, but add some additional flags to the response? I am using an API that returns some data to me about photos, but I want to add a flag to the response I get called favorite: boolean so I can easily manage whether or not the photo is a favorite or not.
The vanilla response from the API looks something like this (but much simpler):
{
  "photos": [
    { "id": 1001, "url": "site.com/img/1001" },
    { "id": 1002, "url": "site.com/img/1002" }
  ]
}

I am wondering if there is a way to add the favorite flag so that the object I work with looks like this:
{
  "photos": [
    { "id": 1001, "url": "site.com/img/1001", "favorite": false },
    { "id": 1002, "url": "site.com/img/1002", "favorite": false }
  ]
}

Here is my code where I get the response from the API:
  getRecentPhotos(): Observable<any> {
    let photos =  this.http
      .get(this.getRecentPhotosUrl)
      .map((res: Response) => {
        return res.json();
      })
      .catch(this.handleError);
    return photos;
  }

Is it possible to add the favorite flag to the response I get back from that function?
Thanks

A: You have most of the code, you just need to add favorite flag in mapper,
.map((res: Response) => {
    let _result = res.json();
    _result = _result.map(_x => {
          _x = {favorite: false};
          return _x;
    })
    return _result ;
  })

redpajama_set_name: RedPajamaStackExchange


text:
Q: A few possibly duplicate questions about Java REST - what should we do? Please check out these links:

*

*https://stackoverflow.com/questions/1710199/which-is-the-best-java-rest-api-restlet-or-jersey

*REST in Java

*Java REST implementation: Jersey vs CXF

*Easiest frameworks to implement Java REST web services
I can't say that they are entirely duplicate of one another, but the difference is small. This information is too important to split between four different questions. What should we do? Which questions should be closed as duplicates?


Kettles that release red hot steam onto their handles, cupboard drawers that don't quite slot in and of course, those pesky USB sticks that take three or four attempts to insert before realising you had right the first time. These niggles are part of everyday life and albeit annoying, their poor design is usually pretty easy to ignore. But in industry, the bad design of manufacturing environments and equipment is much more significant than a few seconds wasted twisting a USB stick.
As part of the modernisation of manufacturing facilities, industrial automation has become invaluable. The undeniable benefits of increased productivity, improved efficiency and reduction in costs have meant that automation has quickly secured its place as a reigning champion of manufacturing operations.
Although such advanced machinery has crept onto the factory floor, human workers still play a vital role in operations. For this man and machine collaboration to succeed, it's important to design and create an appropriate and effective level of interaction between workers and machinery. This is where industrial ergonomics comes in.
Ergonomics describes the interaction between humans and other elements of a system, in this case, factory employees and their respective industrial machinery. Good ergonomics applies design principles to co-ordinate the devices, systems and working conditions in a factory with the requirements of the workers. By increasing human well-being and easing navigation, good ergonomic design can improve the overall performance of a system and its workers.
Already, manufacturers are opting for automated equipment to speed up and improve their productivity, but implemented into an ergonomically designed environment, this increased productivity can be taken a step further.
For example, adjusting the body and height of workspaces for employees can not only reduce risk of injury, but also improve staff motivation by giving them more freedom to move. What's more, creating easier reach zones for employees can dramatically speed up production. Even simple changes, such as improving the lighting and temperature for employees are easy ways to minimise potential accidents. That being said, ergonomic design must be uniquely created for each manufacturing environment.
Inevitably, when organisations add industrial automation to the equation, health and safety becomes an even greater concern. Organisations will strategically place dangerous automated machinery outside of the workspaces of employees, but by implementing intelligent equipment, like human machine interfaces (HMIs) workers can gain a greater view the processes performed by machinery, without having to get up close and personal. This set-up will not only allow for improved productivity from human employees, but will also cut the risks of potential accidents.
Despite the increasing number of robotics and industrial machinery on production lines, it remains clear that people are a vital resource for manufacturers. For modern industrial environments that use automated machinery, it's essential that the ergonomic needs of human workers aren't forgotten. Let's face it, without seamless collaboration between these workers and their respective machines, production will be about as seamless as fitting a USB stick into a port on the first go.
Robert Holloway is head of order fulfilment at European Automation.


text:
Part of HuffPost Environment. ©2021 Verizon Media. All rights reserved.
Forest Trends, Contributor
Pioneering Finance for Conservation
Are Companies Keeping Their Climate Pledges? Find Out Wednesday in New York
09/22/2015 09:32 am ET Updated Sep 22, 2016
Dozens of companies and scores of governments won greenie points at last year's UN Climate Summit for endorsing the New York Declaration on Forests and aiming to end deforestation. On Wednesday, at Climate Week NYC, we get to learn how they are progressing one year on.
By Steve Zwick. Re-posted from Ecosystem Marketplace
22 September 2015 | NEW YORK | Climate Week NYC kicked off here yesterday and runs through September 28, with more than 150 events scattered across the city and a Friday visit from Pope Francis. You can bet that companies will step up with promises to save the planet, as 53 of them did last year when they endorsed the New York Declaration on Forests, but how do you know which promises are being kept, and which are just words?
If you're in New York, you'll get two chances for at least some answers this week, as Forest Trends' Supply Change project offers findings from its analysis of companies that endorsed the Declaration (a text of which is available here). The Supply Change findings will be released on Wednesday at 8 a.m., in a report entitled "Firm Commitments: Tracking Company Endorsers of the New York Declaration on Forests", and the release will be followed by two events offering a deeper dive into the implications.
The first event takes place on Wednesday, from 10 a.m. to 11:30 a.m. at the offices of Hunton and Williams (200 Park Avenue, #53) and is entitled The New York Declaration on Forests: One Year of Business Progress and the Pathway to Paris. Key business and civil-society actors on deforestation will discuss the progress made to date and the role of corporate leadership and collective action as well as the potential for forests to feature at the heart of a strong climate agreement at year-end climate talks in Paris - and what must to be done to turn this potential into reality.
The second event takes place a day later, on Thursday, from 10am to 12noon, at the Rainforest Alliance Headquarters (233 Broadway), and is entitled Report Launch - Firm Commitments: Tracking Company Endorsers of the New York Declaration on Forests. Forest Trends' Ecosystem Marketplace will present detailed findings from the report with discussions from other topic experts on these and other implications of the Declaration to advance transparency in the implementation of deforestation-free commitments.
Supply-Change.org tracks nearly 300 companies that have made commitments to reduce deforestation from their supply chains, and the New York Declaration on Forests includes commitments from 53 corporations - as well as 37 national governments, 20 sub-national (state) governments, 16 indigenous organizations, and 54 environmental groups (including Ecosystem Marketplace publisher Forest Trends). The endorsers set a goal to halve deforestation by 2020 and to eliminate all deforestation by the year 2030. Commercial agriculture is particularly key since is drives at least 70% of tropical deforestation, with production of soy, palm oil, timber and pulp, and cattle being the "big four" commodities.
"Firm Commitments" looks at who the 53 company endorsers of the Declaration are and then focuses in on the performance of 41 companies - primarily name-brand food retailers and manufacturers based in developed countries - which have been profiled on Supply-Change.org. The report examines what concrete steps they're taking towards fulfilling their pledges and how they compare to companies that haven't endorsed the Declaration.
We also look to see which of the "big four" commodities are getting greener, and which aren't. Then we assess the correlation between sustainability and other practices, such as support for human rights, peatland protection, and transparency in supply chains.
The sessions are open to the public, and the report will be available for download on Wednesday at 8 a.m. Eastern time at http://forest-trends.org/releases/p/firm-commitments.
Watch Sea Lions 'Surfing' Off Santa Barbara Island For The Sheer Joy Of It Should We Spend $1 Trillion A Year On This Climate Technology? We May Have To. Federal Officials Seeking Person Who Scraped 'Trump' Into Manatee's Back Several Gorillas Test Positive For Coronavirus At San Diego Zoo Safari Park
Climate Change Green Deforestation Redd Climate Week


There comes a time in everyone's life where we experience something that can change the direction of our choices and decisions. Several have impacted me, and one stands out strong among the others.
It was 1973 and I was a sophomore in college at Eastern Kentucky University. I was very in tune with the Vietnam War and the Civil Rights Movement. I told my parents that I wanted to quit college and go join Angela Davis' fight for our people. Their response to me was: "The best thing you can do for our Civil Rights Movement is to stay in college and get your degree!"
I was disheartened and deflated, but I stayed and graduated in 1975. I went on to receive my masters' degree in personnel management at Kentucky State University. As usual, my parents were right.
My degree ultimately got me a job at BellSouth in their management training program. I made a career in some form of management throughout my 35 years of work. It allowed me to travel, meet some great people, honor diversity, and maximize the unique talents of others in the workplace.
I often think about where I would be if they had allowed me to just drop out. I met my husband of 34 years in college. I made meaningful lifelong friends there and learned how to solve my mistakes on my own.
If my parents were living, I would thank them again. I would tell them how much their encouragement meant to me. My parents, Arthur and Noralee Walters, taught my brother Reggie, sister Artye, and me many life lessons. They taught us to set our goals high; and if you don't reach them, at least you are further along than if you did not have high aspirations. They taught all of us that we possess gifts that we should share with others. They taught us a sense of family, and how important love and respect are. They taught us that "family" extends further than your immediate household.
So, here is our family today … my brother, sister, myself, and our five collective children beginning a grassroots initiative that we hope our community will embrace.
It is called The Arthur M. Walters Bridge Builders Project (AMWBBP).
It is designed to honor our father's legacy and to "give back." He was past executive director of the Louisville Urban League and was a diligent activist to ensure equal rights for all. The project will focus on helping minority students who are making a positive impact and pursuing their college degrees.
We are having our first annual benefit concert on Sunday, Sept. 21, at 5 p.m. on the campus of Bellarmine University, Wyatt Hall Center for the Arts. We ask that you join with us and help us reach a sell-out crowd of 350 people. Tickets are $35 and student tickets are $10.
• Everyone has a gift to bless others with. Use it!
• Do what you can to push our youth to their greatest potential, which includes college educations! It will make the difference in how they are able to give back to their communities…the circle will continue…we learn, we grow, we give back. Kudos to all who are currently doing just that! Are you?
Please support our vision. We will be most appreciative. This is our way of using our gifts and encouraging our youth.
Please contact me at (502) 228-1611 for tickets or request your tickets through our Facebook page at The Arthur M. Walters Bridge Builders Project.
Michele Barnett is the project director for The Arthur M. Walters Bridge Builders Project.