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; }
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; }