增加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 {
for(int x=0; x {
int _y = y;
unsigned int _vl = 0;
if(x {
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

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 {
for(int x=0; x {
int _y = y;
unsigned char _vl = 0;
BYTE * pData = (BYTE*)imageBuffer + dwOneLine*y + x/8;

if(x {
BYTE BitMask = (1 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;
}

你可能感兴趣的:(DI)