Exemple #1
0
void FontAtlas::findNewCharacters(const std::u16string& u16Text, std::unordered_map<unsigned short, unsigned short>& charCodeMap)
{
    std::u16string newChars;
    FT_Encoding charEncoding = _fontFreeType->getEncoding();

    //find new characters
    if (_letterDefinitions.empty())
    {
        // fixed #16169: new android project crash in android 5.0.2 device (Nexus 7) when use 3.12.
        // While using clang compiler with gnustl_static on android, the copy assignment operator of `std::u16string`
        // will affect the memory validity, it means after `newChars` is destroyed, the memory of `u16Text` holds
        // will be a dead region. `u16text` represents the variable in `Label::_utf16Text`, when somewhere
        // allocates memory by `malloc, realloc, new, new[]`, the generated memory address may be the same
        // as `Label::_utf16Text` holds. If doing a `memset` or other memory operations, the orignal `Label::_utf16Text`
        // will be in an unknown state. Meanwhile, a bunch lots of logic which depends on `Label::_utf16Text`
        // will be broken.

        // newChars = u16Text;

        // Using `append` method is a workaround for this issue. So please be carefuly while using the assignment operator
        // of `std::u16string`.
        newChars.append(u16Text);
    }
    else
    {
        auto length = u16Text.length();
        newChars.reserve(length);
        for (size_t i = 0; i < length; ++i)
        {
            auto outIterator = _letterDefinitions.find(u16Text[i]);
            if (outIterator == _letterDefinitions.end())
            {
                newChars.push_back(u16Text[i]);
            }
        }
    }

    if (!newChars.empty())
    {
        switch (charEncoding)
        {
        case FT_ENCODING_UNICODE:
        {
            for (auto u16Code : newChars)
            {
                charCodeMap[u16Code] = u16Code;
            }
            break;
        }
        case FT_ENCODING_GB2312:
        {
            conversionU16TOGB2312(newChars, charCodeMap);
            break;
        }
        default:
            OUTPUT_LOG("FontAtlas::findNewCharacters: Unsupported encoding:%d", charEncoding);
            break;
        }
    }
}
Exemple #2
0
std::vector<char16_t> getChar16VectorFromUTF16String(const std::u16string& utf16)
{
    std::vector<char16_t> ret;
    size_t len = utf16.length();
    ret.reserve(len);
    for (size_t i = 0; i < len; ++i)
    {
        ret.push_back(utf16[i]);
    }
    return ret;
}
bool convertUTF16ToUTF8String(const std::u16string& utf16, std::string &Out) {
  assert(Out.empty());

  // Avoid OOB by returning early on empty input.
  if (utf16.empty())
    return true;

  const UTF16 *Src = reinterpret_cast<const UTF16 *>(utf16.data());
  const UTF16 *SrcEnd = reinterpret_cast<const UTF16 *>(utf16.data() + utf16.length());

  // Byteswap if necessary.
  std::vector<UTF16> ByteSwapped;
  if (Src[0] == UNI_UTF16_BYTE_ORDER_MARK_SWAPPED) {
    ByteSwapped.insert(ByteSwapped.end(), Src, SrcEnd);
    for (size_t I = 0, E = ByteSwapped.size(); I != E; ++I)
      ByteSwapped[I] = SwapByteOrder_16(ByteSwapped[I]);
    Src = &ByteSwapped[0];
    SrcEnd = &ByteSwapped[ByteSwapped.size() - 1] + 1;
  }

  // Skip the BOM for conversion.
  if (Src[0] == UNI_UTF16_BYTE_ORDER_MARK_NATIVE)
    Src++;

  // Just allocate enough space up front.  We'll shrink it later.
  Out.resize(utf16.length() * UNI_MAX_UTF8_BYTES_PER_CODE_POINT + 1);
  UTF8 *Dst = reinterpret_cast<UTF8 *>(&Out[0]);
  UTF8 *DstEnd = Dst + Out.size();

  ConversionResult CR =
      ConvertUTF16toUTF8(&Src, SrcEnd, &Dst, DstEnd, strictConversion);
  assert(CR != targetExhausted);

  if (CR != conversionOK) {
    Out.clear();
    return false;
  }

  Out.resize(reinterpret_cast<char *>(Dst) - &Out[0]);
  return true;
}
Exemple #4
0
bool mapToDimension(std::u16string& value)
{
    if (stripLeadingWhitespace(value).empty())
        return false;
    if (value[0] == '+') {
        if (value.erase(0, 1).empty())
            return false;
    }
    size_t pos = 0;
    while (value[pos] == '0')
        ++pos;
    if (0 < pos) {
        if (value.erase(0, pos).empty())
            return false;
    }
    pos = 0;
    while (isDigit(value[pos]))
        ++pos;
    if (value.length() <= pos) {
        value += u"px";
        return true;
    }
    size_t end = pos;
    if (value[pos] == '.') {
        ++pos;
        if (value.length() <= pos || !isDigit(value[pos])) {
            value.replace(end, std::u16string::npos, u"px");
            return true;
        }
        ++pos;
        while (isDigit(value[pos]))
            ++pos;
    }
    if (pos < value.length() && value[pos] == '%') {
        value.erase(++pos);
        return true;
    }
    value.replace(pos, std::u16string::npos, u"px");    // TODO: Check whether floating point length should be allowed
    return true;
}
Exemple #5
0
bool mapToInteger(std::u16string& value)
{
    if (stripLeadingWhitespace(value).empty())
        return false;
    const char16_t* input = value.c_str();
    const char16_t* end = input + value.length();
    int u;
    end = parseInt(input, end, u);
    if (!end)
        return false;
    value.erase(end - input);
    return true;
}
Exemple #6
0
std::string utf16_to_ascii8(const std::u16string& utf16_string)
{
	// Strip extended codes, map to '#' instead (placeholder)
	std::vector<u8> out;
	out.reserve(utf16_string.length() + 1);

	for (const auto& code : utf16_string)
	{
		out.push_back(code > 0xFF ? '#': (u8)code);
	}

	out.push_back(0);
	return { reinterpret_cast<char*>(out.data()) };
}
Exemple #7
0
bool UserDictionaryDecoder::DecodeArticle(
        IBitStream *bstr,
        std::u16string &res,
        std::u16string const& prefix,
        LenTable& ltArticles,
        std::vector<char32_t>& articleSymbols)
{
    unsigned len = bstr->read(16);
    if (len == 0xFFFF) {
        len = bstr->read(32);
    }
    res.clear();
    unsigned symIdx;
    std::vector<uint32_t> vec;
    while ((unsigned)res.length() < len) {
        ltArticles.Decode(*bstr, symIdx);
        unsigned sym = articleSymbols.at(symIdx);
        vec.push_back(sym);
        if (sym >= 0x10000) {
            if (sym >= 0x10040) {
                unsigned startIdx = bstr->read(BitLength(len));
                unsigned len = sym - 0x1003d;
                res += res.substr(startIdx, len);
                vec.push_back(startIdx);
            } else {
                unsigned startIdx = bstr->read(BitLength(prefix.length()));
                unsigned len = sym - 0xfffd;
                res += prefix.substr(startIdx, len);
                vec.push_back(startIdx);
            }
        } else {
            res += (char16_t)sym;
        }
    }
    return true;
}
Exemple #8
0
bool mapToPixelLength(std::u16string& value)
{
    if (stripLeadingWhitespace(value).empty())
        return false;
    const char16_t* input = value.c_str();
    const char16_t* end = input + value.length();
    int u;
    end = parseInt(input, end, u);
    if (!end || u < 0)
        return false;
    if (0 < u)
        value.replace(end - input, std::u16string::npos, u"px");
    else
        value.erase(end - input);
    return true;
}
Exemple #9
0
void FontAtlas::findNewCharacters(const std::u16string& u16Text, std::unordered_map<unsigned short, unsigned short>& charCodeMap)
{
    std::u16string newChars;
    FT_Encoding charEncoding = _fontFreeType->getEncoding();

    //find new characters
    if (_letterDefinitions.empty())
    {
        newChars = u16Text;
    }
    else
    {
        auto length = u16Text.length();
        newChars.reserve(length);
        for (size_t i = 0; i < length; ++i)
        {
            auto outIterator = _letterDefinitions.find(u16Text[i]);
            if (outIterator == _letterDefinitions.end())
            {
                newChars.push_back(u16Text[i]);
            }
        }
    }

    if (!newChars.empty())
    {
        switch (charEncoding)
        {
        case FT_ENCODING_UNICODE:
        {
            for (auto u16Code : newChars)
            {
                charCodeMap[u16Code] = u16Code;
            }
            break;
        }
        case FT_ENCODING_GB2312:
        {
            conversionU16TOGB2312(newChars, charCodeMap);
            break;
        }
        default:
            CCLOG("FontAtlas::findNewCharacters: Unsupported encoding:%d", charEncoding);
            break;
        }
    }
}
bool HTMLElementImp::toPxOrPercentage(std::u16string& value)
{
    stripLeadingAndTrailingWhitespace(value);
    if (value.empty())
        return false;
    const char16_t* s = value.c_str();
    while (*s) {
        if (*s == '%')
            break;
        if (!isDigit(*s))
            return false;
        ++s;
    }
    if (!*s) {
        value += u"px";
        return true;
    }
    assert(*s == '%');
    if (!s[1] && 1 < value.length())
        return true;
    return false;
}
Exemple #11
0
void ctr::news::add(std::u16string title, std::u16string message, void* image, u32 imageSize, bool jpeg) {
    if(!initialized) {
        ctr::err::set(initError);
        return;
    }

    ctr::err::parse(ctr::err::SOURCE_NEWS_ADD_NOTIFICATION, (u32) NEWS_AddNotification((const u16*) title.c_str(), title.length(), (const u16*) message.c_str(), message.length(), image, imageSize, jpeg));
}
Exemple #12
0
void FontAtlas::conversionU16TOGB2312(const std::u16string& u16Text, std::unordered_map<unsigned short, unsigned short>& charCodeMap)
{
    size_t strLen = u16Text.length();
    auto gb2312StrSize = strLen * 2;
    auto gb2312Text = new (std::nothrow) char[gb2312StrSize];
    memset(gb2312Text, 0, gb2312StrSize);

    switch (_fontFreeType->getEncoding())
    {
    case FT_ENCODING_GB2312:
    {
#if CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT
        WideCharToMultiByte(936, NULL, (LPCWCH)u16Text.c_str(), strLen, (LPSTR)gb2312Text, gb2312StrSize, NULL, NULL);
#elif CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
        conversionEncodingJNI((char*)u16Text.c_str(), gb2312StrSize, "UTF-16LE", gb2312Text, "GB2312");
#else
        if (_iconv == nullptr)
        {
            _iconv = iconv_open("gb2312", "utf-16le");
        }

        if (_iconv == (iconv_t)-1)
        {
            CCLOG("conversion from utf16 to gb2312 not available");
        }
        else
        {
            char* pin = (char*)u16Text.c_str();
            char* pout = gb2312Text;
            size_t inLen = strLen * 2;
            size_t outLen = gb2312StrSize;

            iconv(_iconv, (char**)&pin, &inLen, &pout, &outLen);
        }
#endif
    }
    break;
    default:
        CCLOG("Unsupported encoding:%d", _fontFreeType->getEncoding());
        break;
    }

    unsigned short gb2312Code = 0;
    unsigned char* dst = (unsigned char*)&gb2312Code;
    unsigned short u16Code;
    for (size_t index = 0, gbIndex = 0; index < strLen; ++index)
    {
        u16Code = u16Text[index];
        if (u16Code < 256)
        {
            charCodeMap[u16Code] = u16Code;
            gbIndex += 1;
        }
        else
        {
            dst[0] = gb2312Text[gbIndex + 1];
            dst[1] = gb2312Text[gbIndex];
            charCodeMap[u16Code] = gb2312Code;

            gbIndex += 2;
        }
    }

    delete[] gb2312Text;
}
Exemple #13
0
bool FontAtlas::prepareLetterDefinitions(const std::u16string& utf16String)
{
    FontFreeType* fontTTf = dynamic_cast<FontFreeType*>(_font);
    if(fontTTf == nullptr)
        return false;
    
    size_t length = utf16String.length();

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

    auto scaleFactor = CC_CONTENT_SCALE_FACTOR();
    auto  pixelFormat = fontTTf->getOutlineSize() > 0 ? Texture2D::PixelFormat::AI88 : Texture2D::PixelFormat::A8; 

    bool existNewLetter = false;
    int bottomHeight = _commonLineHeight - _fontAscender;

    float startY = _currentPageOrigY;

    for (size_t 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;
                tempDef.clipBottom     = bottomHeight - (tempDef.height + tempRect.origin.y + offsetAdjust);

                if (_currentPageOrigX + tempDef.width > CacheTextureWidth)
                {
                    _currentPageOrigY += _commonLineHeight;
                    _currentPageOrigX = 0;
                    if(_currentPageOrigY + _commonLineHeight >= CacheTextureHeight)
                    {
                        unsigned char *data = nullptr;
                        if(pixelFormat == Texture2D::PixelFormat::AI88)
                        {
                            data = _currentPageData + CacheTextureWidth * (int)startY * 2;
                        }
                        else
                        {
                            data = _currentPageData + CacheTextureWidth * (int)startY;
                        }
                        _atlasTextures[_currentPage]->updateWithData(data, 0, startY, 
                            CacheTextureWidth, CacheTextureHeight - startY);

                        startY = 0.0f;

                        _currentPageOrigY = 0;
                        memset(_currentPageData, 0, _currentPageDataSize);
                        _currentPage++;
                        auto tex = new (std::nothrow) Texture2D;
                        if (_antialiasEnabled)
                        {
                            tex->setAntiAliasTexParameters();
                        } 
                        else
                        {
                            tex->setAliasTexParameters();
                        }
                        tex->initWithData(_currentPageData, _currentPageDataSize, 
                            pixelFormat, CacheTextureWidth, CacheTextureHeight, Size(CacheTextureWidth,CacheTextureHeight) );
                        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;
                tempDef.clipBottom = 0;
                _currentPageOrigX += 1;
            }

            _fontLetterDefinitions[tempDef.letteCharUTF16] = tempDef;
        }       
    }

    if(existNewLetter)
    {
        if (_rendererRecreate)
        {
            _atlasTextures[_currentPage]->initWithData(_currentPageData, _currentPageDataSize, 
                pixelFormat, CacheTextureWidth, CacheTextureHeight, Size(CacheTextureWidth,CacheTextureHeight) );
        } 
        else
        {
            unsigned char *data = nullptr;
            if(pixelFormat == Texture2D::PixelFormat::AI88)
            {
                data = _currentPageData + CacheTextureWidth * (int)startY * 2;
            }
            else
            {
                data = _currentPageData + CacheTextureWidth * (int)startY;
            }
            _atlasTextures[_currentPage]->updateWithData(data, 0, startY, 
                CacheTextureWidth, _currentPageOrigY - startY + _commonLineHeight);
        }
    }
    return true;
}
Exemple #14
0
bool toInteger(const std::u16string& value, int& output)
{
    const char16_t* input = value.c_str();
    const char16_t* end = input + value.length();
    return parseInt(input, end, output);    // Do not care what follows after digits.
}
Exemple #15
0
void FontAtlas::conversionU16TOGB2312(const std::u16string& u16Text, std::unordered_map<unsigned short, unsigned short>& charCodeMap)
{
    size_t strLen = u16Text.length();
    auto gb2312StrSize = strLen * 2;
    auto gb2312Text = new (std::nothrow) char[gb2312StrSize];
    memset(gb2312Text, 0, gb2312StrSize);

    switch (_fontFreeType->getEncoding())
    {
    case FT_ENCODING_GB2312:
    {

        if (_iconv == nullptr)
        {
            _iconv = iconv_open("gb2312", "utf-16le");
        }

        if (_iconv == (iconv_t)-1)
        {
            OUTPUT_LOG("conversion from utf16 to gb2312 not available");
        }
        else
        {
            char* pout = gb2312Text;
            size_t inLen = strLen * 2;
            size_t outLen = gb2312StrSize;

#if _LIBICONV_VERSION == 0x109 || _LIBICONV_VERSION == 0x010F
            const char* pin = (char*)u16Text.c_str();
            iconv(_iconv, &pin, &inLen, &pout, &outLen);
#else
            char* pin = (char*)u16Text.c_str();
            iconv(_iconv, &pin, &inLen, &pout, &outLen);
#endif
        }

    }
    break;
    default:
        OUTPUT_LOG("Unsupported encoding:%d", _fontFreeType->getEncoding());
        break;
    }

    unsigned short gb2312Code = 0;
    unsigned char* dst = (unsigned char*)&gb2312Code;
    unsigned short u16Code;
    for (size_t index = 0, gbIndex = 0; index < strLen; ++index)
    {
        u16Code = u16Text[index];
        if (u16Code < 256)
        {
            charCodeMap[u16Code] = u16Code;
            gbIndex += 1;
        }
        else
        {
            dst[0] = gb2312Text[gbIndex + 1];
            dst[1] = gb2312Text[gbIndex];
            charCodeMap[u16Code] = gb2312Code;

            gbIndex += 2;
        }
    }

    delete[] gb2312Text;
}