根据所选择的TrueType字体生成点阵数据
2008-02-26 20:27:06 来源:WEB开发网3、通过选入字体的DC得到字体的点阵数据,这个处理依靠如下的函数, DWORD GetGlyphOutline( UINT nChar,
UINT nFormat,
LPGLYPHMETRICS lpgm,
DWORD cbBuffer,
LPVOID lpBuffer,
const MAT2 FAR* lpmat2 ) const;
Remarks
Retrieves the outline curve or bitmap for an outline character in the current font.
具体请参考 msdn 可以得到 anti-alias 等多种格式的数据。但是这个有一个问题就是如果对应一个字体的size的各个参数,这里面的麻烦很多,后来总结如下如下:
还有补充的就是 GetGlyphOutline 数据是有一定的对齐方式的,要进行一些处理,代码如下:
BOOL CreateFontMatrix(int iAA,
UINT nChar,
unsigned char **pOutPut,
int *iBytesPreLine,
int *iLine,
int *iBaseLine,
int *iBox_x,
int *iBox_y)
{
unsigned char *pBuf;
TEXTMETRIC tm;
GLYPHMETRICS glyph;
int width,height,box_x,box_y,ori_x,ori_y,size,iAdjust;
BOOL bRel = TRUE;
MAT2 mat2 =
{
{ 0, 1, },
{ 0, 0, },
{ 0, 0, },
{ 0, 1, }
};
//Get glyph outline
memset(&glyph,0,sizeof(GLYPHMETRICS));
size = m_pFontDC->GetGlyphOutline(nChar,m_nFormat,&glyph,0,NULL,&mat2);
if (size >= 0) // if char is space, the size may be zero
{
int count = 0;
int data = 0;
pBuf = new unsigned char[size];
m_pFontDC->GetTextMetrics(&tm);
m_pFontDC->GetGlyphOutline(nChar,m_nFormat,&glyph,size,pBuf,&mat2);
ori_x = glyph.gmptGlyphOrigin.x;
//if ori_x is negative,set ori_x zero
ori_x = (ori_x < 0) ? 0 : ori_x;
ori_y = tm.tmAscent - glyph.gmptGlyphOrigin.y;
box_x = glyph.gmBlackBoxX;
box_y = glyph.gmBlackBoxY;
width = glyph.gmCellIncX;
iAdjust = (box_x+3)&0xfffc; //DWORD align
if((box_x + ori_x) > width)
box_x = width - ori_x;
height= m_pLf->lfHeight;
//convert
int index = 0;
if (iAA == AA_2)
{
width = (width%4 == 0)?width/4:(width/4+1); //here,to 2bits/pix
*pOutPut = new unsigned char[width*height + 1];
memset(*pOutPut,0,width*height + 1);
//if size == 0 all data is 0
if(size > 0)
{
for (int i = 0; i < box_y; i++)
{
for (int j = 0; j < box_x; j++)
{
//int k = pBuf[i*iAdjust + j];
data = AA2_GRAG_MATRIX[pBuf[i*iAdjust + j]];
index = (i + ori_y)*width + (j + ori_x)/4;
switch((j + ori_x)%4)
{
case 0:
(*pOutPut)[index] |= (data<<6)&0xC0;
break;
case 1:
(*pOutPut)[index] |= (data<<4)&0x30;
break;
case 2:
(*pOutPut)[index] |= (data<<2)&0x0C;
break;
case 3:
(*pOutPut)[index] |= data&0x03;
break;
default:
{}
}
}//end j
}//end i
}
}//end AA 2*2
else if (iAA == AA_4)
{
width = (width%2 == 0)?width/2:(width/2+1); //here,to 4bits/pix
*pOutPut = new unsigned char[width*height + 1];
memset(*pOutPut,0,width*height + 1);
//if size == 0 all data is 0
if(size > 0)
{
for (int i = 0; i < box_y; i++)
{
for (int j = 0; j < box_x; j++)
{
ASSERT(pBuf[i*iAdjust + j] <= 17);
data = AA4_GRAG_MATRIX[pBuf[i*iAdjust + j]];
index = (i + ori_y)*width + (j + ori_x)/2;
switch((j + ori_x)%2)
{
case 0:
(*pOutPut)[index] |= (data<<4)&0xF0;
break;
case 1:
(*pOutPut)[index] |= data&0x0F;
break;
default:
{}
}
}//end j
}//end i
}
}//end AA 4*4
else //start Normal
{
//Note: monochrome bitmap,the first data in pBuff is on the Left-bottom
// one bit per pix
width = (width%8 == 0)?width/8:(width/8+1); //here,to 4bits/pix
if (width == 0)
width = 1;
*pOutPut = new unsigned char[width*height + 1];
memset(*pOutPut,0,width*height + 1);
//if size == 0 all data is 0
if(size > 0)
{
for (int i = 0; i < box_y; i++)
{
for (int j = 0; j < width; j++)
{
(*pOutPut)[(i + ori_y)*width + j] |= data<<(8-ori_x);
data = pBuf[i*(size/box_y) + j];
(*pOutPut)[(i + ori_y)*width + j] |= data>>ori_x;
}//end j
}//end i
}
}//end else(normal bitmap)
if(pBuf != NULL)
delete[] pBuf;
//set return result
*iBytesPreLine = width;
*iLine = height;
*iBaseLine = tm.tmAscent;
*iBox_x = glyph.gmCellIncX;//box_x;
*iBox_y = box_y;
bRel = TRUE;
}
else//if size
bRel = FALSE;
return bRel;
}
结束语
得于8小时之内,写于8小时之外。
更多精彩
赞助商链接