mirror of https://github.com/axmolengine/axmol.git
Label:support font that contains GB2312 char map.
This commit is contained in:
parent
3cc039b063
commit
9edd66d4a7
|
@ -24,6 +24,11 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include "2d/CCFontAtlas.h"
|
||||
#if CC_TARGET_PLATFORM != CC_PLATFORM_WIN32 && CC_TARGET_PLATFORM != CC_PLATFORM_WINRT && CC_TARGET_PLATFORM != CC_PLATFORM_ANDROID
|
||||
#include <iconv.h>
|
||||
#elif CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
|
||||
#include "android/jni/Java_org_cocos2dx_lib_Cocos2dxHelper.h"
|
||||
#endif
|
||||
#include "2d/CCFontFreeType.h"
|
||||
#include "base/ccUTF8.h"
|
||||
#include "base/CCDirector.h"
|
||||
|
@ -31,7 +36,6 @@
|
|||
#include "base/CCEventDispatcher.h"
|
||||
#include "base/CCEventType.h"
|
||||
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
const int FontAtlas::CacheTextureWidth = 512;
|
||||
|
@ -41,6 +45,8 @@ const char* FontAtlas::CMD_RESET_FONTATLAS = "__cc_RESET_FONTATLAS";
|
|||
|
||||
FontAtlas::FontAtlas(Font &theFont)
|
||||
: _font(&theFont)
|
||||
, _fontFreeType(nullptr)
|
||||
, _iconv(nullptr)
|
||||
, _currentPageData(nullptr)
|
||||
, _fontAscender(0)
|
||||
, _rendererRecreatedListener(nullptr)
|
||||
|
@ -49,23 +55,23 @@ FontAtlas::FontAtlas(Font &theFont)
|
|||
{
|
||||
_font->retain();
|
||||
|
||||
FontFreeType* fontTTf = dynamic_cast<FontFreeType*>(_font);
|
||||
if (fontTTf)
|
||||
_fontFreeType = dynamic_cast<FontFreeType*>(_font);
|
||||
if (_fontFreeType)
|
||||
{
|
||||
_lineHeight = _font->getFontMaxHeight();
|
||||
_fontAscender = fontTTf->getFontAscender();
|
||||
_fontAscender = _fontFreeType->getFontAscender();
|
||||
auto texture = new (std::nothrow) Texture2D;
|
||||
_currentPage = 0;
|
||||
_currentPageOrigX = 0;
|
||||
_currentPageOrigY = 0;
|
||||
_letterPadding = 0;
|
||||
|
||||
if(fontTTf->isDistanceFieldEnabled())
|
||||
if (_fontFreeType->isDistanceFieldEnabled())
|
||||
{
|
||||
_letterPadding += 2 * FontFreeType::DistanceMapSpread;
|
||||
}
|
||||
_currentPageDataSize = CacheTextureWidth * CacheTextureHeight;
|
||||
auto outlineSize = fontTTf->getOutlineSize();
|
||||
auto outlineSize = _fontFreeType->getOutlineSize();
|
||||
if(outlineSize > 0)
|
||||
{
|
||||
_lineHeight += 2 * outlineSize;
|
||||
|
@ -94,8 +100,7 @@ FontAtlas::FontAtlas(Font &theFont)
|
|||
FontAtlas::~FontAtlas()
|
||||
{
|
||||
#if CC_ENABLE_CACHE_TEXTURE_DATA
|
||||
FontFreeType* fontTTf = dynamic_cast<FontFreeType*>(_font);
|
||||
if (fontTTf && _rendererRecreatedListener)
|
||||
if (_fontFreeType && _rendererRecreatedListener)
|
||||
{
|
||||
auto eventDispatcher = Director::getInstance()->getEventDispatcher();
|
||||
eventDispatcher->removeEventListener(_rendererRecreatedListener);
|
||||
|
@ -107,6 +112,14 @@ FontAtlas::~FontAtlas()
|
|||
relaseTextures();
|
||||
|
||||
delete []_currentPageData;
|
||||
|
||||
#if CC_TARGET_PLATFORM != CC_PLATFORM_WIN32 && CC_TARGET_PLATFORM != CC_PLATFORM_WINRT && CC_TARGET_PLATFORM != CC_PLATFORM_ANDROID
|
||||
if (_iconv)
|
||||
{
|
||||
iconv_close(_iconv);
|
||||
_iconv = nullptr;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void FontAtlas::relaseTextures()
|
||||
|
@ -120,8 +133,7 @@ void FontAtlas::relaseTextures()
|
|||
|
||||
void FontAtlas::purgeTexturesAtlas()
|
||||
{
|
||||
FontFreeType* fontTTf = dynamic_cast<FontFreeType*>(_font);
|
||||
if (fontTTf && _atlasTextures.size() > 1)
|
||||
if (_fontFreeType && _atlasTextures.size() > 1)
|
||||
{
|
||||
auto eventDispatcher = Director::getInstance()->getEventDispatcher();
|
||||
eventDispatcher->dispatchCustomEvent(CMD_PURGE_FONTATLAS,this);
|
||||
|
@ -131,8 +143,7 @@ void FontAtlas::purgeTexturesAtlas()
|
|||
|
||||
void FontAtlas::listenRendererRecreated(EventCustom *event)
|
||||
{
|
||||
FontFreeType* fontTTf = dynamic_cast<FontFreeType*>(_font);
|
||||
if (fontTTf)
|
||||
if (_fontFreeType)
|
||||
{
|
||||
auto eventDispatcher = Director::getInstance()->getEventDispatcher();
|
||||
eventDispatcher->dispatchCustomEvent(CMD_PURGE_FONTATLAS,this);
|
||||
|
@ -160,13 +171,133 @@ bool FontAtlas::getLetterDefinitionForChar(char16_t utf16Char, FontLetterDefinit
|
|||
}
|
||||
}
|
||||
|
||||
bool FontAtlas::prepareLetterDefinitions(const std::u16string& utf16String)
|
||||
void FontAtlas::conversionU16TOGB2312(const std::u16string& u16Text, std::unordered_map<unsigned short, unsigned short>& charCodeMap)
|
||||
{
|
||||
FontFreeType* fontTTf = dynamic_cast<FontFreeType*>(_font);
|
||||
if(fontTTf == nullptr)
|
||||
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;
|
||||
}
|
||||
|
||||
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.resize(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 FontAtlas::prepareLetterDefinitions(const std::u16string& utf16Text)
|
||||
{
|
||||
if (_fontFreeType == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t length = utf16String.length();
|
||||
std::unordered_map<unsigned short, unsigned short> codeMapOfNewChar;
|
||||
findNewCharacters(utf16Text, codeMapOfNewChar);
|
||||
if (codeMapOfNewChar.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
float offsetAdjust = _letterPadding / 2;
|
||||
long bitmapWidth;
|
||||
|
@ -175,117 +306,106 @@ bool FontAtlas::prepareLetterDefinitions(const std::u16string& utf16String)
|
|||
FontLetterDefinition tempDef;
|
||||
|
||||
auto scaleFactor = CC_CONTENT_SCALE_FACTOR();
|
||||
auto pixelFormat = fontTTf->getOutlineSize() > 0 ? Texture2D::PixelFormat::AI88 : Texture2D::PixelFormat::A8;
|
||||
auto pixelFormat = _fontFreeType->getOutlineSize() > 0 ? Texture2D::PixelFormat::AI88 : Texture2D::PixelFormat::A8;
|
||||
|
||||
bool existNewLetter = false;
|
||||
float startY = _currentPageOrigY;
|
||||
|
||||
for (size_t i = 0; i < length; ++i)
|
||||
for (auto&& it : codeMapOfNewChar)
|
||||
{
|
||||
auto outIterator = _letterDefinitions.find(utf16String[i]);
|
||||
auto bitmap = _fontFreeType->getGlyphBitmap(it.second, bitmapWidth, bitmapHeight, tempRect, tempDef.xAdvance);
|
||||
if (bitmap && bitmapWidth > 0 && bitmapHeight > 0)
|
||||
{
|
||||
tempDef.validDefinition = true;
|
||||
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 (outIterator == _letterDefinitions.end())
|
||||
{
|
||||
existNewLetter = true;
|
||||
|
||||
auto bitmap = fontTTf->getGlyphBitmap(utf16String[i],bitmapWidth,bitmapHeight,tempRect,tempDef.xAdvance);
|
||||
if (bitmap && bitmapWidth > 0 && bitmapHeight > 0)
|
||||
if (bitmapHeight > _currLineHeight)
|
||||
{
|
||||
tempDef.validDefinition = true;
|
||||
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 (bitmapHeight > _currLineHeight)
|
||||
_currLineHeight = static_cast<int>(bitmapHeight)+1;
|
||||
}
|
||||
if (_currentPageOrigX + tempDef.width > CacheTextureWidth)
|
||||
{
|
||||
_currentPageOrigY += _currLineHeight;
|
||||
_currLineHeight = 0;
|
||||
_currentPageOrigX = 0;
|
||||
if (_currentPageOrigY + _lineHeight >= CacheTextureHeight)
|
||||
{
|
||||
_currLineHeight = static_cast<int>(bitmapHeight) + 1;
|
||||
}
|
||||
if (_currentPageOrigX + tempDef.width > CacheTextureWidth)
|
||||
{
|
||||
_currentPageOrigY += _currLineHeight;
|
||||
_currLineHeight = 0;
|
||||
_currentPageOrigX = 0;
|
||||
if(_currentPageOrigY + _lineHeight >= CacheTextureHeight)
|
||||
unsigned char *data = nullptr;
|
||||
if (pixelFormat == Texture2D::PixelFormat::AI88)
|
||||
{
|
||||
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);
|
||||
data = _currentPageData + CacheTextureWidth * (int)startY * 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
data = _currentPageData + CacheTextureWidth * (int)startY;
|
||||
}
|
||||
_atlasTextures[_currentPage]->updateWithData(data, 0, startY,
|
||||
CacheTextureWidth, CacheTextureHeight - startY);
|
||||
|
||||
startY = 0.0f;
|
||||
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();
|
||||
}
|
||||
_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;
|
||||
_fontFreeType->renderCharAt(_currentPageData, _currentPageOrigX, _currentPageOrigY, bitmap, bitmapWidth, bitmapHeight);
|
||||
|
||||
tempDef.width = 0;
|
||||
tempDef.height = 0;
|
||||
tempDef.U = 0;
|
||||
tempDef.V = 0;
|
||||
tempDef.offsetX = 0;
|
||||
tempDef.offsetY = 0;
|
||||
tempDef.textureID = 0;
|
||||
_currentPageOrigX += 1;
|
||||
}
|
||||
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;
|
||||
|
||||
_letterDefinitions[utf16String[i]] = tempDef;
|
||||
}
|
||||
tempDef.width = 0;
|
||||
tempDef.height = 0;
|
||||
tempDef.U = 0;
|
||||
tempDef.V = 0;
|
||||
tempDef.offsetX = 0;
|
||||
tempDef.offsetY = 0;
|
||||
tempDef.textureID = 0;
|
||||
_currentPageOrigX += 1;
|
||||
}
|
||||
|
||||
_letterDefinitions[it.first] = tempDef;
|
||||
}
|
||||
|
||||
if(existNewLetter)
|
||||
unsigned char *data = nullptr;
|
||||
if (pixelFormat == Texture2D::PixelFormat::AI88)
|
||||
{
|
||||
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 + _lineHeight);
|
||||
data = _currentPageData + CacheTextureWidth * (int)startY * 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
data = _currentPageData + CacheTextureWidth * (int)startY;
|
||||
}
|
||||
_atlasTextures[_currentPage]->updateWithData(data, 0, startY, CacheTextureWidth, _currentPageOrigY - startY + _lineHeight);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ class Font;
|
|||
class Texture2D;
|
||||
class EventCustom;
|
||||
class EventListenerCustom;
|
||||
class FontFreeType;
|
||||
|
||||
struct FontLetterDefinition
|
||||
{
|
||||
|
@ -109,10 +110,17 @@ public:
|
|||
|
||||
protected:
|
||||
void relaseTextures();
|
||||
|
||||
void findNewCharacters(const std::u16string& u16Text, std::unordered_map<unsigned short, unsigned short>& charCodeMap);
|
||||
|
||||
void conversionU16TOGB2312(const std::u16string& u16Text, std::unordered_map<unsigned short, unsigned short>& charCodeMap);
|
||||
|
||||
std::unordered_map<ssize_t, Texture2D*> _atlasTextures;
|
||||
std::unordered_map<char16_t, FontLetterDefinition> _letterDefinitions;
|
||||
float _lineHeight;
|
||||
Font* _font;
|
||||
FontFreeType* _fontFreeType;
|
||||
void* _iconv;
|
||||
|
||||
// Dynamic GlyphCollection related stuff
|
||||
int _currentPage;
|
||||
|
|
|
@ -99,6 +99,7 @@ FontFreeType::FontFreeType(bool distanceFieldEnabled /* = false */,int outline /
|
|||
, _outlineSize(0.0f)
|
||||
, _lineHeight(0)
|
||||
, _fontAtlas(nullptr)
|
||||
, _encoding(FT_ENCODING_UNICODE)
|
||||
{
|
||||
if (outline > 0)
|
||||
{
|
||||
|
@ -154,7 +155,8 @@ bool FontFreeType::createFontObject(const std::string &fontName, int fontSize)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (FT_Select_Charmap(face, face->charmaps[foundIndex]->encoding))
|
||||
_encoding = face->charmaps[foundIndex]->encoding;
|
||||
if (FT_Select_Charmap(face, _encoding))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -53,35 +53,38 @@ class CC_DLL FontFreeType : public Font
|
|||
public:
|
||||
static const int DistanceMapSpread;
|
||||
|
||||
static FontFreeType * create(const std::string &fontName, int fontSize, GlyphCollection glyphs, const char *customGlyphs,bool distanceFieldEnabled = false,int outline = 0);
|
||||
static FontFreeType* create(const std::string &fontName, int fontSize, GlyphCollection glyphs,
|
||||
const char *customGlyphs,bool distanceFieldEnabled = false,int outline = 0);
|
||||
|
||||
static void shutdownFreeType();
|
||||
|
||||
bool isDistanceFieldEnabled() const { return _distanceFieldEnabled;}
|
||||
float getOutlineSize() const { return _outlineSize; }
|
||||
void renderCharAt(unsigned char *dest,int posX, int posY, unsigned char* bitmap,long bitmapWidth,long bitmapHeight);
|
||||
bool isDistanceFieldEnabled() const { return _distanceFieldEnabled;}
|
||||
|
||||
virtual FontAtlas * createFontAtlas() override;
|
||||
virtual int * getHorizontalKerningForTextUTF16(const std::u16string& text, int &outNumLetters) const override;
|
||||
|
||||
unsigned char * getGlyphBitmap(unsigned short theChar, long &outWidth, long &outHeight, Rect &outRect,int &xAdvance);
|
||||
|
||||
virtual int getFontMaxHeight() const override { return _lineHeight; }
|
||||
virtual int getFontAscender() const;
|
||||
float getOutlineSize() const { return _outlineSize; }
|
||||
|
||||
protected:
|
||||
void renderCharAt(unsigned char *dest,int posX, int posY, unsigned char* bitmap,long bitmapWidth,long bitmapHeight);
|
||||
|
||||
FT_Encoding getEncoding() const { return _encoding; }
|
||||
|
||||
int* getHorizontalKerningForTextUTF16(const std::u16string& text, int &outNumLetters) const override;
|
||||
|
||||
FontFreeType(bool distanceFieldEnabled = false,int outline = 0);
|
||||
virtual ~FontFreeType();
|
||||
bool createFontObject(const std::string &fontName, int fontSize);
|
||||
unsigned char* getGlyphBitmap(unsigned short theChar, long &outWidth, long &outHeight, Rect &outRect,int &xAdvance);
|
||||
|
||||
int getFontAscender() const;
|
||||
|
||||
virtual FontAtlas* createFontAtlas() override;
|
||||
virtual int getFontMaxHeight() const override { return _lineHeight; }
|
||||
private:
|
||||
FontFreeType(bool distanceFieldEnabled = false, int outline = 0);
|
||||
virtual ~FontFreeType();
|
||||
|
||||
bool createFontObject(const std::string &fontName, int fontSize);
|
||||
|
||||
bool initFreeType();
|
||||
FT_Library getFTLibrary();
|
||||
|
||||
int getHorizontalKerningForChars(unsigned short firstChar, unsigned short secondChar) const;
|
||||
unsigned char * getGlyphBitmapWithOutline(unsigned short theChar, FT_BBox &bbox);
|
||||
int getHorizontalKerningForChars(unsigned short firstChar, unsigned short secondChar) const;
|
||||
unsigned char* getGlyphBitmapWithOutline(unsigned short code, FT_BBox &bbox);
|
||||
|
||||
static FT_Library _FTlibrary;
|
||||
static bool _FTInitialized;
|
||||
|
@ -92,6 +95,8 @@ private:
|
|||
float _outlineSize;
|
||||
int _lineHeight;
|
||||
FontAtlas* _fontAtlas;
|
||||
|
||||
FT_Encoding _encoding;
|
||||
};
|
||||
|
||||
/// @endcond
|
||||
|
|
|
@ -531,6 +531,18 @@ public class Cocos2dxHelper {
|
|||
editor.remove(key);
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
public static byte[] conversionEncoding(byte[] text, String fromCharset,String newCharset)
|
||||
{
|
||||
try {
|
||||
String str = new String(text,fromCharset);
|
||||
return str.getBytes(newCharset);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// ===========================================================
|
||||
// Inner and Anonymous Classes
|
||||
|
|
|
@ -413,3 +413,25 @@ void deleteValueForKeyJNI(const char* key)
|
|||
t.env->DeleteLocalRef(stringArg1);
|
||||
}
|
||||
}
|
||||
|
||||
void conversionEncodingJNI(const char* src, int byteSize, const char* fromCharset, char* dst, const char* newCharset)
|
||||
{
|
||||
JniMethodInfo methodInfo;
|
||||
|
||||
if (JniHelper::getStaticMethodInfo(methodInfo, CLASS_NAME, "conversionEncoding", "([BLjava/lang/String;Ljava/lang/String;)[B")) {
|
||||
jbyteArray strArray = methodInfo.env->NewByteArray(byteSize);
|
||||
methodInfo.env->SetByteArrayRegion(strArray, 0, byteSize, reinterpret_cast<const jbyte*>(src));
|
||||
|
||||
jstring stringArg1 = methodInfo.env->NewStringUTF(fromCharset);
|
||||
jstring stringArg2 = methodInfo.env->NewStringUTF(newCharset);
|
||||
|
||||
jbyteArray newArray = (jbyteArray)methodInfo.env->CallStaticObjectMethod(methodInfo.classID, methodInfo.methodID, strArray, stringArg1, stringArg2);
|
||||
jsize theArrayLen = methodInfo.env->GetArrayLength(newArray);
|
||||
methodInfo.env->GetByteArrayRegion(newArray, 0, theArrayLen, (jbyte*)dst);
|
||||
|
||||
methodInfo.env->DeleteLocalRef(strArray);
|
||||
methodInfo.env->DeleteLocalRef(stringArg1);
|
||||
methodInfo.env->DeleteLocalRef(stringArg2);
|
||||
methodInfo.env->DeleteLocalRef(methodInfo.classID);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,4 +54,7 @@ extern void setFloatForKeyJNI(const char* key, float value);
|
|||
extern void setDoubleForKeyJNI(const char* key, double value);
|
||||
extern void setStringForKeyJNI(const char* key, const char* value);
|
||||
extern void deleteValueForKeyJNI(const char* key);
|
||||
|
||||
extern void conversionEncodingJNI(const char* src, int byteSize, const char* fromCharset, char* dst, const char* newCharset);
|
||||
|
||||
#endif /* __Java_org_cocos2dx_lib_Cocos2dxHelper_H__ */
|
||||
|
|
Loading…
Reference in New Issue