Size * FontFreeType::getAdvancesForTextUTF16(unsigned short *pText, int &outNumLetters)
{
    if (!pText)
        return 0;
    
    outNumLetters = cc_wcslen(pText);

    if (!outNumLetters)
        return 0;
    
    Size *pSizes = new Size[outNumLetters];
    if (!pSizes)
        return 0;
    
    for (int c = 0; c<outNumLetters; ++c)
    {
        int advance = 0;
        int kerning = 0;
        
        advance = getAdvanceForChar(pText[c]) - getBearingXForChar(pText[c]);
        
        if ( c < (outNumLetters-1) )
            kerning = getHorizontalKerningForChars(pText[c], pText[c+1]);
        
        pSizes[c].width = (advance + kerning);
    }
    
    return pSizes;
}
Exemple #2
0
unsigned short int  * Font::trimUTF16Text(unsigned short int *text, int newBegin, int newEnd) const
{
    if ( newBegin < 0 || newEnd <= 0 )
        return 0;
    
    if ( newBegin >= newEnd )
        return 0;
    
    if (newEnd >= cc_wcslen(text))
        return 0;
    
    int newLenght = newEnd - newBegin + 2;
    unsigned short* trimmedString = new unsigned short[newLenght];
    
    for(int c = 0; c < (newLenght - 1); ++c)
    {
        trimmedString[c] = text[newBegin + c];
    }
    
    // last char
    trimmedString[newLenght-1] = 0x0000;
    
    // done
    return trimmedString;
}
void Label::alignText()
{
    if (_fontAtlas == nullptr)
    {
        return;
    }

    for (const auto& batchNode:_batchNodes)
    {
        batchNode->getTextureAtlas()->removeAllQuads();
    }
    _fontAtlas->prepareLetterDefinitions(_currentUTF16String);
    auto textures = _fontAtlas->getTextures();
    if (textures.size() > _batchNodes.size())
    {
        for (auto index = _batchNodes.size(); index < textures.size(); ++index)
        {
            auto batchNode = SpriteBatchNode::createWithTexture(textures[index]);
            batchNode->setAnchorPoint(Point::ANCHOR_TOP_LEFT);
            batchNode->setPosition(Point::ZERO);
            Node::addChild(batchNode,0,Node::INVALID_TAG);
            _batchNodes.push_back(batchNode);
        }
    }
    LabelTextFormatter::createStringSprites(this);    
    if(_maxLineWidth > 0 && _contentSize.width > _maxLineWidth && LabelTextFormatter::multilineText(this) )      
        LabelTextFormatter::createStringSprites(this);

    if(_labelWidth > 0 || (_currNumLines > 1 && _hAlignment != TextHAlignment::LEFT))
        LabelTextFormatter::alignText(this);

    int strLen = cc_wcslen(_currentUTF16String);
    Rect uvRect;
    Sprite* letterSprite;
    for(const auto &child : _children) {
        int tag = child->getTag();
        if(tag >= strLen)
        {
            SpriteBatchNode::removeChild(child, true);
        }
        else if(tag >= 0)
        {
            letterSprite = dynamic_cast<Sprite*>(child);
            if (letterSprite)
            {
                uvRect.size.height = _lettersInfo[tag].def.height;
                uvRect.size.width  = _lettersInfo[tag].def.width;
                uvRect.origin.x    = _lettersInfo[tag].def.U;
                uvRect.origin.y    = _lettersInfo[tag].def.V;

                letterSprite->setTexture(textures[_lettersInfo[tag].def.textureID]);
                letterSprite->setTextureRect(uvRect);
            }          
        }
    }

    updateQuads();

    updateColor();
}
Exemple #4
0
char * cc_utf16_to_utf8 (const unsigned short  *str,
                  int             len,
                  long            *items_read,
                  long            *items_written)
{
	if (str == NULL)
		return NULL;
    
    
    std::u16string utf16;
    int utf16Len = len < 0 ? cc_wcslen(str) : len;
    
    for (int i = 0; i < utf16Len; ++i)
    {
        utf16.push_back(str[i]);
    }
    
	char* ret = NULL;
    std::string outUtf8;
    bool succeed = StringUtils::UTF16ToUTF8(utf16, outUtf8);
    
    if (succeed)
    {
        ret = new char[outUtf8.length() + 1];
        ret[outUtf8.length()] = '\0';
        memcpy(ret, outUtf8.data(), outUtf8.length());
    }
    
    return ret;
}
void RSimpleHTMLParser::textHandler(void *ctx, const char *s, int len)
{
	//CCLog("[Parser Text]%s", s);

	CCAssert(m_rCurrentElement, "[CCRich]: must specify a parent element!");

	unsigned short* utf16str = cc_utf8_to_utf16(s);
	size_t utf16size = cc_wcslen(utf16str);

	if ( utf16size == 0 )
		return;

	for ( size_t i = 0; i < utf16size; i++ )
	{
		REleGlyph* ele = new REleGlyph(utf16str[i]);
		if ( ele->parse(this) )
		{
			m_rCurrentElement->addChildren(ele);
		}
		else
		{
			CC_SAFE_DELETE(ele);
		}
	}

	CC_SAFE_DELETE_ARRAY(utf16str);
}
Exemple #6
0
unsigned short int  * Font::getUTF16Text(const char *text, int &outNumLetters) const
{
    unsigned short* utf16String = cc_utf8_to_utf16(text);
    
    if(!utf16String)
        return 0;
    
    outNumLetters = cc_wcslen(utf16String);
    return utf16String;
}
Exemple #7
0
std::vector<unsigned short> cc_utf16_vec_from_utf16_str(const unsigned short* str)
{
    int len = cc_wcslen(str);
    std::vector<unsigned short> str_new;

    for (int i = 0; i < len; ++i)
    {
        str_new.push_back(str[i]);
    }
    return str_new;
}
bool Label::setOriginalString(unsigned short *stringToSet)
{
    if (_originalUTF16String)
    {
        delete [] _originalUTF16String;
    }

    int newStringLenght = cc_wcslen(stringToSet);
    _originalUTF16String = new unsigned short int [newStringLenght + 1];
    memset(_originalUTF16String, 0, (newStringLenght + 1) * 2);
    memcpy(_originalUTF16String, stringToSet, (newStringLenght * 2));
    _originalUTF16String[newStringLenght] = 0;

    return true;
}
void Label::resetCurrentString()
{
    if ((!_currentUTF16String) && (!_originalUTF16String))
        return;
    
    // set the new string
    if (_currentUTF16String)
    {
        delete [] _currentUTF16String;
        _currentUTF16String = 0;
    }
    
    int stringLenght = cc_wcslen(_originalUTF16String);
    _currentUTF16String = new unsigned short int [stringLenght + 1];
    memcpy(_currentUTF16String, _originalUTF16String, stringLenght * 2);
    _currentUTF16String[stringLenght] = 0;
    
}
Exemple #10
0
bool Label::setText(const char *stringToRender, float lineWidth, TextHAlignment alignment, bool lineBreakWithoutSpaces)
{
    if (!_fontAtlas)
        return false;
    
    // carloX
    // reset the string
    resetCurrentString();
    
    
    _width                  = lineWidth;
    _alignment              = alignment;
    _lineBreakWithoutSpaces = lineBreakWithoutSpaces;
    
    // release all the sprites
    moveAllSpritesToCache();
    
    // store locally common line height
    _commonLineHeight = _fontAtlas->getCommonLineHeight();
    if (_commonLineHeight <= 0)
        return false;
    
    int numLetter = 0;
    unsigned short* utf16String = cc_utf8_to_utf16(stringToRender);
    if(!utf16String)
        return false;
    
    numLetter = cc_wcslen(utf16String);
    SpriteBatchNode::initWithTexture(&_fontAtlas->getTexture(0), numLetter);
    _cascadeColorEnabled = true;
    
    //
    setCurrentString(utf16String);
    setOriginalString(utf16String);
    
    // align text
    alignText();
    
    // done here
    return true;
}
Exemple #11
0
void Label::computeStringNumLines()
{
    int quantityOfLines = 1;

    unsigned int stringLen = _currentUTF16String ? cc_wcslen(_currentUTF16String) : -1;
    if (stringLen < 1)
    {
        _currNumLines = stringLen;
        return;
    }

    // count number of lines
    for (unsigned int i = 0; i < stringLen - 1; ++i)
    {
        if (_currentUTF16String[i] == '\n')
        {
            quantityOfLines++;
        }
    }

    _currNumLines = quantityOfLines;
}
Exemple #12
0
int Label::getStringLenght() const
{
    return _currentUTF16String ? cc_wcslen(_currentUTF16String) : 0;
}
Exemple #13
0
int Font::getUTF16TextLenght(unsigned short int *text) const
{
     return cc_wcslen(text);
}
Exemple #14
0
int Label::getStringLength() const
{
    return _currentUTF16String ? cc_wcslen(_currentUTF16String) : (int)_originalUTF8String.length();
}
Exemple #15
0
bool FontAtlas::prepareLetterDefinitions(unsigned short *utf16String)
{
    FontFreeType* fontTTf = dynamic_cast<FontFreeType*>(_font);
    if(fontTTf == nullptr)
        return false;

    int length = cc_wcslen(utf16String);

    float offsetAdjust = _letterPadding / 2;  
    int bitmapWidth;
    int bitmapHeight;
    Rect tempRect;
    FontLetterDefinition tempDef;

    auto contentSize = Size(CacheTextureWidth,CacheTextureHeight);
    auto scaleFactor = CC_CONTENT_SCALE_FACTOR();
    auto  pixelFormat = fontTTf->getOutlineSize() > 0 ? Texture2D::PixelFormat::AI88 : Texture2D::PixelFormat::A8; 

    bool existNewLetter = false;
    for (int i = 0; i < length; ++i)
    {
        auto outIterator = _fontLetterDefinitions.find(utf16String[i]);

        if (outIterator == _fontLetterDefinitions.end())
        {  
            existNewLetter = true;

            auto bitmap = fontTTf->getGlyphBitmap(utf16String[i],bitmapWidth,bitmapHeight,tempRect,tempDef.xAdvance);
            if (bitmap)
            {
                tempDef.validDefinition = true;
                tempDef.letteCharUTF16   = utf16String[i];
                tempDef.width            = tempRect.size.width + _letterPadding;
                tempDef.height           = tempRect.size.height + _letterPadding;
                tempDef.offsetX          = tempRect.origin.x + offsetAdjust;
                tempDef.offsetY          = _fontAscender + tempRect.origin.y - offsetAdjust;

                if (_currentPageOrigX + tempDef.width > CacheTextureWidth)
                {
                    _currentPageOrigY += _commonLineHeight;
                    _currentPageOrigX = 0;
                    if(_currentPageOrigY + _commonLineHeight >= CacheTextureHeight)
                    {             
                        _atlasTextures[_currentPage]->initWithData(_currentPageData, _currentPageDataSize, pixelFormat, CacheTextureWidth, CacheTextureHeight, contentSize );
                        _currentPageOrigY = 0;
                        memset(_currentPageData, 0, _currentPageDataSize);
                        _currentPage++;
                        auto tex = new Texture2D;
                        addTexture(tex,_currentPage);
                        tex->release();
                    }  
                }
                fontTTf->renderCharAt(_currentPageData,_currentPageOrigX,_currentPageOrigY,bitmap,bitmapWidth,bitmapHeight);

                tempDef.U                = _currentPageOrigX;
                tempDef.V                = _currentPageOrigY;
                tempDef.textureID        = _currentPage;
                _currentPageOrigX        += tempDef.width + 1;
                // take from pixels to points
                tempDef.width  =    tempDef.width  / scaleFactor;
                tempDef.height =    tempDef.height / scaleFactor;      
                tempDef.U      =    tempDef.U      / scaleFactor;
                tempDef.V      =    tempDef.V      / scaleFactor;
            }
            else{
                if(tempDef.xAdvance)
                    tempDef.validDefinition = true;
                else
                    tempDef.validDefinition = false;

                tempDef.letteCharUTF16   = utf16String[i];
                tempDef.width            = 0;
                tempDef.height           = 0;
                tempDef.U                = 0;
                tempDef.V                = 0;
                tempDef.offsetX          = 0;
                tempDef.offsetY          = 0;
                tempDef.textureID        = 0;
                _currentPageOrigX += 1;
            }

            _fontLetterDefinitions[tempDef.letteCharUTF16] = tempDef;
        }       
    }

    if(existNewLetter)
    {
        _atlasTextures[_currentPage]->initWithData(_currentPageData, _currentPageDataSize, pixelFormat, CacheTextureWidth, CacheTextureHeight, contentSize );
    }
    return true;
}
Exemple #16
0
void UITextArea::createFontChars()
{
    int nextFontPositionX = 0;
    int nextFontPositionY = 0;
    //unsigned short prev = -1;
    int kerningAmount = 0;

    CCSize tmpSize = CCSizeZero;

    int longestLine = 0;
    unsigned int totalHeight = 0;

    unsigned int quantityOfLines = 1;
	if (!m_sString) return;
    unsigned int stringLen = cc_wcslen(m_sString);
    if (stringLen == 0)
    {
        return;
    }

    for (unsigned int i = 0; i < stringLen - 1; ++i)
    {
        unsigned short c = m_sString[i];
        if (c == '\n')
        {
            quantityOfLines++;
        }
    }

    totalHeight = m_pConfiguration->m_nCommonHeight * quantityOfLines;
    nextFontPositionY = 0-(m_pConfiguration->m_nCommonHeight - m_pConfiguration->m_nCommonHeight * quantityOfLines);

    for (unsigned int i= 0; i < stringLen; i++)
    {
        unsigned short c = m_sString[i];

        if (c == '\n')
        { 
            nextFontPositionX = 0;
            nextFontPositionY -= m_pConfiguration->m_nCommonHeight;
            continue;
        }

        tFontDefHashElement *element = NULL;

        // unichar is a short, and an int is needed on HASH_FIND_INT
        unsigned int key = c;
        HASH_FIND_INT(m_pConfiguration->m_pFontDefDictionary, &key, element);
        CCAssert(element, "FontDefinition could not be found!");

        ccBMFontDef fontDef = element->fontDef;

        CCRect rect = fontDef.rect;
        rect = CC_RECT_PIXELS_TO_POINTS(rect);

        rect.origin.x += m_tImageOffset.x;
        rect.origin.y += m_tImageOffset.y;

        CCSprite *fontChar;

        fontChar = (CCSprite*)(this->getChildByTag(i));
        if( ! fontChar )
        {
            fontChar = new CCSprite();
            fontChar->initWithTexture(m_pobTextureAtlas->getTexture(), rect);
            this->addChild(fontChar, 0, i);
            fontChar->release();
        }
        else
        {
            // reusing fonts
            fontChar->setTextureRect(rect, false, rect.size);

            // restore to default in case they were modified
            fontChar->setVisible(true);
            fontChar->setOpacity(255);
        }

        // See issue 1343. cast( signed short + unsigned integer ) == unsigned integer (sign is lost!)
        int yOffset = m_pConfiguration->m_nCommonHeight - fontDef.yOffset;
        CCPoint fontPos = ccp( (float)nextFontPositionX + fontDef.xOffset + fontDef.rect.size.width*0.5f + kerningAmount,
            (float)nextFontPositionY + yOffset - rect.size.height*0.5f * CC_CONTENT_SCALE_FACTOR() );
        fontChar->setPosition(CC_POINT_PIXELS_TO_POINTS(fontPos));

        // update kerning
        nextFontPositionX += fontDef.xAdvance + kerningAmount;
        //prev = c;

        // Apply label properties
        fontChar->setOpacityModifyRGB(m_bIsOpacityModifyRGB);
        // Color MUST be set before opacity, since opacity might change color if OpacityModifyRGB is on
		if ( i < colors.size())
		{
			fontChar->setColor(colors.at(i));
		}
		else
			fontChar->setColor(m_tColor);

        // only apply opacity if it is different than 255 )
        // to prevent modifying the color too (issue #610)
        if( m_cOpacity != 255 )
        {
            fontChar->setOpacity(m_cOpacity);
        }

        if (longestLine < nextFontPositionX)
        {
            longestLine = nextFontPositionX;
        }
    }

    tmpSize.width  = (float) longestLine;
    tmpSize.height = (float) totalHeight;

    this->setContentSize(CC_SIZE_PIXELS_TO_POINTS(tmpSize));
    
}
GlyphDef * FontFreeType::getGlyphDefintionsForText(const char *pText, int &outNumGlyphs, bool UTF16text)
{
    unsigned short* utf16String = 0;
    
    if (UTF16text)
    {
        utf16String = (unsigned short*) pText;
    }
    else
    {
        utf16String = cc_utf8_to_utf16(pText);
    }
    
    //
    if  (!utf16String)
        return 0;
    
    int numChar = cc_wcslen(utf16String);
    if (!numChar)
        return 0;

    // allocate the needed Glyphs
    GlyphDef *pGlyphs = new GlyphDef[numChar];
    assert( pGlyphs != NULL );
    if (!pGlyphs)
        return 0;
    
    // sore result as CCRect
    for (int c=0; c<numChar; ++c)
    {
        Rect tempRect;
        
        if( !getBBOXFotChar(utf16String[c], tempRect) )
        {
            log("Warning: Cannot find definition for glyph: %c in font:%s", utf16String[c], _fontName.c_str());
            
            tempRect.origin.x       = 0;
            tempRect.origin.y       = 0;
            tempRect.size.width     = 0;
            tempRect.size.height    = 0;
            
            pGlyphs[c].setRect(tempRect);
            pGlyphs[c].setUTF16Letter(utf16String[c]);
            pGlyphs[c].setValid(false);
            pGlyphs[c].setPadding(_letterPadding);
            
        }
        else
        {
            
            pGlyphs[c].setRect(tempRect);
            pGlyphs[c].setUTF16Letter(utf16String[c]);
            pGlyphs[c].setPadding(_letterPadding);
            pGlyphs[c].setValid(true);
            
        }
    }
    
    outNumGlyphs = numChar;
    
    // free memory
    if (!UTF16text)
        delete [] utf16String;
    
    // done
    return pGlyphs;
}