1. 程式人生 > >cocos2dx3.0的label字型去描邊

cocos2dx3.0的label字型去描邊

</pre></h4><p><pre name="code" class="cpp">

    近日,一直被3.0的字型描邊所困擾,在安卓手機下字型沒問題,挺好看,但是在iphone手機上顯示特別不清晰,一直很怪異的感覺,尤其是白色的label,後來我的同事兼師父將底層改了下(3.2之後的版本貌似就不存在這個問題了)。

       方法:找到專案/cocos2d/cocos/2d/platform目錄下的       CCDevice.h檔案   的靜態gettexturedatafortext方法改成這個(即加一個引數)

static Data getTextureDataForText(const char * text, const FontDefinition& textDefinition, TextAlign align, int &width, int &height, bool& hasPremultipliedAlpha);
,然後把相應平臺的這個函式分別增一個引數(因為只有ios好像有這個問題,所以其他的平臺暫時不用改,但是需要在功能函式新增一個實參):

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