提取TrueType字体轮廓的问题

jiajia4212 2007-04-12 10:10:57
我用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;
...全文
680 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
jiajia4212 2007-04-12
  • 打赏
  • 举报
回复
为什么要这样呢?先写GGO_BITMAP得到的不是存放位图缓冲区的大小吗?但是我是要提取矢量轮廓啊?
还有就是把那个数据类型展开,是不是重新定义一下GLYPHMETRICS?
iu_81 2007-04-12
  • 打赏
  • 举报
回复
首先是GGO_BITMAP
iu_81 2007-04-12
  • 打赏
  • 举报
回复
你仔细看看我写的
jiajia4212 2007-04-12
  • 打赏
  • 举报
回复
要重新定义那个结构GLYPHMETRICS吗?我知道那个函数要调用两次,现在就是在调用第一次获取缓冲区的时候得到的老是-1,所以不知道出了什么问题。
非常感谢你的热心回答,希望你能帮我想想到底是哪里不对
iu_81 2007-04-12
  • 打赏
  • 举报
回复
int cbBuffer=dc->GetGlyphOutline(nChar,GGO_NATIVE,&gmm,0,NULL,&mat2);
=======================================================================
调用两次GetGlyphOutline
int cbBuffer=dc->GetGlyphOutline(nChar,GGO_BITMAP,&gmm,0,NULL,&mat2);
int cbBuffer=dc->GetGlyphOutline(nChar,GGO_NATIVE,&gmm,数据缓冲区大小, 数据缓冲区,&mat2);
iu_81 2007-04-12
  • 打赏
  • 举报
回复
自定义数据类型:glyphmetrics
成员:gmblackboxx 数据类型:整数型
成员:gmblackboxy 数据类型:整数型
成员:gmptglyphorigin 数据类型:pointapi
成员:gmcellincx 数据类型:短整数型
成员:gmcellincy 数据类型:短整数型

改成:

自定义数据类型:glyphmetrics
成员:gmblackboxx 数据类型:整数型
成员:gmblackboxy 数据类型:整数型
成员:x 数据类型:整数型
成员:y 数据类型:整数型
成员:gmcellincx 数据类型:短整数型
成员:gmcellincy 数据类型:短整数型
jiajia4212 2007-04-12
  • 打赏
  • 举报
回复
不好意思,程序里面是这么写的,但是刚才粘贴的时候出错了。
还是不知道什么原因啊,字库应该是已经在操作系统中的吧,不用再设置什么了吧
缓冲区的值还是-1
iu_81 2007-04-12
  • 打赏
  • 举报
回复
MAT2 mat2 =
    {
    { 0, 1},
    { 0, 0 },
    { 0, 0 },
    { 0, 1}
    };
jiajia4212 2007-04-12
  • 打赏
  • 举报
回复
为什么我得到的缓冲区大小还是-1啊,就是说有错误
GLYPHMETRICS gm,gmm;
MAT2 mat2=
{
{0,1,}
}; {0,1,},
{0,0,},
{0,0,},


UINT nChar='A';
::memset(&gmm,0,sizeof(GLYPHMETRICS));
int cbBuffer=dc->GetGlyphOutline(nChar,GGO_NATIVE,&gmm,0,NULL,&mat2);
iu_81 2007-04-12
  • 打赏
  • 举报
回复
看这个例子
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;
}
iu_81 2007-04-12
  • 打赏
  • 举报
回复
GetGlyphOutline 数据是有一定的对齐方式,memset(&gmm,0,sizeof(GLYPHMETRICS));
不想低调 2007-04-12
  • 打赏
  • 举报
回复
帮顶
Oversense 2007-04-12
  • 打赏
  • 举报
回复
GetGlyphOutline有例子的,以前我弄过,是用的那个开源的
jiajia4212 2007-04-12
  • 打赏
  • 举报
回复
就是一个非常不正常的数,cbBuffer的值:4294967265,我定义的是DWORD
freshui 2007-04-12
  • 打赏
  • 举报
回复
不可能吧 哪能有多大?
jiajia4212 2007-04-12
  • 打赏
  • 举报
回复
没有人会吗?高手啊。。。。。。。。。。

64,683

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧