cocos2dx3.0的label字型去描邊
阿新 • • 發佈:2019-02-15
</pre></h4><p><pre name="code" class="cpp">
近日,一直被3.0的字型描邊所困擾,在安卓手機下字型沒問題,挺好看,但是在iphone手機上顯示特別不清晰,一直很怪異的感覺,尤其是白色的label,後來我的同事兼師父將底層改了下(3.2之後的版本貌似就不存在這個問題了)。
方法:找到專案/cocos2d/cocos/2d/platform目錄下的 CCDevice.h檔案 的靜態gettexturedatafortext方法改成這個(即加一個引數)
,然後把相應平臺的這個函式分別增一個引數(因為只有ios好像有這個問題,所以其他的平臺暫時不用改,但是需要在功能函式新增一個實參):static Data getTextureDataForText(const char * text, const FontDefinition& textDefinition, TextAlign align, int &width, int &height, bool& hasPremultipliedAlpha);
ios/CCDevice.mm
Data Device::getTextureDataForText(const char * text, const FontDefinition& textDefinition, TextAlign align, int &width, int &height, bool& hasPremultipliedAlpha) { Data ret; do { tImageInfo info = {0}; info.width = textDefinition._dimensions.width; info.height = textDefinition._dimensions.height; info.hasShadow = textDefinition._shadow._shadowEnabled; info.shadowOffset.width = textDefinition._shadow._shadowOffset.width; info.shadowOffset.height = textDefinition._shadow._shadowOffset.height; info.shadowBlur = textDefinition._shadow._shadowBlur; info.shadowOpacity = textDefinition._shadow._shadowOpacity; info.hasStroke = textDefinition._stroke._strokeEnabled; info.strokeColorR = textDefinition._stroke._strokeColor.r / 255.0f; info.strokeColorG = textDefinition._stroke._strokeColor.g / 255.0f; info.strokeColorB = textDefinition._stroke._strokeColor.b / 255.0f; info.strokeSize = textDefinition._stroke._strokeSize; info.tintColorR = textDefinition._fontFillColor.r / 255.0f; info.tintColorG = textDefinition._fontFillColor.g / 255.0f; info.tintColorB = textDefinition._fontFillColor.b / 255.0f; if (! _initWithString(text, align, textDefinition._fontName.c_str(), textDefinition._fontSize, &info)) { break; } height = (short)info.height; width = (short)info.width; ret.fastSet(info.data,width * height * 4); hasPremultipliedAlpha = true; } while (0); return ret; }
win32/CCDevice.cpp
Data Device::getTextureDataForText(const char * text, const FontDefinition& textDefinition, TextAlign align, int &width, int &height, bool& hasPremultipliedAlpha) { Data ret; do { BitmapDC& dc = sharedBitmapDC(); if (! dc.setFont(textDefinition._fontName.c_str(), textDefinition._fontSize)) { log("Can't found font(%s), use system default", textDefinition._fontName.c_str()); } // draw text SIZE size = {textDefinition._dimensions.width, textDefinition._dimensions.height}; CC_BREAK_IF(! dc.drawText(text, size, align)); int dataLen = size.cx * size.cy * 4; unsigned char* dataBuf = (unsigned char*)malloc(sizeof(unsigned char) * dataLen); CC_BREAK_IF(! dataBuf); struct { BITMAPINFOHEADER bmiHeader; int mask[4]; } bi = {0}; bi.bmiHeader.biSize = sizeof(bi.bmiHeader); CC_BREAK_IF(! GetDIBits(dc.getDC(), dc.getBitmap(), 0, 0, NULL, (LPBITMAPINFO)&bi, DIB_RGB_COLORS)); width = (short)size.cx; height = (short)size.cy; // copy pixed data bi.bmiHeader.biHeight = (bi.bmiHeader.biHeight > 0) ? - bi.bmiHeader.biHeight : bi.bmiHeader.biHeight; GetDIBits(dc.getDC(), dc.getBitmap(), 0, height, dataBuf, (LPBITMAPINFO)&bi, DIB_RGB_COLORS); // change pixel's alpha value to 255, when it's RGB != 0 COLORREF * pPixel = NULL; for (int y = 0; y < height; ++y) { pPixel = (COLORREF *)dataBuf + y * width; for (int x = 0; x < width; ++x) { COLORREF& clr = *pPixel; clr = (0xffffff | (GetRValue(clr) << 24)); ++pPixel; } } ret.fastSet(dataBuf,dataLen); } while (0); return ret; }
最後,將CCTexture2D.cpp的initWithString(const char *text, const FontDefinition& textDefinition)方法改成:
bool Texture2D::initWithString(const char *text, const FontDefinition& textDefinition)
{
if(!text || 0 == strlen(text))
{
return false;
}
#if CC_ENABLE_CACHE_TEXTURE_DATA
// cache the texture data
VolatileTextureMgr::addStringTexture(this, text, textDefinition);
#endif
bool ret = false;
Device::TextAlign align;
if (TextVAlignment::TOP == textDefinition._vertAlignment)
{
align = (TextHAlignment::CENTER == textDefinition._alignment) ? Device::TextAlign::TOP
: (TextHAlignment::LEFT == textDefinition._alignment) ? Device::TextAlign::TOP_LEFT : Device::TextAlign::TOP_RIGHT;
}
else if (TextVAlignment::CENTER == textDefinition._vertAlignment)
{
align = (TextHAlignment::CENTER == textDefinition._alignment) ? Device::TextAlign::CENTER
: (TextHAlignment::LEFT == textDefinition._alignment) ? Device::TextAlign::LEFT : Device::TextAlign::RIGHT;
}
else if (TextVAlignment::BOTTOM == textDefinition._vertAlignment)
{
align = (TextHAlignment::CENTER == textDefinition._alignment) ? Device::TextAlign::BOTTOM
: (TextHAlignment::LEFT == textDefinition._alignment) ? Device::TextAlign::BOTTOM_LEFT : Device::TextAlign::BOTTOM_RIGHT;
}
else
{
CCASSERT(false, "Not supported alignment format!");
return false;
}
#if (CC_TARGET_PLATFORM != CC_PLATFORM_ANDROID) && (CC_TARGET_PLATFORM != CC_PLATFORM_IOS)
CCASSERT(textDefinition._stroke._strokeEnabled == false, "Currently stroke only supported on iOS and Android!");
#endif
PixelFormat pixelFormat = g_defaultAlphaPixelFormat;
unsigned char* outTempData = nullptr;
ssize_t outTempDataLen = 0;
int imageWidth;
int imageHeight;
auto textDef = textDefinition;
auto contentScaleFactor = CC_CONTENT_SCALE_FACTOR();
textDef._fontSize *= contentScaleFactor;
textDef._dimensions.width *= contentScaleFactor;
textDef._dimensions.height *= contentScaleFactor;
textDef._stroke._strokeSize *= contentScaleFactor;
textDef._shadow._shadowEnabled = false;
bool hasPremultipliedAlpha;
Data outData = Device::getTextureDataForText(text, textDef, align, imageWidth, imageHeight, hasPremultipliedAlpha);
if(outData.isNull())
{
return false;
}
Size imageSize = Size((float)imageWidth, (float)imageHeight);
pixelFormat = convertDataToFormat(outData.getBytes(), imageWidth*imageHeight*4, PixelFormat::RGBA8888, pixelFormat, &outTempData, &outTempDataLen);
ret = initWithData(outTempData, outTempDataLen, pixelFormat, imageWidth, imageHeight, imageSize);
if (outTempData != nullptr && outTempData != outData.getBytes())
{
free(outTempData);
}
_hasPremultipliedAlpha = hasPremultipliedAlpha;
return ret;
}