提取TrueType字体轮廓的问题
我用CDC的GetGlyphOutline函数提取TrueType字体的轮廓,我根据msdn上面的描述,第一次使用设置缓冲区为0,然后得到字体需要的缓冲区的大小,但是得到的缓冲区的大小是一个非常大的数,所以分配内存失败,这是为什么呢?大家帮我看看,代码如下:
MAT2 mat2;
mat2.eM11.value=1;
mat2.eM11.fract=0;
mat2.eM12.value=0;
mat2.eM12.fract=0;
mat2.eM21.value=0;
mat2.eM21.fract=0;
mat2.eM22.value=1;
mat2.eM22.fract=0;
UINT nChar= 'A ';
DWORD cbBuffer=dc-> GetGlyphOutlinenChar,GGO_NATIVE,&gmm,0,NULL,&mat2);//得到缓冲区的大小;
if(cbBuffer==GDI_ERROR)/
return;
[解决办法]
看这个例子
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;
}