增加GDI字体的支持,原来是那么简单

一直很想给引擎增加GDI字体的支持,不是说freetype不好,只是在Windows下我将来发布的时候可以少待带一个freetype6的库,但是freetype在linux/unix下还是不二的选择
以前一直没弄的原因还是懒,这次是没办法,在做Web3D。必须减少引擎的尺寸。没办法,只能拿掉FreeType了。
写了写,也就三个小时搞定了。世上无难事,只怕是懒人啊。

其实用到得函数只有一个,GetGlyphOutline 代码如下:

bool xGdiGlyphFontCharLoader::_loadResource(wchar_t& _char , xGdiGlyphFontChar*& pRes, int& ResSize,unsigned int arg)
{
    //if(FT_Load_Glyph( m_FT_Face, FT_Get_Char_Index( m_FT_Face, _char ), FT_LOAD_DEFAULT ))
    //    throw std::runtime_error("FT_Load_Glyph failed");

    UINT  uFormat = GGO_GRAY8_BITMAP;
    GLYPHMETRICS GlyphMetrics;
    MAT2 glyphMat = {{0,1},{0,0},{0,0},{0,1}};;

    if(GDI_ERROR == GetGlyphOutline(m_hFontDC , _char , GGO_METRICS  , &GlyphMetrics , 0 , NULL , &glyphMat ) )
        return false;

    int BufferLen = GetGlyphOutline(m_hFontDC , _char , uFormat , &GlyphMetrics , 0 , 0 , &glyphMat);
    char* imageBuffer = new char[BufferLen] ;
   
    GetGlyphOutline(m_hFontDC , _char , uFormat , &GlyphMetrics , BufferLen , imageBuffer , &glyphMat);

    if(pRes == NULL)
    {
        pRes = new xGdiGlyphFontChar(m_pRenderer ,  this );
        if(pRes == NULL)
            return false;
    }

    //取道位图数据
    //把位图数据拷贝自己定义的数据区里.这样旧可以画到需要的东西上面了。
    int width  =  GlyphMetrics.gmBlackBoxX;
    int height =  GlyphMetrics.gmBlackBoxY;
    int bitmap_width  = width;
    int bitmap_height = height;
    int bitmap_pitch  = (GlyphMetrics.gmBlackBoxX + 3) & ~3;

    pRes->m_adv_x = GlyphMetrics.gmCellIncX;
    pRes->m_adv_y = GlyphMetrics.gmCellIncY + GlyphMetrics.gmBlackBoxY;
    pRes->m_left = (float)GlyphMetrics.gmptGlyphOrigin.x;
    pRes->m_top  = (float)GlyphMetrics.gmptGlyphOrigin.y;

    int   tex_pitch =  0;
    unsigned char* tex_pixel = NULL;
    IBaseTexture* pTexture = NULL;
#ifndef _FONT_FULL_TEXTURE_
    if(pRes->m_pTexture != NULL)
    {
        pRes->m_pTexture->KillObject();
    }

    if(width == 0 || height == 0)
    {
        return true;
    }

    if(m_pRenderer->isTextureSupport( PIXELFORMAT_ALPHA8 ) )
    {
        pRes->m_pTexture = m_pRenderer->createLockableTexture(  width,height, PIXELFORMAT_ALPHA8   , false);//Alpha8);
    }                                                                                                
    else                                                                                            
    {                                                                                                
        pRes->m_pTexture = m_pRenderer->createLockableTexture(  width,height, PIXELFORMAT_B8G8R8A8 , false);//RGBA);
    }
   
    if(pRes->m_pTexture == NULL)
        return width == 0 && height == 0;

    pTexture = pRes->m_pTexture;
    xTextureLockArea lockInfo;
    pTexture->lock(eLock_WriteDiscard , lockInfo);
    tex_pixel = (unsigned char*)lockInfo.m_pixels ;
    tex_pitch = lockInfo.m_picth ;

    pRes->m_tex_w = width ;
    pRes->m_tex_h = height;

#else
    pTexture = m_pTexture;
    pRes->m_tex_idx = m_idxManager.useIndex();
    pRes->m_tex_y   = pRes->m_tex_idx / m_nCharOfRow;
    int nFontWidth  = m_tex_w / m_nCharOfRow;
    int nFontHeight = m_tex_h / m_nCharOfRow;


    pRes->m_tex_y   = nFontHeight * pRes->m_tex_y;
    pRes->m_tex_x   = (pRes->m_tex_idx % m_nCharOfRow ) * nFontWidth;

    pRes->m_tex_w = width ;
    pRes->m_tex_h = height;

    xTextureLockArea lockInfo;
    pTexture->lock(eLock_WriteDiscard , lockInfo);
    tex_pixel = (unsigned char*)lockInfo.m_pixels ;
    tex_pitch = lockInfo.m_picth ;
    if(pTexture->format() == PIXELFORMAT_B8G8R8A8)
    {
        tex_pixel += lockInfo.m_picth * pRes->m_tex_y + pRes->m_tex_x * 4;
    }
    else
    {
        tex_pixel += lockInfo.m_picth * pRes->m_tex_y + pRes->m_tex_x;
    }
   
#endif



    float grayScale = 1.0f;

    if( m_bAntilias == false ) grayScale = 1.3f;
    //灰度图
    if( uFormat == GGO_GRAY8_BITMAP )
    {
        bitmap_pitch  = (GlyphMetrics.gmBlackBoxX + 3) & ~3;;
        BYTE * lineSrc = (BYTE *)imageBuffer;

        for(int y=0; y  < height ; y++)
        {
            for(int x=0; x < width; x++)
            {
                int _y = y;
                unsigned int _vl =  0;
                if(x < bitmap_width && y < bitmap_height)
                {
                    BYTE Value = lineSrc[x];
                    _vl = (Value / 64.0f * 255);
                    if(Value > 0)
                    {
                        _vl = (int)(grayScale * _vl);
                        if(_vl > 255)
                            _vl = 255;
                    }


                }
                //if(_vl > 25 && _vl < 220) _vl = 220;


                if(pTexture->format() == PIXELFORMAT_B8G8R8A8)
                {

                    tex_pixel[(4*x + _y * tex_pitch)+0] = 0xff;
                    tex_pixel[(4*x + _y * tex_pitch)+1] = 0xff;
                    tex_pixel[(4*x + _y * tex_pitch)+2] = 0xff;
                    tex_pixel[(4*x + _y * tex_pitch)+3] = (unsigned char)_vl;
                }
                else
                {
                    tex_pixel[(1*x + _y * tex_pitch)+0] = (unsigned char)_vl;
                }               
            }

            lineSrc += bitmap_pitch;
        }
    }
    else if(uFormat == GGO_BITMAP) //单色图
    {
        int dwOneLine = (bitmap_width/8 + 3) / 4 * 4;
        for(int y=0; y  < height ; y++)
        {
            for(int x=0; x < width; x++)
            {
                int _y = y;
                unsigned char _vl =  0;
                BYTE * pData = (BYTE*)imageBuffer + dwOneLine*y + x/8;

                if(x < bitmap_width && y < bitmap_height)
                {
                     BYTE BitMask = (1 << 7-(x%8));
                     BOOL bBit =  *pData & BitMask;
                    _vl =   bBit ? 0xFFFFFFFF : 0x00000000;
                }
                unsigned int iVal = _vl; iVal = (int)(grayScale * iVal);
                if(iVal > 255) iVal = 255;

                if(pTexture->format() == PIXELFORMAT_B8G8R8A8)
                {
                    tex_pixel[(4*x + _y * tex_pitch)+0] = 0xff;
                    tex_pixel[(4*x + _y * tex_pitch)+1] = 0xff;
                    tex_pixel[(4*x + _y * tex_pitch)+2] = 0xff;
                    tex_pixel[(4*x + _y * tex_pitch)+3] = (unsigned char)iVal;
                }
                else
                {
                    tex_pixel[(1*x + _y * tex_pitch)+0] = (unsigned char)iVal;
                }

            }
        }
    }
    pTexture->unlock(lockInfo);
    pTexture->validate();
    ResSize = 1;
    return true;
}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值